
 X#Q                 @   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 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" m# Z# d  d l$ m% Z% m& Z& m' Z' m( Z( e)   Z* e j+ d  Z, Gd d   d e-  Z. Gd d   d e/  Z0 Gd d   d e)  Z1 Gd d   d e  Z2 d d   Z3 d d   Z4 d d   Z5 d S)    )unicode_literalsN)BytesIO)chain)settings)signing)DisallowedHostImproperlyConfiguredRequestDataTooBig)uploadhandler)MultiPartParserMultiPartParserError)six)ImmutableListMultiValueDict)escape_uri_pathforce_bytes	force_str
force_text
iri_to_uri)is_same_domainlimited_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   A/home/ubuntu/projects/ifolica/build/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   s   t  d d  |  _ t  d d  |  _ i  |  _ i  |  _ t   |  _ d |  _ d |  _ 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content_typeZcontent_params)selfr   r   r    __init__2   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__E   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_hostL   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)r8   r   DEBUGsplit_domain_portvalidate_hostZALLOWED_HOSTSr   )r/   r7   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    r5   r   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    r1   z   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defaultrF   rG   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}schemer7   r+   )formatrN   r8   r1   )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}rN   r7   r+   )	r1   r   rN   netlocrO   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*   rE   rV   )r/   headerrL   r   r   r    rN      s    	zHttpRequest.schemec             C   s   |  j  d k S)NrW   )rN   )r/   r   r   r    r6      s    zHttpRequest.is_securec             C   s   |  j  j d  d k S)NZHTTP_X_REQUESTED_WITHZXMLHttpRequest)r*   rE   )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)r[   hasattrr]   r^   )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   n  |  j  S)N)rd   re   )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_   AttributeErrorrd   )r/   rf   r   r   r    rf      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   rf   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   n  t j d  k	 rl t |  j j d  pN d  t j k rl 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CONTENT_LENGTHr   z;Request body exceeded settings.DATA_UPLOAD_MAX_MEMORY_SIZE.   )r_   _read_startedr!   r   ZDATA_UPLOAD_MAX_MEMORY_SIZEintr*   rE   r	   readrm   IOErrorr   reraiser   argssysexc_infor   _stream)r/   er   r   r    body  s    	'9zHttpRequest.bodyc             C   s%   t    |  _ t   |  _ d |  _ d  S)NT)r&   r^   r   rg   r-   )r/   r   r   r    _mark_post_parse_error  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\   Nrm   zmultipart/form-dataz!application/x-www-form-urlencoded)r,   r&   r[   r   r^   rg   rp   r_   r{   r.   r   rm   rl   r*   r   rz   )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)Nrg   c             s   s   |  ] } | d  Vq d S)   Nr   )ra   lr   r   r    	<genexpr><  s    z$HttpRequest.close.<locals>.<genexpr>)r_   r   from_iterablerg   listsclose)r/   fr   r   r    r   :  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)NTro   )
rp   rx   rr   rs   r   rt   r   ru   rv   rw   )r/   ru   kwargsry   r   r   r    rr   G  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)NTro   )
rp   rx   readliners   r   rt   r   ru   rv   rw   )r/   ru   r   ry   r   r   r    r   N  s
    	zHttpRequest.readlinec             c   s&   x |  j    } | s Pn  | Vq Wd  S)N)r   )r/   bufr   r   r    
xreadlinesU  s
    zHttpRequest.xreadlinesc             C   s   t  t |    S)N)listiter)r/   r   r   r    	readlines^  s    zHttpRequest.readlines)#r   r   r   r"   r[   rd   r0   r3   r8   r?   r5   r1   rI   rM   rP   rT   rV   propertyrN   r6   rZ   r\   setterre   rf   rl   rz   r{   r}   r   rr   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                s`  t  t |   j   | s% t j } n  | |  _ | p7 d } i d d 6t j d 6| d 6} t j r t	 | t
  r y | j |  } Wq t k
 r | j d  } Yq Xn  x t | |  D] \ } } |  j | |  q Wnv xs t | |  D]b \ } } y | j |  } Wn! t k
 r/| j d  } Yn X|  j t | | d d |  q W| |  _ d  S)	Nr%   Tkeep_blank_valuesZfields_limitr\   z
iso-8859-1errorsreplace)superr&   r0   r   DEFAULT_CHARSETr\   ZDATA_UPLOAD_MAX_NUMBER_FIELDSr   PY3
isinstancebytesdecodeUnicodeDecodeErrorr   
appendlistr   _mutable)r/   Zquery_stringr$   r\   Zparse_qsl_kwargsrJ   rL   )r2   r   r    r0   v  s2    	

	zQueryDict.__init__c             C   s%   |  j  d  k r t j |  _  n  |  j  S)N)r[   r   r   )r/   r   r   r    r\     s    zQueryDict.encodingc             C   s   | |  _  d  S)N)r[   )r/   rL   r   r   r    r\     s    c             C   s   |  j  s t d   n  d  S)Nz$This QueryDict instance is immutable)r   rh   )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_textr\   r   r&   __setitem__)r/   rJ   rL   )r2   r   r    r     s    
zQueryDict.__setitem__c                s$   |  j    t t |   j |  d  S)N)r   r   r&   __delitem__)r/   rJ   )r2   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$   Tr\   )r2   r\   r   	iterlistssetlist)r/   resultrJ   rL   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$   Tr\   )r2   r\   idr   r   r   copydeepcopy)r/   memor   rJ   rL   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   r\   )ra   elt)r/   r   r    rc     s   	 z%QueryDict.setlist.<locals>.<listcomp>)r   r   r\   r   r&   r   )r/   rJ   list_)r2   )r/   r    r     s    
zQueryDict.setlistc                s#   |  j    t t |   j | |  S)N)r   r   r&   setlistdefault)r/   rJ   Zdefault_list)r2   r   r    r     s    
zQueryDict.setlistdefaultc                sK   |  j    t | |  j  } t | |  j  } t t |   j | |  d  S)N)r   r   r\   r   r&   r   )r/   rJ   rL   )r2   r   r    r     s    
zQueryDict.appendlistc                s#   |  j    t t |   j | |  S)N)r   r   r&   pop)r/   rJ   ru   )r2   r   r    r     s    
zQueryDict.popc                s   |  j    t t |   j   S)N)r   r   r&   popitem)r/   )r2   r   r    r     s    
zQueryDict.popitemc                s!   |  j    t t |   j   d  S)N)r   r   r&   clear)r/   )r2   r   r    r     s    
zQueryDict.clearc                sG   |  j    t | |  j  } t | |  j  } t t |   j | |  S)N)r   r   r\   r   r&   
setdefault)r/   rJ   rK   )r2   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    encode  s    z#QueryDict.urlencode.<locals>.encodec             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   r\   )ra   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   r[   r0   r   r\   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r2   r    r&   b  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)sr\   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~   ]:ro   r   )r%   r%   )lowerhost_validation_rematchrsplitlentuple)r7   rS   r   r   r    r:     s    

r:   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   )rD   r   )r7   Zallowed_hostspatternr   r   r    r;   $  s
    %r;   )6
__future__r   r   rerv   ior   	itertoolsr   Zdjango.confr   Zdjango.corer   Zdjango.core.exceptionsr   r   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   r   Z#django.utils.six.moves.urllib.parser   r   r   r   objectrI   compiler   rs   r   	Exceptionr!   r#   r&   r   r:   r;   r   r   r   r    <module>   s2   ("		 8