archiving community contributions on YouTube: unpublished captions, title and description translations and caption credits
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

83 lines
2.8 KiB

  1. from os import system
  2. from os.path import isfile
  3. HEROKU = False
  4. if isfile("../Procfile") and isfile("../requirements.txt"):
  5. print("Heroku detected... using 20 threads instead of 50.")
  6. HEROKU = True
  7. if HEROKU:
  8. if not "aioquic" in open("../requirements.txt").read():
  9. print("Installing aioquic on this Heroku instance since it wasn't installed on deploy...")
  10. system("python3 -m pip install --user aioquic")
  11. import asyncio
  12. from typing import cast
  13. from urllib.parse import urlparse
  14. from aioquic.h3.connection import H3_ALPN
  15. from aioquic.asyncio.client import connect
  16. from aioquic.quic.configuration import QuicConfiguration
  17. from http3_base import HttpClient, prepare_response, perform_http_request
  18. from urllib.parse import urlparse
  19. class HTTP3Response:
  20. def __init__(self, input) -> None:
  21. headers, content, url, redirect = input
  22. self.content = content
  23. try:
  24. self.text = content.decode()
  25. except:
  26. print("Text decoding error")
  27. self.text = ""
  28. self.headers = {}
  29. for k, v in headers.items():
  30. self.headers[k.decode()] = v.decode()
  31. try:
  32. self.status_code = int(headers[b":status"])
  33. self.url = url
  34. except:
  35. print("Status code not included as header, defaulting to 200")
  36. self.status_code = 200
  37. self.ok = self.status_code < 400
  38. async def main(address, headers={}):
  39. parsed = urlparse(address)
  40. configuration = QuicConfiguration(
  41. is_client=True, alpn_protocols=H3_ALPN
  42. )
  43. async with connect(parsed.netloc, port=443, configuration=configuration, create_protocol=HttpClient) as client:
  44. client = cast(HttpClient, client)
  45. redirect = False
  46. while True:
  47. events = await perform_http_request(client=client, url=address, headers=headers)
  48. oheaders, ocontent = prepare_response(events)
  49. statuscode = int(oheaders[b":status"])
  50. if statuscode >= 300 and statuscode < 400 and b"location" in oheaders.keys():
  51. redirect = True
  52. origurl = address
  53. parsedorig = urlparse(origurl)
  54. address = oheaders[b"location"].decode()
  55. parsednew = urlparse(address)
  56. if not parsednew.scheme and not parsednew.netloc:
  57. address = parsedorig.scheme + "://" + parsedorig.netloc + address
  58. else:
  59. break
  60. return HTTP3Response((oheaders, ocontent, address, redirect))
  61. def get(url, headers={}, params={}):
  62. plist = []
  63. for item in params:
  64. k, v = item
  65. plist.append(str(k)+"="+str(v))
  66. if plist:
  67. pstring = "?"+"&".join(plist)
  68. else:
  69. pstring = ""
  70. url = url+pstring
  71. loop = asyncio.new_event_loop()
  72. return loop.run_until_complete(main(url, headers=headers))