flask / app.py
LPX55's picture
Update app.py
2143c8e verified
from flask import Flask, request, Response
import requests
import re
import urllib.parse
import logging
logging.basicConfig(level=logging.INFO)
app = Flask(__name__)
HOME_PAGE = """
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }
.container { max-width: 600px; margin: 0 auto; }
input[type="text"] { width: 70%; padding: 10px; margin: 10px 0; }
button { padding: 10px 20px; background: #4285f4; color: white; border: none; cursor: pointer; }
.note { margin-top: 20px; color: #666; font-size: 0.9em; }
</style>
</head>
<body>
<div class="container">
<form id="proxyForm">
<input type="text" id="urlInput" placeholder="Enter URL" required>
<button type="submit">Access</button>
</form>
<div><span><a href="https://lpx55-flask.hf.space" target="_blank">Frameless Space.</a></span></div>
</div>
<script>
document.getElementById('proxyForm').addEventListener('submit', function(e) {
e.preventDefault();
const url = document.getElementById('urlInput').value;
if(url) {
window.location.href = '/go/' + encodeURIComponent(btoa(url));
}
});
</script>
</body>
</html>
"""
@app.route('/')
def index():
return HOME_PAGE
@app.route('/go/<path:encoded_url>')
def proxy_path(encoded_url):
try:
# Base64 decode the URL
url = urllib.parse.unquote(encoded_url)
url = str(base64_decode(url))
return proxy_request(url)
except Exception as e:
logging.error(f"Proxy path error: {e}")
return f"Proxy error: {str(e)}", 500
def base64_decode(encoded):
# Add padding to ensure correct decoding
padding = 4 - (len(encoded) % 4)
if padding < 4:
encoded += "=" * padding
try:
return bytes.decode(base64.b64decode(encoded))
except:
try:
# Try URL-safe Base64 decoding
return bytes.decode(base64.urlsafe_b64decode(encoded))
except:
# If decoding fails, return the original value
return encoded
def proxy_request(url):
try:
# If the URL is not a complete HTTP URL, add the protocol
if not url.startswith('http'):
url = 'https://' + url
logging.info(f"Proxying request: {url}")
# Create a session to maintain cookies and state
session = requests.Session()
# Build request headers
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'identity', # Disable compression
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
}
# Send the request
resp = session.get(url, headers=headers, stream=True, verify=False, timeout=30)
# Get the response content
content = resp.content
content_type = resp.headers.get('Content-Type', 'text/html')
# If it's HTML content, modify all links
if 'text/html' in content_type:
content = rewrite_links(content, url)
# Create the response object
response = Response(content)
# Copy the original response headers
for key, value in resp.headers.items():
if key.lower() not in ['content-encoding', 'content-length', 'transfer-encoding',
'connection', 'content-security-policy']:
response.headers[key] = value
return response
except Exception as e:
logging.error(f"Proxy request failed: {e}")
return f"Failed to access {url}: {str(e)}", 500
def rewrite_links(content, base_url):
try:
# Decode the content
content_str = content.decode('utf-8', errors='replace')
# Parse the base URL information
parsed_base = urllib.parse.urlparse(base_url)
base_domain = f"{parsed_base.scheme}://{parsed_base.netloc}"
# Replace all links
def encode_url(url):
# Convert relative URL to absolute URL
if url.startswith('/'):
absolute_url = base_domain + url
elif not url.startswith('http') and not url.startswith('data:') and not url.startswith('#'):
absolute_url = urllib.parse.urljoin(base_url, url)
else:
absolute_url = url
# Encode the URL as Base64 and add the proxy prefix
if absolute_url.startswith('http'):
encoded = base64.b64encode(absolute_url.encode()).decode()
return f"/go/{urllib.parse.quote(encoded)}"
return url
# 1. Replace href attributes
content_str = re.sub(r'href=["\'](.*?)["\']',
lambda m: f'href="{encode_url(m.group(1))}"', content_str)
# 2. Replace src attributes
content_str = re.sub(r'src=["\'](.*?)["\']',
lambda m: f'src="{encode_url(m.group(1))}"', content_str)
# 3. Replace action attributes (forms)
content_str = re.sub(r'action=["\'](.*?)["\']',
lambda m: f'action="{encode_url(m.group(1))}"', content_str)
# 4. Replace URLs in CSS
content_str = re.sub(r'url\([\'"]?(.*?)[\'"]?\)',
lambda m: f'url({encode_url(m.group(1))})', content_str)
# 5. Inject JavaScript handling script
script = """
<script>
(function() {
// Create Base64 encoding function
function encodeURL(url) {
if(url && url.startsWith('http')) {
return '/go/' + encodeURIComponent(btoa(url));
}
return url;
}
// Rewrite XHR
const originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
if(url && url.startsWith('http')) {
arguments[1] = encodeURL(url);
}
return originalOpen.apply(this, arguments);
};
// Rewrite Fetch
const originalFetch = window.fetch;
window.fetch = function(resource, init) {
if(typeof resource === 'string' && resource.startsWith('http')) {
arguments[0] = encodeURL(resource);
}
return originalFetch.apply(this, arguments);
};
// Listen for all clicks, handle links
document.addEventListener('click', function(e) {
const target = e.target.closest('a');
if(target && target.href && target.href.startsWith('http') &&
!target.href.includes('/go/')) {
e.preventDefault();
location.href = encodeURL(target.href);
}
}, true);
})();
</script>
"""
# Insert the script before the body end tag
if '</body>' in content_str:
content_str = content_str.replace('</body>', script + '</body>')
else:
content_str += script
return content_str.encode('utf-8', errors='replace')
except Exception as e:
logging.error(f"Link rewriting error: {e}")
return content
import base64
@app.route('/go', methods=['GET'])
def proxy_get():
url = request.args.get('url', '')
if not url:
return HOME_PAGE
# Base64 encode the URL and redirect
encoded_url = base64.b64encode(url.encode()).decode()
return proxy_request(url)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=True)