From 6e75df935d3c793d3c07e5e32e1c01a477a2ad4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Schneider?= Date: Wed, 3 Aug 2011 15:29:57 +0200 Subject: [PATCH] Fix cookie and redirection management and a TODO list - Disable urllib2 auto redirection with a handler - Fix HTTP response 304 - Fix cookies management --- pocs/TODO | 8 +++++++ pocs/poc1.py | 60 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 52 insertions(+), 16 deletions(-) create mode 100644 pocs/TODO diff --git a/pocs/TODO b/pocs/TODO new file mode 100644 index 0000000..79e1453 --- /dev/null +++ b/pocs/TODO @@ -0,0 +1,8 @@ +- https support +- HTML filters support +- split the code +- fix multi cookie management +- add log management +- new configuration file +- add user / password storage and recording + diff --git a/pocs/poc1.py b/pocs/poc1.py index 39c9114..e3de001 100644 --- a/pocs/poc1.py +++ b/pocs/poc1.py @@ -4,6 +4,7 @@ from gevent import monkey monkey.patch_all() +import urllib import urllib2 import sys import traceback @@ -11,24 +12,41 @@ from cgi import escape from gevent.pywsgi import WSGIServer -#import poster.streaminghttp +import poster.streaminghttp -#opener = poster.streaminghttp.register_openers() +opener = poster.streaminghttp.register_openers() +# TODO: create a true configuration file drop_headers = ['transfer-encoding'] config = { - 'sfd.local': + 'sfd.local:8088': { 'remote_host': 'www.sfdiabete.org', 'ssl': False }, - 'linuxfr.local': + 'linuxfr.local:8088': { 'remote_host': 'linuxfr.org', } } +class RpRedirectHandler(urllib2.HTTPRedirectHandler): + + def http_error_302(self, req, fp, code, msg, headers): + """ Disable the auto """ + infourl = urllib.addinfourl(fp, headers, req.get_full_url()) + infourl.code = code + infourl.msg = msg + return infourl + +class DefaultErrorHandler(urllib2.HTTPDefaultErrorHandler): + def http_error_default(self, req, fp, code, msg, headers): + result = urllib2.HTTPError(req.get_full_url(), code, msg, headers, fp) + result.status = code + return result + + class RequestApp(object): def __init__(self, global_config): @@ -37,9 +55,7 @@ class RequestApp(object): self.config = None def __call__(self, env, start_response): - """ - """ - print "call" + """ """ self.env = env local_host = env['HTTP_HOST'] # TODO: manage auth and url mapping @@ -53,27 +69,32 @@ class RequestApp(object): def on_request(self, start_response): # TODO: manage header and cookie modifications print "on_request" - print self.env + # Clean this lines if self.env.get('QUERY_STRING'): url = "http://" + self.config['remote_host'] + self.env['PATH_INFO'] + "?" + self.env['QUERY_STRING'] else: url = "http://" + self.config['remote_host'] + self.env['PATH_INFO'] - print url + print self.env['REQUEST_METHOD'] + " " + url if self.env['REQUEST_METHOD'] == 'POST': data = self.env['wsgi.input'].read() - req = urllib2.Request(url, data) + req = urllib2.Request(url, data, + {'Content-Length': self.env['CONTENT_LENGTH'], + 'Content-Type': self.env['CONTENT_TYPE']}) else: req = urllib2.Request(url) # Pass the browser headers to the request + # TODO: move this in on_req header parser for name in (name for name in self.env if name.startswith('HTTP_')): value = self.env[name] - print name + if name == "HTTP_REFERER": + referer = value.replace(self.env["HTTP_HOST"], self.config['remote_host']) + req.add_header("Referer", referer) if name != "HTTP_HOST" and name != "HTTP_REFERER": name = name.split('HTTP_')[1].replace('_', '-') - req.add_header(name, value) - print req.headers + req.add_header(name, value) try: - response = urllib2.urlopen(req) + opener = urllib2.build_opener(RpRedirectHandler, DefaultErrorHandler) + response = opener.open(req) except Exception: ex = sys.exc_info()[1] path = self.env['PATH_INFO'] @@ -88,9 +109,16 @@ class RequestApp(object): return self.on_response(start_response, response.code, response.msg, response.headers, data) def on_response(self, start_response, code, status, headers, data): + # TODO; use an response object print "on_response" - print '{0} {1}'.format(code, status) for key, value in headers.items(): + if key == 'location': + # TODO; move this in a default conf + location = value.replace(self.config['remote_host'], self.env["HTTP_HOST"]) + headers[key] = location + if key == 'set-cookie': + # TODO : add cookie parser here + pass if key in drop_headers: del headers[key] start_response('%d %s' % (code, status), headers.items()) @@ -104,7 +132,7 @@ def serve(host,port): def _demo(): - serve('localhost', 80) + serve('localhost', 8088) if __name__ == "__main__": _demo()