forgot to add proxyapp. committing current state which is a bit broken on 2nd request
authorlkcl <lkcl@teenymac.(none)>
Wed, 14 Jul 2010 15:25:28 +0000 (16:25 +0100)
committerlkcl <lkcl@teenymac.(none)>
Wed, 14 Jul 2010 15:25:28 +0000 (16:25 +0100)
ProxyServer.py
httpd.py

index 4d3e20f9765834e8565c286f7286cf303593a6e2..18a22689e8a27fa7494ee46d7b7d8cacdc482bee 100644 (file)
@@ -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
index 55c10900a79298815fc15bc3854c453680210a8a..6dc90c4acaa36816e9dea7b24990bdec198152de 100644 (file)
--- 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"])