2009-09-07 4 views
0

나는 프록시 기능을위한 간단한 파이썬 스크립트를 작성했다. 요청한 웹 페이지에 다른 http 요청이 여러 개 있으면 잘 작동합니다. Google지도는 페이지가 상당히 느리게 렌더링됩니다.간단한 HTTP 프록시 스크립트에 어떤 문제가 있습니까? (파이썬 소켓 기반)

내 코드에서 병목 현상이 무엇인지, 그리고 어떻게 향상시킬 수 있는지에 대한 힌트가 있습니까? 이 코드는 들여 쓰기입니다

result['protocal'] = vl[2] 

result['protocol'] = vl[2] 

해야한다 :

#!/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() 

답변

0

나는 당신의 속도 문제가 무엇인지 모르겠지만, 여기에 내가 선택하는 것으로 다른 니트는 너무 깊은 수준 :

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

this 데코레이터를 사용하여 개별 메소드를 한 줄씩 프로파일 링 할 수 있습니다.

+0

고마워요. 내 게시물에 고정했습니다. – Kent

0

어쨌든 우선 연결에 대한 모든 후속 요청은 동일한 호스트에 대한 것입니다.

+0

당신은 무엇이라고 말합니까? – njzk2

관련 문제