diff options
author | dzwdz | 2024-02-22 22:22:54 +0100 |
---|---|---|
committer | dzwdz | 2024-02-22 22:22:54 +0100 |
commit | 7a767e3c540b2fdaf227002b5010c3106b5b97f5 (patch) | |
tree | d1ec0931e9c04c6d33f2fd0a16d09427e48ba40e /helld.py | |
parent | c88059af91bb201b5d27e3cbf3166d8840c3f376 (diff) |
limit redirects, filesize
Diffstat (limited to 'helld.py')
-rw-r--r-- | helld.py | 93 |
1 files changed, 93 insertions, 0 deletions
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() |