💾 Archived View for gem.rmgr.dev › files › gemring.py captured on 2024-07-08 at 23:37:07.

View Raw

More Information

⬅️ Previous capture (2022-04-28)

-=-=-=-=-=-=-

#Usage: python3 gemrng.py --cert /path/to/cert.crt --key /path/to/key.key --port 1965 --list /path/to/list.txt
#This is super duper alpha software
import ssl
import socket
import socketserver
import re
from urllib.parse import urlparse
import argparse

parser = argparse.ArgumentParser(description='Run a gemring on the Gemini protocol')
parser.add_argument('--cert', type=str,
                   help='certificate location for the server', required=True)
parser.add_argument('--key', type=str,
                   help='private key location for the server', required=True)
parser.add_argument('--port', type=int, default=1965,
                   help='port to run on (default: 1965)')
parser.add_argument('--list', type=str, default="ring.txt",
                   help='text file containing a list of gemini capsules to link to (default: ring.txt)')


args = parser.parse_args()

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(args.cert, args.key)

NO_SITE_FOUND = b'59 NO_SITE_FOUND\r\n' 
MAX_REQUEST_LENGTH = 1024
ring_data = []
with open (args.list, "r") as myfile:
    ring_data=myfile.readlines()
    
with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
    sock.bind(('0.0.0.0', args.port))
    sock.listen(5)
    while True:
        try:
            sockconn, addr = sock.accept()
            ssl_socket = context.wrap_socket(sockconn, server_side=True)
            request = ssl_socket.recv(MAX_REQUEST_LENGTH)
            url = urlparse(request)
            path = url.path.decode('ascii').rstrip()
            if len(path) > 0 and path[0] == '/':
                x = int(re.search("\d",path).group(0))
                code = "30 "
                meta = ""
                #If we go beyond the last record, loop to zero
                if "next" in path:
                    if (x + 1) < len(ring_data):
                        meta = ring_data[x+1]
                    elif (x + 1 >= len(ring_data)):
                        meta = ring_data[0]
                #If we go below zero, loop to the last record
                elif "prev" in path:
                    if (x - 1) >= 0:
                        meta = ring_data[x-1]
                    elif (x - 1) < 0:
                        meta = ring_data[len(ring_data) - 1]
                response = code + meta + "\r\n"
                print(response)
                if len(meta) == 0:
                    ssl_socket.send(NO_SITE_FOUND)
                else:
                    ssl_socket.send(response.encode('utf-8'))
            else:
                ssl_socket.send(NO_SITE_FOUND)
            ssl_socket.close()
        except socket.error:
            print ('err')
        except KeyboardInterrupt:
            print("shutting down")
            sock.close()
            break;