]> review.fuel-infra Code Review - packages/trusty/python-eventlet.git/blob - examples/twisted/twisted_http_proxy.py
Add python-eventlet package to MOS 9.0 repository
[packages/trusty/python-eventlet.git] / examples / twisted / twisted_http_proxy.py
1 """Listen on port 8888 and pretend to be an HTTP proxy.
2 It even works for some pages.
3
4 Demonstrates how to
5  * plug in eventlet into a twisted application (join_reactor)
6  * call green functions from places where blocking calls
7    are not allowed (deferToGreenThread)
8  * use eventlet.green package which provides [some of] the
9    standard library modules that don't block other greenlets.
10 """
11 import re
12 from twisted.internet.protocol import Factory
13 from twisted.internet import reactor
14 from twisted.protocols import basic
15
16 from eventlet.twistedutil import deferToGreenThread
17 from eventlet.twistedutil import join_reactor
18 from eventlet.green import httplib
19
20 class LineOnlyReceiver(basic.LineOnlyReceiver):
21
22     def connectionMade(self):
23         self.lines = []
24
25     def lineReceived(self, line):
26         if line:
27             self.lines.append(line)
28         elif self.lines:
29             self.requestReceived(self.lines)
30             self.lines = []
31
32     def requestReceived(self, lines):
33         request = re.match('^(\w+) http://(.*?)(/.*?) HTTP/1..$', lines[0])
34         #print request.groups()
35         method, host, path = request.groups()
36         headers = dict(x.split(': ', 1) for x in lines[1:])
37         def callback(result):
38             self.transport.write(str(result))
39             self.transport.loseConnection()
40         def errback(err):
41             err.printTraceback()
42             self.transport.loseConnection()
43         d = deferToGreenThread(http_request, method, host, path, headers=headers)
44         d.addCallbacks(callback, errback)
45
46 def http_request(method, host, path, headers):
47     conn = httplib.HTTPConnection(host)
48     conn.request(method, path, headers=headers)
49     response = conn.getresponse()
50     body = response.read()
51     print(method, host, path, response.status, response.reason, len(body))
52     return format_response(response, body)
53
54 def format_response(response, body):
55     result = "HTTP/1.1 %s %s" % (response.status, response.reason)
56     for k, v in response.getheaders():
57         result += '\r\n%s: %s' % (k, v)
58     if body:
59         result += '\r\n\r\n'
60         result += body
61         result += '\r\n'
62     return result
63
64 class MyFactory(Factory):
65     protocol = LineOnlyReceiver
66
67 print(__doc__)
68 reactor.listenTCP(8888, MyFactory())
69 reactor.run()