root / trunk / twisted / web2 / proxy.py

Revision 17455, 6.8 kB (checked in by stephen, 3 years ago)

Remove deprecated 'from twisted.protocols import foo' imports from our examples.

Authors: jerub
Reviewer: exarkun
Closes #1637

A quick little script was used to find imports from 'twisted.protocols', then
go through and import those files and see if a DeprecationWarning? comes up.

import os
for line in os.popen('find . -name \*.py | xargs grep twisted.protocols', 'r'):

fname, code = line.strip().split(':', 1)
code = code.strip()
try:

exec code

except DeprecationWarning?:

print fname, '->', code

except:

pass

By this method, a large number of deprecated imports were discovered and
corrected.

Line 
1 raise ImportError("FIXME: this file probably doesn't work.")
2
3 # Copyright (c) 2001-2004 Twisted Matrix Laboratories.
4 # See LICENSE for details.
5
6
7 """Simplistic HTTP proxy support.
8
9 This comes in two main variants - the Proxy and the ReverseProxy.
10
11 When a Proxy is in use, a browser trying to connect to a server (say,
12 www.yahoo.com) will be intercepted by the Proxy, and the proxy will covertly
13 connect to the server, and return the result.
14
15 When a ReverseProxy is in use, the client connects directly to the ReverseProxy
16 (say, www.yahoo.com) which farms off the request to one of a pool of servers,
17 and returns the result.
18
19 Normally, a Proxy is used on the client end of an Internet connection, while a
20 ReverseProxy is used on the server end.
21 """
22
23 # twisted imports
24 from twisted.web2 import http
25 from twisted.internet import reactor, protocol
26 from twisted.web2 import resource, server
27 from zope.interface import implements, Interface
28
29 # system imports
30 import urlparse
31
32
33 class ProxyClient(http.HTTPClient):
34     """Used by ProxyClientFactory to implement a simple web proxy."""
35
36     def __init__(self, command, rest, version, headers, data, father):
37         self.father = father
38         self.command = command
39         self.rest = rest
40         if headers.has_key("proxy-connection"):
41             del headers["proxy-connection"]
42         headers["connection"] = "close"
43         self.headers = headers
44         self.data = data
45
46     def connectionMade(self):
47         self.sendCommand(self.command, self.rest)
48         for header, value in self.headers.items():
49             self.sendHeader(header, value)
50         self.endHeaders()
51         self.transport.write(self.data)
52
53     def handleStatus(self, version, code, message):
54         self.father.transport.write("%s %s %s\r\n" % (version, code, message))
55
56     def handleHeader(self, key, value):
57         self.father.transport.write("%s: %s\r\n" % (key, value))
58
59     def handleEndHeaders(self):
60         self.father.transport.write("\r\n")
61    
62     def handleResponsePart(self, buffer):
63         self.father.transport.write(buffer)
64
65     def handleResponseEnd(self):
66         self.transport.loseConnection()
67         self.father.channel.transport.loseConnection()
68
69
70 class ProxyClientFactory(protocol.ClientFactory):
71     """Used by ProxyRequest to implement a simple web proxy."""
72
73     def __init__(self, command, rest, version, headers, data, father):
74         self.father = father
75         self.command = command
76         self.rest = rest
77         self.headers = headers
78         self.data = data
79         self.version = version
80
81
82     def buildProtocol(self, addr):
83         return ProxyClient(self.command, self.rest, self.version,
84                            self.headers, self.data, self.father)
85
86
87     def clientConnectionFailed(self, connector, reason):
88         self.father.transport.write("HTTP/1.0 501 Gateway error\r\n")
89         self.father.transport.write("Content-Type: text/html\r\n")
90         self.father.transport.write("\r\n")
91         self.father.transport.write('''<H1>Could not connect</H1>''')
92
93
94
95 class ProxyRequest(http.Request):
96     """Used by Proxy to implement a simple web proxy."""
97
98     protocols = {'http': ProxyClientFactory}
99     ports = {'http': 80}
100
101     def process(self):
102         parsed = urlparse.urlparse(self.uri)
103         protocol = parsed[0]
104         host = parsed[1]
105         port = self.ports[protocol]
106         if ':' in host:
107             host, port = host.split(':')
108             port = int(port)
109         rest = urlparse.urlunparse(('','')+parsed[2:])
110         if not rest:
111             rest = rest+'/'
112         class_ = self.protocols[protocol]
113         headers = self.getAllHeaders().copy()
114         if not headers.has_key('host'):
115             headers['host'] = host
116         self.content.seek(0, 0)
117         s = self.content.read()
118         clientFactory = class_(self.method, rest, self.clientproto, headers,
119                                s, self)
120         reactor.connectTCP(host, port, clientFactory)
121
122
123 class Proxy(http.HTTPChannel):
124     """This class implements a simple web proxy.
125
126     Since it inherits from twisted.protocols.http.HTTPChannel, to use it you
127     should do something like this::
128
129         from twisted.web2 import http
130         f = http.HTTPFactory()
131         f.protocol = Proxy
132
133     Make the HTTPFactory a listener on a port as per usual, and you have
134     a fully-functioning web proxy!
135     """
136
137     requestFactory = ProxyRequest
138
139
140 class ReverseProxyRequest(http.Request):
141     """Used by ReverseProxy to implement a simple reverse proxy."""
142
143     def process(self):
144         self.received_headers['host'] = self.factory.host
145         clientFactory = ProxyClientFactory(self.method, self.uri,
146                                             self.clientproto,
147                                             self.getAllHeaders(),
148                                             self.content.read(), self)
149         reactor.connectTCP(self.factory.host, self.factory.port,
150                            clientFactory)
151
152 class ReverseProxy(http.HTTPChannel):
153     """Implements a simple reverse proxy.
154
155     For details of usage, see the file examples/proxy.py"""
156
157     requestFactory = ReverseProxyRequest
158
159 class IConnector(Interface):
160     """attribute name"""
161     def connect(factory):
162         """connect ClientFactory"""
163
164 class TCPConnector:
165     implements(IConnector)
166     def __init__(self, host, port):
167         self.host = host
168         self.name = host
169         self.port = port
170     def connect(self, factory):
171         reactor.connectTCP(self.host, self.port, factory)
172
173
174 class UNIXConnector:
175     implements(IConnector)
176     name = 'n/a'
177     def __init__(self, socket):
178         self.socket = socket
179     def connect(self, factory):
180         reactor.connectUNIX(self.socket, factory)
181
182
183 def ReverseProxyResource(host, port, path):
184     return ReverseProxyResourceConnector(TCPConnector(host, port), path)
185
186 class ReverseProxyResourceConnector:
187     """Resource that renders the results gotten from another server
188
189     Put this resource in the tree to cause everything below it to be relayed
190     to a different server.
191     """
192     isLeaf = True
193     implements(resource.IResource)
194
195     def __init__(self, connector, path):
196         self.connector = connector
197         self.path = path
198
199     def render(self, request):
200         request.received_headers['host'] = self.connector.name
201         request.content.seek(0, 0)
202         qs = urlparse.urlparse(request.uri)[4]
203         path = self.path+'/'.join(request.postpath)
204         if qs:
205             rest = path + '?' + qs
206         else:
207             rest = path
208         clientFactory = ProxyClientFactory(request.method, rest,
209                                      request.clientproto,
210                                      request.getAllHeaders(),
211                                      request.content.read(),
212                                      request)
213         self.connector.connect(clientFactory)
214         return server.NOT_DONE_YET
Note: See TracBrowser for help on using the browser.