archiving community contributions on YouTube: unpublished captions, title and description translations and caption credits
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 

83 Zeilen
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))