[Twisted-Python] twisted reverse proxy for web filtering

Mike Kazantsev mk.fraggod at gmail.com
Wed Dec 10 20:46:09 EST 2008

On Sun, 30 Nov 2008 21:54:17 -0600
"dave fowler" <davefowler at gmail.com> wrote:

> I'd like to use python and in my research I think a twisted reverse proxy is
> what I want.  I've done the examples for setting up a proxy, including one
> that counts the words on the pages you visit, but i cannot find anything on
> fetching the destination and re-directing.  I've been sifting through the
> many classes of the proxy examples and am pretty lost.  Does anyone have
> some example code for something like this?
> Thanks
> Dave

I use following code to add '/trac' child to nevow (twisted.web extension) page with https-only access, mangling 'Location' header of returned answer to prevent redirects to non-existing urls.
You can probably mangle request the same way before passing it to render method, overriding returned headers and/or data afterwards in client class.
I doubt it'll be the fastest solution out there, but it certainly should be quite flexible.

from urllib import quote as urlquote
from twisted.web.proxy import ReverseProxyResource, ProxyClient, ProxyClientFactory

redirect = '<html><head><title>302 Found</title><meta http-equiv="REFRESH" content="0; url=%s"><script>document.write("<style>a {color:#fff;visibility:hidden;}<style>");window.location="%s"</script></head><body><a href="%s">click here</a></body></html>'

class SokLeechFactory(ProxyClientFactory):
	protocol = SokLeech

class SokLeech(ProxyClient):
	def handleHeader(self, key, value):
		'''Wrapper method to mangle Location header to point to original host'''
		if key == 'Location': value = value.replace(self.father.received_headers['host'], self.father.origin)
		ProxyClient.handleHeader(self, key, value)

class SslLinker(ReverseProxyResource):
	'''Wrapper class to inject some mangling into proxy protocol'''
	proxyClientFactoryClass = SokLeechFactory
	def getChild(self, path, request):
		return self.__class__(self.host, self.port, self.path + '/' + urlquote(path, safe=""))
	def render(self, request):
		'''Wrapper method to store host from original request'''
		if not request.isSecure():
			secure_url = 'https://%s:%s%s'%(request.getRequestHostname(), cfg.web.pen.split(':',3)[1], request.uri)
			return redirect.replace('%s', secure_url)
		request.origin = request.getRequestHostname()
		ReverseProxyResource.render(self, request)

class Page(LivePage):
	child_trac = SslLinker(self.cfg.trac.host, self.cfg.trac.port, '/svc/trac')

Mike Kazantsev // fraggod.net
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
Url : http://twistedmatrix.com/pipermail/twisted-python/attachments/20081211/8f5d6f31/attachment.pgp 

More information about the Twisted-Python mailing list