From f1719d1ad0dd02fa29c583c534a96d8b7b1ff214 Mon Sep 17 00:00:00 2001 From: lkcl Date: Wed, 14 Jul 2010 16:25:28 +0100 Subject: [PATCH] forgot to add proxyapp. committing current state which is a bit broken on 2nd request --- ProxyServer.py | 82 ++++++++++++++++++++++++++++++++++++++------------ httpd.py | 6 +++- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/ProxyServer.py b/ProxyServer.py index 4d3e20f..18a2268 100644 --- a/ProxyServer.py +++ b/ProxyServer.py @@ -73,6 +73,8 @@ class ProxyConnection: if not self.sock: raise socket.error, msg + self.ss = httpd.SockStream(self.sock) + def close(self): """Close the connection to the HTTP server.""" if self.sock: @@ -124,6 +126,7 @@ class ProxyServerRequestHandler(object): """Serve a request.""" self.client = client self.hr = args[0] + print "on_query", reqtype, repr(self.hr.headers), str(self.hr.headers) if not hasattr(self.client, "proxy"): self.client.proxy = ProxyConnection() self.client.proxy.connect() @@ -147,13 +150,16 @@ class ProxyServerRequestHandler(object): # send command req = "%s %s %s\n" % (reqtype, self.hr.path, self.hr.request_version) print "req", req - yield multitask.send(p.sock, req) + yield p.ss.write(req) # send headers hdrs = str(self.hr.headers) print "hdrs", hdrs - yield multitask.send(p.sock, hdrs) - yield multitask.send(p.sock, "\n") + yield p.ss.write(hdrs) + yield p.ss.write('\r\n') + + conntype = self.hr.headers.get('Connection', "") + keepalive = conntype.lower() == 'keep-alive' # now content if self.hr.headers.has_key('content-length'): @@ -164,22 +170,33 @@ class ProxyServerRequestHandler(object): while size_remaining: chunk_size = min(size_remaining, max_chunk_size) data = self.hr.rfile.read(chunk_size) + print "proxy rfile read", repr(data) yield multitask.send(p.sock, data) - size_remaining -= len(L[-1]) + size_remaining -= len(data) # now read response and write back + # HTTP/1.0 200 OK status line etc. + line = (yield p.ss.readline()) + yield self.client.writeMessage(line) + res = '' - while True: - #data = p.read() - data = (yield multitask.recv(p.sock, 1024)) - print "reading from proxy", repr(data) - if data == '': - break - res += data + try: + while 1: + line = (yield p.ss.readline()) + print "reading from proxy", repr(line) + res += line + if line in ['\n', '\r\n']: + break + except StopIteration: + if httpd._debug: print "proxy read stopiter" + # TODO: close connection + except: + if httpd._debug: + print 'proxy read error', \ + (traceback and traceback.print_exc() or None) + # TODO: close connection f = StringIO(res) - requestline = f.readline() - yield self.client.writeMessage(requestline) # Examine the headers and look for a Connection directive respheaders = mimetools.Message(f, 0) @@ -202,20 +219,45 @@ class ProxyServerRequestHandler(object): yield self.client.writeMessage(val+"\r\n") # check connection for "closed" header - conntype = respheaders.get('Connection', "") - if conntype.lower() == 'close': - self.hr.close_connection = 1 - elif (conntype.lower() == 'keep-alive' and - self.hr.protocol_version >= "HTTP/1.1"): - self.hr.close_connection = 0 + if keepalive: + conntype = respheaders.get('Connection', "") + if conntype.lower() == 'close': + self.hr.close_connection = 1 + elif (conntype.lower() == 'keep-alive' and + self.hr.protocol_version >= "HTTP/1.1"): + self.hr.close_connection = 0 # write rest of data print "writing to client body" yield self.client.writeMessage("\r\n") - yield self.client.writeMessage(f.read()) + + if respheaders.has_key('content-length'): + max_chunk_size = 10*1024*1024 + size_remaining = int(respheaders["content-length"]) + while size_remaining: + chunk_size = min(size_remaining, max_chunk_size) + data = (yield p.ss.read(chunk_size)) + print "reading from proxy expecting", size_remaining, repr(data) + yield self.client.writeMessage(data) + size_remaining -= len(data) + else: + while True: + #data = p.read() + try: + data = (yield p.ss.read(1024)) + except httpd.ConnectionClosed: + break + print "reading from proxy", repr(data) + if data == '': + break + yield self.client.writeMessage(data) + + if self.hr.close_connection: + print 'proxy wants client to close_connection' try: yield self.client.connectionClosed() + pass except httpd.ConnectionClosed: print 'close_connection done' pass diff --git a/httpd.py b/httpd.py index 55c1090..6dc90c4 100644 --- a/httpd.py +++ b/httpd.py @@ -324,14 +324,17 @@ class Protocol(object): raise ConnectionClosed self.hr.raw_requestline = raw_requestline + pos = self.hr.rfile.tell() + #self.hr.rfile.truncate(0) self.hr.rfile.write(data) print "parseRequests write after" - self.hr.rfile.seek(0) + self.hr.rfile.seek(pos) print "parseRequests seek after" if not self.hr.parse_request(): raise ConnectionClosed print "parseRequests parse_req after" + print "parseRequest headers", repr(self.hr.headers), str(self.hr.headers) try: yield self.messageReceived(self.hr) except: @@ -502,6 +505,7 @@ class Client(Protocol): if _debug: print 'messageReceived cmd=', msg.command, msg.path msg.response_cookies = process_cookies(msg.headers, self.remote) + # slightly bad, this: read everything, put it into memory... if msg.headers.has_key('content-length'): max_chunk_size = 10*1024*1024 size_remaining = int(msg.headers["content-length"]) -- 2.30.2