home.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. from urllib.parse import quote
  2. from flask import Blueprint, Response,request,redirect
  3. import requests,re
  4. from requests.utils import (
  5. CaseInsensitiveDict)
  6. from fgh.utils.proxy import proxy, check_url
  7. from fgh.utils.regex_util import exp2, exp4
  8. home = Blueprint('home',__name__)
  9. # 分支文件使用 jsDelivr 镜像的开关,0为关闭,默认关闭
  10. jsdelivr = 0
  11. """
  12. 先生效白名单再匹配黑名单,pass_list 匹配到的会直接302到jsdelivr而忽略设置
  13. 生效顺序 白->黑->pass,可以前往https://github.com/hunshcn/gh-proxy/issues/41 查看示例
  14. 每个规则一行,可以封禁某个用户的所有仓库,也可以封禁某个用户的特定仓库,下方用黑名单示例,白名单同理
  15. user1 # 封禁user1的所有仓库
  16. user1/repo1 # 封禁user1的repo1
  17. */repo1 # 封禁所有叫做repo1的仓库
  18. """
  19. white_list = '''
  20. '''
  21. black_list = '''
  22. '''
  23. pass_list = '''
  24. '''
  25. white_list = [tuple([x.replace(' ', '') for x in i.split('/')]) for i in white_list.split('\n') if i]
  26. black_list = [tuple([x.replace(' ', '') for x in i.split('/')]) for i in black_list.split('\n') if i]
  27. pass_list = [tuple([x.replace(' ', '') for x in i.split('/')]) for i in pass_list.split('\n') if i]
  28. @home.route('/')
  29. def index():
  30. if 'q' in request.args:
  31. return redirect('/' + request.args.get('q'))
  32. return "hello world"
  33. @home.route('/<path:u>', methods=['GET', 'POST'])
  34. def handler(u):
  35. # 自动加上https://
  36. u = u if u.startswith('http') else 'https://' + u
  37. if u.rfind('://', 3, 9) == -1:
  38. u = u.replace('s:/', 's://', 1) # uwsgi 会将//传递为/
  39. # save the original url to db
  40. pass_by = False
  41. m = check_url(u)
  42. if m:
  43. m = tuple(m.groups())
  44. if white_list:
  45. for i in white_list:
  46. if m[:len(i)] == i or i[0] == '*' and len(m) == 2 and m[1] == i[1]:
  47. break
  48. else: # 如果 for 循环完成而没有break被执行,那么会执行else
  49. return Response('Forbidden by white list.', status=403)
  50. for i in black_list:
  51. if m[:len(i)] == i or i[0] == '*' and len(m) == 2 and m[1] == i[1]:
  52. return Response('Forbidden by black list.', status=403)
  53. for i in pass_list:
  54. if m[:len(i)] == i or i[0] == '*' and len(m) == 2 and m[1] == i[1]:
  55. pass_by = True
  56. break
  57. else:
  58. return Response('Invalid input.', status=403)
  59. # 替换其中的 /blob/ 为 @,并将 github.com 替换为 cdn.jsdelivr.net/gh
  60. if (jsdelivr or pass_by) and exp2.match(u):
  61. u = u.replace('/blob/', '@', 1).replace('github.com', 'cdn.jsdelivr.net/gh', 1)
  62. return redirect(u)
  63. elif (jsdelivr or pass_by) and exp4.match(u):
  64. u = re.sub(r'(\.com/.*?/.+?)/(.+?/)', r'\1@\2', u, 1)
  65. _u = u.replace('raw.githubusercontent.com', 'cdn.jsdelivr.net/gh', 1)
  66. u = u.replace('raw.github.com', 'cdn.jsdelivr.net/gh', 1) if _u == u else _u
  67. return redirect(u)
  68. else:
  69. if exp2.match(u):
  70. u = u.replace('/blob/', '/raw/', 1)
  71. if pass_by:
  72. url = u + request.url.replace(request.base_url, '', 1)
  73. if url.startswith('https:/') and not url.startswith('https://'):
  74. url = 'https://' + url[7:]
  75. return redirect(url)
  76. u = quote(u, safe='/:') # 保留 / 和 :, urlencode编码
  77. return proxy(u)