2929           'FileCookieJar' , 'LWPCookieJar' , 'LoadError' , 'MozillaCookieJar' ]
3030
3131import  os 
32- import  copy 
33- import  datetime 
3432import  re 
33+ import  copy 
3534import  time 
35+ import  datetime 
3636import  urllib .parse , urllib .request 
3737import  threading  as  _threading 
3838import  http .client   # only for the default HTTP port 
3939from  calendar  import  timegm 
40+ from  ipaddress  import  ip_address 
4041
4142debug  =  False    # set to True to enable debugging via the logging module 
4243logger  =  None 
@@ -533,14 +534,21 @@ def parse_ns_headers(ns_headers):
533534
534535
535536IPV4_RE  =  re .compile (r"\.\d+$" , re .ASCII )
537+ def  is_ip (text ):
538+     """Return True if text is a valid IP address.""" 
539+     # This function is a replacement of regex `IPV4_RE` in previous versions. 
540+     try :
541+         ip_address (text )
542+         return  True 
543+     except  ValueError :
544+         return  False 
536545def  is_HDN (text ):
537546    """Return True if text is a host domain name.""" 
538547    # XXX 
539548    # This may well be wrong.  Which RFC is HDN defined in, if any (for 
540549    #  the purposes of RFC 2965)? 
541-     # For the current implementation, what about IPv6?  Remember to look 
542-     #  at other uses of IPV4_RE also, if change this. 
543-     if  IPV4_RE .search (text ):
550+     # Both IPv4 and IPv6 are supported. 
551+     if  is_ip (text ):
544552        return  False 
545553    if  text  ==  "" :
546554        return  False 
@@ -593,7 +601,7 @@ def liberal_is_HDN(text):
593601    For accepting/blocking domains. 
594602
595603    """ 
596-     if  IPV4_RE . search (text ):
604+     if  is_ip (text ):
597605        return  False 
598606    return  True 
599607
@@ -607,9 +615,10 @@ def user_domain_match(A, B):
607615    B  =  B .lower ()
608616    if  not  (liberal_is_HDN (A ) and  liberal_is_HDN (B )):
609617        if  A  ==  B :
610-             # equal IP  addresses 
618+             # equal IPv4  addresses 
611619            return  True 
612620        return  False 
621+     # A and B may be HDNs or a IPv6 addresses now 
613622    initial_dot  =  B .startswith ("." )
614623    if  initial_dot  and  A .endswith (B ):
615624        return  True 
@@ -641,7 +650,8 @@ def eff_request_host(request):
641650
642651    """ 
643652    erhn  =  req_host  =  request_host (request )
644-     if  "."  not  in   req_host :
653+     if  "."  not  in   req_host  and  '['  not  in   req_host :
654+         # detect '[' mainly for IPv6 addr like [::1] 
645655        erhn  =  req_host  +  ".local" 
646656    return  req_host , erhn 
647657
0 commit comments