2014-07-17 1 views
0

클라이언트 (예 : 웹 브라우저)가 localhost:8080을 가리킬 때 해당 요청은 SERVER_ADDR (예 : http://www.yahoo.com)으로 정의 된 주소로 보내야합니다. 그것은 프록시보다 라우터 나로드 밸런서와 같습니다.Twisted 및 Python을 사용하여 라우터 만들기

문제점 : 웹 브라우저가 localhost:8080 일 때 아무 것도 반환되지 않습니다. 파이썬 콘솔에서 HTTP 요청 헤더가 Twisted 앱에 도달 한 것으로 볼 수 있습니다. 브라우저의 요청을 리디렉션하는 데 사용할 수 없습니까?

from twisted.internet import protocol, reactor 

LISTEN_PORT = 8080 
SERVER_PORT = 80 
SERVER_ADDR = 'http://www.yahoo.com' 

class ServerProtocol(protocol.Protocol): 
    def __init__(self): 
     self.buffer = None 
     self.client = None 

    def connectionMade(self): 
     factory = protocol.ClientFactory() 
     factory.protocol = ClientProtocol 
     factory.server = self 

     reactor.connectTCP(SERVER_ADDR, SERVER_PORT, factory) 

    # Client => Proxy 
    def dataReceived(self, data): 
     print 'Data received from Client:' 
     if self.client: 
      self.client.write(data) 
     else: 
      data = data.replace('localhost:8080', SERVER_ADDR) 
      print data 
      self.buffer = data 

    # Proxy => Client 
    def write(self, data): 
     self.transport.write(data) 



class ClientProtocol(protocol.Protocol): 
    def connectionMade(self): 
     self.factory.server.client = self 
     self.write(self.factory.server.buffer) 
     self.factory.server.buffer = '' 

    # Server => Proxy 
    def dataReceived(self, data): 
     print 'Data received from Server: ' 
     print data 
     self.factory.server.write(data) 

    # Proxy => Server 
    def write(self, data): 
     if data: 
      self.transport.write(data) 



def main(): 
    factory = protocol.ServerFactory() 
    factory.protocol = ServerProtocol 

    reactor.listenTCP(LISTEN_PORT, factory) 
    reactor.run() 


if __name__ == '__main__': 
    main() 
+0

이것은 HTTP 프록시가 아닙니다. 오히려 평범한 구형 TCP 프록시 또는 "포트 전달자 (Port Forwarder)"입니다. HTTP를 가로채는 경우 HTTP를 구현해야합니다. –

+0

@JamesMills TCP 프록시/전달자를 만들려고합니다. 그러나 작동하는 것을 쉽게 테스트 할 수있는 방법은 무엇입니까? 웹 브라우저가 작동한다고 생각했지만 분명히 그럴 생각이 없습니다. – Nyxynyx

+1

텔넷으로 테스트하십시오. 웹 브라우저는 HTTP를 말합니다. HTTP 트래픽을 리다이렉트/인터셉트하려면 웹 프록시 (HTTP 프록시)를 사용해야합니다. 그렇지 않으면 TCP 레벨에서 투명하게 "'GET http : // www.google.com /''이 다시 연결됩니다. 야후 웹 서버는 아마도 404 또는 일부 다른 오류를 반환하므로 yahoo.com은 작동하지 않습니다. –

답변

0

그것은 부분적으로 나를 위해 작동 : 나는 http://localhost:8080를 방문 할 때 내 브라우저에서 야후 서버에서 HTTP 오류 400 잘못된 요청을 얻을. 이것은 GET 요청의 Host: localhost:8080 섹션을 Host: http://www.yahoo.com으로 바꾸고 여기의 프로토콜이 유효하지 않기 때문입니다. 그것은 단지 Host: www.yahoo.com이어야합니다.

그런 다음 HTTP/1.1 301 Moved Permanently 리디렉션으로 응답하고 다른 문제가 발생합니다.

편집 : 트위스티드 웹 사이트 (https://twistedmatrix.com/documents/12.3.0/web/examples/#auto2)의 프록시 예제를 살펴보고 소스가 어떻게 구현되는지 살펴보아야합니다.

from twisted.web import proxy, http 
from twisted.internet import reactor 

class ProxyFactory(http.HTTPFactory): 
    def buildProtocol(self, addr): 
     return proxy.Proxy() 

reactor.listenTCP(8080, ProxyFactory()) 
reactor.run() 
+0

감사합니다! 내 의도는 TCP 프록시를 만드는 것이지만 웹 브라우저를 사용하여 가장 쉬운 테스트 방법을 생각하고있었습니다. Telnet과 TCP 소프트웨어로 테스트했을 때 코드가 작동하는 것 같습니다. 그러나 서버가 다시 시작되면 TCP 소프트웨어는 연결을 알지 못하며 프록시에 연결되어 있지만 서버에 다시 연결하지 않습니다. 우리가 뭔가 빠졌나요? – Nyxynyx

+0

@Nyxynyx 모든 TCP 패킷 (예 : SYN, ACK)을 전달하려면 하위 수준에서 가로 채기가 필요하며 꼬임이 적합하지 않다고 생각합니다. "기본 NAT"(http://en.wikipedia.org/wiki/Network_address_translation#Basic_NAT)에서 살펴볼 내용을 살펴보십시오. –

관련 문제