Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(60)

Side by Side Diff: third_party/twisted_8_1/twisted/web/proxy.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.web.test.test_proxy -*-
2 # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5 """
6 Simplistic HTTP proxy support.
7
8 This comes in two main variants - the Proxy and the ReverseProxy.
9
10 When a Proxy is in use, a browser trying to connect to a server (say,
11 www.yahoo.com) will be intercepted by the Proxy, and the proxy will covertly
12 connect to the server, and return the result.
13
14 When a ReverseProxy is in use, the client connects directly to the ReverseProxy
15 (say, www.yahoo.com) which farms off the request to one of a pool of servers,
16 and returns the result.
17
18 Normally, a Proxy is used on the client end of an Internet connection, while a
19 ReverseProxy is used on the server end.
20 """
21
22 import urlparse
23 from urllib import quote as urlquote
24
25 from twisted.internet import reactor
26 from twisted.internet.protocol import ClientFactory
27 from twisted.web.resource import Resource
28 from twisted.web.server import NOT_DONE_YET
29 from twisted.web.http import HTTPClient, Request, HTTPChannel
30
31
32
33 class ProxyClient(HTTPClient):
34 """
35 Used by ProxyClientFactory to implement a simple web proxy.
36 """
37
38 def __init__(self, command, rest, version, headers, data, father):
39 self.father = father
40 self.command = command
41 self.rest = rest
42 if "proxy-connection" in headers:
43 del headers["proxy-connection"]
44 headers["connection"] = "close"
45 self.headers = headers
46 self.data = data
47
48
49 def connectionMade(self):
50 self.sendCommand(self.command, self.rest)
51 for header, value in self.headers.items():
52 self.sendHeader(header, value)
53 self.endHeaders()
54 self.transport.write(self.data)
55
56
57 def handleStatus(self, version, code, message):
58 if message:
59 # Add a whitespace to message, this allows empty messages
60 # transparently
61 message = " %s" % (message,)
62 self.father.transport.write("%s %s%s\r\n" % (version, code, message))
63
64
65 def handleHeader(self, key, value):
66 self.father.transport.write("%s: %s\r\n" % (key, value))
67
68
69 def handleEndHeaders(self):
70 self.father.transport.write("\r\n")
71
72
73 def handleResponsePart(self, buffer):
74 self.father.transport.write(buffer)
75
76
77 def handleResponseEnd(self):
78 self.transport.loseConnection()
79 self.father.channel.transport.loseConnection()
80
81
82
83 class ProxyClientFactory(ClientFactory):
84 """
85 Used by ProxyRequest to implement a simple web proxy.
86 """
87
88 protocol = ProxyClient
89
90
91 def __init__(self, command, rest, version, headers, data, father):
92 self.father = father
93 self.command = command
94 self.rest = rest
95 self.headers = headers
96 self.data = data
97 self.version = version
98
99
100 def buildProtocol(self, addr):
101 return self.protocol(self.command, self.rest, self.version,
102 self.headers, self.data, self.father)
103
104
105 def clientConnectionFailed(self, connector, reason):
106 self.father.transport.write("HTTP/1.0 501 Gateway error\r\n")
107 self.father.transport.write("Content-Type: text/html\r\n")
108 self.father.transport.write("\r\n")
109 self.father.transport.write('''<H1>Could not connect</H1>''')
110 self.father.transport.loseConnection()
111
112
113
114 class ProxyRequest(Request):
115 """
116 Used by Proxy to implement a simple web proxy.
117
118 @ivar reactor: the reactor used to create connections.
119 @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
120 """
121
122 protocols = {'http': ProxyClientFactory}
123 ports = {'http': 80}
124
125 def __init__(self, channel, queued, reactor=reactor):
126 Request.__init__(self, channel, queued)
127 self.reactor = reactor
128
129
130 def process(self):
131 parsed = urlparse.urlparse(self.uri)
132 protocol = parsed[0]
133 host = parsed[1]
134 port = self.ports[protocol]
135 if ':' in host:
136 host, port = host.split(':')
137 port = int(port)
138 rest = urlparse.urlunparse(('', '') + parsed[2:])
139 if not rest:
140 rest = rest + '/'
141 class_ = self.protocols[protocol]
142 headers = self.getAllHeaders().copy()
143 if 'host' not in headers:
144 headers['host'] = host
145 self.content.seek(0, 0)
146 s = self.content.read()
147 clientFactory = class_(self.method, rest, self.clientproto, headers,
148 s, self)
149 self.reactor.connectTCP(host, port, clientFactory)
150
151
152
153 class Proxy(HTTPChannel):
154 """
155 This class implements a simple web proxy.
156
157 Since it inherits from L{twisted.protocols.http.HTTPChannel}, to use it you
158 should do something like this::
159
160 from twisted.web import http
161 f = http.HTTPFactory()
162 f.protocol = Proxy
163
164 Make the HTTPFactory a listener on a port as per usual, and you have
165 a fully-functioning web proxy!
166 """
167
168 requestFactory = ProxyRequest
169
170
171
172 class ReverseProxyRequest(Request):
173 """
174 Used by ReverseProxy to implement a simple reverse proxy.
175
176 @ivar proxyClientFactoryClass: a proxy client factory class, used to create
177 new connections.
178 @type proxyClientFactoryClass: L{ClientFactory}
179
180 @ivar reactor: the reactor used to create connections.
181 @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
182 """
183
184 proxyClientFactoryClass = ProxyClientFactory
185
186 def __init__(self, channel, queued, reactor=reactor):
187 Request.__init__(self, channel, queued)
188 self.reactor = reactor
189
190
191 def process(self):
192 self.received_headers['host'] = self.factory.host
193 clientFactory = self.proxyClientFactoryClass(
194 self.method, self.uri, self.clientproto, self.getAllHeaders(),
195 self.content.read(), self)
196 self.reactor.connectTCP(self.factory.host, self.factory.port,
197 clientFactory)
198
199
200
201 class ReverseProxy(HTTPChannel):
202 """
203 Implements a simple reverse proxy.
204
205 For details of usage, see the file examples/proxy.py.
206 """
207
208 requestFactory = ReverseProxyRequest
209
210
211
212 class ReverseProxyResource(Resource):
213 """
214 Resource that renders the results gotten from another server
215
216 Put this resource in the tree to cause everything below it to be relayed
217 to a different server.
218
219 @ivar proxyClientFactoryClass: a proxy client factory class, used to create
220 new connections.
221 @type proxyClientFactoryClass: L{ClientFactory}
222
223 @ivar reactor: the reactor used to create connections.
224 @type reactor: object providing L{twisted.internet.interfaces.IReactorTCP}
225 """
226
227 proxyClientFactoryClass = ProxyClientFactory
228
229
230 def __init__(self, host, port, path, reactor=reactor):
231 """
232 @param host: the host of the web server to proxy.
233 @type host: C{str}
234
235 @param port: the port of the web server to proxy.
236 @type port: C{port}
237
238 @param path: the base path to fetch data from. Note that you shouldn't
239 put any trailing slashes in it, it will be added automatically in
240 request. For example, if you put B{/foo}, a request on B{/bar} will
241 be proxied to B{/foo/bar}. Any required encoding of special
242 characters (such as " " or "/") should have been done already.
243
244 @type path: C{str}
245 """
246 Resource.__init__(self)
247 self.host = host
248 self.port = port
249 self.path = path
250 self.reactor = reactor
251
252
253 def getChild(self, path, request):
254 """
255 Create and return a proxy resource with the same proxy configuration
256 as this one, except that its path also contains the segment given by
257 C{path} at the end.
258 """
259 return ReverseProxyResource(
260 self.host, self.port, self.path + '/' + urlquote(path, safe=""))
261
262
263 def render(self, request):
264 """
265 Render a request by forwarding it to the proxied server.
266 """
267 # RFC 2616 tells us that we can omit the port if it's the default port,
268 # but we have to provide it otherwise
269 if self.port == 80:
270 request.received_headers['host'] = self.host
271 else:
272 request.received_headers['host'] = "%s:%d" % (self.host, self.port)
273 request.content.seek(0, 0)
274 qs = urlparse.urlparse(request.uri)[4]
275 if qs:
276 rest = self.path + '?' + qs
277 else:
278 rest = self.path
279 clientFactory = self.proxyClientFactoryClass(
280 request.method, rest, request.clientproto,
281 request.getAllHeaders(), request.content.read(), request)
282 self.reactor.connectTCP(self.host, self.port, clientFactory)
283 return NOT_DONE_YET
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/web/monitor.py ('k') | third_party/twisted_8_1/twisted/web/resource.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698