#!/usr/bin/python3 import asyncio, traceback, socket, ssl from urllib.parse import urlparse, quote from flask import Flask, request, redirect, send_file, Response from hypercorn.config import Config from hypercorn.asyncio import serve app = Flask(__name__) @app.route("/") def root(): return send_file("home.html") @app.route("/external.png") def external(): return send_file("external.png") @app.route("/cross-server.png") def crosserver(): return send_file("cross-server.png") @app.route("/style.css") def style(): return send_file("style.css") @app.route("/gem") def relay(): url = request.args.get('gemini') queries = request.args.get('query') if url == None: return redirect("/") code = "

Something went wrong...

\n" title = "Something went wrong..." print("GET " + url + "?" + queries) try: gsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) fulladdr = "gemini://" + url + ("?" + queries if queries != None else "") gemsocket = ssl._create_unverified_context().wrap_socket(gsocket, server_hostname=urlparse(fulladdr).hostname) gemsocket.connect((urlparse(fulladdr).hostname, 1965)) gemsocket.send(bytes(fulladdr + "\r\n", "UTF-8")) received = "" mimetype = "" gemraw = bytearray() num = 0 ok = False binary = False while True: gemresponse = gemsocket.recv(2048) try: if num == 0: try: mimetype = gemresponse.decode().replace("\r","").split("\n")[0].split(" ")[1].split(";")[0] ok = gemresponse.decode().replace("\r","").split("\n")[0].split(" ")[0][0] == "2" print("Non-ordinary type! " + mimetype) except: pass elif num >= 1 and ok and not mimetype in ["text/gemini", ""]: for i in gemresponse: gemraw.append(i) try: if gemresponse.decode() != "": received += gemresponse.decode() else: break except: binary = True num+=1 except: return f'\nSomething went wrong...

Something went wrong...

The file that the Gemini server sent couldn\'t be decoded by Gem2Browser.

' print(mimetype) if binary: return Response(bytes(gemraw), mimetype="text/gemini" if mimetype=="" else mimetype) received = received.replace("\r", "") firstline = True redirected = False gemtext = True code = "" escaped = False for i in received.split("\n"): i = i.replace("<", "<") if firstline: if i.split(" ")[0][0] == "3": if i.split(" ")[1][0] == "/": return redirect("/gem?gemini=" + urlparse(fulladdr).hostname + quote(i.split(" ")[1], safe='')) return redirect("/gem?gemini=" + quote(i.split(" ")[1][9:], safe='')) elif i.split(" ")[0][0] == "1": return f'\nInput required

Input required

The specified Gemini server wants more data:

{i}




' elif i.split(" ")[0][0] != "2": return f'\nSomething went wrong...

Something went wrong...

The specified Gemini server returned a status of: {i}

' else: firstline = False if i.split(" ")[1].split(";")[0] != "text/gemini": print("Unrecognised type: " + i.split(" ")[1]) return Response(" ".join(received.split("\n")[1:]), mimetype=i.split(" ")[1]) else: if escaped: if i[0:3] == "```": code += "\n" escaped = False else: code += i + "\n" else: if i[0:2] == "# ": if title == "Something went wrong...": title = i[2:] temp = i[2:] code += f"

{temp}

\n" elif i[0:3] == "## ": temp = i[3:] code += f"

{temp}

\n" elif i[0:3] == "```": code += "
\n"
                        escaped = True
                    elif i[0:4] == "### ":
                        temp = i[4:]
                        code += f"

{temp}

\n" elif i[0:2] == "* ": temp = i[2:] code += f"\n" elif i[0:2] == "=>": temp = " ".join(i[2:].strip().replace(" ", " ").split(" ")) goto = temp.split(" ")[0] prse = urlparse(goto) extra = "" extracomment = goto if prse.netloc == "" and prse.scheme == "": isdir = url[len(url) - 1] == "/" isabs = goto[0] == "/" or goto[0:2] == "//" dubleslash = goto[0:2] == "//" if isabs: tempurl = urlparse(fulladdr).hostname + (goto[1:] if dubleslash else goto) elif isdir: tempurl = url + goto else: tempurl = "/".join(url.split("/")[:-1]) + "/" + goto tempurl = quote(tempurl, safe='') goto = f"/gem?gemini={tempurl}" elif prse.scheme != "gemini": extra = "" extracomment = f"This link points to an address that isn't gemini ({prse.scheme})" else: if prse.hostname != urlparse(fulladdr).hostname: extra = "" extracomment = f"This link points to an address that isn't from the server you're currently connecting to ({prse.hostname})" goto = goto.replace("gemini://", "") goto = quote(goto, safe='') goto = f"/gem?gemini={goto}" if temp.split(" ") == 1: comment = goto else: comment = " ".join(temp.split(" ")[1:]) code += f"

{comment} {extra}

\n" elif i[0:2] == "> ": code += f"

{i}

\n" else: code += f"

{i}

\n" if title == "Something went wrong...": title = "gemini://" + url except: code += "
" + traceback.format_exc() + "
" return f'\n{title}{code}' # Run the Hypercorn ASGI server conf = Config() conf.bind = "0.0.0.0:2009" asyncio.run(serve(app, conf))