feat: add home route and template for proxy instructions
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.
This commit is contained in:
parent
f77ec2c177
commit
5d32aa7c8f
2 changed files with 138 additions and 19 deletions
92
app.py
92
app.py
|
@ -1,15 +1,22 @@
|
||||||
from flask import Flask, request, Response
|
from flask import Flask, request, Response, render_template
|
||||||
import requests
|
import requests
|
||||||
import re
|
import re
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
FONT_STATIC_URL = 'https://fonts.gstatic.com'
|
FONT_STATIC_URL = "https://fonts.gstatic.com"
|
||||||
FONT_API_URL = 'https://fonts.googleapis.com'
|
FONT_API_URL = "https://fonts.googleapis.com"
|
||||||
|
|
||||||
PATTERN = rb'fonts\.gstatic\.com'
|
PATTERN = rb"fonts\.gstatic\.com"
|
||||||
|
|
||||||
@app.route('/s/<path:path>', methods=['GET'])
|
|
||||||
|
@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):
|
def proxy_fonts_static(path):
|
||||||
url = f"{FONT_STATIC_URL}/s/{path}"
|
url = f"{FONT_STATIC_URL}/s/{path}"
|
||||||
response = requests.get(url, stream=True)
|
response = requests.get(url, stream=True)
|
||||||
|
@ -19,34 +26,81 @@ def proxy_fonts_static(path):
|
||||||
yield chunk
|
yield chunk
|
||||||
|
|
||||||
# Remove hop-by-hop headers
|
# Remove hop-by-hop headers
|
||||||
headers = {key: value for key, value in response.headers.items() if key.lower() not in [
|
headers = {
|
||||||
'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'te', 'trailers', 'transfer-encoding', 'upgrade']}
|
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)
|
return Response(generate(), status=response.status_code, headers=headers)
|
||||||
|
|
||||||
@app.route('/<path:path>', methods=['GET'])
|
|
||||||
|
@app.route("/<path:path>", methods=["GET"])
|
||||||
def proxy_fonts_api(path):
|
def proxy_fonts_api(path):
|
||||||
query_string = request.query_string.decode('utf-8')
|
query_string = request.query_string.decode("utf-8")
|
||||||
url = f"{FONT_API_URL}/{path}"
|
url = f"{FONT_API_URL}/{path}"
|
||||||
if query_string:
|
if query_string:
|
||||||
url += f"?{query_string}"
|
url += f"?{query_string}"
|
||||||
headers = {key: value for (key, value) in request.headers.items() if key.lower() != 'host'}
|
headers = {
|
||||||
headers['Accept-Encoding'] = '' # Disable Accept-Encoding to avoid compressed responses
|
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)
|
response = requests.get(url, headers=headers)
|
||||||
replacement = request.host.encode('utf-8') # Convert the host to bytes for replacement
|
replacement = request.host.encode(
|
||||||
|
"utf-8"
|
||||||
|
) # Convert the host to bytes for replacement
|
||||||
|
|
||||||
if 'text/css' in response.headers.get('Content-Type', ''):
|
if "text/css" in response.headers.get("Content-Type", ""):
|
||||||
content = response.content
|
content = response.content
|
||||||
content = re.sub(PATTERN, replacement, content)
|
content = re.sub(PATTERN, replacement, content)
|
||||||
|
|
||||||
headers = {key: value for key, value in response.headers.items() if key.lower() not in [
|
headers = {
|
||||||
'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'te', 'trailers', 'transfer-encoding', 'upgrade']}
|
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)
|
return Response(content, status=response.status_code, headers=headers)
|
||||||
else:
|
else:
|
||||||
# For non-CSS content, return as is
|
# For non-CSS content, return as is
|
||||||
headers = {key: value for key, value in response.headers.items() if key.lower() not in [
|
headers = {
|
||||||
'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization', 'te', 'trailers', 'transfer-encoding', 'upgrade']}
|
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)
|
return Response(response.content, status=response.status_code, headers=headers)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
app.run(host='0.0.0.0', port=5678)
|
if __name__ == "__main__":
|
||||||
|
app.run(host="0.0.0.0", port=5678)
|
||||||
|
|
65
templates/index.html
Normal file
65
templates/index.html
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||||
|
/>
|
||||||
|
<title>GoogleDonts</title>
|
||||||
|
<link
|
||||||
|
href="https://nobsdelivr.private.coffee/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
}
|
||||||
|
.hero {
|
||||||
|
background: gray;
|
||||||
|
color: white;
|
||||||
|
padding: 100px 0;
|
||||||
|
}
|
||||||
|
.hero h1 {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
}
|
||||||
|
.hero p {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
.example-code {
|
||||||
|
background-color: #e9ecef;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header class="hero text-center">
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="display-4">Welcome to GoogleDonts</h1>
|
||||||
|
<p class="lead">
|
||||||
|
GoogleDonts is a proxy service to Google Fonts. It allows you to use
|
||||||
|
Google Fonts without any data being sent to Google.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main class="container text-center my-5">
|
||||||
|
<p class="lead">
|
||||||
|
To use the proxy, simply replace
|
||||||
|
<code>https://fonts.googleapis.com/</code> with <code>{{ domain }}</code> in
|
||||||
|
the URL.
|
||||||
|
</p>
|
||||||
|
<p>Example:</p>
|
||||||
|
<div class="example-code">
|
||||||
|
<code>{{ domain }}css?family=Montserrat:400,700</code>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<footer class="text-center py-4">
|
||||||
|
<p>
|
||||||
|
Brought to you by <a href="https://private.coffee">Private.coffee</a>
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
<script src="https://nobsdelivr.private.coffee/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue