]> jfr.im git - irc/quakenet/qwebirc.git/commitdiff
Add HTTP X-Forwarded-For support (fixes issue 30).
authorChris Porter <redacted>
Fri, 31 Jul 2009 00:09:45 +0000 (01:09 +0100)
committerChris Porter <redacted>
Fri, 31 Jul 2009 00:09:45 +0000 (01:09 +0100)
config.py.example
qwebirc/engines/ajaxengine.py
qwebirc/root.py

index ac727d9d0c2d0a076bce0d2bce192e152c14e6df..36871a2af89c1696f3e98dcce6e0378c96bee692 100644 (file)
@@ -118,6 +118,20 @@ FEEDBACK_SMTP_HOST, FEEDBACK_SMTP_PORT = "127.0.0.1", 25
 #         http://instance/adminengine
 ADMIN_ENGINE_HOSTS = ["127.0.0.1"]
 
+# PROXY OPTIONS
+# ---------------------------------------------------------------------
+#
+# OPTION: FORWARDED_FOR_HEADER
+#         If you're using a proxy that passes through a forwarded-for
+#         header set this option to the header name, also set
+#         FORWARDED_FOR_IPS.
+#FORWARDED_FOR_HEADER="x-forwarded-for"
+# OPTION: FORWARDED_FOR_IPS
+#         This option specifies the IP addresses that forwarded-for
+#         headers will be accepted from.
+#FORWARDED_FOR_IPS=["127.0.0.1"]
+
 # EXECUTION OPTIONS
 # ---------------------------------------------------------------------
 #
index a7acb464e6ee8bec3b9a8b1c2ce180d7dd3930bb..a6aca3ebe39feab55db98cad71a814984fe7763d 100644 (file)
@@ -183,7 +183,7 @@ class AJAXEngine(resource.Resource):
   def newConnection(self, request):
     ticket = login_optional(request)
     
-    _, ip, port = request.transport.getPeer()
+    ip = request.getClientIP()
 
     nick = request.args.get("nick")
     if not nick:
index 99464c1fb93d91edf97fcc92e81a66f6f6f80038..73d039aac679b9b893599e813ad2e9e8d0c32719 100644 (file)
@@ -4,6 +4,7 @@ import engines
 import mimetypes
 import config
 import sigdebug
+import re
 
 class RootResource(resource.Resource):
   def getChild(self, name, request):
@@ -35,10 +36,36 @@ class TimeoutHTTPChannel(http.HTTPChannel):
     self.cancelTimeout()
     http.HTTPChannel.connectionLost(self, reason)
 
+class ProxyRequest(server.Request):
+  ip_re = re.compile(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$")
+  def validIP(self, ip):
+    m = self.ip_re.match(ip)
+    if m is None:
+      return False
+    return all(int(m.group(x)) < 256 for x in range(1, 4+1))
+    
+  def getClientIP(self):
+    real_ip = http.Request.getClientIP(self)
+    if real_ip not in config.FORWARDED_FOR_IPS:
+      return real_ip
+      
+    fake_ips = self.getHeader(config.FORWARDED_FOR_HEADER)
+    if fake_ips is None:
+      return real_ip
+      
+    fake_ip = fake_ips.split(",")[-1].strip()
+    if not self.validIP(fake_ip):
+      return real_ip
+      
+    return fake_ip
+    
 class RootSite(server.Site):
   # we do this ourselves as the built in timeout stuff is really really buggy
   protocol = TimeoutHTTPChannel
   
+  if hasattr(config, "FORWARDED_FOR_HEADER"):
+    requestFactory = ProxyRequest
+
   def __init__(self, path, *args, **kwargs):
     root = RootResource()
     server.Site.__init__(self, root, *args, **kwargs)