3
(h#Q                 @   sP  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,G dd de-Z.G dd de/Z0G dd de)Z1G dd deZ2dd Z3dd Z4dd Z5d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   7/tmp/pip-install-q3hcpn_q/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
d9ddZeddf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d1d2 Zd3d4 Zd5d6 Z e Z!d7d8 Z"dS );HttpRequestzA basic HTTP request.Nc             C   sZ   t dd| _t dd| _i | _i | _t | _d| _d| _d | _	d | _
d| _d | _d | _d S )NT)mutable 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   sD   | j d ks| j  r$td| jj S t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   sh   t jrd| jkr| jd }nHd| jkr2| jd }n2| jd }| j }|| j 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)r/   hostZserver_portr   r   r    _get_raw_hostL   s    


zHttpRequest._get_raw_hostc             C   s`   | j  }tjr|S t|\}}|r2t|tjr2|S d| }|rL|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)r9   r   DEBUGsplit_domain_portvalidate_hostZALLOWED_HOSTSr   )r/   r8   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    r6   r   s    
zHttpRequest.get_portFc             C   sN   dt | j|r | jjd r dnd| jjddrFd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   sz   y| j | }W n" tk
r0   |tk	r*|S  Y nX ytj|| dj||d}W n$ tjk
rt   |tk	rn|S  Y n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defaultrG   rH   Zcookie_valuevaluer   r   r    get_signed_cookie   s    zHttpRequest.get_signed_cookiec             C   s   dj | j| j | j d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})schemer8   r+   )formatrO   r9   r1   )r/   r   r   r    get_raw_uri   s    zHttpRequest.get_raw_uric             C   sR   |dkrd| j   }t|}|jo&|jsJdj| j| j | jd}t||}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})rO   r8   r+   )	r1   r   rO   netlocrP   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   sN   t jrFyt j\}}W n tk
r0   tdY nX | jj||krFdS | j S )NzJThe SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.https)r   ZSECURE_PROXY_SSL_HEADER
ValueErrorr   r*   rF   rW   )r/   headerrM   r   r   r    rO      s    zHttpRequest.schemec             C   s
   | j dkS )NrX   )rO   )r/   r   r   r    r7      s    zHttpRequest.is_securec             C   s   | j jddkS )NZHTTP_X_REQUESTED_WITHZXMLHttpRequest)r*   rF   )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| `t| dr"| `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S r   )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)re   rf   )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.)r`   AttributeErrorre   )r/   rg   r   r   r    rg      s    
c             C   s*   t | jdd| _t||| j| j}|j S )z:Returns a tuple of (POST QueryDict, FILES MultiValueDict).zEYou cannot alter upload handlers after the upload has been processed.)warning)r   rg   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	rDt| jjdp2dtjkrDtdy| j	 | _
W n> tk
r } z"tjtt|j tj d  W Y d d }~X n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*   rF   r	   readrn   IOErrorr   reraiser   argssysexc_infor   _stream)r/   er   r   r    body  s    

.zHttpRequest.bodyc             C   s   t  | _t | _d| _d S )NT)r&   r_   r   rh   r-   )r/   r   r   r    _mark_post_parse_error  s    z"HttpRequest._mark_post_parse_errorc             C   s   | j dkr&t| jdt  | _| _dS | jrDt| d rD| j  dS | j	dkrt| drdt
| j}n| }y| j| j|\| _| _W q tk
r   | j   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(   )r]   Nrn   zmultipart/form-dataz!application/x-www-form-urlencoded)r,   r&   r\   r   r_   rh   rq   r`   r|   r.   r   rn   rm   r*   r   r{   )r/   datar   r   r    _load_post_and_files  s$    




z HttpRequest._load_post_and_filesc             C   s:   t | dr6x*tjdd | jj D D ]}|j  q&W d S )Nrh   c             s   s   | ]}|d  V  qdS )   Nr   )rb   lr   r   r    	<genexpr><  s    z$HttpRequest.close.<locals>.<genexpr>)r`   r   from_iterablerh   listsclose)r/   fr   r   r    r   :  s    
 zHttpRequest.closec             O   sX   d| _ y| jj||S  tk
rR } z"tjtt|j tj	 d  W Y d d }~X nX d S )NTrp   )
rq   ry   rs   rt   r   ru   r   rv   rw   rx   )r/   rv   kwargsrz   r   r   r    rs   G  s
    zHttpRequest.readc             O   sX   d| _ y| jj||S  tk
