

_VO                 @   s  d  d l  m 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
 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 m Z d  d l m Z m Z m Z m Z m Z d  d l  m! Z! d  d l" m# Z# m$ Z$ m% Z% m& Z& m' Z' e(   Z) e j* d  Z+ Gd d   d e,  Z- Gd d   d e.  Z/ Gd d   d e(  Z0 Gd d   d e  Z1 d d   Z2 d d   Z3 d d   Z4 d S)    )unicode_literalsN)BytesIO)chain)settings)signing)DisallowedHostImproperlyConfigured)uploadhandler)MultiPartParserMultiPartParserError)six)ImmutableListMultiValueDict)escape_uri_pathforce_bytes	force_str
force_text
iri_to_uri)is_same_domain)	parse_qslquote	urlencodeurljoinurlsplitz/^([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-ghmbqnp_/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 d d   Z d	 d
   Z	 d d   Z
 d d d  Z e d d d d  Z d d   Z d 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 d& d%    Z d' d(   Z e d) d*    Z d+ d,   Z d- d.   Z d/ d0   Z d1 d2   Z d3 d4   Z d5 d6   Z  e  Z! d7 d8   Z" d S)9HttpRequestzA basic HTTP request.Nc             C   ss   t  d d  |  _ t  d d  |  _ i  |  _ i  |  _ t   |  _ d |  _ d |  _ d  |  _	 d  |  _
 d |  _ d  S)NmutableT F)	QueryDictGETPOSTCOOKIESMETAr   ZFILESpathZ	path_infomethodZresolver_match_post_parse_error)selfr   r   r   __init__0   s    						zHttpRequest.__init__c             C   s\   |  j  d  k s |  j   r0 t d |  j j  St d |  j j |  j  t |  j    f  S)Nz<%s>z<%s: %s %r>)r+   get_full_pathr   	__class__r   )r-   r   r   r   __repr__A   s    zHttpRequest.__repr__c             C   s   t  j r( d |  j k r( |  j d } ni d |  j k rG |  j d } nJ |  j d } |  j   } | |  j   ru d n d k r d | | f } n  | 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_hostH   s    	zHttpRequest._get_raw_hostc             C   s   |  j    } t j r | St |  \ } } | rG t | t j  rG | Sd | } | rh | d | 7} n
 | d 7} t |   d S)z>Return the HTTP host using the environment or request headers.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)r6   r   DEBUGsplit_domain_portvalidate_hostZALLOWED_HOSTSr   )r-   r5   domainportmsgr   r   r   get_host[   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-   r;   r   r   r   r3   n   s    zHttpRequest.get_portFc             C   sm   d t  |  j  | r. |  j j d  r. d n d |  j j d d  re d t |  j j d d   n d f S)Nz%s%s%s/r$   QUERY_STRING?)r   r*   endswithr)   getr   )r-   Zforce_append_slashr   r   r   r/   v   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
        Attempts to return a signed cookie. If the signature fails or the
        cookie has expired, raises an exception... unless you provide the
        default argument in which case that value will be returned instead.
        saltmax_age)r(   KeyErrorRAISE_ERRORr   Zget_cookie_signerZunsignZBadSignature)r-   keydefaultrD   rE   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}schemer5   r*   )formatrL   r6   r/   )r-   r   r   r   get_raw_uri   s    		zHttpRequest.get_raw_uric             C   s   | d k r d |  j    } n  t |  } | j o: | j sy d j d |  j d |  j   d |  j  } t | |  } n  t |  S)a  
        Builds an absolute URI from the location and the variables available in
        this request. If no ``location`` is specified, the absolute URI is
        built on ``request.get_full_path()``. Anyway, if the location is
        absolute, it is simply converted to an RFC 3987 compliant URI and
        returned and if location is relative or is scheme-relative (i.e.,
        ``//example.com/``), it is urljoined to a base URL constructed from the
        request variables.
        Nz//%sz{scheme}://{host}{path}rL   r5   r*   )	r/   r   rL   netlocrM   r=   r*   r   r   )r-   locationbitsZcurrent_urir   r   r   build_absolute_uri   s    
zHttpRequest.build_absolute_uric             C   s   d S)zg
        Hook for subclasses like WSGIRequest to implement. Returns 'http' by
        default.
        httpr   )r-   r   r   r   _get_scheme   s    zHttpRequest._get_schemec             C   sf   t  j r\ y t  j \ } } Wn t k
 r< t d   Yn X|  j j |  | k r\ d Sn  |  j   S)NzJThe SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.https)r   ZSECURE_PROXY_SSL_HEADER
