aigenai commited on
Commit
ae71ac2
·
verified ·
1 Parent(s): 4cd04ee

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -91
app.py CHANGED
@@ -31,50 +31,37 @@ class Config:
31
  """配置类"""
32
  ASSET_URL = "https://1pages.nbid.bid/"
33
  PREFIX = "/"
34
- JSDELIVR = 0 # 是否使用 jsDelivr 镜像
35
  CACHE_TTL = 3600
36
  MAX_RETRIES = 3
37
- TIMEOUT = 20
38
- CHUNK_SIZE = 1024 * 1024 # 10KB 分块大小
39
- SIZE_LIMIT = 1024 * 1024 * 1024 * 99 # 999GB 文件大小限制
40
-
41
  RATE_LIMIT = {
42
  "window_ms": 15 * 60 * 1000, # 15分钟
43
- "max": 200 # 限制每个IP最多100个请求
44
  }
45
  WHITE_LIST: List[str] = [] # 白名单
46
- BLACK_LIST: List[str] = [] # 黑名单
47
- PASS_LIST: List[str] = [] # 直接通过名单(使用 jsDelivr)
48
 
49
  # 请求头
50
  DEFAULT_HEADERS = {
51
- "User-Agent": "git/2.41.0", # 使用 Git 用户代理
52
- "Accept": "*/*",
53
- "Accept-Encoding": "gzip, deflate, br"
54
  }
55
 
56
  # CORS设置
57
  CORS = {
58
  "allow_origins": ["*"],
59
- "allow_methods": ["GET", "POST", "OPTIONS", "HEAD"],
60
  "allow_headers": ["*"],
61
  "max_age": 1728000
62
  }
63
 
64
- # URL模式(完善匹配模式)
65
  PATTERNS = {
66
- # 发布和归档
67
- "releases": r"^(?:https?:\/\/)?github\.com\/(?P<author>.+?)\/(?P<repo>.+?)\/(?:releases|archive)\/.*$",
68
- # blob和raw文件
69
- "blob": r"^(?:https?:\/\/)?github\.com\/(?P<author>.+?)\/(?P<repo>.+?)\/(?:blob|raw)\/.*$",
70
- # Git操作
71
- "git": r"^(?:https?:\/\/)?github\.com\/(?P<author>.+?)\/(?P<repo>.+?)\/(?:info\/refs\?service=)?git-.*$",
72
- # Raw内容
73
- "raw": r"^(?:https?:\/\/)?raw\.(?:githubusercontent|github)\.com\/(?P<author>.+?)\/(?P<repo>.+?)\/.+?\/.+$",
74
- # Gist
75
- "gist": r"^(?:https?:\/\/)?gist\.(?:githubusercontent|github)\.com\/(?P<author>.+?)\/.+?\/.+$",
76
- # 标签
77
- "tags": r"^(?:https?:\/\/)?github\.com\/(?P<author>.+?)\/(?P<repo>.+?)\/tags.*$"
78
  }
79
 
80
  class RateLimiter:
@@ -276,58 +263,6 @@ def create_interface():
276
  path = 'https://' + path
277
 
278
  try:
279
- # 检查URL格式
280
- match = None
281
- for pattern in Config.PATTERNS.values():
282
- if re.match(pattern, path):
283
- match = re.match(pattern, path)
284
- break
285
-
286
- if not match:
287
- return JSONResponse({"error": "不支持的URL格式"}, status_code=400)
288
-
289
- # 检查白名单和黑名单
290
- author, repo = match.group('author', 'repo')
291
- if Config.WHITE_LIST and not any(
292
- (a == '*' or a == author) and (r == '*' or r == repo)
293
- for a, r in [x.split('/') for x in Config.WHITE_LIST]
294
- ):
295
- return JSONResponse({"error": "不在白名单中"}, status_code=403)
296
-
297
- if any(
298
- (a == '*' or a == author) and (r == '*' or r == repo)
299
- for a, r in [x.split('/') for x in Config.BLACK_LIST]
300
- ):
301
- return JSONResponse({"error": "在黑名单中"}, status_code=403)
302
-
303
- # 处理 jsDelivr 重定向
304
- use_jsdelivr = Config.JSDELIVR or any(
305
- (a == '*' or a == author) and (r == '*' or r == repo)
306
- for a, r in [x.split('/') for x in Config.PASS_LIST]
307
- )
308
-
309
- if use_jsdelivr and ('blob' in path or 'raw.githubusercontent.com' in path):
310
- # 转换为 jsDelivr URL
311
- if 'blob' in path:
312
- path = path.replace('/blob/', '@').replace('github.com', 'cdn.jsdelivr.net/gh', 1)
313
- else:
314
- path = re.sub(r'(\.com/.*?/.+?)/(.+?/)', r'\1@\2', path, 1)
315
- path = path.replace('raw.githubusercontent.com', 'cdn.jsdelivr.net/gh', 1)
316
- return RedirectResponse(path)
317
-
318
- # 处理 blob 到 raw 的转换
319
- if 'blob' in path:
320
- path = path.replace('/blob/', '/raw/', 1)
321
-
322
- # 处理 Git 请求
323
- if 'git-upload-pack' in path or 'git-receive-pack' in path or 'info/refs' in path:
324
- headers = dict(request.headers)
325
- headers.update({
326
- 'User-Agent': 'git/2.41.0',
327
- 'Accept': 'application/x-git-upload-pack-result, */*',
328
- })
329
- proxy.session.headers.update(headers)
330
-
331
  # 获取代理响应
