
    h_                        d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlm	Z	m
Z
mZmZ d dlmZ d dlmZ d dlmZmZmZ d dlmZ d d	lmZmZ d d
lmZmZmZ d dlmZ d dl m!Z!m"Z" d dl#m$Z$ d dl%m&Z&m'Z' d dl(m)Z) ddl*m+Z+  e,       Z- e)d      Z. G d de/      Z0 G d de1      Z2 G d d      Z3 G d de      Z4 G d de      Z5 G d d      Z6d Z7d  Z8d! Z9d" Z:y)#    N)BytesIO)chain)quote	urlencodeurljoinurlsplit)settings)signing)DisallowedHostImproperlyConfiguredRequestDataTooBig)uploadhandler)MultiPartParserMultiPartParserError)CaseInsensitiveMappingImmutableListMultiValueDict)RemovedInDjango40Warning)escape_uri_path
iri_to_uri)cached_property)is_same_domainlimited_parse_qsl)_lazy_re_compile   )parse_headerz1^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9\.:]+\])(:\d+)?$c                       e Zd Zy)UnreadablePostErrorN)__name__
__module____qualname__     V/var/www/html/ranktracker/api/venv/lib/python3.12/site-packages/django/http/request.pyr   r      s    r#   r   c                       e Zd ZdZy)RawPostDataExceptionz
    You cannot access raw_post_data from a request that has
    multipart/* POST data if it has been accessed via POST,
    FILES, etc..
    N)r   r    r!   __doc__r"   r#   r$   r&   r&   #   s    
 	r#   r&   c                   t   e Zd ZdZdZg Zd Zd Zed        Z	ed        Z
d Zd Zd	 Zd
 Zd Zd&dZd&dZd ZeddfdZd Zd'dZed        Zd Zed        Zd Zd Zed        Zej<                  d        Zd Zed        Z e j<                  d        Z d Z!ed        Z"d Z#d  Z$d! Z%d" Z&d# Z'd$ Z(d% Z)y)(HttpRequestzA basic HTTP request.Nc                     t        d      | _        t        d      | _        i | _        i | _        t               | _        d| _        d| _        d | _	        d | _
        d | _        d | _        y )NT)mutable )	QueryDictGETPOSTCOOKIESMETAr   FILESpath	path_infomethodresolver_matchcontent_typecontent_paramsselfs    r$   __init__zHttpRequest.__init__3   sa    
 T*d+		#%
	" "r#   c                     | j                   | j                         sd| j                  j                  z  S d| j                  j                  d| j                   d| j                         dS )Nz<%s><:  >)r5   get_full_path	__class__r   r9   s    r$   __repr__zHttpRequest.__repr__E   sU    ;;d&8&8&:DNN3333 '; $ 7 7dFXFXFZ[[r#   c                 ,    t        | j                        S N)HttpHeadersr1   r9   s    r$   headerszHttpRequest.headersJ   s    499%%r#   c                 L    t        | j                  j                  dd            S )z%Return a list of MediaType instances.Acceptz*/*)parse_accept_headerrG   getr9   s    r$   accepted_typeszHttpRequest.accepted_typesN   s      #4<<#3#3He#DEEr#   c                 @    t        fd| j                  D              S )Nc              3   @   K   | ]  }|j                          y wrE   )match).0accepted_type
media_types     r$   	<genexpr>z&HttpRequest.accepts.<locals>.<genexpr>T   s$      
 
+
s   )anyrL   )r:   rR   s    `r$   acceptszHttpRequest.acceptsS   s#     
!%!4!4
 
 	
r#   c                    t        j                  |j                  dd            \  | _        | _        d| j                  v r8	 t        j                  | j                  d          | j                  d   | _        yy# t        $ r Y yw xY w)z/Set content_type, content_params, and encoding.CONTENT_TYPEr,   charsetN)	cgir   rK   r7   r8   codecslookupencodingLookupError)r:   metas     r$   _set_content_type_paramsz$HttpRequest._set_content_type_paramsY   s    141A1A$((>[]B^1_.4.+++?d11)<= !% 3 3I > ,  s   "A: :	BBc                    t         j                  rd| j                  v r| j                  d   }|S d| j                  v r| j                  d   }|S | j                  d   }| j                         }|| j	                         rdndk7  r|d|}|S )z
        Return the HTTP host using the environment or request headers. Skip
        allowed hosts protection, so may return an insecure host.
        HTTP_X_FORWARDED_HOST	HTTP_HOSTSERVER_NAME44380:)r	   USE_X_FORWARDED_HOSTr1   get_port	is_secure)r:   hostserver_ports      r$   _get_raw_hostzHttpRequest._get_raw_hostd   s     (('49949945D  DII%99[)D 	 99]+D--/K(8udC"&4r#   c                     | j                         }t        j                  }t        j                  r|sg d}t	        |      \  }}|rt        ||      r|S d|z  }|r|d|z  z  }t        |      |dz  }t        |      )z>Return the HTTP host using the environment or request headers.)z
.localhostz	127.0.0.1z[::1]zInvalid HTTP_HOST header: %r.z) You may need to add %r to ALLOWED_HOSTS.zB The domain name provided is not valid according to RFC 1034/1035.)rl   r	   ALLOWED_HOSTSDEBUGsplit_domain_portvalidate_hostr   )r:   rj   allowed_hostsdomainportmsgs         r$   get_hostzHttpRequest.get_hostw   s    !!# !..>>-@M(.mFM:K1D8CBVKK !%% [[ %%r#   c                     t         j                  r(d| j                  v r| j                  d   }t        |      S | j                  d   }t        |      S )z3Return the port number for the request as a string.HTTP_X_FORWARDED_PORTSERVER_PORT)r	   USE_X_FORWARDED_PORTr1   str)r:   rt   s     r$   rh   zHttpRequest.get_port   sL    ((-D		-Q9945D 4y 99]+D4yr#   c                 :    | j                  | j                  |      S rE   )_get_full_pathr3   r:   force_append_slashs     r$   rA   zHttpRequest.get_full_path   s    ""499.@AAr#   c                 :    | j                  | j                  |      S rE   )r}   r4   r~   s     r$   get_full_path_infozHttpRequest.get_full_path_info   s    ""4>>3EFFr#   c           	          t        |      |r|j                  d      sdnd| j                  j                  dd      r*dt	        | j                  j                  dd            z   S dS )N/r,   QUERY_STRING?)r   endswithr1   rK   r   )r:   r3   r   s      r$   r}   zHttpRequest._get_full_path   sq     D!%dmmC.@CbHEIYY]]SaceEfS:diimmNB?@@n
 	
 mon
 	
r#   r,   c                     	 | j                   |   }	 t        j                  ||z         j                  ||      }|S # t        $ r |t        ur|cY S  w xY w# t        j                  $ r |t        ur|cY S  w xY w)z
        Attempt to return a signed cookie. If the signature fails or the
        cookie has expired, raise an exception, unless the `default` argument
        is provided,  in which case return that value.
        )salt)max_age)r0   KeyErrorRAISE_ERRORr
   get_cookie_signerunsignBadSignature)r:   keydefaultr   r   cookie_valuevalues          r$   get_signed_cookiezHttpRequest.get_signed_cookie   s    	<<,L	--3:>EEg F /E   	k)		 ## 	k)		s    > *A AAA97A9c                 v    dj                  | j                  | j                         | j                               S )z
        Return an absolute URI from variables available in this request. Skip
        allowed hosts protection, so may return insecure URI.
        z{scheme}://{host}{path})schemerj   r3   )formatr   rl   rA   r9   s    r$   get_raw_urizHttpRequest.get_raw_uri   s;    
 )//;;##%##% 0 
 	
r#   c                    |d| j                         z  }nt        |      }t        |      }|j                  r|j                  s|j
                  j                  d      rd|j                  sX|j                  sLd|j
                  vr>d|j
                  vr0|j                  d      r|dd }| j                  |z   }t        |      S t        | j                  | j
                  z   |      }t        |      S )a  
        Build an absolute URI from the location and the variables available in
        this request. If no ``location`` is specified, build the absolute URI
        using request.get_full_path(). If the location is absolute, convert it
        to an RFC 3987 compliant URI and return it. If location is relative or
        is scheme-relative (i.e., ``//example.com/``), urljoin() it to a base
        URL constructed from the request variables.
        Nz//%sr   z/./z/../z//   )
rA   r{   r   r   netlocr3   
startswith_current_scheme_hostr   r   )r:   locationbitss      r$   build_absolute_urizHttpRequest.build_absolute_uri   s       2 2 44H 8}H! 		$$S)$++dkk*vTYY/F &&t,'|H44x? (## #4#<#<tyy#H(S(##r#   c                 V    dj                  | j                  | j                               S )Nz{}://{})r   r   rv   r9   s    r$   r   z HttpRequest._current_scheme_host   s    T]]_==r#   c                      y)zf
        Hook for subclasses like WSGIRequest to implement. Return 'http' by
        default.
        httpr"   r9   s    r$   _get_schemezHttpRequest._get_scheme   s    
 r#   c                     t         j                  r:	 t         j                  \  }}| j                  j                  |      }|	||k(  rdS dS | j                         S # t        $ r t        d      w xY w)NzJThe SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.httpsr   )r	   SECURE_PROXY_SSL_HEADER
ValueErrorr   r1   rK   r   )r:   headersecure_valueheader_values       r$   r   zHttpRequest.scheme   s|    ++'/'G'G$
  99==0L'".,">wJFJ!!  *` s   A A0c                      | j                   dk(  S )Nr   )r   r9   s    r$   ri   zHttpRequest.is_secure  s    {{g%%r#   c                 v    t        j                  dt        d       | j                  j	                  d      dk(  S )Nzfrequest.is_ajax() is deprecated. See Django 3.1 release notes for more details about this deprecation.r   )
stacklevelHTTP_X_REQUESTED_WITHXMLHttpRequest)warningswarnr   r1   rK   r9   s    r$   is_ajaxzHttpRequest.is_ajax  s5    7$		
 yy}}459IIIr#   c                     | j                   S rE   	_encodingr9   s    r$   r\   zHttpRequest.encoding  s    ~~r#   c                 L    || _         t        | d      r| `t        | d      r| `yy)z
        Set the encoding used for GET/POST accesses. If the GET or POST
        dictionary has already been created, remove and recreate it on the
        next access (so that it is decoded correctly).
        r.   _postN)r   hasattrr.   r   )r:   vals     r$   r\   zHttpRequest.encoding  s.     44!
 "r#   c                 |    t         j                  D cg c]  }t        j                  ||        c}| _        y c c}w rE   )r	   FILE_UPLOAD_HANDLERSr   load_handler_upload_handlers)r:   handlers     r$   _initialize_handlersz HttpRequest._initialize_handlers  s8    080M0M!O%, "/!;!;GT!J !O !Os   9c                 R    | j                   s| j                          | j                   S rE   )r   r   r9   s    r$   upload_handlerszHttpRequest.upload_handlers"  s#    $$%%'$$$r#   c                 @    t        | d      rt        d      || _        y )N_fileszGYou cannot set the upload handlers after the upload has been processed.)r   AttributeErrorr   )r:   r   s     r$   r   zHttpRequest.upload_handlers)  s     4" !jkk /r#   c                     t        | j                  d      | _        t        ||| j                  | j                        }|j	                         S )z9Return a tuple of (POST QueryDict, FILES MultiValueDict).zEYou cannot alter upload handlers after the upload has been processed.)warning)r   r   r   r\   parse)r:   r1   	post_dataparsers       r$   parse_file_uploadzHttpRequest.parse_file_upload/  sC    ,  [ 
 !y$2F2FV||~r#   c                    t        | d      s| j                  rt        d      t        j                  Dt        | j                  j                  d      xs d      t        j                  kD  rt        d      	 | j                         | _
        t        | j                        | _        | j                  S # t        $ r}t        |j                   |d }~ww xY w)N_bodyz?You cannot access body after reading from request's data streamCONTENT_LENGTHr   z;Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.)r   _read_startedr&   r	   DATA_UPLOAD_MAX_MEMORY_SIZEintr1   rK   r   readr   OSErrorr   argsr   _stream)r:   es     r$   bodyzHttpRequest.body8  s    tW%!!*+lmm 44@		&67<1=@d@dd'(eff:!YY[
 #4::.DLzz  :)16629:s   9B4 4	C=CCc                 @    t               | _        t               | _        y rE   )r-   r   r   r   r9   s    r$   _mark_post_parse_errorz"HttpRequest._mark_post_parse_errorJ  s    [
$&r#   c                    | j                   dk7  r,t        | j                        t               c| _        | _        y| j                  rt        | d      s| j                          y| j                  dk(  rOt        | d      rt        | j                        }n| }	 | j                  | j                  |      \  | _        | _        y| j                  dk(  r7t        | j                  | j                        t               c| _        | _        yt        | j                        t               c| _        | _        y# t        $ r | j                           w xY w)zFPopulate self._post and self._files if the content-type is a form typer/   )r\   Nr   zmultipart/form-dataz!application/x-www-form-urlencoded)r5   r-   r   r   r   r   r   r   r   r7   r   r   r   r1   r   r   )r:   datas     r$   _load_post_and_filesz HttpRequest._load_post_and_filesN  s   ;;& &/&H.JZ#DJgdG&<'') 55tW%tzz**.*@*@D*Q'
DK "EE&/		DNN&SUcUe#DJ&/&H.JZ#DJ ( 
 ++-s   )D5 5Ec                     t        | d      rJt        j                  d | j                  j	                         D              D ]  }|j                           y y )Nr   c              3   &   K   | ]	  }|d      yw)r   Nr"   )rP   list_s     r$   rS   z$HttpRequest.close.<locals>.<genexpr>m  s     (Seq(Ss   )r   r   from_iterabler   listsclose)r:   fs     r$   r   zHttpRequest.closek  sG    4"(((St{{?P?P?R(SS 	 #r#   c                     d| _         	  | j                  j                  |i |S # t        $ r}t	        |j
                   |d }~ww xY wNT)r   r   r   r   r   r   r:   r   kwargsr   s       r$   r   zHttpRequest.readx  sL    !	6$4<<$$d5f55 	6%qvv.A5	6   % 	AAAc                     d| _         	  | j                  j                  |i |S # t        $ r}t	        |j
                   |d }~ww xY wr   )r   r   readliner   r   r   r   s       r$   r   zHttpRequest.readline  sL    !	6(4<<(($9&99 	6%qvv.A5	6r   c                 .    t        | j                  d      S )Nr#   )iterr   r9   s    r$   __iter__zHttpRequest.__iter__  s    DMM3''r#   c                     t        |       S rE   )listr9   s    r$   	readlineszHttpRequest.readlines  s    Dzr#   )FrE   )*r   r    r!   r'   r   r   r;   rC   r   rG   rL   rU   r_   rl   rv   rh   rA   r   r}   r   r   r   r   r   r   propertyr   ri   r   r\   setterr   r   r   r   r   r   r   r   r   r   r   r"   r#   r$   r)   r)   ,   s_    I#$\
 & & F F
	?&&(BG
 .9r4 .	
"$H > > " "&J   __
 
O % % 0 0
  "'[:66(r#   r)   c                   D     e Zd ZdZddhZ fdZ fdZed        Z xZ	S )rF   HTTP_rW   r   c                     i }|j                         D ]  \  }}| j                  |      }|s|||<     t        |   |       y rE   )itemsparse_header_namesuperr;   )r:   environrG   r   r   namerB   s         r$   r;   zHttpHeaders.__init__  sL    $]]_ 	&MFE))&1D %	& 	!r#   c                 B    t         |   |j                  dd            S )z:Allow header lookup using underscores in place of hyphens._-)r   __getitem__replacer:   r   rB   s     r$   r   zHttpHeaders.__getitem__  s    w"3;;sC#899r#   c                     |j                  | j                        r|t        | j                        d  }n|| j                  vry |j	                  dd      j                         S )Nr   r   )r   HTTP_PREFIXlenUNPREFIXED_HEADERSr   title)clsr   s     r$   r   zHttpHeaders.parse_header_name  sU    S__-C012F3111~~c3'--//r#   )
r   r    r!   r  r  r;   r   classmethodr   __classcell__rB   s   @r$   rF   rF     s2    K(*:;": 0 0r#   rF   c                        e Zd ZdZdZdZd fd	Zedd       Ze	d        Z
e
j                  d        Z
d Z fd	Z fd
Zd Zd Z fdZd fd	Z fdZ fdZ fdZ fdZd fd	Zd ZddZ xZS )r-   a  
    A specialized MultiValueDict which represents a query string.

    A QueryDict can be used to represent GET or POST data. It subclasses
    MultiValueDict since keys in such data can be repeated, for instance
    in the data from a form with a <select multiple> field.

    By default QueryDicts are immutable, though the copy() method
    will always return a mutable copy.

    Both keys and values set on this class are converted from the given encoding
    (DEFAULT_CHARSET by default) to str.
    TNc                    t         |           |xs t        j                  | _        |xs d}dt        j
                  | j                  d}t        |t              r	 |j                  | j                        }t        |fi |D ]  \  }}| j                  ||        || _        y # t        $ r |j                  d      }Y Jw xY w)Nr,   T)keep_blank_valuesfields_limitr\   z
iso-8859-1)r   r;   r	   DEFAULT_CHARSETr\   DATA_UPLOAD_MAX_NUMBER_FIELDS
isinstancebytesdecodeUnicodeDecodeErrorr   
appendlist_mutable)r:   query_stringr+   r\   parse_qsl_kwargsr   r   rB   s          r$   r;   zQueryDict.__init__  s     <H$<$<#)r!%$BB

 lE*A+224==A ,LM<LM 	(JCOOC'	( & A+22<@As   B' 'CCc                 `     | dd|      }|D ]  }|j                  ||        |sd|_        |S )zt
        Return a new QueryDict with keys (may be repeated) from an iterable and
        values from value.
        r,   Tr+   r\   F)r  r  )r  iterabler   r+   r\   qr   s          r$   fromkeyszQueryDict.fromkeys  s>     D84 	%CLLe$	%AJr#   c                 \    | j                   t        j                  | _         | j                   S rE   )r   r	   r  r9   s    r$   r\   zQueryDict.encoding  s#    >>!%55DN~~r#   c                     || _         y rE   r   )r:   r   s     r$   r\   zQueryDict.encoding  s	    r#   c                 2    | j                   st        d      y )Nz$This QueryDict instance is immutable)r  r   r9   s    r$   _assert_mutablezQueryDict._assert_mutable  s    }} !GHH r#   c                     | j                          t        || j                        }t        || j                        }t        |   ||       y rE   )r  bytes_to_textr\   r   __setitem__r:   r   r   rB   s      r$   r"  zQueryDict.__setitem__  s>    C/eT]]3C'r#   c                 D    | j                          t        | 	  |       y rE   )r  r   __delitem__r   s     r$   r%  zQueryDict.__delitem__  s    C r#   c                     | j                  dd| j                        }| j                         D ]  \  }}|j                  ||        |S Nr,   Tr  )rB   r\   r   setlist)r:   resultr   r   s       r$   __copy__zQueryDict.__copy__  sF    D4==I**, 	'JCNN3&	'r#   c                    | j                  dd| j                        }||t        |       <   | j                         D ]?  \  }}|j	                  t        j                  ||      t        j                  ||             A |S r'  )rB   r\   idr   r(  copydeepcopy)r:   memor)  r   r   s        r$   __deepcopy__zQueryDict.__deepcopy__  sk    D4==IRX**, 	QJCNN4==d3T]]5$5OP	Qr#   c                     | j                          t        || j                        }|D cg c]  }t        || j                         }}t        |   ||       y c c}w rE   )r  r!  r\   r   r(  )r:   r   r   eltrB   s       r$   r(  zQueryDict.setlist  sQ    C/>CDssDMM2DDU# Es   Ac                 D    | j                          t        | 	  ||      S rE   )r  r   setlistdefault)r:   r   default_listrB   s      r$   r4  zQueryDict.setlistdefault  s!    w%c<88r#   c                     | j                          t        || j                        }t        || j                        }t        |   ||       y rE   )r  r!  r\   r   r  r#  s      r$   r  zQueryDict.appendlist  s>    C/eT]]33&r#   c                 D    | j                          t        |   |g| S rE   )r  r   pop)r:   r   r   rB   s      r$   r8  zQueryDict.pop  s#    w{3&&&r#   c                 @    | j                          t        | 	         S rE   )r  r   popitemr:   rB   s    r$   r:  zQueryDict.popitem  s    w  r#   c                 B    | j                          t        | 	          y rE   )r  r   clearr;  s    r$   r=  zQueryDict.clear  s    r#   c                     | j                          t        || j                        }t        || j                        }t        |   ||      S rE   )r  r!  r\   r   