rR } z"tjtt|j tj	 d  W Y d d }~X nX d S )NTrp   )
rq   ry   readlinert   r   ru   r   rv   rw   rx   )r/   rv   r   rz   r   r   r    r   N  s
    zHttpRequest.readlinec             c   s   x| j  }|sP |V  qW d 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)F)N)#r   r   r   r"   r\   re   r0   r3   r9   r@   r6   r1   rJ   rN   rQ   rU   rW   propertyrO   r7   r[   r]   setterrf   rg   rm   r{   r|   r~   r   rs   r   r   __iter__r   r   r   r   r    r#   +   s>   
	
	 r#   c                   s   e Zd ZdZdZdZ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  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}|| _|p$d}dtj|d}tjrt	|t
rry|j|}W n tk
rp   |jd}Y nX xt|f|D ]\}}| j|| qW n^x\t|f|D ]L\}}y|j|}W n tk
r   |jd}Y nX | jt||dd| qW || _d S )Nr%   T)keep_blank_valuesZfields_limitr]   z
iso-8859-1replace)errors)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_kwargsrK   rM   )r2   r   r    r0   v  s0    

zQueryDict.__init__c             C   s   | j d krtj| _ | j S )N)r\   r   r   )r/   r   r   r    r]     s    
zQueryDict.encodingc             C   s
   || _ d S )N)r\   )r/   rM   r   r   r    r]     s    c             C   s   | j stdd S )Nz$This QueryDict instance is immutable)r   ri   )r/   r   r   r    _assert_mutable  s    zQueryDict._assert_mutablec                s6   | j   t|| j}t|| j}tt| j|| d S )N)r   bytes_to_textr]   r   r&   __setitem__)r/   rK   rM   )r2   r   r    r     s    zQueryDict.__setitem__c                s   | j   tt| j| d S )N)r   r   r&   __delitem__)r/   rK   )r2   r   r    r     s    zQueryDict.__delitem__c             C   s:   | j dd| jd}x"tj| D ]\}}|j|| qW |S )Nr%   T)r$   r]   )r2   r]   r   	iterlistssetlist)r/   resultrK   rM   r   r   r    __copy__  s    zQueryDict.__copy__c             C   sV   | j dd| jd}||t| < x2tj| D ]$\}}|jtj||tj|| q*W |S )Nr%   T)r$   r]   )r2   r]   idr   r   r   copydeepcopy)r/   memor   rK   rM   r   r   r    __deepcopy__  s
     zQueryDict.__deepcopy__c                s<    j   t| j} fdd|D }tt j|| d S )Nc                s   g | ]}t | jqS r   )r   r]   )rb   elt)r/   r   r    rd     s    z%QueryDict.setlist.<locals>.<listcomp>)r   r   r]   r   r&   r   )r/   rK   list_)r2   )r/   r    r     s    zQueryDict.setlistc                s   | j   tt| j||S )N)r   r   r&   setlistdefault)r/   rK   Zdefault_list)r2   r   r    r     s    zQueryDict.setlistdefaultc                s6   | j   t|| j}t|| j}tt| j|| d S )N)r   r   r]   r   r&   r   )r/   rK   rM   )r2   r   r    r     s    zQueryDict.appendlistc                s   | j   tt| j|f| S )N)r   r   r&   pop)r/   rK   rv   )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                s2   | j   t|| j}t|| j}tt| j||S )N)r   r   r]   r   r&   
setdefault)r/   rK   rL   )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                sr   g }r"t jfdd ndd  x<j D ]0\}t j|j fdd|D  q4W d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S )N)r   )r   r   r   r   r    r     s    c             3   s    | ]} t |jV  qd S )N)r   r]   )rb   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)NFN)N)N)N)r   r   r   r"   r   r\   r0   r   r]   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   )r2   r    r&   b  s(   r&   c             C   s    t | trtj| |dS | S d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   sV   | j  } tj| sdS | d dkr*| dfS | jdd}t|dkrJt|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   ]:rp   r   )r%   r%   )lowerhost_validation_rematchrsplitlentuple)r8   rT   r   r   r    r;     s    
r;   c             C   sB   | j dr| dd n| } x"|D ]}|dks6t| |r dS q W d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   )rE   r   )r8   Zallowed_hostspatternr   r   r    r<   $  s
    
r<   )6
__future__r   r   rerw   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   objectrJ   compiler   rt   r   	Exceptionr!   r#   r&   r   r;   r<   r   r   r   r    <module>   s6   
	  9  