ValueErrorr   r)   rC   rT   )r-   headerrJ   r   r   r   rL      s    	zHttpRequest.schemec             C   s   |  j  d k S)NrU   )rL   )r-   r   r   r   r4      s    zHttpRequest.is_securec             C   s   |  j  j d  d k S)NZHTTP_X_REQUESTED_WITHZXMLHttpRequest)r)   rC   )r-   r   r   r   is_ajax   s    zHttpRequest.is_ajaxc             C   s   |  j  S)N)	_encoding)r-   r   r   r   encoding   s    zHttpRequest.encodingc             C   s=   | |  _  t |  d  r! |  ` n  t |  d  r9 |  ` n  d S)z
        Sets the encoding used for GET/POST accesses. If the GET or POST
        dictionary has already been created, it is removed and recreated on the
        next access (so that it is decoded correctly).
        _get_postN)rY   hasattrr[   r\   )r-   valr   r   r   rZ      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   n  |  j  S)N)rb   rc   )r-   r   r   r   upload_handlers   s    	zHttpRequest.upload_handlersc             C   s+   t  |  d  r t d   n  | |  _ d  S)N_fileszGYou cannot set the upload handlers after the upload has been processed.)r]   AttributeErrorrb   )r-   rd   r   r   r   rd      s    c             C   s=   t  |  j d d |  _ t | | |  j |  j  } | j   S)z:Returns a tuple of (POST QueryDict, FILES MultiValueDict).warningzEYou cannot alter upload handlers after the upload has been processed.)r   rd   r
   rZ   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   n  y |  j   |  _ WnK t k
 r } z+ t j t t | j	   t
 j   d  WYd  d  } ~ Xn Xt |  j  |  _ n  |  j S)N_bodyz?You cannot access body after reading from request's data stream   )r]   _read_startedr    readrk   IOErrorr   reraiser   argssysexc_infor   _stream)r-   er   r   r   body   s    	9zHttpRequest.bodyc             C   s(   t  d  |  _ t   |  _ d |  _ d  S)Nr$   T)r%   r\   r   re   r,   )r-   r   r   r   _mark_post_parse_error  s    z"HttpRequest._mark_post_parse_errorc             C   s`  |  j  d k r8 t d d |  j t   |  _ |  _ d S|  j r_ t |  d  r_ |  j   d S|  j	 j
 d d  j d  r t |  d  r t |  j  } n |  } y% |  j |  j	 |  \ |  _ |  _ Wq\t k
 r |  j     Yq\Xnn |  j	 j
 d d  j d  r7t |  j d |  j t   |  _ |  _ n% t d d |  j t   |  _ |  _ d S)	zFPopulate self._post and self._files if the content-type is a form typer'   r$   rZ   Nrk   CONTENT_TYPEzmultipart/form-dataz!application/x-www-form-urlencoded)r+   r%   rY   r   r\   re   rm   r]   rw   r)   rC   
startswithr   rk   rj   r   rv   )r-   datar   r   r   _load_post_and_files  s$    %
%
+z HttpRequest._load_post_and_filesc             C   sP   t  |  d  rL x: t j d d   |  j j   D  D] } | j   q5 Wn  d  S)Nre   c             s   s   |  ] } | d  Vq d S)   Nr   )r_   lr   r   r   	<genexpr>2  s    z$HttpRequest.close.<locals>.<genexpr>)r]   r   from_iterablere   listsclose)r-   fr   r   r   r   0  s    ,zHttpRequest.closec             O   sr   d |  _  y |  j j | |   SWnK t k
 rm } z+ t j t t | j   t j	   d  WYd  d  } ~ Xn Xd  S)NTrl   )
