From 7a767e3c540b2fdaf227002b5010c3106b5b97f5 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Thu, 22 Feb 2024 22:22:54 +0100 Subject: limit redirects, filesize --- helld.py | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 helld.py (limited to 'helld.py') diff --git a/helld.py b/helld.py new file mode 100644 index 0000000..68d24ac --- /dev/null +++ b/helld.py @@ -0,0 +1,93 @@ +# Hellish Gemini daemon, in both behaviour and code quality. +# +# openssl req -newkey rsa:4096 -nodes -keyout key.pem -nodes -x509 -out cert.pem +# python3 helld.py cert.pem key.pem + +import socket +import threading +import socketserver +import ssl +import sys +import time +import random +from urllib.parse import urlparse + +handlers = [] + +def register(addr): + def dec(fn): + handlers.append((addr, fn)) + return dec + +@register('/normal') +def normal(s, _): + s.sendall(b'20 text/gemini\r\n# hello\nnothing strange going on here\n') + +@register('/noclose') +def noclose(s, rh): + s.sendall(b'20 text/gemini\r\nquick before the connection is killed i need to tell you tha') + close(rh.request) + +@register('/sleep1') +def sleep1(s, rh): + s.sendall(b'20 text/gemini\r\nabout to take a nap') + time.sleep(120) + +@register('/sleep2') +def sleep(s, rh): + time.sleep(120) + s.sendall(b'20 text/gemini\r\ntook a nap') + +@register('/128mb') +def lotsofdata(s, rh): + s.sendall(b'20 text/gemini\r\n') + for n in range(128): + s.sendall(b'lol ' * (1024 * 1024 // 4)) + +@register('/4mb') +def sensibleamountofdata(s, rh): + buffer = b'20 text/gemini\r\n' + b'lol ' * (1024 * 1024) + buffer = buffer[:4*1024*1024] + s.sendall(buffer) + +@register('/over4mb') +def nonsensibleamountofdata(s, rh): + buffer = b'20 text/gemini\r\n' + b'lol ' * (1024 * 1024) + buffer = buffer[:4*1024*1024+1] + s.sendall(buffer) + +@register('/loop') +def loop(s, rh): + s.sendall(f'30 /loop/{random.randint(0, 2**32)}\r\n'.encode('utf-8')) + +@register('/index') +def index(s, rh): + s.sendall(b'20 text/gemini\r\n') + for addr, _ in handlers: + s.sendall(f'=> {addr}\n'.encode('utf-8')) + +@register('') +def toindex(s, rh): + s.sendall(b'30 /index\r\n') + +class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): + def handle(self): + s = context.wrap_socket(self.request, server_side=True) + req = s.read().decode('utf-8').rstrip('\r\n') + print(req) + req = urlparse(req) + for addr, fn in handlers: + if req.path.startswith(addr): + fn(s, self) + break + +class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): + pass + +if __name__ == "__main__": + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + context.load_cert_chain(sys.argv[1], sys.argv[2]) + + ThreadedTCPServer.allow_reuse_address = True + server = ThreadedTCPServer(('0.0.0.0', 1965), ThreadedTCPRequestHandler) + server.serve_forever() -- cgit 1.4.1-2-gfad0