Kumi
5d32aa7c8f
Integrated a new home route in the application that renders a template with instructions on how to use the Google Fonts proxy service, enhancing user guidance. This change includes the addition of an `index.html` template, which provides a clear example and usage instructions, and minor refactoring of existing routes for improved readability.
106 lines
2.9 KiB
Python
106 lines
2.9 KiB
Python
from flask import Flask, request, Response, render_template
|
|
import requests
|
|
import re
|
|
|
|
app = Flask(__name__)
|
|
|
|
FONT_STATIC_URL = "https://fonts.gstatic.com"
|
|
FONT_API_URL = "https://fonts.googleapis.com"
|
|
|
|
PATTERN = rb"fonts\.gstatic\.com"
|
|
|
|
|
|
@app.route("/")
|
|
def home():
|
|
domain = request.url_root
|
|
return render_template("index.html", domain=domain)
|
|
|
|
|
|
@app.route("/s/<path:path>", methods=["GET"])
|
|
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
|
|
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",
|
|
]
|
|
}
|
|
return Response(generate(), status=response.status_code, headers=headers)
|
|
|
|
|
|
@app.route("/<path:path>", methods=["GET"])
|
|
def proxy_fonts_api(path):
|
|
query_string = request.query_string.decode("utf-8")
|
|
url = f"{FONT_API_URL}/{path}"
|
|
if query_string:
|
|
url += f"?{query_string}"
|
|
headers = {
|
|
key: value for (key, value) in request.headers.items() if key.lower() != "host"
|
|
}
|
|
headers["Accept-Encoding"] = (
|
|
"" # Disable Accept-Encoding to avoid compressed responses
|
|
)
|
|
|
|
response = requests.get(url, headers=headers)
|
|
replacement = request.host.encode(
|
|
"utf-8"
|
|
) # Convert the host to bytes for replacement
|
|
|
|
if "text/css" in response.headers.get("Content-Type", ""):
|
|
content = response.content
|
|
content = re.sub(PATTERN, replacement, content)
|
|
|
|
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",
|
|
]
|
|
}
|
|
return Response(content, status=response.status_code, headers=headers)
|
|
else:
|
|
# For non-CSS content, return as is
|
|
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",
|
|
]
|
|
}
|
|
return Response(response.content, status=response.status_code, headers=headers)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app.run(host="0.0.0.0", port=5678)
|