rm   rt   rn   ro   r   rp   r   rq   rr   rs   )r-   rq   kwargsru   r   r   r   rn   =  s
    	zHttpRequest.readc             O   sr   d |  _  y |  j j | |   SWnK t k
 rm } z+ t j t t | j   t j	   d  WYd  d  } ~ Xn Xd  S)NTrl   )
rm   rt   readlinero   r   rp   r   rq   rr   rs   )r-   rq   r   ru   r   r   r   r   D  s
    	zHttpRequest.readlinec             c   s&   x |  j    } | s Pn  | Vq Wd  S)N)r   )r-   bufr   r   r   
xreadlinesK  s
    zHttpRequest.xreadlinesc             C   s   t  t |    S)N)listiter)r-   r   r   r   	readlinesT  s    zHttpRequest.readlines)#r   r   r   r!   rY   rb   r.   r1   r6   r=   r3   r/   rG   rK   rN   rR   rT   propertyrL   r4   rX   rZ   setterrc   rd   rj   rv   rw   r{   r   rn   r   r   __iter__r   r   r   r   r   r"   )   s>   		 r"   c                   sK  e  Z d  Z d Z d Z d Z d d d   f 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 unicode.
    TNFc                sN  t  t |   j   | s% t j } n  | |  _ t j r t | t	  r y | j
 |  } Wq t k
 r| | j
 d  } Yq Xn  x t | p d d d d | D] \ } } |  j | |  q Wn x| t | p d d d D]b \ } } y | j
 |  } Wn! t k
 r| j
 d  } Yn X|  j t | | d d |  q W| |  _ d  S)Nz
iso-8859-1r$   keep_blank_valuesTrZ   errorsreplace)superr%   r.   r   DEFAULT_CHARSETrZ   r   PY3
isinstancebytesdecodeUnicodeDecodeErrorr   
appendlistr   _mutable)r-   Zquery_stringr#   rZ   rH   rJ   )r0   r   r   r.   l  s.    		zQueryDict.__init__c             C   s%   |  j  d  k r t j |  _  n  |  j  S)N)rY   r   r   )r-   r   r   r   rZ     s    zQueryDict.encodingc             C   s   | |  _  d  S)N)rY   )r-   rJ   r   r   r   rZ     s    c             C   s   |  j  s t d   n  d  S)Nz$This QueryDict instance is immutable)r   rf   )r-   r   r   r   _assert_mutable  s    	zQueryDict._assert_mutablec                sK   |  j    t | |  j  } t | |  j  } t t |   j | |  d  S)N)r   bytes_to_textrZ   r   r%   __setitem__)r-   rH   rJ   )r0   r   r   r     s    
zQueryDict.__setitem__c                s$   |  j    t t |   j |  d  S)N)r   r   r%   __delitem__)r-   rH   )r0   r   r   r     s    
zQueryDict.__delitem__c             C   sR   |  j  d d d d |  j } x- t j |   D] \ } } | j | |  q. W| S)Nr$   r#   TrZ   )r0   rZ   r   	iterlistssetlist)r-   resultrH   rJ   r   r   r   __copy__  s    zQueryDict.__copy__c             C   sz   |  j  d d d d |  j } | | t |   <xE t j |   D]4 \ } } | j t j | |  t j | |   q> W| S)Nr$   r#   TrZ   )r0   rZ   idr   r   r   copydeepcopy)r-   memor   rH   rJ   r   r   r   __deepcopy__  s
    ,zQueryDict.__deepcopy__c                sR     j    t |   j  }   f d d   | D } t t    j | |  d  S)Nc                s"   g  |  ] } t  |   j   q Sr   )r   rZ   )r_   elt)r-   r   r   ra     s   	 z%QueryDict.setlist.<locals>.<listcomp>)r   r   rZ   r   r%   r   )r-   rH   list_)r0   )r-   r   r     s    
zQueryDict.setlistc                s#   |  j    t t |   j | |  S)N)r   r   r%   setlistdefault)r-   rH   Zdefault_list)r0   r   r   r     s    
zQueryDict.setlistdefaultc                sK   |  j    t | |  j  } t | |  j  } t t |   j | |  d  S)N)r   r   rZ   r   r%   r   )r-   rH   rJ   )r0   r   r   r     s    
zQueryDict.appendlistc                s#   |  j    t t |   j | |  S)N)r   r   r%   pop)r-   rH   rq   )r0   r   r   r     s    
zQueryDict.popc                s   |  j    t t |   j   S)N)r   r   r%   popitem)r-   )r0   r   r   r     s    
zQueryDict.popitemc                s!   |  j    t t |   j   d  S)N)r   r   r%   clear)r-   )r0   r   r   r     s    
zQueryDict.clearc                sG   |  j    t | |  j  } t | |  j  } t t |   j | |  S)N)r   r   rZ   r   r%   
setdefault)r-   rH   rI   )r0   r   r   r     s    
zQueryDict.setdefaultc             C   s   |  j  i   S)z&Returns a mutable copy of this object.)r   )r-   r   r   r   r     s    zQueryDict.copyc                s   g  }  r3 t    j    f d d     n d d     xR  j   D]D \  } t    j   | j     f d d   | D  qL Wd j |  S)a  
        Returns an encoded string of all query string arguments.

        :arg safe: Used to specify characters which do not 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   <lambda>  s    z%QueryDict.urlencode.<locals>.<lambda>c             S   s   t  i | |  6 S)N)r   )r   r   r   r   r   r     s    c             3   s*   |  ]  }    t  |  j   Vq d  S)N)r   rZ   )r_   r   )encoder   r-   r   r   r~     s   z&QueryDict.urlencode.<locals>.<genexpr>&)r   rZ   r   extendjoin)r-   r   outputr   r   )r   r   r   r-   r   r     s    zQueryDict.urlencode)r   r   r   r!   r   rY   r.   r   rZ   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r0   r   r%   X  s(   r%   c             C   s*   t  |  t  r" t j |  | d  S|  Sd S)u   
    Converts basestring objects to unicode, using the given encoding. Illegally
    encoded input characters are replaced with Unicode "unknown" codepoint
    (�).

    Returns any non-basestring objects without change.
    r   N)r   r   r   	text_type)srZ   r   r   r   r     s    r   c             C   su   |  j    }  t j |   s d S|  d d k r9 |  d f S|  j d d  } t |  d k rg t |  S| d d f S)	z
    Return a (domain, port) tuple from a given host.

    Returned domain is lower-cased. If the host is invalid, the domain will be
    empty.
    r$   r|   ]:rl   r   )r$   r$   )lowerhost_validation_rematchrsplitlentuple)r5   rQ   r   r   r   r8     s    

r8   c             C   sY   |  j  d  r |  d d  n |  }  x- | D]% } | d k sM t |  |  r, d Sq, Wd S)a5  
    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 lower-cased and has
    already had the port, if any, stripped off.

    Return ``True`` for a valid host, ``False`` otherwise.
    .Nr|   *TFr   )rB   r   )r5   Zallowed_hostspatternr   r   r   r9     s
    %r9   )5
__future__r   r   rerr   ior   	itertoolsr   Zdjango.confr   Zdjango.corer   Zdjango.core.exceptionsr   r   Zdjango.core.filesr	   Zdjango.http.multipartparserr
   r   Zdjango.utilsr   Zdjango.utils.datastructuresr   r   Zdjango.utils.encodingr   r   r   r   r   Zdjango.utils.httpr   Z#django.utils.six.moves.urllib.parser   r   r   r   r   objectrG   compiler   ro   r   	Exceptionr    r"   r%   r   r8   r9   r   r   r   r   <module>   s2   ((		 0