2024-08-05 14:16:37 +00:00
|
|
|
from flask import Flask, request, Response, render_template
|
2024-08-05 14:10:59 +00:00
|
|
|
import requests
|
|
|
|
import re
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
2024-08-05 14:16:37 +00:00
|
|
|
FONT_STATIC_URL = "https://fonts.gstatic.com"
|
|
|
|
FONT_API_URL = "https://fonts.googleapis.com"
|
2024-08-05 14:10:59 +00:00
|
|
|
|
2024-08-05 14:16:37 +00:00
|
|
|
PATTERN = rb"fonts\.gstatic\.com"
|
2024-08-05 14:10:59 +00:00
|
|
|
|
2024-08-05 14:16:37 +00:00
|
|
|
|
|
|
|
@app.route("/")
|
|
|
|
def home():
|
|
|
|
domain = request.url_root
|
|
|
|
return render_template("index.html", domain=domain)
|
|
|
|
|
|
|
|
|
|
|
|
@app.route("/s/<path:path>", methods=["GET"])
|
2024-08-05 14:10:59 +00:00
|
|
|
def proxy_fonts_static(path):
|
|
|
|
url = f"{FONT_STATIC_URL}/s/{path}"
|
|
|
|
response = requests.get(url, stream=True)
|
|
|
|
|
|
|
|
def generate():
|
|
|
|
for chunk in response.iter_content(chunk_size=8192):
|
|
|
|
yield chunk
|
|
|
|
|
|
|
|
# Remove hop-by-hop headers
|
2024-08-05 14:16:37 +00:00
|
|
|
headers = {
|
|
|
|
key: value
|
|
|
|
for key, value in response.headers.items()
|
|
|
|
if key.lower()
|
|
|
|
not in [
|
|
|
|
"connection",
|
|
|
|
"keep-alive",
|
|
|
|
"proxy-authenticate",
|
|
|
|
"proxy-authorization",
|
|
|
|
"te",
|
|
|
|
"trailers",
|
|
|
|
"transfer-encoding",
|
|
|
|
"upgrade",
|
|
|
|
]
|
|
|
|
}
|
2024-08-05 14:10:59 +00:00
|
|
|
return Response(generate(), status=response.status_code, headers=headers)
|
|
|
|
|
2024-08-05 14:16:37 +00:00
|
|
|
|
|
|
|
@app.route("/<path:path>", methods=["GET"])
|
2024-08-05 14:10:59 +00:00
|
|
|
def proxy_fonts_api(path):
|
2024-08-05 14:16:37 +00:00
|
|
|
query_string = request.query_string.decode("utf-8")
|
2024-08-05 14:10:59 +00:00
|
|
|
url = f"{FONT_API_URL}/{path}"
|
|
|
|
if query_string:
|
|
|
|
url += f"?{query_string}"
|
2024-08-05 14:16:37 +00:00
|
|
|
headers = {
|
|
|
|
key: value for (key, value) in request.headers.items() if key.lower() != "host"
|
|
|
|
}
|
|
|
|
headers["Accept-Encoding"] = (
|
|
|
|
"" # Disable Accept-Encoding to avoid compressed responses
|
|
|
|
)
|
2024-08-05 14:10:59 +00:00
|
|
|
|
|
|
|
response = requests.get(url, headers=headers)
|
2024-08-05 14:16:37 +00:00
|
|
|
replacement = request.host.encode(
|
|
|
|
"utf-8"
|
|
|
|
) # Convert the host to bytes for replacement
|
2024-08-05 14:10:59 +00:00
|
|
|
|
2024-08-05 14:16:37 +00:00
|
|
|
if "text/css" in response.headers.get("Content-Type", ""):
|
2024-08-05 14:10:59 +00:00
|
|
|
content = response.content
|
|
|
|
content = re.sub(PATTERN, replacement, content)
|
|
|
|
|
2024-08-05 14:16:37 +00:00
|
|
|
headers = {
|
|
|
|
key: value
|
|
|
|
for key, value in response.headers.items()
|
|
|
|
if key.lower()
|
|
|
|
not in [
|
|
|
|
"connection",
|
|
|
|
"keep-alive",
|
|
|
|
"proxy-authenticate",
|
|
|
|
"proxy-authorization",
|
|
|
|
"te",
|
|
|
|
"trailers",
|
|
|
|
"transfer-encoding",
|
|
|
|
"upgrade",
|
|
|
|
]
|
|
|
|
}
|
2024-08-05 14:10:59 +00:00
|
|
|
return Response(content, status=response.status_code, headers=headers)
|
|
|
|
else:
|
|
|
|
# For non-CSS content, return as is
|
2024-08-05 14:16:37 +00:00
|
|
|
headers = {
|
|
|
|
key: value
|
|
|
|
for key, value in response.headers.items()
|
|
|
|
if key.lower()
|
|
|
|
not in [
|
|
|
|
"connection",
|
|
|
|
"keep-alive",
|
|
|
|
"proxy-authenticate",
|
|
|
|
"proxy-authorization",
|
|
|
|
"te",
|
|
|
|
"trailers",
|
|
|
|
"transfer-encoding",
|
|
|
|
"upgrade",
|
|
|
|
]
|
|
|
|
}
|
2024-08-05 14:10:59 +00:00
|
|
|
return Response(response.content, status=response.status_code, headers=headers)
|
|
|
|
|
2024-08-05 14:16:37 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
app.run(host="0.0.0.0", port=5678)
|