U
    fe                     @   sn  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
m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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& d dl'm(Z( e) Z*e(dZ+G dd de,Z-G dd de.Z/G dd dZ0G dd deZ1G dd deZ2G dd dZ3dd Z4dd Z5d d! Z6d"d# Z7dS )$    N)BytesIO)chain)	parse_qslquote	urlencodeurljoinurlsplit)settings)signing)DisallowedHostImproperlyConfiguredRequestDataTooBigTooManyFieldsSent)uploadhandler)MultiPartParserMultiPartParserErrorTooManyFilesSent)CaseInsensitiveMappingImmutableListMultiValueDict)escape_uri_path
iri_to_uri)cached_property)is_same_domainparse_header_parameters)_lazy_re_compilez4^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9\.:]+\])(:[0-9]+)?$c                   @   s   e Zd ZdS )UnreadablePostErrorN)__name__
__module____qualname__ r    r    7/tmp/pip-unpacked-wheel-_jot26k8/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                   @   sj  e Zd ZdZdZg ZeddgZdd Zdd Z	d	d
 Z
dd Zedd Zedd Zdd Zdd Zdd Zdd Zdd ZdIddZdJddZd d! Zed"dfd#d$ZdKd%d&Zed'd( Zd)d* Zed+d, Zd-d. Zed/d0 Zej d1d0 Zd2d3 Z!ed4d5 Z"e"j d6d5 Z"d7d8 Z#ed9d: Z$d;d< Z%d=d> Z&d?d@ Z'dAdB Z(dCdD Z)dEdF Z*dGdH Z+dS )LHttpRequestzA basic HTTP request.Nresolver_match_streamc                 C   sT   t dd| _t dd| _i | _i | _t | _d| _d| _d | _	d | _
d | _d | _d S )NT)mutable )	QueryDictGETPOSTCOOKIESMETAr   ZFILESpath	path_infomethodr%   content_typecontent_paramsselfr    r    r!   __init__<   s    zHttpRequest.__init__c                 C   s6   | j d ks|  sd| jj S d| jj| j |  f S )Nz<%s>z<%s: %s %r>)r0   get_full_path	__class__r   r3   r    r    r!   __repr__N   s    zHttpRequest.__repr__c                 C   s(   | j  }| jD ]}||kr||= q|S N)__dict__copynon_picklable_attrs)r4   Zobj_dictattrr    r    r!   __getstate__W   s
    

zHttpRequest.__getstate__c              	   C   sJ   t  | }| jD ](}t| |rt||t t| || q||t| < |S r9   )r;   r<   hasattrsetattrdeepcopygetattrid)r4   memoobjr=   r    r    r!   __deepcopy__^   s    


zHttpRequest.__deepcopy__c                 C   s
   t | jS r9   )HttpHeadersr-   r3   r    r    r!   headersf   s    zHttpRequest.headersc                 C   s   t | jddS )z%Return a list of MediaType instances.Acceptz*/*)parse_accept_headerrH   getr3   r    r    r!   accepted_typesj   s    zHttpRequest.accepted_typesc                    s   t  fdd| jD S )Nc                 3   s   | ]}|  V  qd S r9   )match).0Zaccepted_type
media_typer    r!   	<genexpr>p   s    z&HttpRequest.accepts.<locals>.<genexpr>)anyrL   )r4   rP   r    rO   r!   acceptso   s    zHttpRequest.acceptsc                 C   s\   t |dd\| _| _d| jkrXzt| jd  W n tk
rJ   Y nX | jd | _dS )z/Set content_type, content_params, and encoding.CONTENT_TYPEr(   charsetN)r   rK   r1   r2   codecslookupLookupErrorencoding)r4   metar    r    r!   _set_content_type_paramst   s    

z$HttpRequest._set_content_type_paramsc                 C   sh   t jrd| jkr| jd }nHd| jkr2| jd }n2| jd }|  }||  rRdndkrdd||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_NAME44380z%s:%s)r	   ZUSE_X_FORWARDED_HOSTr-   get_port	is_secure)r4   hostZserver_portr    r    r!   _get_raw_host   s    

zHttpRequest._get_raw_hostc                 C   sn   |   }tj}tjr"|s"dddg}t|\}}|r@t||r@|S d| }|rZ|d| 7 }n|d7 }t|dS )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.N)ra   r	   ZALLOWED_HOSTSDEBUGsplit_domain_portvalidate_hostr   )r4   r`   allowed_hosts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)r4   rg   r    r    r!   r^      s    
zHttpRequest.get_portFc                 C   s   |  | j|S r9   )_get_full_pathr.   r4   force_append_slashr    r    r!   r6      s    zHttpRequest.get_full_pathc                 C   s   |  | j|S r9   )rk   r/   rl   r    r    r!   get_full_path_info   s    zHttpRequest.get_full_path_infoc              	   C   sH   dt ||r|dsdnd| jddr@dt| jdd ndf S )N%s%s%s/r(   QUERY_STRING?)r   endswithr-   rK   r   )r4   r.   rm   r    r    r!   rk      s    zHttpRequest._get_full_pathr(   c                 C   s   z| j | }W n& tk
r4   |tk	r.| Y S  Y nX ztj|| dj||d}W n( tjk
r|   |tk	rv| Y S  Y n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)r4   keydefaultrt   ru   Zcookie_valuevaluer    r    r!   get_signed_cookie   s      
zHttpRequest.get_signed_cookiec                 C   s   |dkrd|    }nt|}t|}|jr2|js|jdr|js|jsd|jkrd|jkr|drt|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//%srp   z/./z/../z//   )
r6   rj   r   schemenetlocr.   
startswith_current_scheme_hostr   r   )r4   locationbitsr    r    r!   build_absolute_uri   s(    	


zHttpRequest.build_absolute_uric                 C   s   d | j|  S )Nz{}://{})formatr}   ri   r3   r    r    r!   r     s    z HttpRequest._current_scheme_hostc                 C   s   dS )zf
        Hook for subclasses like WSGIRequest to implement. Return 'http' by
        default.
        httpr    r3   r    r    r!   _get_scheme  s    zHttpRequest._get_schemec                 C   sr   t jrjzt j\}}W n tk
r0   tdY nX | j|}|d k	rj|dd^}}| |krfdS dS |  S )NzJThe SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.,   httpsr   )	r	   ZSECURE_PROXY_SSL_HEADER
ValueErrorr   r-   rK   splitstripr   )r4   headerZsecure_valueheader_value_r    r    r!   r}     s    
zHttpRequest.schemec                 C   s
   | j dkS )Nr   )r}   r3   r    r    r!   r_     s    zHttpRequest.is_securec                 C   s   | j S r9   	_encodingr3   r    r    r!   rY   !  s    zHttpRequest.encodingc                 C   s&   || _ t| dr| `t| dr"| `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)r   r?   r*   r   )r4   valr    r    r!   rY   %  s
    

c                    s    fddt jD  _d S )Nc                    s   g | ]}t | qS r    )r   Zload_handler)rN   handlerr3   r    r!   
<listcomp>3  s   z4HttpRequest._initialize_handlers.<locals>.<listcomp>)r	   ZFILE_UPLOAD_HANDLERS_upload_handlersr3   r    r3   r!   _initialize_handlers2  s    
z HttpRequest._initialize_handlersc                 C   s   | j s|   | j S r9   )r   r   r3   r    r    r!   upload_handlers8  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.)r?   AttributeErrorr   )r4   r   r    r    r!   r   ?  s
    
c                 C   s*   t | jdd| _t||| 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   rY   parse)r4   r-   Z	post_dataparserr    r    r!   parse_file_uploadH  s    zHttpRequest.parse_file_uploadc              
   C   s   t | ds| jrtdtjd k	rDt| jdp2dtjkrDtdzBz|  | _W n. tk
r } zt|j |W 5 d }~X Y nX W 5 | j	
  X t| 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.)r?   _read_startedr"   r	   ZDATA_UPLOAD_MAX_MEMORY_SIZEintr-   rK   r   r&   closereadr   OSErrorr   argsr   )r4   er    r    r!   bodyT  s*    
"zHttpRequest.bodyc                 C   s   t  | _t | _d S r9   )r)   r   r   r   r3   r    r    r!   _mark_post_parse_erroro  s    z"HttpRequest._mark_post_parse_errorc              	   C   s   | j dkr&t| jdt  | _| _dS | jrBt| dsB|   dS | j	dkrt| drbt
| j}n| }z| | j|\| _| _W q ttfk
r   |    Y qX n@| j	dkrt| j| jdt  | _| _nt| jdt  | _| _dS )zFPopulate self._post and self._files if the content-type is a form typer+   )rY   Nr   zmultipart/form-dataz!application/x-www-form-urlencoded)r0   r)   r   r   r   r   r   r?   r   r1   r   r   r   r-   r   r   r   )r4   datar    r    r!   _load_post_and_filess  s0    







z HttpRequest._load_post_and_filesc                 C   s6   t | dr2tdd | j D D ]}|  q$d S )Nr   c                 s   s   | ]}|d  V  qdS )r   Nr    )rN   list_r    r    r!   rQ     s     z$HttpRequest.close.<locals>.<genexpr>)r?   r   from_iterabler   listsr   )r4   fr    r    r!   r     s    
zHttpRequest.closec              
   O   sJ   d| _ z| jj||W S  tk
rD } zt|j |W 5 d }~X Y nX d S NT)r   r&   r   r   r   r   r4   r   kwargsr   r    r    r!   r     s
    zHttpRequest.readc              
   O   sJ   d| _ z| jj||W S  tk
rD } zt|j |W 5 d }~X Y nX d S r   )r   r&   readliner   r   r   r   r    r    r!   r     s
    zHttpRequest.readlinec                 C   s   t | jdS )N    )iterr   r3   r    r    r!   __iter__  s    zHttpRequest.__iter__c                 C   s   t | S r9   )listr3   r    r    r!   	readlines  s    zHttpRequest.readlines)F)F)N),r   r   r   r#   r   r   	frozensetr<   r5   r8   r>   rF   r   rH   rL   rS   r[   ra   ri   r^   r6   rn   rk   rw   r{   r   r   r   propertyr}   r_   rY   setterr   r   r   r   r   r   r   r   r   r   r   r    r    r    r!   r$   3   s^   	




)






&r$   c                       sp   e Zd ZdZddhZ fddZ fddZedd	 Zed
d Z	edd Z
edd Zedd Z  ZS )rG   ZHTTP_rT   r   c                    s<   i }|  D ]\}}| |}|r|||< qt | d S r9   )itemsparse_header_namesuperr5   )r4   environrH   r   rz   namer7   r    r!   r5     s    

zHttpHeaders.__init__c                    s   t  |ddS )z:Allow header lookup using underscores in place of hyphens.r   -)r   __getitem__replacer4   rx   r   r    r!   r     s    zHttpHeaders.__getitem__c                 C   s>   | | jr |t| jd  }n|| jkr.d S |dd S )Nr   r   )r   HTTP_PREFIXlenUNPREFIXED_HEADERSr   titleclsr   r    r    r!   r     s
    
zHttpHeaders.parse_header_namec                 C   s,   | dd }|| jkr|S | j | S Nr   r   )r   upperr   r   r   r    r    r!   to_wsgi_name  s    
zHttpHeaders.to_wsgi_namec                 C   s   | dd S r   )r   r   r   r    r    r!   to_asgi_name  s    zHttpHeaders.to_asgi_namec                    s    fdd|  D S )Nc                    s   i | ]\}}  ||qS r    )r   rN   header_namerz   r   r    r!   
<dictcomp>  s    z-HttpHeaders.to_wsgi_names.<locals>.<dictcomp>r   r   rH   r    r   r!   to_wsgi_names  s    
zHttpHeaders.to_wsgi_namesc                    s    fdd|  D S )Nc                    s   i | ]\}}  ||qS r    )r   r   r   r    r!   r     s    z-HttpHeaders.to_asgi_names.<locals>.<dictcomp>r   r   r    r   r!   to_asgi_names  s    
zHttpHeaders.to_asgi_names)r   r   r   r   r   r5   r   classmethodr   r   r   r   r   __classcell__r    r    r   r!   rG     s   



rG   c                       s   e Zd ZdZdZdZd) fdd	Ze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  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    |ptj| _|pd}d| jtjd}t|trhz|| j}W n t	k
rf   |d}Y nX z&t
|f|D ]\}}| || qvW n, tk
r } ztd|W 5 d }~X Y nX || _d S )Nr(   T)keep_blank_valuesrY   max_num_fieldsz
iso-8859-1zRThe number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.)r   r5   r	   DEFAULT_CHARSETrY   ZDATA_UPLOAD_MAX_NUMBER_FIELDS
isinstancebytesdecodeUnicodeDecodeErrorr   
appendlistr   r   _mutable)r4   Zquery_stringr'   rY   Zparse_qsl_kwargsrx   rz   r   r   r    r!   r5     s,    

zQueryDict.__init__r(   c                 C   s2   | dd|d}|D ]}| || q|s.d|_|S )zt
        Return a new QueryDict with keys (may be repeated) from an iterable and
        values from value.
        r(   Tr'   rY   F)r   r   )r   iterablerz   r'   rY   qrx   r    r    r!   fromkeys   s    zQueryDict.fromkeysc                 C   s   | j d krtj| _ | j S r9   )r   r	   r   r3   r    r    r!   rY   -  s    
zQueryDict.encodingc                 C   s
   || _ d S r9   r   )r4   rz   r    r    r!   rY   3  s    c                 C   s   | j stdd S )Nz$This QueryDict instance is immutable)r   r   r3   r    r    r!   _assert_mutable7  s    zQueryDict._assert_mutablec                    s2   |    t|| j}t|| j}t || d S r9   )r   bytes_to_textrY   r   __setitem__r4   rx   rz   r   r    r!   r   ;  s    zQueryDict.__setitem__c                    s   |    t | d S r9   )r   r   __delitem__r   r   r    r!   r   A  s    zQueryDict.__delitem__c                 C   s4   | j dd| jd}|  D ]\}}||| q|S Nr(   Tr   )r7   rY   r   setlist)r4   resultrx   rz   r    r    r!   __copy__E  s    zQueryDict.__copy__c                 C   sP   | j dd| jd}||t| < |  D ]$\}}|t||t|| q&|S r   )r7   rY   rC   r   r   r;   rA   )r4   rD   r   rx   rz   r    r    r!   rF   K  s
    zQueryDict.__deepcopy__c                    s8       t| j} fdd|D }t || d S )Nc                    s   g | ]}t | jqS r    )r   rY   )rN   eltr3   r    r!   r   U  s     z%QueryDict.setlist.<locals>.<listcomp>)r   r   rY   r   r   )r4   rx   r   r   r3   r!   r   R  s    zQueryDict.setlistc                    s   |    t ||S r9   )r   r   setlistdefault)r4   rx   Zdefault_listr   r    r!   r   X  s    zQueryDict.setlistdefaultc                    s2   |    t|| j}t|| j}t || d S r9   )r   r   rY   r   r   r   r   r    r!   r   \  s    zQueryDict.appendlistc                    s   |    t j|f| S r9   )r   r   pop)r4   rx   r   r   r    r!   r   b  s    zQueryDict.popc                    s   |    t  S r9   )r   r   popitemr3   r   r    r!   r   f  s    zQueryDict.popitemc                    s   |    t   d S r9   )r   r   clearr3   r   r    r!   r   j  s    zQueryDict.clearc                    s.   |    t|| j}t|| j}t ||S r9   )r   r   rY   r   
setdefault)r4   rx   ry   r   r    r!   r   n  s    zQueryDict.setdefaultc                 C   s
   |  i S )z%Return a mutable copy of this object.)rF   r3   r    r    r!   r;   t  s    zQueryDict.copyc                    sb   g }r" jfdd ndd   D ]$\}| fdd|D  q2d|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 r9   )r   r   r    r    r!   r     s    c                 3   s,   | ]$}  jt| jV  qd S r9   )r   rY   rj   )rN   r   )r   r   r4   r    r!   rQ     s   z&QueryDict.urlencode.<locals>.<genexpr>&)r   rY   r   extendjoin)r4   r   outputr   r    )r   r   r   r4   r!   r   x  s    
zQueryDict.urlencode)NFN)r(   FN)N)N)N)r   r   r   r#   r   r   r5   r   r   r   rY   r   r   r   r   r   rF   r   r   r   r   r   r   r   r;   r   r   r    r    r   r!   r)     s0   

r)   c                   @   s8   e Zd Zdd Zdd Zdd Zedd Zd	d
 ZdS )	MediaTypec                 C   s.   t |r
|nd\}| _|d\| _}| _d S )Nr(   rp   )r   params	partition	main_typesub_type)r4   Zmedia_type_raw_lineZ	full_typer   r    r    r!   r5     s    

zMediaType.__init__c                 C   s:   d dd | j D }d| j| jr0d| j nd|f S )Nr(   c                 s   s   | ]\}}d ||f V  qdS )z; %s=%sNr    )rN   r   r   r    r    r!   rQ     s     z$MediaType.__str__.<locals>.<genexpr>ro   z/%s)r   r   r   r  r  )r4   Z
params_strr    r    r!   __str__  s    zMediaType.__str__c                 C   s   d| j j| f S )Nz<%s: %s>)r7   r   r3   r    r    r!   r8     s    zMediaType.__repr__c                 C   s   | j dko| jdkS )N*)r  r  r3   r    r    r!   is_all_types  s    zMediaType.is_all_typesc                 C   s6   | j r
dS t|}| j|jkr2| jd|jhkr2dS dS )NTr  F)r  r   r  r  )r4   otherr    r    r!   rM     s    zMediaType.matchN)	r   r   r   r5   r  r8   r   r  rM   r    r    r    r!   r     s   
r   c                 C   s   t | trt| |dS | S d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   rj   )srY   r    r    r!   r     s    
r   c                 C   sx   |   } t| sdS | d dkr*| dfS | dd}t|dkrF|n
|d df\}}|d	rl|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   r|   r   .N)lowerhost_validation_rerM   rsplitr   rs   )r`   r   rf   rg   r    r    r!   rc     s    
 rc   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 )r  N)r   )rN   patternr`   r    r!   rQ     s    z validate_host.<locals>.<genexpr>)rR   )r`   re   r    r  r!   rd     s    rd   c                 C   s   dd |  dD S )Nc                 S   s   g | ]}|  rt|qS r    )r   r   )rN   tokenr    r    r!   r     s      z'parse_accept_header.<locals>.<listcomp>r   )r   )r   r    r    r!   rJ     s    rJ   )8rV   r;   ior   	itertoolsr   urllib.parser   r   r   r   r   Zdjango.confr	   Zdjango.corer
   Zdjango.core.exceptionsr   r   r   r   Zdjango.core.filesr   Zdjango.http.multipartparserr   r   r   Zdjango.utils.datastructuresr   r   r   Zdjango.utils.encodingr   r   Zdjango.utils.functionalr   Zdjango.utils.httpr   r   Zdjango.utils.regex_helperr   objectrw   r  r   r   	Exceptionr"   r$   rG   r)   r   r   rc   rd   rJ   r    r    r    r!   <module>   s@   
   3 ,"