Browse Source

support for Cloudflare

pull/12/merge
lilydjwg 3 years ago
parent
commit
0c9c828eef
4 changed files with 67 additions and 4 deletions
  1. +2
    -2
      README.md
  2. +48
    -0
      cloudflare.py
  3. +1
    -0
      config.py
  4. +16
    -2
      main.py

+ 2
- 2
README.md View File

@@ -26,9 +26,9 @@ curl -F 'name=@path/to/image' http://<your_host>/

Requirement
===========
* Python 3.2+
* Python 3.5+
* The `file` command
* [tornado](https://github.com/facebook/tornado).
* [tornado](https://github.com/facebook/tornado) 3.2+

TODO
====


+ 48
- 0
cloudflare.py View File

@@ -0,0 +1,48 @@
import ipaddress
import asyncio
import logging

import tornado.web
from tornado.httpclient import AsyncHTTPClient
from tornado.platform.asyncio import to_asyncio_future

CLOUDFLARE_IPS = []

logger = logging.getLogger(__name__)

async def update_cloudflare_ips():
global CLOUDFLARE_IPS

urls = ['https://www.cloudflare.com/ips-v4',
'https://www.cloudflare.com/ips-v6']
client = AsyncHTTPClient()
coros = [to_asyncio_future(client.fetch(url)) for url in urls]
rs, _ = await asyncio.wait(coros)

new = []
for r in rs:
r = r.result()
new.extend(ipaddress.ip_network(line)
for line in r.body.decode('utf-8').splitlines())
CLOUDFLARE_IPS = new

async def updater():
while True:
try:
await update_cloudflare_ips()
logger.info('cloudflare ips updated.')
except Exception:
logger.exception('error when update cloudflare ips')
await asyncio.sleep(24 * 3600)

class CfApplication(tornado.web.Application):
def __call__(self, request):
cfip = request.headers.get('Cf-Connecting-IP')
if cfip:
ip = request.remote_ip
for net in CLOUDFLARE_IPS:
if ip in net:
request.remote_ip = cfip
request.protocol = request.headers.get('X-Forwarded-Proto', 'http')
break
return super().__call__(request)

+ 1
- 0
config.py View File

@@ -5,3 +5,4 @@ DB = 'elimage.db'

XHEADERS = True # you may set this to false if not behind another server
TRUSTED_DOWNSTREAM = ['127.0.0.1']
CLOUDFLARE = False

+ 16
- 2
main.py View File

@@ -190,16 +190,29 @@ def main():
import tornado.httpserver
from tornado.options import define, options

from tornado.platform.asyncio import AsyncIOMainLoop
import asyncio
AsyncIOMainLoop().install()

define("port", default=DEFAULT_PORT, help="run on the given port", type=int)
define("datadir", default=DEFAULT_DATA_DIR, help="the directory to put uploaded data", type=str)
define("fork", default=False, help="fork after startup", type=bool)
define("cloudflare", default=False, help="check for Cloudflare IPs", type=bool)

tornado.options.parse_command_line()
if options.fork:
if os.fork():
sys.exit()

application = tornado.web.Application([
if options.cloudflare:
import cloudflare
Application = cloudflare.CfApplication
loop = asyncio.get_event_loop()
loop.create_task(cloudflare.updater())
else:
Application = tornado.web.Application

application = Application([
(r"/", IndexHandler),
(r"/" + SCRIPT_PATH, ToolHandler),
(r"/([a-fA-F0-9]{2}/[a-fA-F0-9]{38})(\.\w*)?", MyStaticFileHandler, {
@@ -217,7 +230,8 @@ def main():
trusted_downstream=TRUSTED_DOWNSTREAM,
)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()

asyncio.get_event_loop().run_forever()

if __name__ == "__main__":
try:


Loading…
Cancel
Save