From aad4bba29daf1e2cb0e309e10792f89d38f0abdd Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 10 Dec 2008 16:35:21 +0600 Subject: [PATCH] added examples/twisted_http_proxy.py --- examples/twisted_http_proxy.py | 67 ++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 examples/twisted_http_proxy.py diff --git a/examples/twisted_http_proxy.py b/examples/twisted_http_proxy.py new file mode 100644 index 0000000..262f534 --- /dev/null +++ b/examples/twisted_http_proxy.py @@ -0,0 +1,67 @@ +"""Listen on port 8888 and pretend to be an HTTP proxy. +It even works for some pages. + +Demonstrates how to + * plug in eventlet into a twisted application (join_reactor) + * call green functions from places where blocking calls + are not allowed (deferToGreenThread) + * use eventlet.green package which provides [some of] the + standard library modules that don't block other greenlets. +""" +import re +from twisted.internet.protocol import Factory +from twisted.internet import reactor +from twisted.protocols import basic + +from eventlet.twistedutil import deferToGreenThread +from eventlet.twistedutil import join_reactor +from eventlet.green import httplib + +class LineOnlyReceiver(basic.LineOnlyReceiver): + + def connectionMade(self): + self.lines = [] + + def lineReceived(self, line): + if line: + self.lines.append(line) + elif self.lines: + self.requestReceived(self.lines) + self.lines = [] + + def requestReceived(self, lines): + request = re.match('^(\w+) http://(.*?)(/.*?) HTTP/1..$', lines[0]) + print request.groups() + method, host, path = request.groups() + headers = dict(x.split(': ', 1) for x in lines[1:]) + def callback(result): + self.transport.write(str(result)) + self.transport.loseConnection() + def errback(err): + err.printTraceback() + self.transport.loseConnection() + d = deferToGreenThread(http_request, method, host, path, headers=headers) + d.addCallbacks(callback, errback) + +def http_request(method, host, path, headers): + conn = httplib.HTTPConnection(host) + conn.request(method, path, headers=headers) + response = conn.getresponse() + return format_response(response) + +def format_response(response): + body = response.read() + result = "HTTP/1.1 %s %s" % (response.status, response.reason) + for k, v in response.getheaders(): + result += '\r\n%s: %s' % (k, v) + if body: + result += '\r\n\r\n' + result += body + result += '\r\n' + return result + +class MyFactory(Factory): + protocol = LineOnlyReceiver + +reactor.listenTCP(8888, MyFactory()) +reactor.run()