2009-09-07 9 views
0

J'ai écrit un simple script python pour une fonctionnalité de proxy. Cela fonctionne cependant, si la page Web demandée a de nombreuses autres demandes http, par ex. Google Maps, la page est rendue assez lente.Qu'est-ce qui ne va pas avec mon simple script de proxy HTTP? (python socket based)

Des conseils sur ce qui pourrait être le goulot d'étranglement dans mon code, et comment je peux améliorer?

#!/usr/bin/python 
import socket,select,re 
from threading import Thread 

class ProxyServer(): 
    def __init__(self, host, port): 
     self.host=host 
     self.port=port 
     self.sk1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

    def startServer(self): 
     self.sk1.bind((self.host,self.port)) 
     self.sk1.listen(256) 
     print "proxy is ready for connections..." 
     while(1): 
      conn,clientAddr = self.sk1.accept() 
      # print "new request coming in from " + str(clientAddr) 
      handler = RequestHandler(conn) 
      handler.start() 


class RequestHandler(Thread): 

    def __init__(self, sk1): 
     Thread.__init__(self) 
     self.clientSK = sk1 
     self.buffer = '' 
     self.header = {} 





    def run(self): 
     sk1 = self.clientSK 
     sk2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     while 1: 
      self.buffer += sk1.recv(8192) 
      if self.buffer.find('\n') != -1: 
       break; 

     self.header = self.processHeader(self.buffer) 
     if len(self.header)>0: #header got processed 
      hostString = self.header['Host'] 
      host=port='' 
      if hostString.__contains__(':'): # with port number 
       host,port = hostString.split(':') 
      else: 
       host,port = hostString,"80" 
      sk2.connect((host,int(port))) 

     else: 
      sk1.send('bad request') 
      sk1.close(); 
      return 
     inputs=[sk1,sk2] 
     sk2.send(self.buffer) 
     #counter 
     count = 0 
     while 1: 
      count+=1 
      rl, wl, xl = select.select(inputs, [], [], 3) 
      if xl: 
       break 
      if rl: 
       for x in rl: 
        data = x.recv(8192) 
        if x is sk1: 
         output = sk2 
        else: 
         output = sk1 
        if data: 
         output.send(data) 
         count = 0 
      if count == 20: 
       break 


     sk1.close() 
     sk2.close() 



    def processHeader(self,header): 
     header = header.replace("\r\n","\n") 
     lines = header.split('\n')  
     result = {} 
     uLine = lines[0] # url line 
     if len(uLine) == 0: return result # if url line empty return empty dict 
     vl = uLine.split(' ') 
     result['method'] = vl[0] 
     result['url'] = vl[1] 
     result['protocol'] = vl[2] 
     for line in lines[1: - 1]: 
      if len(line)>3: # if line is not empty 
       exp = re.compile(': ') 
       nvp = exp.split(line, 1) 
       if(len(nvp)>1): 
        result[nvp[0]] = nvp[1] 
     return result 




if __name__ == "__main__": 
    HOST, PORT = "0.0.0.0", 8088 
    proxy = ProxyServer(HOST,PORT) 
    proxy.startServer() 

Répondre

0

Je ne suis pas sûr de ce que vos problèmes de vitesse sont, mais voici quelques autres nits je trouve choisir:

result['protocal'] = vl[2] 

devrait être

result['protocol'] = vl[2] 

Ce code est indentée niveau trop profond:

sk2.connect((host,int(port))) 

Vous pouvez utiliser le décorateur this pour profiler vos méthodes individuelles par ligne.

+0

Merci pour la correction. J'ai corrigé dans mon message. – Kent

0

Er, bien avant tout que vous êtes en supposant que toutes les demandes ultérieures sur une connexion vont être pour le même hôte ...

+0

qu'est-ce qui vous fait dire ça? – njzk2

Questions connexes