URL emulator (sockets question)

pythonhda pythonhda at yahoo.com.replacepythonwithlinux
Thu Aug 14 11:15:36 EDT 2003


Hi All,

I writing a program to emulate a URL (essentially a very simple raw data proxy). The client should always think that it is only talking to the proxy and the proxy acts like the url it's emulating.

My *immediate* problem is how do I tell the client that the web server has finished sending? 

I know that when you recieve 0 bytes from the web server, it means that it is done sending...so how do I indicate the same thing to the browser? I've tried various combos of 'shutdown' and 'close' but the browser (Opera) indicates a premature disconnection. 

I was thinking of using it as a proxy between my cellphone and some wap sites I'm developing/debugging. I don't like to type out long urls on the phone and I figured this would be a good learning experience.


--- Code Start ---
import socket
import sys
import select
import re

IMG = re.compile(r'(src="[^"]+")')

class ProxyServer:
    def __init__(self, port, url, rmtport):
        self.port = port
        self.url = url
        self.rmtport = rmtport
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.clients = {}
        self.count = 0
        
    def start(self):
        self.socket.bind((socket.gethostname(), self.port))
        self.socket.listen(5)
        
        while 1:
            try:
                self.clisocket, self.clientaddress = self.socket.accept()
                self.returnIP = self.clisocket.getsockname()
                self.proxy()
                self.count += 1
            except KeyboardInterrupt:
                self.socket.close()

    def proxy(self):
        websvr = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        websvr.connect((self.url, self.rmtport))

        self.request = ''
        self.response = ''

        f = file("proxydata_%s.data" % self.count, 'w')

        while 1:
            try:
                r, w, e = select.select([self.clisocket, websvr], 
                                        [self.clisocket, websvr], [], 30)
                # if client requests something
                if self.clisocket in r: 
                    request = self.clisocket.recv(1024)
                    f.write("\n--RAW REQUEST\n%s" % request)
                    self.request = self.transreq(request, f)
                    self.done = False
                # if websvr writable and have someting to send
                if websvr in w and self.request != '': 
                    self.sendit(websvr, self.request)
                    self.request = ''
                # if websvr readable and hasn't returned ''
                if websvr in r and not self.done: 
                    response = websvr.recv(1024)
                    if response == '':
                        self.done = True
                    else:
                        self.response = self.transresp(response, f)
                # if client writable and last response wasn't ''
                if self.clisocket in w and self.response != '':
                    self.sendit(self.clisocket, self.response)
                    self.response = ''
                # if self.done:
                    # What should I put here??
            except socket.timeout:
                pass
            
        self.count += 1
        f.close()

    def sendit(self, sock, data):
        l = len(data)
        sent = 0
        while sent < l:
            sent += sock.send(data)
            data = data[sent:]

    def transreq(self, request, f=None):
        request = request.replace("%s:%s" % self.returnIP, self.url)
        return request

    def transresp(self, response, f=None):
        if f is not None:
            f.write("\n--RAW RESPONSE\n%s" % response)
        response = response.replace(self.url, "%s:%s" % self.returnIP)
        response = IMG.sub('', response)
        response = response.replace("\r\n0\r\n", "\r\n")
        return response
            
if __name__ == "__main__":
    wapsite = "www.somewapsite.com"
    svr = ProxyServer(9000, wapsite, 80)
    svr.start()

--- END ---

Any suggestions/tips? Thanks,

pythonhda




More information about the Python-list mailing list