# Copyright (c) 2001-2004 Twisted Matrix Laboratories. # See LICENSE for details. """Simplistic HTTP proxy support. This comes in two main variants - the Proxy and the ReverseProxy. When a Proxy is in use, a browser trying to connect to a server (say, www.yahoo.com) will be intercepted by the Proxy, and the proxy will covertly connect to the server, and return the result. When a ReverseProxy is in use, the client connects directly to the ReverseProxy (say, www.yahoo.com) which farms off the request to one of a pool of servers, and returns the result. Normally, a Proxy is used on the client end of an Internet connection, while a ReverseProxy is used on the server end. """ # twisted imports from twisted.internet import reactor, protocol from twisted.web import resource, server, http # system imports import urlparse class ProxyClient(http.HTTPClient): """Used by ProxyClientFactory to implement a simple web proxy.""" def __init__(self, command, rest, version, headers, data, father): self.father = father self.command = command self.rest = rest if headers.has_key("proxy-connection"): del headers["proxy-connection"] headers["connection"] = "close" self.headers = headers self.data = data def connectionMade(self): self.sendCommand(self.command, self.rest) for header, value in self.headers.items(): self.sendHeader(header, value) self.endHeaders() self.transport.write(self.data) def handleStatus(self, version, code, message): self.father.transport.write("%s %s %s\r\n" % (version, code, message)) def handleHeader(self, key, value): self.father.transport.write("%s: %s\r\n" % (key, value)) def handleEndHeaders(self): self.father.transport.write("\r\n") def handleResponsePart(self, buffer): self.father.transport.write(buffer) def handleResponseEnd(self): self.transport.loseConnection() self.father.channel.transport.loseConnection() class ProxyClientFactory(protocol.ClientFactory): """Used by ProxyRequest to implement a simple web proxy.""" protocol = ProxyClient def __init__(self, command, rest, version, headers, data, father): self.father = father self.command = command self.rest = rest self.headers = headers self.data = data self.version = version def buildProtocol(self, addr): return self.protocol(self.command, self.rest, self.version, self.headers, self.data, self.father) def clientConnectionFailed(self, connector, reason): self.father.transport.write("HTTP/1.0 501 Gateway error\r\n") self.father.transport.write("Content-Type: text/html\r\n") self.father.transport.write("\r\n") self.father.transport.write('''