setdefault)r:   r   r   rB   s      r$   r?  zQueryDict.setdefault  sA    C/7w!#w//r#   c                 $    | j                  i       S )z%Return a mutable copy of this object.)r0  r9   s    r$   r-  zQueryDict.copy#  s      $$r#   c                      g }r!j                   j                        fdnd  j                         D ]!  \  }|j                   fd|D               # dj	                  |      S )ah  
        Return an encoded string of all query string arguments.

        `safe` specifies characters which don't require quoting, for example::

            >>> q = QueryDict(mutable=True)
            >>> q['next'] = '/a&b/'
            >>> q.urlencode()
            'next=%2Fa%26b%2F'
            >>> q.urlencode(safe='/')
            'next=/a%26b/'
        c                 :    t        |       dt        |      S )N=)r   )kvsafes     r$   encodez#QueryDict.urlencode.<locals>.encode8  s    #(D>5D>CCr#   c                     t        | |i      S rE   )r   )rD  rE  s     r$   rG  z#QueryDict.urlencode.<locals>.encode;  s     !Q((r#   c              3      K   | ]H  } j                  j                        t        |      j                  j                               J y wrE   )rG  r\   r{   )rP   rE  rG  rD  r:   s     r$   rS   z&QueryDict.urlencode.<locals>.<genexpr>>  s>       qxx.Admm0LMs   AA&)rG  r\   r   extendjoin)r:   rF  outputr   rG  rD  s   ``  @@r$   r   zQueryDict.urlencode'  sm     ;;t}}-DD)

 	HAuMM  	
 xxr#   )NFN)r,   FNrE   )r   r    r!   r'   r  r   r;   r  r  r   r\   r   r  r"  r%  r*  r0  r(  r4  r  r8  r:  r=  r?  r-  r   r  r  s   @r$   r-   r-     s      HI ( 
 
  
 __ I(!$9''!0% r#   r-   c                   4    e Zd Zd Zd Zd Zed        Zd Zy)	MediaTypec                     t        |r|j                  d      nd      \  }| _        |j                  d      \  | _        }| _        y )Nasciir#   r   )r   rG  params	partition	main_typesub_type)r:   media_type_raw_line	full_typer   s       r$   r;   zMediaType.__init__F  sC    !-3F&&w/C"
	4; ,5+>+>s+C(4=r#   c                     dj                  d | j                  j                         D              }| j                  | j                  rd| j                  z  nd|S )Nr,   c              3   P   K   | ]  \  }}d |d|j                  d         yw)z; rC  rQ  N)r  )rP   rD  rE  s      r$   rS   z$MediaType.__str__.<locals>.<genexpr>M  s*      
1 AHHW-.
s   $&z/%s)rL  rR  r   rT  rU  )r:   
params_strs     r$   __str__zMediaType.__str__L  sW    WW 
))+
 


 NN'+}}UT]]""<
 	
r#   c                 <    d| j                   j                  d| dS )Nr=   r>   r@   )rB   r!   r9   s    r$   rC   zMediaType.__repr__W  s    !^^88$??r#   c                 B    | j                   dk(  xr | j                  dk(  S )N*)rT  rU  r9   s    r$   is_all_typeszMediaType.is_all_typesZ  s    ~~$=#)==r#   c                     | j                   ryt        |      }| j                  |j                  k(  r| j                  d|j                  hv ryy)NTr^  F)r_  rO  rT  rU  )r:   others     r$   rO   zMediaType.match^  sB    % >>U__,3BW1Wr#   N)	r   r    r!   r;   r[  rC   r   r_  rO   r"   r#   r$   rO  rO  E  s,    D	
@ > >r#   rO  c                 @    t        | t              rt        | |d      S | S )u   
    Convert bytes objects to strings, using the given encoding. Illegally
    encoded input characters are replaced with Unicode "unknown" codepoint
    (�).

    Return any non-bytes objects without change.
    r   )r  r  r{   )sr\   s     r$   r!  r!  j  s"     !U1h	**r#   c                     | j                         } t        j                  |       sy| d   dk(  r| dfS | j                  dd      }t	        |      dk(  r|n|d   df\  }}|j                  d	      r|d
d n|}||fS )z
    Return a (domain, port) tuple from a given host.

    Returned domain is lowercased. If the host is invalid, the domain will be
    empty.
    )r,   r,   ]r,   rf   r   r   r   .N)lowerhost_validation_rerO   rsplitr  r   )rj   r   rs   rt   s       r$   rp   rp   x  s     ::<D##D)Bx3Rx;;sADt9>4Q}LFD"OOC0VCR[fF4<r#   c                 ,     t         fd|D              S )a4  
    Validate the given host for this site.

    Check that the host looks valid and matches a host or host pattern in the
    given list of ``allowed_hosts``. Any pattern beginning with a period
    matches a domain and all its subdomains (e.g. ``.example.com`` matches
    ``example.com`` and any subdomain), ``*`` matches anything, and anything
    else must match exactly.

    Note: This function assumes that the given host is lowercased and has
    already had the port, if any, stripped off.

    Return ``True`` for a valid host, ``False`` otherwise.
    c              3   D   K   | ]  }|d k(  xs t        |        yw)r^  N)r   )rP   patternrj   s     r$   rS   z validate_host.<locals>.<genexpr>  s$     \7w#~>g!>>\s    )rT   )rj   rr   s   ` r$   rq   rq     s     \m\\\r#   c                 ~    | j                  d      D cg c]  }|j                         st        |        c}S c c}w )N,)splitstriprO  )r   tokens     r$   rJ   rJ     s,    *0,,s*;Mu{{}IeMMMs   ::);rY   rZ   r-  r   ior   	itertoolsr   urllib.parser   r   r   r   django.confr	   django.corer
   django.core.exceptionsr   r   r   django.core.filesr   django.http.multipartparserr   r   django.utils.datastructuresr   r   r   django.utils.deprecationr   django.utils.encodingr   r   django.utils.functionalr   django.utils.httpr   r   django.utils.regex_helperr   multipartparserr   objectr   ri  r   r   	Exceptionr&   r)   rF   r-   rO  r!  rp   rq   rJ   r"   r#   r$   <module>r     s    
      < <     , M  > = 3 ? 6 )h%&Z[ 	' 		9 	^ ^B0( 04[  [ | J,]$Nr#   