Reverse Proxy¶
A Reverse Proxy forwards the requests it receives from the internet to one or more slave webservers. Lighttpd and Apache both provide reverse proxy modules. Any absolute urls in the response will contain the scheme (possibly the hostname) and port number on which the slave is running. These must be rewritten before being returned to the client. In Nevow this can be handled by vhost.VHostMonsterResource.
Example 1¶
You have an existing webserver running on port 80, doing name based virtual hosting of several existing websites and want to run a Nevow based site alongside them on the same IP.
Solution¶
Forward all requests at this virtual host to the Nevow slave server.
Sample Nevow App¶
from zope.interface import implements
from twisted.application import service, strports
from nevow import appserver, inevow, loaders, rend, url, vhost
class MyPage(rend.Page):
'''
I am a simple resource for demo purposes only. I will return a 'MyPage'
for any child you ask me to locate. I display the current url as calculated
nevow.url.
'''
addSlash = True
docFactory = loaders.xmlstr('''
<html xmlns:n='http://nevow.com/ns/nevow/0.1'>
<head>
<title n:render='urlpath'></title>
</head>
<body>
<h1 n:render='urlpath'></h1>
</body>
</html>
''')
def render_urlpath(self, ctx, data):
return ctx.tag[url.here]
def locateChild(self, ctx, segments):
return MyPage(), segments[1:]
class VhostFakeRoot:
'''
I am a wrapper to be used at site root when you want to combine
vhost.VHostMonsterResource with nevow.guard. If you are using guard, you
will pass me a guard.SessionWrapper resource.
'''
implements(inevow.IResource)
def __init__(self, wrapped):
self.wrapped = wrapped
def renderHTTP(self, ctx):
return self.wrapped.renderHTTP(ctx)
def locateChild(self, ctx, segments):
'''Returns a VHostMonster if the first segment is 'vhost'. Otherwise
delegates to the wrapped resource.'''
if segments[0] == 'vhost':
return vhost.VHostMonsterResource(), segments[1:]
else:
return self.wrapped.locateChild(ctx, segments)
siteRoot = VhostFakeRoot(MyPage())
application = service.Application('reverse proxy / vhost example')
strports.service('8080', appserver.NevowSite(siteRoot)).setServiceParent(application)
Save as eg sample.tac and run using twistd -noy sample.tac
Sample Lighttpd Config:¶
$HTTP['host'] =~ '^(www.example.com)$' {
url.rewrite-once = ('^/(.*)' => '/vhost/http/%0/$1')
# In lighttpd we alter the path manually using rewrite rule. %0
# refers to the hostname and $1 is the path.
proxy.server = ( '' =>
( (
'host' => '127.0.0.1',
'port' => 8080
) )
)
}
If you prefer a mixed deployment strategy where static content is served through the faster lighttpd while dynamic content is still served by twisted you can use the following recipe.
$HTTP['host'] =~ '^(www.example.org)$' {
url.rewrite-once = (
'^/static/.*' => '$0',
'^/(.*)' => '/vhost/http/%0/$1'
)
$HTTP['url'] !~ '^/static/' {
proxy.server = ( '' =>
( (
'host' => '127.0.0.1',
'port' => 8080
) )
)
}
server.document-root = '/path/to/your/project/trunk/'
}
- There are 2 assumptions in this recipe:
- The static content is located at the /static/ subtree of the website.
- The project root contains a ‘static’ directory that is used to serve static content.
Sample Apache Config (Ref)¶
<VirtualHost www.example.com>
ProxyPass / http://localhost:8080/vhost/http/www.example.com/
ServerName www.example.com
</VirtualHost>
Example 2¶
Nevow is only to be used for part of an existing static site at a non-root url
Sample Lighttpd Config:¶
TODO
Sample Apache Config¶
TODO