[Twisted-web] Nevow VHostMonsterResource and lighttpd

Richard Wall m-lists at the-moon.net
Thu Dec 15 17:02:50 MST 2005


I got Nevow examples.tac and a simple Mantissa app working behind a
lighttpd reverse proxy, by adding a VHostMonsterResource to the root
resource in each case.

However, the lighttpd proxy request headers seem to contain enough
information about the public request (scheme, hostname, port), that I
wonder if VHostMonsterResource is always necessary.

For example given lighttpd listening on localhost.localdomain:10080 and
netcat listening at localhost.localdomain:8080, the headers look like
this...

richard at lazar:~$ nc -v -l -p 8080
listening on [any] 8080 ...
connect to [127.0.0.1] from localhost.localdomain [127.0.0.1] 34734
GET / HTTP/1.0
Host: localhost.localdomain:10080
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.7.12)
Gecko/20051010 Firefox/1.0.7 (Ubuntu package 1.0.7)
Accept:
text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: UTF-8,*
Keep-Alive: 300
X-Forwarded-For: 127.0.0.1
X-Host: localhost.localdomain:10080
X-Forwarded-Proto: http

Infact, in my case anyway, the only problem running behind a proxy is
that twisted.web refers to it's listening port instead of reading it
from the http headers. Looking at  twisted.web.server the following
change fixes the port problem for me...

Index: /home/richard/lib/Twisted/trunk/twisted/web/server.py
===================================================================
--- /home/richard/lib/Twisted/trunk/twisted/web/server.py	(revision 15339)
+++ /home/richard/lib/Twisted/trunk/twisted/web/server.py	(working copy)
@@ -342,11 +342,17 @@
         return self.session

     def _prePathURL(self, prepath):
-        port = self.getHost().port
         if self.isSecure():
             default = 443
         else:
             default = 80
+
+        hostheader = self.getHeader('host')
+        if hostheader:
+            port = int(dict(zip(('hostname', 'port'),
hostheader.split(":"))).get('port', default))
+        else:
+            port = self.getHost().port
+
         if port == default:
             hostport = ''
         else:

...which just checks if there is a host header and gets the port number
from there if it's available. I can't think that this would break
anything and I hope someone will consider applying it.

The second problem, I suppose, is with https. I haven't been able test
it yet because I haven't got ssl working with lighttpd, but i should
think the solution would be to check for the "X-Forwarded-Proto" header
and if it exists, replace the request.isSecure method as in
VHostMonsterResource. Once I am able to try this, I'll submit a patch.

I'm not sure though whether this header is standard in reverse proxies
or whether it's specific to lighttpd. Will try and check with Apache.

The only remaining need for VHostMonsterResource then, is when you want
to serve a Nevow app at a none root url. I wondered if it might be
possible to add another header (eg X-Root-Path) using mod_headers and
use that somewhere in the nevow.url class. Again, if I get chance to
test this, I'll submit a patch.
-- 
Richard Wall

PS. According to Jan Knesche, Lighttpd mod_proxy will shortly have the
ability to forward requests to a Unix socket which I think will provide
quite a neat way of doing name based virtual hosting of multiple
twisted.web sites.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: port-from-http-header.patch
Type: text/x-patch
Size: 824 bytes
Desc: not available
Url : http://twistedmatrix.com/pipermail/twisted-web/attachments/20051216/1e70bd3e/port-from-http-header.bin


More information about the Twisted-web mailing list