from functools import cache import json from flask import ( Flask, make_response, redirect, request, jsonify, render_template, send_from_directory, send_file, ) import os import json import requests from datetime import datetime import dotenv import re import tools import urllib.parse dotenv.load_dotenv() app = Flask(__name__) BLOCKED_PATHS = ["https.js"] def find(name, path): for root, dirs, files in os.walk(path): if name in files: return os.path.join(root, name) # Assets routes @app.route("/assets/<path:path>") def send_assets(path): if path.endswith(".json"): return send_from_directory( "templates/assets", path, mimetype="application/json" ) if os.path.isfile("templates/assets/" + path): return send_from_directory("templates/assets", path) # Try looking in one of the directories filename: str = path.split("/")[-1] if ( filename.endswith(".png") or filename.endswith(".jpg") or filename.endswith(".jpeg") or filename.endswith(".svg") ): if os.path.isfile("templates/assets/img/" + filename): return send_from_directory("templates/assets/img", filename) if os.path.isfile("templates/assets/img/favicon/" + filename): return send_from_directory("templates/assets/img/favicon", filename) return render_template("404.html"), 404 # region Special routes @app.route("/favicon.png") def faviconPNG(): return send_from_directory("templates/assets/img", "favicon.png") @app.route("/.well-known/<path:path>") def wellknown(path): # Try to proxy to https://nathan.woodburn.au/.well-known/ req = requests.get(f"https://nathan.woodburn.au/.well-known/{path}") return make_response( req.content, 200, {"Content-Type": req.headers["Content-Type"]} ) # endregion # region Main routes @app.route("/") def index(): return render_template("index.html") @app.route("/proxy/<path:url>") def proxy(url: str): # Decode the URL url = urllib.parse.unquote(url) # Get last path segment path = url.split("/")[-1] if path in BLOCKED_PATHS: return render_template("404.html"), 403 content: requests.Response = tools.proxy(url) if not content.status_code < 500: print(content.text) return render_template("500.html"), 500 # Get the content type contentType = content.headers.get("Content-Type") if "text/html" in contentType: response = make_response(tools.cleanProxyContent(content.text,url,request.host_url)) response.headers["Content-Type"] = contentType return response, content.status_code # Clean JS if "text/javascript" in contentType or 'application/javascript' in contentType: response = make_response(tools.proxyCleanJS(content.text,url,request.host_url)) response.headers["Content-Type"] = contentType return response, content.status_code response = make_response(content.content) response.headers["Content-Type"] = contentType return response, content.status_code @app.route("/<path:path>") def catch_all(path: str): if os.path.isfile("templates/" + path): return render_template(path) # Try with .html if os.path.isfile("templates/" + path + ".html"): return render_template(path + ".html") if os.path.isfile("templates/" + path.strip("/") + ".html"): return render_template(path.strip("/") + ".html") # Try to find a file matching if path.count("/") < 1: # Try to find a file matching filename = find(path, "templates") if filename: return send_file(filename) return render_template("404.html"), 404 # endregion #region API routes @app.route("/api/v1/ssl/<domain>") def api_ssl(domain: str): regexmatch = re.match(r"^([a-z0-9]+(-[a-z0-9]+)*\.)*([a-z0-9]+([-a-z0-9])*)$", domain) if not regexmatch: return api_error("Please provide a valid domain to check") result = tools.check_ssl(domain) return jsonify(result) @app.route("/api/v1/curl/<path:url>") def api_curl(url: str): # Decode the URL url = urllib.parse.unquote(url) result = tools.curl(url) return jsonify(result) # endregion # region Error Catching # 404 catch all @app.errorhandler(404) def not_found(e): return render_template("404.html"), 404 def api_error(e): return jsonify({"success": False, "message": str(e)}) # endregion if __name__ == "__main__": app.run(debug=True, port=5000, host="0.0.0.0")