⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 http_match.py

📁 一个java写的proxy的例子
💻 PY
字号:
from proxy4_base import *from connection import *class ServerPool:    def __init__(self):        self.map = {} # {(ipaddr, port) -> {server -> ('available'|'busy')}}        self.http_versions = {} # {(ipaddr, port) -> http_version}        self.callbacks = {} # {(ipaddr, port) -> [functions to call]}        make_timer(60, self.expire_servers)            # Usage:    #   reserve_server to receive a server or None    #   unreserve_server to put a server back on the available set    #    #   register_server to add a server (busy)    #   unregister_server to remove a server (busy or not)    #    #   register_callback to express an interest in a server        def count_servers(self, addr):        "How many server objects connect to this address?"        return len(self.map.get(addr, {}))        def reserve_server(self, addr):        for server,status in self.map.get(addr, {}).items():            if status[0] == 'available':                # Let's reuse this one                self.map[addr][server] = ('busy', )                print color(6, 'reserve_server'), addr, server                return server        return None    def unreserve_server(self, addr, server):        #print color(6, 'unreserve_server'), addr, server        assert self.map.has_key(addr), '%s missing %s' % (self.map, addr)        assert self.map[addr].has_key(server), '%s missing %s' % (self.map[addr], server)        assert self.map[addr][server][0] == 'busy'        self.map[addr][server] = ('available', time.time())        self.invoke_callbacks(addr)            def register_server(self, addr, server):        "Register the server as being used"        #print color(6, 'register_server'), addr, server        if not self.map.has_key(addr):            self.map[addr] = {}        self.map[addr][server] = ('busy',)            def unregister_server(self, addr, server):        "Unregister the server"        #print color(6, 'unregister_server'), addr, server        assert self.map.has_key(addr), '%s missing %s' % (self.map, addr)        assert self.map[addr].has_key(server), '%s missing %s' % (self.map[addr], server)        del self.map[addr][server]        if not self.map[addr]: del self.map[addr]        self.invoke_callbacks(addr)    def register_callback(self, addr, callback):        # Callbacks are called whenever a server may be available        # for (addr).  It's the callback's responsibility to re-register        # if someone else has stolen the server already.        if not self.callbacks.has_key(addr):            self.callbacks[addr] = []        self.callbacks[addr].append(callback)    def connection_limit(self, addr):        if self.http_versions.get(addr, 1.1) <= 1.0:            # For older versions of HTTP, we open lots of connections            return 6        else:            return 2            def set_http_version(self, addr, http_version):        self.http_versions[addr] = http_version        self.invoke_callbacks(addr)            def expire_servers(self):        expire_time = time.time() - 300 # Unused for five minutes        to_expire = []        for addr,set in self.map.items():            for server,status in set.items():                if status[0] == 'available' and status[1] < expire_time:                    # It's old .. let's get rid of it                    to_expire.append(server)        for server in to_expire:            server.close()        make_timer(60, self.expire_servers)            def invoke_callbacks(self, addr):        # Notify whoever wants to know about a server becoming available        if self.callbacks.has_key(addr):            callbacks = self.callbacks[addr]            del self.callbacks[addr]             for callback in callbacks:                callback()        serverpool = ServerPool()            class ClientServerMatchmaker:    # States:    #    # dns:      Client has sent all of the browser information    #           We have asked for a DNS lookup    #           We are waiting for an IP address    #       =>  Either we get an IP address, we redirect, or we fail    #    # server:   We have an IP address    #           We are looking for a suitable server    #       =>  Either we find a server from ServerPool and use it    #           (go into 'response'), or we create a new server    #           (go into 'connect'), or we wait a bit (stay in 'server')    #    # connect:  We have a brand new server object    #           We are waiting for it to connect    #       =>  Either it connects and we send the request (go into    #           'response'), or it fails and we notify the client    #    # response: We have sent a request to the server    #           We are waiting for it to respond    #       =>  Either it responds and we have a client/server match    #           (go into 'done'), it doesn't and we retry (go into    #           'server'), or it doesn't and we give up (go into 'done')    #    # done:     We are done matching up the client and server        def __init__(self, client, request, headers, content):        words = split(request)        hostname, document = stripsite(join(words[1:-1], ' '))        port = 80        m = re.match(r'^(.*):(\d+)$', hostname)        if m:            hostname = m.group(1)            port = int(m.group(2))                    self.client = client        self.request = request        self.hostname = hostname        self.port = port        self.document = document        self.headers = headers        self.content = content        # Temporary HACK        if hostname == '_proxy' and document == '/xul':            local_server.ServerHandleDirectly(                self.client,                'HTTP/1.0 200 OK\r\n',                'Content-type: text/xul\r\n'                '\r\n',                open('/home/amitp/xul/google.xul', 'r').read())            return                if hostname == '_proxy' and document == '/sidegoogle':            local_server.ServerHandleDirectly(                self.client,                'HTTP/1.0 200 OK\r\n',                'Content-type: text/html\r\n'                '\r\n',                '<html><body><script>sidebar.addPanel("Google", "http://_proxy/xul", "");</script></body></html>')            return        self.state = 'dns'        dns_lookups.background_lookup(self.hostname, self.handle_dns)    def handle_dns(self, hostname, answer):        assert self.state == 'dns'        if not self.client.connected:            # The browser has already closed this connection, so abort            return        if answer.isFound():            self.ipaddr = answer.data[0]            self.state = 'server'            self.find_server()        elif answer.isRedirect():            # Let's use a different hostname            new_url = answer.data            if self.port != 80: new_url = new_url + ':%s' % self.port            new_url = new_url + self.document            self.state = 'done'            local_server.ServerHandleDirectly(                self.client,                'HTTP/1.0 301 Use different host\r\n',                'Content-type: text/html\r\n'                'Location: http://%s\r\n'                '\r\n' % new_url,                'Host %s is an abbreviation for %s\r\n'                % (hostname, answer.data))        else:            # Couldn't look up the host, so close this connection            self.state = 'done'            local_server.ServerHandleDirectly(                self.client,                'HTTP/1.0 504 Host not found\r\n',                'Content-type: text/html\r\n'                '\r\n',                'Host %s not found .. %s\r\n' % (hostname, answer.data))    def find_server(self):        assert self.state == 'server'        if not self.client.connected: return        addr = (self.ipaddr, self.port)        server = serverpool.reserve_server(addr)        if server:            # Let's reuse it            message(6, 'resurrecting', None, None, server)            self.state = 'connect'            self.server_connected(server)        elif serverpool.count_servers(addr)>=serverpool.connection_limit(addr):            # There are too many connections right now, so register us            # as an interested party for getting a connection later            serverpool.register_callback(addr, self.find_server)        else:            # Let's make a new one            self.state = 'connect'            server = http_server.HttpServer(self.ipaddr, self.port, self)            serverpool.register_server(addr, server)            def server_connected(self, server):        if not self.client.connected:            # The client has aborted, so let's return this server            # connection to the pool            server.reuse()            return        self.server = server        self.state = 'response'        # At this point, we tell the server that we are the client.        # Once we get a response, we transfer to the real client.        self.server.client_send_request(split(self.request)[0],                                        self.hostname,                                         self.document,                                        self.headers,                                        self.content,                                        self)            def server_abort(self):        # The server had an error, so we need to tell the client        # that we couldn't connect        if self.client.connected:            self.client.server_no_response()            def server_close(self):        message(6, 'resurrection failed', None,                self.server.sequence_number, self.server)        # Look for a server again        if self.server.sequence_number > 0:            # It has already handled a request, so the server is allowed            # to kill the connection.  Let's find another server object.            self.state = 'server'            self.find_server()        else:            # The server didn't handle the original request, so we just            # tell the client, sorry.            if self.client.connected:                self.client.server_no_response()    def server_response(self, response, headers):        # Okay, transfer control over to the real client        if self.client.connected:            self.server.client = self.client            self.client.server_response(self.server, response, headers)        else:            self.server.client_abort()            import http_server, local_serverimport dns_lookups

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -