- def cancelTimeout(self):
- if self.customTimeout is not None:
- try:
- self.customTimeout.cancel()
- self.customTimeout = None
- except error.AlreadyCalled:
- pass
-
- def connectionLost(self, reason):
- self.cancelTimeout()
- http.HTTPChannel.connectionLost(self, reason)
+ def _getClientIP(self):
+ # twisted.web.http.Request.getClientIP returns None if not IPv4;
+ # client.host has the real address
+
+ if not hasattr(self, "client") or not hasattr(self.client, "host"):
+ return None
+
+ real_ip = self.client.host
+
+ if real_ip[:7] == "::ffff:":
+ real_ip = real_ip[7:]
+
+ if not hasattr(config, "FORWARDED_FOR_HEADER"):
+ return real_ip
+
+ 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
+
+ def getClientIP(self):
+ ip = self._getClientIP()
+
+ if ip is None:
+ return None
+
+ # make absolutely sure that the address doesn't start with : before we
+ # try to use it as a string to the IRC server!
+ return ip.lstrip(":")
+
+class HTTPChannel(http.HTTPChannel):
+ def timeoutConnection(self):
+ self.transport.abortConnection()