106 lines
2.9 KiB
Python
106 lines
2.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
# vi:si:et:sw=4:sts=4:ts=4
|
|
|
|
import tornado.web
|
|
import tornado.httpclient
|
|
import tornado.gen
|
|
|
|
from .utils import run_async
|
|
from . import link
|
|
|
|
import logging
|
|
logger = logging.getLogger('proxy')
|
|
|
|
|
|
class ProxyHandler(tornado.web.RequestHandler):
|
|
SUPPORTED_METHODS = ['GET', 'POST', 'PUT', 'DELETE']
|
|
|
|
@tornado.web.asynchronous
|
|
def _handle_response(self, response):
|
|
if response.error:
|
|
logger.debug('ERROR %s', str(response.error))
|
|
self.set_status(response.code)
|
|
if response.body:
|
|
self.write(response.body)
|
|
else:
|
|
self.write('Internal server error:\n' + str(response.error))
|
|
else:
|
|
if response.code:
|
|
self.set_status(response.code)
|
|
allowed_headers = (
|
|
'X-Ed25519-Key',
|
|
'X-Ed25519-Signature',
|
|
'Accept-Ranges',
|
|
'Cache-Control',
|
|
'Connection',
|
|
'Content-Encoding',
|
|
'Content-Length',
|
|
'Content-Range',
|
|
'Content-Type',
|
|
'Date',
|
|
'ETag',
|
|
'Last-Modified',
|
|
'Location',
|
|
'Range',
|
|
'Server',
|
|
'Vary'
|
|
)
|
|
for header in allowed_headers:
|
|
v = response.headers.get(header)
|
|
if v:
|
|
self.set_header(header, v)
|
|
|
|
ignored = set(response.headers.keys()) - set([h.lower() for h in allowed_headers])
|
|
if ignored:
|
|
print('IGNORED', ignored)
|
|
|
|
if response.data:
|
|
self.write(response.data)
|
|
elif response.body:
|
|
chunk = True
|
|
while chunk:
|
|
chunk = response.body.read(4096)
|
|
self.write(chunk)
|
|
self.finish()
|
|
|
|
@run_async
|
|
def _fetch_response(self, url, fingerprint, callback):
|
|
response = link.read(url, self.request.body, self.request.headers, fingerprint)
|
|
callback(response)
|
|
|
|
def remote_url(self):
|
|
self.set_status(500)
|
|
self.write('Internal server error:\n')
|
|
self.finish()
|
|
return None
|
|
|
|
@tornado.web.asynchronous
|
|
@tornado.gen.coroutine
|
|
def proxy(self):
|
|
url = self.remote_url()
|
|
if isinstance(url, tuple):
|
|
url, fingerprint = url
|
|
else:
|
|
fingerprint = None
|
|
if url:
|
|
logger.debug('request to %s', url)
|
|
response = yield tornado.gen.Task(self._fetch_response, url, fingerprint)
|
|
self._handle_response(response)
|
|
|
|
@tornado.web.asynchronous
|
|
def get(self):
|
|
return self.proxy()
|
|
|
|
@tornado.web.asynchronous
|
|
def post(self):
|
|
return self.proxy()
|
|
|
|
@tornado.web.asynchronous
|
|
def put(self):
|
|
return self.proxy()
|
|
|
|
@tornado.web.asynchronous
|
|
def delete(self):
|
|
return self.proxy()
|
|
|