Update app.py
Browse files
app.py
CHANGED
|
@@ -106,14 +106,15 @@ class GitHubProxy:
|
|
| 106 |
return any(white_item in url for white_item in Config.WHITE_LIST)
|
| 107 |
|
| 108 |
@lru_cache(maxsize=1000)
|
| 109 |
-
def fetch_github_content(self, url: str, method: str = "GET") -> ProxyResponse:
|
| 110 |
"""获取GitHub内容(带缓存)"""
|
| 111 |
try:
|
| 112 |
response = self.session.request(
|
| 113 |
method=method,
|
| 114 |
url=url,
|
| 115 |
timeout=Config.TIMEOUT,
|
| 116 |
-
allow_redirects=False
|
|
|
|
| 117 |
)
|
| 118 |
|
| 119 |
headers = dict(response.headers)
|
|
@@ -130,9 +131,23 @@ class GitHubProxy:
|
|
| 130 |
redirect_url=redirect_url
|
| 131 |
)
|
| 132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
return ProxyResponse(
|
| 134 |
status=response.status_code,
|
| 135 |
-
content=
|
| 136 |
headers=headers
|
| 137 |
)
|
| 138 |
|
|
@@ -222,10 +237,63 @@ def create_interface():
|
|
| 222 |
"""创建Gradio界面"""
|
| 223 |
proxy = GitHubProxy()
|
| 224 |
|
| 225 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
gr.Markdown("""
|
| 227 |
# 🚀 GitHub Proxy
|
| 228 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 229 |
### 功能特点
|
| 230 |
- ✨ 支持多种GitHub URL格式
|
| 231 |
- 🔄 自动处理重定向
|
|
@@ -282,11 +350,12 @@ def create_interface():
|
|
| 282 |
examples=[
|
| 283 |
["github.com/microsoft/vscode/blob/main/README.md"],
|
| 284 |
["raw.githubusercontent.com/microsoft/vscode/main/README.md"],
|
| 285 |
-
["
|
| 286 |
],
|
| 287 |
inputs=url_input
|
| 288 |
)
|
| 289 |
|
|
|
|
| 290 |
return app
|
| 291 |
|
| 292 |
if __name__ == "__main__":
|
|
|
|
| 106 |
return any(white_item in url for white_item in Config.WHITE_LIST)
|
| 107 |
|
| 108 |
@lru_cache(maxsize=1000)
|
| 109 |
+
def fetch_github_content(self, url: str, method: str = "GET", stream: bool = False) -> ProxyResponse:
|
| 110 |
"""获取GitHub内容(带缓存)"""
|
| 111 |
try:
|
| 112 |
response = self.session.request(
|
| 113 |
method=method,
|
| 114 |
url=url,
|
| 115 |
timeout=Config.TIMEOUT,
|
| 116 |
+
allow_redirects=False,
|
| 117 |
+
stream=stream
|
| 118 |
)
|
| 119 |
|
| 120 |
headers = dict(response.headers)
|
|
|
|
| 131 |
redirect_url=redirect_url
|
| 132 |
)
|
| 133 |
|
| 134 |
+
# 如果是流式响应,直接返回response对象
|
| 135 |
+
if stream:
|
| 136 |
+
return ProxyResponse(
|
| 137 |
+
status=response.status_code,
|
| 138 |
+
content=response, # 返回response对象以支持流式传输
|
| 139 |
+
headers=headers
|
| 140 |
+
)
|
| 141 |
+
|
| 142 |
+
# 检查是否是二进制内容
|
| 143 |
+
content_type = response.headers.get('content-type', '')
|
| 144 |
+
is_binary = not any(text_type in content_type.lower() for text_type in ['text', 'json', 'xml', 'html'])
|
| 145 |
+
|
| 146 |
+
content = response.content if is_binary else response.text
|
| 147 |
+
|
| 148 |
return ProxyResponse(
|
| 149 |
status=response.status_code,
|
| 150 |
+
content=content,
|
| 151 |
headers=headers
|
| 152 |
)
|
| 153 |
|
|
|
|
| 237 |
"""创建Gradio界面"""
|
| 238 |
proxy = GitHubProxy()
|
| 239 |
|
| 240 |
+
def proxy_download(request: gr.Request):
|
| 241 |
+
"""处理直接代理请求"""
|
| 242 |
+
# 从路径中提取GitHub URL
|
| 243 |
+
path = request.headers.get('x-path', '')
|
| 244 |
+
if not path:
|
| 245 |
+
return gr.Error("无效的请求路径")
|
| 246 |
+
|
| 247 |
+
# 移除开头的斜杠
|
| 248 |
+
if path.startswith('/'):
|
| 249 |
+
path = path[1:]
|
| 250 |
+
|
| 251 |
+
# 检查并处理URL
|
| 252 |
+
if not path.startswith(('http://', 'https://')):
|
| 253 |
+
path = 'https://' + path
|
| 254 |
+
|
| 255 |
+
try:
|
| 256 |
+
# 获取代理响应
|
| 257 |
+
response = proxy.proxy_request(path, request)
|
| 258 |
+
|
| 259 |
+
if 'error' in response:
|
| 260 |
+
return gr.Error(response['error'])
|
| 261 |
+
|
| 262 |
+
if 'redirect_url' in response:
|
| 263 |
+
return gr.Redirect(response['redirect_url'])
|
| 264 |
+
|
| 265 |
+
# 获取文件内容(使用流式传输)
|
| 266 |
+
proxy_response = proxy.fetch_github_content(path, stream=True)
|
| 267 |
+
if proxy_response.error:
|
| 268 |
+
return gr.Error(proxy_response.error)
|
| 269 |
+
|
| 270 |
+
# 返回文件响应
|
| 271 |
+
headers = {
|
| 272 |
+
'Content-Type': proxy_response.headers.get('content-type', 'application/octet-stream'),
|
| 273 |
+
'Content-Disposition': proxy_response.headers.get('content-disposition', 'attachment'),
|
| 274 |
+
}
|
| 275 |
+
return gr.FileBinaryResponse(
|
| 276 |
+
proxy_response.content.raw,
|
| 277 |
+
headers=headers,
|
| 278 |
+
status=proxy_response.status
|
| 279 |
+
)
|
| 280 |
+
|
| 281 |
+
except Exception as e:
|
| 282 |
+
logging.error(f"Proxy error: {str(e)}")
|
| 283 |
+
return gr.Error(f"代理请求失败: {str(e)}")
|
| 284 |
+
|
| 285 |
+
# 添加直接代理路由
|
| 286 |
+
app = gr.App()
|
| 287 |
+
app.add_route("/.*", proxy_download, method="GET")
|
| 288 |
+
|
| 289 |
+
with gr.Blocks(title="GitHub Proxy", theme=gr.themes.Soft()) as blocks:
|
| 290 |
gr.Markdown("""
|
| 291 |
# 🚀 GitHub Proxy
|
| 292 |
|
| 293 |
+
### 使用方法
|
| 294 |
+
1. 直接访问: `https://your-domain.com/github-url`
|
| 295 |
+
2. 或者在下方输入GitHub URL进行测试
|
| 296 |
+
|
| 297 |
### 功能特点
|
| 298 |
- ✨ 支持多种GitHub URL格式
|
| 299 |
- 🔄 自动处理重定向
|
|
|
|
| 350 |
examples=[
|
| 351 |
["github.com/microsoft/vscode/blob/main/README.md"],
|
| 352 |
["raw.githubusercontent.com/microsoft/vscode/main/README.md"],
|
| 353 |
+
["github.com/ollama/ollama/releases/download/v0.5.1/ollama-windows-amd64.zip"]
|
| 354 |
],
|
| 355 |
inputs=url_input
|
| 356 |
)
|
| 357 |
|
| 358 |
+
app.blocks = blocks
|
| 359 |
return app
|
| 360 |
|
| 361 |
if __name__ == "__main__":
|