From 7e8566fcd85940de1397dec3f72995a8a639ef0b Mon Sep 17 00:00:00 2001 From: gz Date: Fri, 29 May 2026 09:40:09 +0800 Subject: [PATCH] Initial commit --- app.py | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ uwsgi.ini | 30 +++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 app.py create mode 100644 uwsgi.ini diff --git a/app.py b/app.py new file mode 100644 index 0000000..83e0600 --- /dev/null +++ b/app.py @@ -0,0 +1,112 @@ +from flask import Flask, request, Response +import requests +import re + +app = Flask(__name__) + +# 首页 +@app.route('/') +def home(): + return ''' + + + + 🌐 国外网站代理访问 + + + +

🌐 Github / 国外网站加速代理

+
+ + +
+ + + ''' + +# 统一替换 html 内资源链接与表单 action +def replace_all_resources(html, target_url): + def replace_match(match): + attr, url = match.group(1), match.group(2) + if url.startswith('http'): + proxied_url = f"/proxy?url={url}" + elif url.startswith('//'): + proxied_url = f"/proxy?url=https:{url}" + elif url.startswith('/'): + base = re.match(r'(https?://[^/]+)', target_url).group(1) + proxied_url = f"/proxy?url={base}{url}" + else: + base = target_url.rsplit('/', 1)[0] + proxied_url = f"/proxy?url={base}/{url}" + return f'{attr}="{proxied_url}"' + + # 替换 src / href / action + html = re.sub(r'(src|href|action)=["\'](.*?)["\']', replace_match, html, flags=re.IGNORECASE) + + # 给所有表单加隐藏 input 保留 url 参数 + html = re.sub( + r'(]*>)', + lambda m: f'{m.group(1)}', + html, + flags=re.IGNORECASE + ) + + return html + +# 代理接口 +@app.route('/proxy') +def proxy(): + target_url = request.args.get('url') + if not target_url: + return '❌ 缺少 url 参数' + + # 自动补全 https:// + if not target_url.startswith(('http://', 'https://')): + target_url = 'https://' + target_url + + try: + headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'} + resp = requests.get(target_url, headers=headers, timeout=8) + + content_type = resp.headers.get('Content-Type', '') + + # 如果是 HTML 页面 + if 'text/html' in content_type: + html = resp.text + # 替换资源和表单 action + html = replace_all_resources(html, target_url) + return Response(html, resp.status_code, content_type=content_type) + + else: + # 其他类型直接转发 + return Response(resp.content, resp.status_code, content_type=content_type) + + except requests.exceptions.RequestException as e: + return f'❌ 网络异常: {e}' + except Exception as e: + return f'❌ 系统错误: {e}' + +# 启动服务 +if __name__ == '__main__': + app.run(host='0.0.0.0', port=8203) diff --git a/uwsgi.ini b/uwsgi.ini new file mode 100644 index 0000000..ea3c79e --- /dev/null +++ b/uwsgi.ini @@ -0,0 +1,30 @@ +[uwsgi] +uid = uwsgi +gid = uwsgi + +# 启动服务监听的地址和端口 +http-socket = 0.0.0.0:8203 + +# 指定虚拟环境路径 +virtualenv = /opt/service/python_prj/pictoHub.env + +# 指定 Flask 应用文件的路径 +wsgi-file = /opt/service/python_prj/proxyHub/app.py + +# 设置 Flask 的应用实例 +callable = app + +# 设置静态文件目录映射 +static-map = /static=/opt/service/python_prj/proxyHub/static/ + +# 日志文件 +logto = /var/log/uwsgi/proxy-project.log + +# 设置进程数 +processes = 4 + +# 启动时的 Python 环境路径 +home = /opt/service/python_prj/pictoHub.env + +# 确保应用正常启动 +touch-reload = /opt/service/python_prj/proxyHub/app.py