Fork of elimage with specific modifications for my instance. https://i.catgirlsin.space
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
1.3KB

  1. import ipaddress
  2. import asyncio
  3. import logging
  4. import tornado.web
  5. from tornado.httpclient import AsyncHTTPClient
  6. from tornado.platform.asyncio import to_asyncio_future
  7. CLOUDFLARE_IPS = []
  8. logger = logging.getLogger(__name__)
  9. async def update_cloudflare_ips():
  10. global CLOUDFLARE_IPS
  11. urls = ['https://www.cloudflare.com/ips-v4',
  12. 'https://www.cloudflare.com/ips-v6']
  13. client = AsyncHTTPClient()
  14. coros = [to_asyncio_future(client.fetch(url)) for url in urls]
  15. rs, _ = await asyncio.wait(coros)
  16. new = []
  17. for r in rs:
  18. r = r.result()
  19. new.extend(ipaddress.ip_network(line)
  20. for line in r.body.decode('utf-8').splitlines())
  21. CLOUDFLARE_IPS = new
  22. async def updater():
  23. while True:
  24. try:
  25. await update_cloudflare_ips()
  26. logger.info('cloudflare ips updated.')
  27. except Exception:
  28. logger.exception('error when update cloudflare ips')
  29. await asyncio.sleep(24 * 3600)
  30. def install():
  31. RH = tornado.web.RequestHandler
  32. RH.prepare = _my_prepare
  33. def _my_prepare(self):
  34. request = self.request
  35. cfip = request.headers.get('Cf-Connecting-IP')
  36. if cfip:
  37. ip = ipaddress.ip_address(request.remote_ip)
  38. for net in CLOUDFLARE_IPS:
  39. if ip in net:
  40. request.remote_ip = cfip
  41. request.protocol = request.headers.get('X-Forwarded-Proto', 'http')
  42. break