#!/usr/bin/python3 import asyncio, traceback, socket, ssl from urllib.parse import urlparse 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 """ Gem2Browser

Gem2Browser

gemini://


""" @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') if url == None: return redirect("/") code = "

Something went wrong...

\n" title = "Something went wrong..." try: gsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) fulladdr = "gemini://" + url gemsocket = ssl._create_unverified_context().wrap_socket(gsocket, server_hostname=urlparse(fulladdr).hostname) gemsocket.connect((urlparse(fulladdr).hostname, 1965)) gemsocket.send(bytes("gemini://" + url + "\r\n", "UTF-8")) received = "" while True: gemresponse = gemsocket.recv(2048) if gemresponse.decode() != "": received += gemresponse.decode() else: break received = received.replace("\r", "") firstline = True redirected = False gemtext = True code = "" for i in received.split("\n"): if firstline: if i.split(" ")[0][0] == "3": return redirect("/gem?gemini=" + i.split(" ")[1][9:]) 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 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: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] == "/" if isdir: print(url + goto) tempurl = url + goto else: tempurl = "/".join(url.split("/")[:-1]) + "/" + goto 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 = 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))