public
Created

Tornado proxy server

  • Download Gist
simplified.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
 
from tornado import httpserver
from tornado import httpclient
from tornado import ioloop
from tornado import web
from tornado import options
from tornado import httputil
from tornado import curl_httpclient
from tornado.options import define, options
 
import gc
gc.enable()
 
import re
response_pattern = re.compile("HTTP/1.[01] ([0-9]+) ([^\r]*)")
 
fwd_headers = [
# 'content-length',
# 'content-encoding',
'transfer-encoding',
]
 
class Application(web.RequestHandler):
def initialize(self):
self.client = curl_httpclient.CurlAsyncHTTPClient(max_clients=32)
 
@web.asynchronous
def get(self):
def header_callback(response):
try:
for k,v in httputil.HTTPHeaders.parse(response).iteritems():
if k.lower() in fwd_headers:
continue
self.set_header(k,v)
except ValueError:
status_code = re.match(response_pattern, response).group(1)
self.set_status(int(status_code))
 
if response == "\r\n":
try:
if self._headers['Content-Encoding'] in ['gzip', 'deflate']:
map(self.clear_header, ['Content-Length', 'Content-Encoding'])
except KeyError:
pass
 
def body_callback(response):
self.write(response)
self.flush()
 
def response_handler(response):
self.finish()
 
# checking, if not transparent proxy
if not self.request.uri.startswith("http://"):
self.request.uri = "http://" + self.request.host + self.request.uri
 
self.client.fetch(
httpclient.HTTPRequest(
url=self.request.uri,
method=self.request.method,
headers=self.request.headers,
body=self.request.body,
follow_redirects=False,
allow_nonstandard_methods=True,
use_gzip=False,
 
streaming_callback=body_callback,
header_callback=header_callback,
),
response_handler
)
 
@web.asynchronous
def post(self):
return self.get()
 
def on_finish(self):
self.clear()
gc.collect()
 
def on_connection_close(self):
self.clear()
gc.collect(2)
 
app = web.Application([
(r".*", Application),
])
 
options.parse_command_line()
options.logging = 'debug'
 
app.listen(8888)
ioloop.IOLoop.instance().start()

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.