332
  response = proxy.proxy_request(path, request)
333
 
@@ -342,23 +277,10 @@ def create_interface():
342
  if proxy_response.error:
343
  return JSONResponse({"error": proxy_response.error}, status_code=proxy_response.status)
344
 
345
- # 检查文件大小限制
346
- content_length = int(proxy_response.headers.get('content-length', 0))
347
- if content_length > Config.SIZE_LIMIT:
348
- return RedirectResponse(path)
349
-
350
  # 返回流式响应
351
  headers = dict(proxy_response.headers)
352
- # 设置正确的内容类型
353
- if 'git-upload-pack' in path:
354
- headers['Content-Type'] = 'application/x-git-upload-pack-result'
355
- elif 'git-receive-pack' in path:
356
- headers['Content-Type'] = 'application/x-git-receive-pack-result'
357
- elif 'info/refs' in path:
358
- headers['Content-Type'] = 'application/x-git-upload-pack-advertisement'
359
-
360
  return StreamingResponse(
361
- proxy_response.content.iter_content(chunk_size=Config.CHUNK_SIZE),
362
  headers=headers,
363
  status_code=proxy_response.status
364
  )
 
31
  """配置类"""
32
  ASSET_URL = "https://1pages.nbid.bid/"
33
  PREFIX = "/"
34
+ JSDELIVR = 0
35
  CACHE_TTL = 3600
36
  MAX_RETRIES = 3
37
+ TIMEOUT = 10
 
 
 
38
  RATE_LIMIT = {
39
  "window_ms": 15 * 60 * 1000, # 15分钟
40
+ "max": 100 # 限制每个IP最多100个请求
41
  }
42
  WHITE_LIST: List[str] = [] # 白名单
 
 
43
 
44
  # 请求头
45
  DEFAULT_HEADERS = {
46
+ "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"
 
 
47
  }
48
 
49
  # CORS设置
50
  CORS = {
51
  "allow_origins": ["*"],
52
+ "allow_methods": ["GET", "POST", "OPTIONS"],
53
  "allow_headers": ["*"],
54
  "max_age": 1728000
55
  }
56
 
57
+ # URL模式
58
  PATTERNS = {
59
+ "releases": r"^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:releases|archive)\/.*$",
60
+ "blob": r"^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:blob|raw)\/.*$",
61
+ "git": r"^(?:https?:\/\/)?github\.com\/.+?\/.+?\/(?:info|git-).*$",
62
+ "raw": r"^(?:https?:\/\/)?raw\.(?:githubusercontent|github)\.com\/.+?\/.+?\/.+?\/.+$",
63
+ "gist": r"^(?:https?:\/\/)?gist\.(?:githubusercontent|github)\.com\/.+?\/.+?\/.+$",
64
+ "tags": r"^(?:https?:\/\/)?github\.com\/.+?\/.+?\/tags.*$"
 
 
 
 
 
 
65
  }
66
 
67
  class RateLimiter:
 
263
  path = 'https://' + path
264
 
265
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  # 获取代理响应
267
  response = proxy.proxy_request(path, request)
268
 
 
277
  if proxy_response.error:
278
  return JSONResponse({"error": proxy_response.error}, status_code=proxy_response.status)
279
 
 
 
 
 
 
280
  # 返回流式响应
281
  headers = dict(proxy_response.headers)
 
 
 
 
 
 
 
 
282
  return StreamingResponse(
283
+ proxy_response.content.iter_content(chunk_size=8192),
284
  headers=headers,
285
  status_code=proxy_response.status
286
  )