import socket
import re

from time import sleep
from select import select
from threading import Thread


class CollectAllProxy(Thread):
    into = []
    outof = []
    inchannel = {}
    outchannel = {}
    is_shutdown = False

    def __init__(self,
                 inhost, inport,
                 outhost, outport):
        self.inhost = inhost
        self.inport = inport
        self.outhost = outhost
        self.outport = outport

        super(CollectAllProxy, self).__init__()

        self.incon = socket.socket(
            socket.AF_INET,
            socket.SOCK_STREAM)

        self.incon.setsockopt(
            socket.SOL_SOCKET,
            socket.SO_REUSEADDR,
            1)

        # bind the socket
        self.incon.bind((self.inhost, self.inport))
        self.incon.listen(10)

    def shutdown(self):
        print "shutting down"
        self.is_shutdown = True

    def run(self):
        self.into.append(self.incon)
        while not self.is_shutdown:
            sleep(.1)
            print "selecting"
            rready, wready, xready = select(self.into, [], [], 1)
            print "done selecting"
            for self.inc in rready:
                print "running rready"

                if self.incon == self.inc:
                    print "begin accept"
                    (clientsocket, addr) = self.inc.accept()
                    self.handle_accept(clientsocket, addr)
        self.incon.close()

    def handle_accept(self, clientsocket, addr):
        # set low so we have to iter over recv
        bufsize = 50
        eof_re = re.compile("\r\n\r\n")

        message = ""
        recved = clientsocket.recv(bufsize)
        while recved:
            print "*%s*" % recved
            message += recved
            if eof_re.search(message):
                break
            recved = clientsocket.recv(bufsize)
            print "---\nCNT:", message, ":TNC\n----\n"

        reply = self.forward_message(clientsocket, message)

        self.send_response(clientsocket, reply)

        clientsocket.close()

    def forward_message(self, clientsocket, message):
        out = socket.socket(
            socket.AF_INET,
            socket.SOCK_STREAM)

        out.connect((self.outhost, self.outport))

        out.send(message)

        reply = ""
        newContent = True
        buffsize = 50
        while newContent:
            sleep(.01)
            newContent = out.recv(buffsize)
            if not newContent:
                break
            reply += newContent

        reply += "\nINJECTED!\n"
        reply = self.adjust_content_length(reply)

        print "\nThe Reply:\n"
        print reply
        print "\n---end reply---\n"

        return reply

    def adjust_content_length(self, reply):

        bits = reply.split("\r\n\r\n")

        if len(bits) == 1:
            return reply

        new_content_length = "Content-Length: " + str(len(bits[1]))

        clre = re.compile(r"Content-Length: .*", re.I)
        bits[0] = clre.sub(new_content_length, bits[0])

        return "\r\n\r\n".join(bits)

    def send_response(self, clientsocket, http):
        print "\n--- ready to send ---\n"
        print http
        print "\n--- done sending ---\n"
        clientsocket.send(http)


if __name__ == '__main__':
    cap = CollectAllProxy(
        '127.0.0.1', 8877,
        '127.0.0.1', 8000)
    cap.run()

@@ -97,16 +97,440 @@
 Thread%0A%0A
+from StringIO import StringIO%0Afrom httplib import HTTPResponse%0A%0A%0Aclass StringySocket(StringIO):%0A    def makefile(self, *args, **kw):%0A        return self%0A%0A%0Aclass StringyHttpResponse(object):%0A    def __init__(self, content):%0A        ss = StringySocket(content)%0A        response = HTTPResponse(ss)%0A        response.begin()%0A%0A        self.response = response%0A%0A    def getheaders(self):%0A        return self.response.getheaders()%0A%0A
 %0Aclass C
@@ -2286,63 +2286,8 @@
 ize)
-%0A            print %22---%5CnCNT:%22, message, %22:TNC%5Cn----%5Cn%22
 %0A%0A  
@@ -2416,32 +2416,138 @@
 socket.close()%0A%0A
+    def inject_header(self, pageparts):%0A        pass%0A%0A    def inject_body(self, pageparts):%0A        pass%0A%0A
     def forward_
@@ -3074,32 +3074,114 @@
 _length(reply)%0A%0A
+        response = StringyHttpResponse(reply)%0A        print response.getheaders()%0A
         print %22%5C

use HTTPResponse with StringIO to get response in a more httlib friendly way