From c383b024c0198eb81b1b815e93783471490339ef Mon Sep 17 00:00:00 2001 From: hunshnet <337490703@qq.com> Date: Thu, 9 Apr 2020 22:26:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Epython=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 27 ++++++++++++++++++++ README.md | 39 ++++++++++++++++++++++------- app/main.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ app/uwsgi.ini | 3 +++ entrypoint.sh | 26 +++++++++++++++++++ 5 files changed, 155 insertions(+), 9 deletions(-) create mode 100644 Dockerfile create mode 100644 app/main.py create mode 100644 app/uwsgi.ini create mode 100644 entrypoint.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3ece28d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +FROM tiangolo/uwsgi-nginx:python3.7 + +LABEL maintainer="Sebastian Ramirez " + +RUN pip install flask requests + +COPY ./app /app +WORKDIR /app + +# Make /app/* available to be imported by Python globally to better support several use cases like Alembic migrations. +ENV PYTHONPATH=/app + +# Move the base entrypoint to reuse it +RUN mv /entrypoint.sh /uwsgi-nginx-entrypoint.sh +# Copy the entrypoint that will generate Nginx additional configs +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] + +# Run the start script provided by the parent image tiangolo/uwsgi-nginx. +# It will check for an /app/prestart.sh script (e.g. for migrations) +# And then will start Supervisor, which in turn will start Nginx and uWSGI + +EXPOSE 80 + +CMD ["/start.sh"] diff --git a/README.md b/README.md index 2818dbd..3b4773e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # gh-proxy ## 简介 -利用Cloudflare Workers对github release、archive以及项目文件进行加速,并且支持clone,部署无需服务器且自带cdn。 +github release、archive以及项目文件的加速项目,支持clone,有Cloudflare Workers无服务器版本以及Python版本 ## 演示 @@ -9,12 +9,10 @@ ## 使用 -直接在copy出来的url前加`https://shrill-pond-3e81.hunsh.workers.dev/`即可 +直接在copy出来的url前加`https://gh.api.99988866.xyz/`即可 也可以直接访问,在input输入 -注意,如果是项目文件会302到jsdeliver,由国内加速会更快。 - ***大量使用请自行部署,以上域名仅为演示使用。*** 以下都是合法输入(仅示例,文件不存在): @@ -29,17 +27,39 @@ - commit文件:https://github.com/hunshcn/project/blob/1111111111111111111111111111/filename -## 自行部署 +## cf worker版本自行部署 首页:https://workers.cloudflare.com 注册,登陆,`Start building`,取一个子域名,`Create a Worker`。 -复制 [index.js](https://cdn.jsdeliver.net/hunshcn/gh-proxy@master/index.js) 或 [index2.js](https://cdn.jsdeliver.net/hunshcn/gh-proxy@master/index2.js) 到左侧代码框,`Save and deploy`。如果正常,右侧应显示首页。 +复制 [index.js](https://cdn.jsdeliver.net/hunshcn/gh-proxy@master/index.js) 到左侧代码框,`Save and deploy`。如果正常,右侧应显示首页。 + +`index.js`默认配置下clone走github.com.cnpmjs.org,项目文件会走jsDeliver,如需走worker,修改Config变量即可 + +## Python版本部署 + +### Docker部署 +``` +docker run -d --name="gh-proxy-py" \ + -p 0.0.0.0:80:80 \ + --restart=always \ + hunsh/gh-proxy-py:latest +``` +第一个80是你要暴露出去的端口 + +### 直接部署 +安装依赖(请使用python3) -`index.js`的clone走github.com.cnpmjs.org,`index2.js`的clone走你的cf worker,请自行选择 +```pip install flask requests``` -## 计费 +按需求修改`app/main.py`的前几项配置 + +### 注意 + +默认配置下clone走github.com.cnpmjs.org,项目文件会走jsDeliver,如需走worker,修改配置即可 + +## Cloudflare Workers计费 到 `overview` 页面可参看使用情况。免费版每天有 10 万次免费请求,并且有每分钟1000次请求的限制。 @@ -47,8 +67,9 @@ ## Changelog -2020.03.22 初始版本 +2020.04.09 增加Python版本(使用Flask) 2020.03.23 新增了clone的支持 +2020.03.22 初始版本 ## 链接 diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..432bbef --- /dev/null +++ b/app/main.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +import re + +import requests +from flask import Flask, Response, redirect, request + +# config +# git使用cnpmjs镜像、分支文件使用jsDelivr镜像的开关,0为关闭,默认开启 +jsdelivr = 1 +cnpmjs = 1 +HOST = '127.0.0.1' # 监听地址,建议监听本地然后由web服务器反代 +PORT = 80 # 监听端口 +ASSET_URL = 'https://hunshcn.github.io/gh-proxy' # 主页 + +app = Flask(__name__) +app.debug = True +CHUNK_SIZE = 1024 * 10 +index_html = requests.get(ASSET_URL, timeout=10).text +exp1 = re.compile(r'^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:releases|archive)\/.*$') +exp2 = re.compile(r'^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:blob)\/.*$') +exp3 = re.compile(r'^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:info|git-upload-pack).*$') + + +@app.route('/') +def index(): + if 'q' in request.args: + return redirect('/' + request.args.get('q')) + return index_html + + +@app.route('/') +def proxy(u): + u = u if u.startswith('http') else 'https://' + u + u = u.replace(':/g', '://g', 1) # uwsgi会将//传递为/ + if jsdelivr and exp2.match(u): + u = u.replace('/blob/', '@').replace('github.com', 'cdn.jsdelivr.net/gh') + return redirect(u) + elif cnpmjs and exp3.match(u): + u = u.replace('github.com', 'github.com.cnpmjs.org') + request.url.replace(request.base_url, '') + return redirect(u) + # elif exp1.match(u): + else: + headers = {} + r_headers = {} + for i in ['Range', 'User-Agent']: + if i in request.headers: + r_headers[i] = request.headers.get(i) + try: + r = requests.get(u, headers=r_headers, stream=True) + for i in ['Content-Type']: + if i in r.headers: + headers[i] = r.headers.get(i) + if r.status_code == 200: + headers = dict(r.headers) + + def generate(): + for chunk in r.iter_content(chunk_size=CHUNK_SIZE): + yield chunk + + return Response(generate(), headers=headers, status=r.status_code) + except Exception as e: + headers['content-type'] = 'text/html; charset=UTF-8' + return Response('server error' + str(e), status=500, headers=headers) + # else: + # return Response('Illegal input', status=403, mimetype='text/html; charset=UTF-8') + + +if __name__ == '__main__': + app.run(host=HOST, port=PORT) diff --git a/app/uwsgi.ini b/app/uwsgi.ini new file mode 100644 index 0000000..327bbb2 --- /dev/null +++ b/app/uwsgi.ini @@ -0,0 +1,3 @@ +[uwsgi] +module = main +callable = app diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..c0f461d --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,26 @@ +#! /usr/bin/env bash +set -e + +/uwsgi-nginx-entrypoint.sh + +# Get the listen port for Nginx, default to 80 +USE_LISTEN_PORT=${LISTEN_PORT:-80} + +if [ -f /app/nginx.conf ]; then + cp /app/nginx.conf /etc/nginx/nginx.conf +else + content_server='server {\n' + content_server=$content_server" listen ${USE_LISTEN_PORT};\n" + content_server=$content_server' location / {\n' + content_server=$content_server' try_files $uri @app;\n' + content_server=$content_server' }\n' + content_server=$content_server' location @app {\n' + content_server=$content_server' include uwsgi_params;\n' + content_server=$content_server' uwsgi_pass unix:///tmp/uwsgi.sock;\n' + content_server=$content_server' }\n' + content_server=$content_server'}\n' + # Save generated server /etc/nginx/conf.d/nginx.conf + printf "$content_server" > /etc/nginx/conf.d/nginx.conf +fi + +exec "$@"