[Twisted-web] Cheetah+twisted.web2

Andrea Arcangeli andrea at cpushare.com
Thu Jan 19 05:52:26 MST 2006


On Wed, Jan 18, 2006 at 10:04:41PM -0800, David Reid wrote:
> On Thu, 2006-01-19 at 00:34 -0500, glyph at divmod.com wrote:
> > 
> > On Wed, 18 Jan 2006 20:34:39 -0800, David Reid <dreid at dreid.org> wrote:
> > 
> > >this is set when the initial request is processed to
> > >self.chanRequest.getRemoteHost() so just set req.remote_addr and use
> > >that farther down the line.
> > 
> > erm, maybe I'm missing something - is there a reason that second attribute name violates the coding standard?
> 
> oh, because I'm a doofus and wasn't paying attention to the code I was
> actually writing. (fixed in r15632)

This fixes one logging bug:

Index: twisted/web2/log.py
===================================================================
--- twisted/web2/log.py	(revision 15632)
+++ twisted/web2/log.py	(working copy)
@@ -144,7 +144,7 @@
         
         self.logMessage(
             '%s - %s [%s] "%s" %s %d "%s" "%s"' %(
-                request.chanRequest.getRemoteHost().host,
+                request.remoteAddr.host,
                 # XXX: Where to get user from?
                 "-",
                 self.logDateString(


This is the diff for klive to adapt to the new logic:

Index: server/web.py
===================================================================
RCS file: /home/andrea/crypto/cvs/klive/server/web.py,v
retrieving revision 1.110
retrieving revision 1.111
diff -u -p -r1.110 -r1.111
--- server/web.py	18 Jan 2006 08:02:23 -0000	1.110
+++ server/web.py	19 Jan 2006 12:39:12 -0000	1.111
@@ -131,7 +131,7 @@ class basefrag_class(object):
 		if ip == self.all:
 			return ''
 		if 1:
-			web_client_ip = req.chanRequest.getRemoteHost().host
+			web_client_ip = req.remoteAddr.host
 			if ip != web_client_ip:
 				return
 		kwargs['host'] = md5.new(ip).hexdigest()
@@ -623,7 +623,7 @@ class smp_class(basefrag_class):
 
 class ip_class(basefrag_class):
 	def render(self, req):
-		ip = req.chanRequest.getRemoteHost().host
+		ip = req.remoteAddr.host
 		entries = [(self.all,), (ip,),]
 		t = Template(file=XMLDIR+'archs.xml')
 		t.entries = (self.render_machine(req, x) for x in entries)
@@ -1063,13 +1063,8 @@ class myvhost(object):
 
 		if not req.prepath and segments[0] == 'vhost':
 			host, port = segments[3].split(':')
-			class remote(object):
-				def __init__(self, host, port):
-					from twisted.internet import address
-					self.client = address.IPv4Address("TCP", host, int(port))
-				def getRemoteHost(self):
-					return self.client
-			req.chanRequest.getRemoteHost = remote(host,port).getRemoteHost
+			from twisted.internet import address
+			req.remoteAddr = address.IPv4Address("TCP", host, int(port))
 			cut_len = len('/'.join(segments[:4])) + 1
 			req.uri = req.uri[cut_len:]
 			req.path = req.path[cut_len:]


A few things on vhost (without going into the guard details yet):

1) the web2.vhost seems buggy not fixing up the req.uri, I had to fixup
req.uri to get logging right in my vhost hack that understand the
twisted.web reverse proxy with clientPass=True (my old twisted.web patch)
2) assuming that I had web2 on the reverse proxy, would it already pass
down the remote_ip information, or only apache2 does that? (the only one
capable of receiving the remote_ip is AutoVHostURIRewrite, but the
deployment only talks about apache2, Also note for me it's fundamentally
important for security reasons to have the port too, one needs the port
to safely indentify a box behind a nat (assuming the nat admin is
capable of logging all connection tracking but if he doesn't he will
take the blame). Is the apache2/twisted.web2 reverseproxy protocol
passing down the peer port too in the x-forwarded-host?
3) if answer to 2 is no, can I forward port to web2 my simple hack to
twisted.web that I need in order to plug klive on top twisted.web2?

Here for reference my old patch that is running on cpushare.com today
and that my web2 vhost hack is understanding and that passes down to
klive both ip and port (setClient was actually used by the nevow.vhost,
now obsoleted by web2 req.remoteAddr)

Index: Twisted/twisted/web/http.py
===================================================================
--- Twisted/twisted/web/http.py	(revision 15632)
+++ Twisted/twisted/web/http.py	(working copy)
@@ -876,6 +876,10 @@
         self.received_headers["host"] = host
         self.host = address.IPv4Address("TCP", host, port)
 
+    def setClient(self, host, port):
+        """Same as setHost but for the client address"""
+        self.client = address.IPv4Address("TCP", host, port)
+
     def getClientIP(self):
         if isinstance(self.client, address.IPv4Address):
             return self.client.host
Index: Twisted/twisted/web/proxy.py
===================================================================
--- Twisted/twisted/web/proxy.py	(revision 15632)
+++ Twisted/twisted/web/proxy.py	(working copy)
@@ -162,23 +162,33 @@
     to a different server.
     """
 
-    def __init__(self, host, port, path):
+    def __init__(self, host, port, path, passClient = False):
         resource.Resource.__init__(self)
         self.host = host
         self.port = port
         self.path = path
+        self.passClient = passClient
 
+    def getPath(self, request):
+        path = self.path
+        if self.passClient:
+            path += '/%s:%d' % (request.client.host, request.client.port)
+        return path
+
     def getChild(self, path, request):
-        return ReverseProxyResource(self.host, self.port, self.path+'/'+path)
+        return ReverseProxyResource(self.host, self.port, self.getPath(request)+'/'+path, False)
 
     def render(self, request):
         request.received_headers['host'] = self.host
         request.content.seek(0, 0)
+
+        path = self.getPath(request)
+
         qs = urlparse.urlparse(request.uri)[4]
         if qs:
-            rest = self.path + '?' + qs
+            rest = path + '?' + qs
         else:
-            rest = self.path
+            rest = path
         clientFactory = ProxyClientFactory(request.method, rest, 
                                      request.clientproto, 
                                      request.getAllHeaders(),

One more question, you said the channel is private, why don't we add __
in front of it. Python is capable of autodocumenting without possibility
for mistakes all private parts of a class.

Thanks a lot!



More information about the Twisted-web mailing list