@@ -76,6 +76,7 @@ def handle_accepted(self, sock, addr):
7676from .log import debug
7777from .log import is_logging_configured
7878from .log import logger
79+ from .proxy_proto import ProxyProtocol
7980
8081
8182timer = getattr (time , 'monotonic' , time .time )
@@ -427,9 +428,9 @@ def unregister(self, fd):
427428 del self .socket_map [fd ]
428429 except KeyError :
429430 debug ("call: unregister(); fd was no longer in socket_map" , self )
430- for l in (self ._r , self ._w ):
431+ for loop in (self ._r , self ._w ):
431432 try :
432- l .remove (fd )
433+ loop .remove (fd )
433434 except ValueError :
434435 pass
435436
@@ -977,8 +978,29 @@ def add_channel(self, map=None, events=None):
977978class Acceptor (AsyncChat ):
978979 """Same as base AsyncChat and supposed to be used to
979980 accept new connections.
981+
982+ All relevant PROXY protocol information is stored in class attributes
983+ described below.
984+
985+ - (bool) proxy_proto_enabled:
986+ enable the use of PROXY protocol (defaults to False).
987+
988+ - (list) proxy_proto_trusted_nets:
989+ the IP networks of the proxies you want to trust. Use a /32 (or /128) network
990+ mask if you want to declare a single IP (defaults to []).
991+
992+ - (bool) proxy_proto_allow_untrusted:
993+ whether or not to parse untrusted proxies headers (defaults to True).
994+
995+ - (instance) proxy_proto_obj:
996+ the ProxyProtocol instance populated with header's information
980997 """
981998
999+ proxy_proto_enabled = False
1000+ proxy_proto_trusted_nets = []
1001+ proxy_proto_allow_untrusted = True
1002+ proxy_proto_obj = None
1003+
9821004 def add_channel (self , map = None , events = None ):
9831005 AsyncChat .add_channel (self , map = map , events = self .ioloop .READ )
9841006
@@ -1045,6 +1067,21 @@ def handle_accept(self):
10451067 debug ("call: handle_accept(); accept() returned ECONNABORTED" ,
10461068 self )
10471069 else :
1070+ if self .proxy_proto_enabled :
1071+ # Retrieve a populated PROXY protocol object. If no exception
1072+ # is raised the returned object is considered valid
1073+ try :
1074+ ProxyProtocol .trusted_networks = self .proxy_proto_trusted_nets
1075+ ProxyProtocol .allow_untrusted = self .proxy_proto_allow_untrusted
1076+ self .proxy_proto_obj = ProxyProtocol .create (sock )
1077+ except Exception as e :
1078+ logger .error ("proxy: {}" .format (e ))
1079+ return
1080+
1081+ if self .proxy_proto_obj .trusted or self .proxy_proto_allow_untrusted :
1082+ # Could result in a (None, None) tuple
1083+ addr = (self .proxy_proto_obj .remote_ip , self .proxy_proto_obj .remote_port )
1084+
10481085 # sometimes addr == None instead of (ip, port) (see issue 104)
10491086 if addr is not None :
10501087 self .handle_accepted (sock , addr )
0 commit comments