Created
March 11, 2022 14:59
-
-
Save iebb/c6fd779f206773e8b089790b4cf075a6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import mimetypes | |
import os.path | |
import urllib.parse | |
import flask | |
import requests | |
import re | |
from flask import Flask, request, Response | |
app = Flask(__name__) | |
HTTP_METHODS = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH'] | |
NETLIFY_URL = "https://f1vp.netlify.app/" | |
EXCL_HEADERS = ['host', 'authorization', 'accept-encoding'] | |
EXCL_RESP_HEADERS = [ | |
'transfer-encoding', 'connection', "content-encoding", "content-length", | |
"vary", "via", "x-amz-cf-id", "x-amz-cf-pop", | |
"x-cache", "x-cff-request", "x-cff-response", "x-mediapackage-request-id", | |
] | |
@app.route("/.netlify/functions/server/authenticate", methods=["POST"]) | |
def authenticate(): | |
return requests.post( | |
"https://api.formula1.com/v2/account/subscriber/authenticate/by-password", | |
json=request.json, | |
headers={ | |
"User-Agent": "RaceControl f1viewer", | |
"apiKey": "fCUCjWrKPu9ylJwRAv8BpGLEgiAuThx7", | |
"Content-Type": "application/json" | |
} | |
).json() | |
@app.route('/proxy/<path:path>', methods=HTTP_METHODS) | |
def reverse_proxy_for_global(path): | |
parse = urllib.parse.urlparse(path) | |
if parse.scheme not in ["http", "https"]: | |
return {"this is": "so not right"} | |
req_headers = {key.lower(): value for (key, value) in request.headers if key.lower() not in EXCL_HEADERS} | |
resp = requests.request( | |
method=request.method, params=request.args, url=path, | |
headers=req_headers, data=request.get_data(), cookies=request.cookies, allow_redirects=True) | |
ret = resp.content | |
if ".m3u8" in path and b"RESOLUTION=1920x1080" in resp.content: # disable 1080p for deta, as it might exceed 5M | |
ret = re.sub(".*RESOLUTION=1920x1080.*\\s+.*\\.m3u8\\s+", "", ret.decode("u8")).encode("u8") | |
headers = [] | |
for name, value in resp.raw.headers.items(): | |
if name.lower() in EXCL_RESP_HEADERS: | |
continue | |
elif name.lower() == "set-cookie": | |
value = value.replace("Path=/", "Path=/proxy/%s://%s/" % (parse.scheme, parse.netloc)) | |
headers.append((name, value)) | |
return Response(ret, resp.status_code, headers) | |
@app.route('/favicon.ico', methods=HTTP_METHODS) | |
@app.route('/css/<path:path>', methods=HTTP_METHODS) | |
@app.route('/js/<path:path>', methods=HTTP_METHODS) | |
def reverse_proxy_for_static(path=''): | |
fp = request.path | |
tmp_file = "/tmp" + fp | |
if os.path.isfile(tmp_file): | |
name, ext = os.path.basename(fp).rsplit(".", 1) | |
canon_name = name + "." + ext | |
mimetype, encoding = mimetypes.guess_type(canon_name) | |
if mimetype is None: | |
mimetype = "application/octet-stream" | |
return flask.send_file( | |
tmp_file, | |
download_name=canon_name, | |
mimetype=mimetype, | |
max_age=86400 | |
) | |
resp = requests.request( | |
method=request.method, params=request.args, url=NETLIFY_URL + fp, | |
headers={key: value for (key, value) in request.headers if key.lower() not in EXCL_HEADERS}, | |
data=request.get_data(), cookies=request.cookies, allow_redirects=True) | |
os.makedirs(os.path.dirname(tmp_file), exist_ok=True) | |
open(tmp_file, "wb+").write(resp.content) | |
headers = [ | |
(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in EXCL_RESP_HEADERS | |
] | |
return Response(resp.content, resp.status_code, headers) | |
@app.route('/<path:path>', methods=HTTP_METHODS) | |
@app.route('/', defaults={'path': ''}, methods=HTTP_METHODS) | |
def reverse_proxy_for_other(path=""): | |
resp = requests.request( | |
method=request.method, params=request.args, url=NETLIFY_URL + path, | |
headers={key: value for (key, value) in request.headers if key.lower() not in EXCL_HEADERS}, | |
data=request.get_data(), cookies=request.cookies, allow_redirects=True) | |
headers = [ | |
(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in EXCL_RESP_HEADERS | |
] | |
return Response(resp.content, resp.status_code, headers) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment