
v^]W                 @   s  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 m  Z  d  d l! m" Z" d  d l# m$ Z$ m% Z% e&   Z' e j( d  Z) Gd d   d e*  Z+ Gd d   d e,  Z- Gd d   d  Z. Gd d   d e  Z/ Gd d   d e  Z0 d d   Z1 d d   Z2 d d   Z3 d S)    N)BytesIO)chain)quote	urlencodeurljoinurlsplit)settings)signing)DisallowedHostImproperlyConfiguredRequestDataTooBig)uploadhandler)MultiPartParserMultiPartParserError)CaseInsensitiveMappingImmutableListMultiValueDict)escape_uri_path
iri_to_uri)cached_property)is_same_domainlimited_parse_qslz1^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9\.:]+\])(:\d+)?$c               @   s   e  Z d  Z d S)UnreadablePostErrorN)__name__
__module____qualname__ r   r   5/tmp/pip-build-8lau8j11/django/django/http/request.pyr      s   r   c               @   s   e  Z d  Z d Z d S)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   c               @   s  e  Z d  Z d Z d Z g  Z d d   Z d d   Z e d d    Z	 d	 d
   Z
 d d   Z d d   Z d d   Z d d d  Z d d d  Z d d   Z e d d d d  Z d d   Z d d d  Z e d d     Z d! d"   Z e d# d$    Z d% d&   Z d' d(   Z e d) d*    Z e j d+ d*    Z d, d-   Z e d. d/    Z e j d0 d/    Z d1 d2   Z e d3 d4    Z  d5 d6   Z! d7 d8   Z" d9 d:   Z# d; d<   Z$ d= d>   Z% d? d@   Z& dA dB   Z' d S)CHttpRequestzA basic HTTP request.Nc             C   s|   t  d d  |  _ t  d d  |  _ i  |  _ i  |  _ t   |  _ d |  _ d |  _ d  |  _	 d  |  _
 d  |  _ d  |  _ d  S)NmutableT )	QueryDictGETPOSTCOOKIESMETAr   ZFILESpath	path_infomethodZresolver_matchcontent_typecontent_params)selfr   r   r   __init__/   s    							zHttpRequest.__init__c             C   sJ   |  j  d  k s |  j   r* d |  j j Sd |  j j |  j  |  j   f S)Nz<%s>z<%s: %s %r>)r*   get_full_path	__class__r   )r-   r   r   r   __repr__A   s    zHttpRequest.__repr__c             C   s   t  |  j  S)N)HttpHeadersr'   )r-   r   r   r   headersF   s    zHttpRequest.headersc             C   sw   t  j | j d d   \ |  _ |  _ d |  j k rs y t j |  j d  Wn t k
 rb Yn X|  j d |  _ d S)z/Set content_type, content_params, and encoding.CONTENT_TYPEr"   charsetN)	cgiparse_headergetr+   r,   codecslookupLookupErrorencoding)r-   metar   r   r   _set_content_type_paramsJ   s    'z$HttpRequest._set_content_type_paramsc             C   s   t  j r( d |  j k r( |  j d } nf d |  j k rG |  j d } nG |  j d } |  j   } | |  j   ru d n d k r d | | f } | S)z
        Return the HTTP host using the environment or request headers. Skip
        allowed hosts protection, so may return an insecure host.
        ZHTTP_X_FORWARDED_HOSTZ	HTTP_HOSTZSERVER_NAMEZ44380z%s:%s)r   ZUSE_X_FORWARDED_HOSTr'   get_port	is_secure)r-   hostZserver_portr   r   r   _get_raw_hostU   s    	zHttpRequest._get_raw_hostc             C   s   |  j    } t j } t j r4 | r4 d d d g } t |  \ } } | r_ t | |  r_ | Sd | } | r | d | 7} n
 | d 7} t |   d S)z>Return the HTTP host using the environment or request headers.	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.N)rC   r   ZALLOWED_HOSTSDEBUGsplit_domain_portvalidate_hostr
   )r-   rB   allowed_hostsdomainportmsgr   r   r   get_hosth   s    	

zHttpRequest.get_hostc             C   s?   t  j r( d |  j k r( |  j d } n |  j d } t |  S)z3Return the port number for the request as a string.ZHTTP_X_FORWARDED_PORTZSERVER_PORT)r   ZUSE_X_FORWARDED_PORTr'   str)r-   rJ   r   r   r   r@   |   s    zHttpRequest.get_portFc             C   s   |  j  |  j |  S)N)_get_full_pathr(   )r-   force_append_slashr   r   r   r/      s    zHttpRequest.get_full_pathc             C   s   |  j  |  j |  S)N)rN   r)   )r-   rO   r   r   r   get_full_path_info   s    zHttpRequest.get_full_path_infoc             C   sg   d t  |  | r( | j d  r( d n d |  j j d d  r_ d t |  j j d d   n d f S)Nz%s%s%s/r"   QUERY_STRING?)r   endswithr'   r8   r   )r-   r(   rO   r   r   r   rN      s    	zHttpRequest._get_full_pathr"   c             C   s   y |  j  | } Wn% t k
 r8 | t k	 r1 | S  Yn Xy) t j d | |  j | d | } Wn( t j k
 r | t k	 r | S  Yn X| S)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)r&   KeyErrorRAISE_ERRORr	   Zget_cookie_signerZunsignZBadSignature)r-   keydefaultrU   rV   Zcookie_valuevaluer   r   r   get_signed_cookie   s    zHttpRequest.get_signed_cookiec             C   s+   d j  d |  j d |  j   d |  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}schemerB   r(   )formatr]   rC   r/   )r-   r   r   r   get_raw_uri   s    		zHttpRequest.get_raw_uric             C   s   | d k r d |  j    } t |  } | j o7 | j s | j j d  r | j r | j r d | j k r d | j k r | j d  r | d d  } |  j | } n t |  j |  j |  } 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//%srQ   z/./z/../z//   )	r/   r   r]   netlocr(   
startswith_current_scheme_hostr   r   )r-   locationbitsr   r   r   build_absolute_uri   s    	&zHttpRequest.build_absolute_uric             C   s   d j  |  j |  j    S)Nz{}://{})r^   r]   rL   )r-   r   r   r   rc      s    z HttpRequest._current_scheme_hostc             C   s   d S)zf
        Hook for subclasses like WSGIRequest to implement. Return 'http' by
        default.
        httpr   )r-   r   r   r   _get_scheme   s    zHttpRequest._get_schemec             C   sy   t  j ro y t  j \ } } Wn t k
 r< t d   Yn X|  j j |  } | d  k	 ro | | k rk d Sd S|  j   S)NzJThe SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.httpsrg   )r   ZSECURE_PROXY_SSL_HEADER
ValueErrorr   r'   r8   rh   )r-   headerZsecure_valueheader_valuer   r   r   r]      s    	zHttpRequest.schemec             C   s   |  j  d k S)Nri   )r]   )r-   r   r   r   rA      s    zHttpRequest.is_securec             C   s   |  j  j d  d k S)NZHTTP_X_REQUESTED_WITHZXMLHttpRequest)r'   r8   )r-   r   r   r   is_ajax   s    zHttpRequest.is_ajaxc             C   s   |  j  S)N)	_encoding)r-   r   r   r   r<      s    zHttpRequest.encodingc             C   s7   | |  _  t |  d  r |  ` t |  d  r3 |  ` d S)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)rn   hasattrr$   ro   )r-   valr   r   r   r<      s
    	c                s#     f d d   t  j D   _ d  S)Nc                s"   g  |  ] } t  j |     q Sr   )r   Zload_handler).0handler)r-   r   r   
<listcomp>  s   	z4HttpRequest._initialize_handlers.<locals>.<listcomp>)r   ZFILE_UPLOAD_HANDLERS_upload_handlers)r-   r   )r-   r   _initialize_handlers  s    z HttpRequest._initialize_handlersc             C   s   |  j  s |  j   |  j  S)N)ru   rv   )r-   r   r   r   upload_handlers
  s    	
zHttpRequest.upload_handlersc             C   s(   t  |  d  r t d   | |  _ d  S)N_fileszGYou cannot set the upload handlers after the upload has been processed.)rp   AttributeErrorru   )r-   rw   r   r   r   rw     s    c             C   s=   t  |  j d d |  _ t | | |  j |  j  } | j   S)z9Return a tuple of (POST QueryDict, FILES MultiValueDict).warningzEYou cannot alter upload handlers after the upload has been processed.)r   rw   r   r<   parse)r-   r'   Z	post_dataparserr   r   r   parse_file_upload  s
    	zHttpRequest.parse_file_uploadc             C   s   t  |  d  s |  j r$ t d   t j d  k	 rf t |  j j d  pK d  t j k rf t d   y |  j	   |  _
 Wn7 t k
 r } z t | j   |  WYd  d  } ~ Xn Xt |  j
  |  _ |  j
 S)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.)rp   _read_startedr   r   ZDATA_UPLOAD_MAX_MEMORY_SIZEintr'   r8   r   readr~   OSErrorr   argsr   _stream)r-   er   r   r   body   s    	'%zHttpRequest.bodyc             C   s   t    |  _ t   |  _ d  S)N)r#   ro   r   rx   )r-   r   r   r   _mark_post_parse_error2  s    z"HttpRequest._mark_post_parse_errorc             C   s<  |  j  d k r5 t d |  j  t   |  _ |  _ d S|  j r\ t |  d  r\ |  j   d S|  j	 d k r t |  d  r t
 |  j  } n |  } y% |  j |  j |  \ |  _ |  _ Wq8t k
 r |  j     Yq8Xn\ |  j	 d k rt |  j d |  j t   |  _ |  _ n" t d |  j  t   |  _ |  _ d S)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)r*   r#   rn   r   ro   rx   r   rp   r   r+   r   r~   r}   r'   r   r   )r-   datar   r   r   _load_post_and_files6  s$    "
%
+z HttpRequest._load_post_and_filesc             C   sM   t  |  d  rI x7 t j d d   |  j j   D  D] } | j   q5 Wd  S)Nrx   c             s   s   |  ] } | d  Vq d S)   Nr   )rr   lr   r   r   	<genexpr>U  s    z$HttpRequest.close.<locals>.<genexpr>)rp   r   from_iterablerx   listsclose)r-   fr   r   r   r   S  s    ,zHttpRequest.closec             O   s^   d |  _  y |  j j | |   SWn7 t k
 rY } z t | j   |  WYd  d  } ~ Xn Xd  S)NT)r   r   r   r   r   r   )r-   r   kwargsr   r   r   r   r   `  s
    	zHttpRequest.readc             O   s^   d |  _  y |  j j | |   SWn7 t k
 rY } z t | j   |  WYd  d  } ~ Xn Xd  S)NT)r   r   readliner   r   r   )r-   r   r   r   r   r   r   r   g  s
    	zHttpRequest.readlinec             C   s   t  |  j d  S)N    )iterr   )r-   r   r   r   __iter__n  s    zHttpRequest.__iter__c             C   s
   t  |   S)N)list)r-   r   r   r   	readlinesq  s    zHttpRequest.readlines)(r   r   r   r   rn   ru   r.   r1   r   r3   r>   rC   rL   r@   r/   rP   rN   rX   r\   r_   rf   rc   rh   propertyr]   rA   rm   r<   setterrv   rw   r}   r   r   r   r   r   r   r   r   r   r   r   r   r    (   sF   	!	r    c                   sX   e  Z d  Z d Z d d h Z   f d d   Z   f d d   Z e d d	    Z   S)
r2   ZHTTP_r4   r   c                sV   i  } x9 | j    D]+ \ } } |  j |  } | r | | | <q Wt   j |  d  S)N)itemsparse_header_namesuperr.   )r-   environr3   rk   r[   name)r0   r   r   r.   z  s    zHttpHeaders.__init__c                s   t    j | j d d   S)z:Allow header lookup using underscores in place of hyphens._-)r   __getitem__replace)r-   rY   )r0   r   r   r     s    zHttpHeaders.__getitem__c             C   sW   | j  |  j  r. | t |  j  d   } n | |  j k rA d  S| j d d  j   S)Nr   r   )rb   HTTP_PREFIXlenUNPREFIXED_HEADERSr   title)clsrk   r   r   r   r     s
    zHttpHeaders.parse_header_name)	r   r   r   r   r   r.   r   classmethodr   r   r   )r0   r   r2   u  s
   r2   c                   sf  e  Z d  Z d Z d Z d Z d d d   f d d  Z e d d d d d	   Z e	 d
 d    Z
 e
 j d d    Z
 d d   Z   f d d   Z   f d d   Z d d   Z d d   Z   f d d   Z d   f d d  Z   f d d   Z   f d d   Z   f d d    Z   f d! d"   Z d   f d# d$  Z d% d&   Z d d' d(  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.
    TNFc                s   t    j   | p t j |  _ | p( d } d d d t j d |  j i } t | t  r y | j |  j  } Wn! t	 k
 r | j d  } Yn Xx- t
 | |  D] \ } } |  j | |  q W| |  _ d  S)Nr"   keep_blank_valuesTZfields_limitr<   z
iso-8859-1)r   r.   r   DEFAULT_CHARSETr<   ZDATA_UPLOAD_MAX_NUMBER_FIELDS
isinstancebytesdecodeUnicodeDecodeErrorr   
appendlist_mutable)r-   Zquery_stringr!   r<   Zparse_qsl_kwargsrY   r[   )r0   r   r   r.     s    	zQueryDict.__init__r"   c             C   sL   |  d d d d | } x | D] } | j  | |  q W| sH d | _ | S)zt
        Return a new QueryDict with keys (may be repeated) from an iterable and
        values from value.
        r"   r!   Tr<   F)r   r   )r   iterabler[   r!   r<   qrY   r   r   r   fromkeys  s    	zQueryDict.fromkeysc             C   s"   |  j  d  k r t j |  _  |  j  S)N)rn   r   r   )r-   r   r   r   r<     s    zQueryDict.encodingc             C   s   | |  _  d  S)N)rn   )r-   r[   r   r   r   r<     s    c             C   s   |  j  s t d   d  S)Nz$This QueryDict instance is immutable)r   ry   )r-   r   r   r   _assert_mutable  s    	zQueryDict._assert_mutablec                sE   |  j    t | |  j  } t | |  j  } t   j | |  d  S)N)r   bytes_to_textr<   r   __setitem__)r-   rY   r[   )r0   r   r   r     s    
zQueryDict.__setitem__c                s   |  j    t   j |  d  S)N)r   r   __delitem__)r-   rY   )r0   r   r   r     s    
zQueryDict.__delitem__c             C   sO   |  j  d d d d |  j } x* |  j   D] \ } } | j | |  q+ W| S)Nr"   r!   Tr<   )r0   r<   r   setlist)r-   resultrY   r[   r   r   r   __copy__  s    zQueryDict.__copy__c             C   sw   |  j  d d d d |  j } | | t |   <xB |  j   D]4 \ } } | j t j | |  t j | |   q; W| S)Nr"   r!   Tr<   )r0   r<   idr   r   copydeepcopy)r-   memor   rY   r[   r   r   r   __deepcopy__  s
    ,zQueryDict.__deepcopy__c                sL     j    t |   j  }   f d d   | D } t   j | |  d  S)Nc                s"   g  |  ] } t  |   j   q Sr   )r   r<   )rr   elt)r-   r   r   rt     s   	 z%QueryDict.setlist.<locals>.<listcomp>)r   r   r<   r   r   )r-   rY   list_)r0   )r-   r   r     s    
zQueryDict.setlistc                s   |  j    t   j | |  S)N)r   r   setlistdefault)r-   rY   Zdefault_list)r0   r   r   r     s    
zQueryDict.setlistdefaultc                sE   |  j    t | |  j  } t | |  j  } t   j | |  d  S)N)r   r   r<   r   r   )r-   rY   r[   )r0   r   r   r     s    
zQueryDict.appendlistc                s   |  j    t   j | |  S)N)r   r   pop)r-   rY   r   )r0   r   r   r     s    
zQueryDict.popc                s   |  j    t   j   S)N)r   r   popitem)r-   )r0   r   r   r     s    
zQueryDict.popitemc                s   |  j    t   j   d  S)N)r   r   clear)r-   )r0   r   r   r     s    
zQueryDict.clearc                sA   |  j    t | |  j  } t | |  j  } t   j | |  S)N)r   r   r<   r   
setdefault)r-   rY   rZ   )r0   r   r   r     s    
zQueryDict.setdefaultc             C   s   |  j  i   S)z%Return a mutable copy of this object.)r   )r-   r   r   r   r     s    zQueryDict.copyc                s   g  }  r3  j   j    f d d     n d d     x@  j   D]2 \  } | j     f d d   | D  qL Wd 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                s    d t  |     t  |    f S)Nz%s=%s)r   )kv)safer   r   encode   s    z#QueryDict.urlencode.<locals>.encodec             S   s   t  |  | i  S)N)r   )r   r   r   r   r   r   #  s    c             3   s<   |  ]2 }    j   j  t |  j   j   Vq d  S)N)r   r<   rM   )rr   r   )r   r   r-   r   r   r   '  s   z&QueryDict.urlencode.<locals>.<genexpr>&)r   r<   r   extendjoin)r-   r   outputr   r   )r   r   r   r-   r   r     s    zQueryDict.urlencode)r   r   r   r   r   rn   r.   r   r   r   r<   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r0   r   r#     s,   r#   c             C   s'   t  |  t  r t |  | d  S|  Sd 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   N)r   r   rM   )sr<   r   r   r   r   0  s    r   c             C   s   |  j    }  t j |   s d	 S|  d
 d k r9 |  d f S|  j d d  } t |  d k rc | 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`   r   .N)r"   r"   r   )lowerhost_validation_rematchrsplitr   rT   )rB   re   rI   rJ   r   r   r   rF   >  s    
.%rF   c                s   t    f d 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   s*   |  ]  } | d  k p! t    |  Vq d S)*N)r   )rr   pattern)rB   r   r   r   c  s    z validate_host.<locals>.<genexpr>)any)rB   rH   r   )rB   r   rG   T  s    rG   )4r6   r9   r   reior   	itertoolsr   urllib.parser   r   r   r   Zdjango.confr   Zdjango.corer	   Zdjango.core.exceptionsr
   r   r   Zdjango.core.filesr   Zdjango.http.multipartparserr   r   Zdjango.utils.datastructuresr   r   r   Zdjango.utils.encodingr   r   Zdjango.utils.functionalr   Zdjango.utils.httpr   r   objectrX   compiler   r   r   	Exceptionr   r    r2   r#   r   rF   rG   r   r   r   r   <module>   s4   "		 N