B
    CVvgwc  ã               @   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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" d dl#m$Z$m%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/ e+e	dƒ�r(e+e	dƒ�s4d dl(m	Z	 e0ƒ Z1e-dƒZ2G dd„ de3ƒZ4G dd„ de5ƒZ6G dd„ dƒZ7G dd„ deƒZ8G dd „ d e ƒZ9G d!d"„ d"ƒZ:d#d$„ Z;d%d&„ Z<d'd(„ Z=d)d*„ Z>dS )+é    N)ÚBytesIO)Úchain)Ú	parse_qslÚquoteÚ	urlencodeÚurljoinÚurlsplit)Úsettings)Úsigning)ÚDisallowedHostÚImproperlyConfiguredÚRequestDataTooBigÚTooManyFieldsSent)Úuploadhandler)ÚMultiPartParserÚMultiPartParserErrorÚTooManyFilesSent)ÚCaseInsensitiveMappingÚImmutableListÚMultiValueDict)ÚRemovedInDjango40Warning)Úescape_uri_pathÚ
iri_to_uri)Úcached_property)Úis_same_domain)Úfunc_supports_parameter)Ú_lazy_re_compileé   )Úparse_headerÚmax_num_fieldsÚ	separator)r   z1^([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-o3oxmrkh/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'   1   s   r'   c               @   s^  e Zd ZdZdZg 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dGdd„ZdHdd„Zdd„ Zeddfdd„Zdd „ ZdId!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d0d1„ Zed2d3„ ƒZ e jd4d3„ ƒZ d5d6„ Z!ed7d8„ ƒZ"d9d:„ Z#d;d<„ Z$d=d>„ Z%d?d@„ Z&dAdB„ Z'dCdD„ Z(dEdF„ Z)dS )JÚHttpRequestzA basic HTTP request.Nc             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ÚmethodZresolver_matchÚcontent_typeÚcontent_params)Úselfr%   r%   r&   Ú__init__A   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>)r3   Úget_full_pathÚ	__class__r"   )r6   r%   r%   r&   Ú__repr__S   s    zHttpRequest.__repr__c             C   s
   t | jƒS )N)ÚHttpHeadersr0   )r6   r%   r%   r&   ÚheadersX   s    zHttpRequest.headersc             C   s   t | j dd¡ƒS )z%Return a list of MediaType instances.ÚAcceptz*/*)Úparse_accept_headerr<   Úget)r6   r%   r%   r&   Úaccepted_types\   s    zHttpRequest.accepted_typesc                s   t ‡ fdd„| jD ƒƒS )Nc             3   s   | ]}|  ˆ ¡V  qd S )N)Úmatch)Ú.0Zaccepted_type)Ú
media_typer%   r&   ú	<genexpr>c   s   z&HttpRequest.accepts.<locals>.<genexpr>)Úanyr@   )r6   rC   r%   )rC   r&   Úacceptsa   s    
zHttpRequest.acceptsc             C   s^   t  | dd¡¡\| _| _d| jkrZyt | jd ¡ W n tk
rL   Y nX | jd | _dS )z/Set content_type, content_params, and encoding.ÚCONTENT_TYPEr+   ÚcharsetN)	Úcgir   r?   r4   r5   ÚcodecsÚlookupÚLookupErrorÚencoding)r6   Úmetar%   r%   r&   Ú_set_content_type_paramsg   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_HOSTr0   Úget_portÚ	is_secure)r6   ÚhostZserver_portr%   r%   r&   Ú_get_raw_hostr   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)rU   r	   ZALLOWED_HOSTSÚDEBUGÚsplit_domain_portÚvalidate_hostr   )r6   rT   Ú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_PORTr0   Ústr)r6   r[   r%   r%   r&   rR   ™   s    
zHttpRequest.get_portFc             C   s   |   | j|¡S )N)Ú_get_full_pathr1   )r6   Úforce_append_slashr%   r%   r&   r8   ¡   s    zHttpRequest.get_full_pathc             C   s   |   | j|¡S )N)r_   r2   )r6   r`   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 )Nz%s%s%sú/r+   ÚQUERY_STRINGú?)r   Úendswithr0   r?   r   )r6   r1   r`   r%   r%   r&   r_   §   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×
        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)r6   ÚkeyÚdefaultrf   rg   Zcookie_valueÚvaluer%   r%   r&   Úget_signed_cookie°   s    zHttpRequest.get_signed_cookiec             C   s   d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})ÚschemerT   r1   )Úformatrn   rU   r8   )r6   r%   r%   r&   Úget_raw_uriÇ   s    zHttpRequest.get_raw_uric             C   sš   |dkrd|   ¡  }nt|ƒ}t|ƒ}|jr2|js’|j d¡r€|js€|js€d|jkr€d|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//%srb   z/./z/../z//é   )
r8   r^   r   rn   Únetlocr1   Ú
startswithÚ_current_scheme_hostr   r   )r6   ÚlocationÚbitsr%   r%   r&   Úbuild_absolute_uriÒ   s    	
zHttpRequest.build_absolute_uric             C   s   d  | j|  ¡ ¡S )Nz{}://{})ro   rn   r]   )r6   r%   r%   r&   rt   ö   s    z HttpRequest._current_scheme_hostc             C   s   dS )zf
        Hook for subclasses like WSGIRequest to implement. Return 'http' by
        default.
        Úhttpr%   )r6   r%   r%   r&   Ú_get_schemeú   s    zHttpRequest._get_schemec             C   s^   t jrVyt j\}}W n tk
r0   tdƒ‚Y nX | j |¡}|d k	rV||krRdS dS |  ¡ S )NzJThe SECURE_PROXY_SSL_HEADER setting must be a tuple containing two values.Úhttpsrx   )r	   ZSECURE_PROXY_SSL_HEADERÚ
ValueErrorr   r0   r?   ry   )r6   ÚheaderZsecure_valueÚheader_valuer%   r%   r&   rn     s    zHttpRequest.schemec             C   s
   | j dkS )Nrz   )rn   )r6   r%   r%   r&   rS     s    zHttpRequest.is_securec             C   s    t jdtdd� | j d¡dkS )Nzfrequest.is_ajax() is deprecated. See Django 3.1 release notes for more details about this deprecation.rq   )Ú
stacklevelZHTTP_X_REQUESTED_WITHZXMLHttpRequest)ÚwarningsÚwarnr   r0   r?   )r6   r%   r%   r&   Úis_ajax  s
    zHttpRequest.is_ajaxc             C   s   | j S )N)Ú	_encoding)r6   r%   r%   r&   rM     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‚   Úhasattrr-   rƒ   )r6   Úvalr%   r%   r&   rM     s
    

c                s   ‡ fdd„t jD ƒˆ _d S )Nc                s   g | ]}t  |ˆ ¡‘qS r%   )r   Zload_handler)rB   Úhandler)r6   r%   r&   ú
<listcomp>-  s   z4HttpRequest._initialize_handlers.<locals>.<listcomp>)r	   ZFILE_UPLOAD_HANDLERSÚ_upload_handlers)r6   r%   )r6   r&   Ú_initialize_handlers,  s    
z HttpRequest._initialize_handlersc             C   s   | j s|  ¡  | j S )N)rˆ   r‰   )r6   r%   r%   r&   Úupload_handlers0  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ˆ   )r6   rŠ   r%   r%   r&   rŠ   7  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   rM   Úparse)r6   r0   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 d¡p2dƒtjkrDtdƒ‚y|  	¡ | _
W n. tk
r€ } zt|jŽ |‚W d d }~X Y 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Úintr0   r?   r   Úreadr‘   ÚOSErrorr!   Úargsr   Ú_stream)r6   Úer%   r%   r&   ÚbodyF  s    

zHttpRequest.bodyc             C   s   t ƒ | _tƒ | _d S )N)r,   rƒ   r   r‹   )r6   r%   r%   r&   Ú_mark_post_parse_errorX  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r¦t| dƒrbt
| jƒ}n| }y|  | j|¡\| _| _W qæ ttfk
r¢   |  ¡  ‚ Y qæX n@| j	dkrÎt| 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.   )rM   Nr‘   zmultipart/form-dataz!application/x-www-form-urlencoded)r3   r,   r‚   r   rƒ   r‹   r“   r„   r›   r4   r   r‘   r�   r0   r   r   rš   )r6   Údatar%   r%   r&   Ú_load_post_and_files\  s$    




z HttpRequest._load_post_and_filesc             C   s:   t | dƒr6x*t dd„ | j ¡ D ƒ¡D ]}| ¡  q&W d S )Nr‹   c             s   s   | ]}|d  V  qdS )r   Nr%   )rB   Úlist_r%   r%   r&   rD   {  s    z$HttpRequest.close.<locals>.<genexpr>)r„   r   Úfrom_iterabler‹   ÚlistsÚclose)r6   Úfr%   r%   r&   r¡   y  s    
 zHttpRequest.closec          
   O   sH   d| _ y| jj||ŽS  tk
rB } zt|jŽ |‚W d d }~X Y nX d S )NT)r“   r˜   r•   r–   r!   r—   )r6   r—   Úkwargsr™   r%   r%   r&   r•   †  s
    zHttpRequest.readc          
   O   sH   d| _ y| jj||ŽS  tk
rB } zt|jŽ |‚W d d }~X Y nX d S )NT)r“   r˜   Úreadliner–   r!   r—   )r6   r—   r£   r™   r%   r%   r&   r¤   �  s
    zHttpRequest.readlinec             C   s   t | jdƒS )Nó    )Úiterr¤   )r6   r%   r%   r&   Ú__iter__”  s    zHttpRequest.__iter__c             C   s   t | ƒS )N)Úlist)r6   r%   r%   r&   Ú	readlines—  s    zHttpRequest.readlines)F)F)N)*r"   r#   r$   r(   r‚   rˆ   r7   r:   r   r<   r@   rF   rO   rU   r]   rR   r8   ra   r_   ri   rm   rp   rw   rt   ry   Úpropertyrn   rS   r�   rM   Úsetterr‰   rŠ   r�   rš   r›   r�   r¡   r•   r¤   r§   r©   r%   r%   r%   r&   r)   :   sJ   

	
$		r)   c                   s@   e Zd ZdZddhZ‡ fdd„Z‡ fdd„Zedd	„ ƒZ‡  Z	S )
r;   ZHTTP_rG   r’   c                s@   i }x*|  ¡ D ]\}}|  |¡}|r|||< qW tƒ  |¡ d S )N)ÚitemsÚparse_header_nameÚsuperr7   )r6   Úenvironr<   r|   rl   Úname)r9   r%   r&   r7      s    
zHttpHeaders.__init__c                s   t ƒ  | dd¡¡S )z:Allow header lookup using underscores in place of hyphens.Ú_ú-)r®   Ú__getitem__Úreplace)r6   rj   )r9   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²   )rs   ÚHTTP_PREFIXÚlenÚUNPREFIXED_HEADERSr´   Útitle)Úclsr|   r%   r%   r&   r­   ¬  s
    
zHttpHeaders.parse_header_name)
r"   r#   r$   rµ   r·   r7   r³   Úclassmethodr­   Ú__classcell__r%   r%   )r9   r&   r;   ›  s
   r;   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ƒrhy| | j¡}W n t	k
rf   | d¡}Y nX y*x$t
|f|ŽD ]\}}|  ||¡ qxW W n, tk
r¾ } ztdƒ|‚W d d }~X Y nX || _d S )Nr+   T)Úkeep_blank_valuesrM   r   z
iso-8859-1zRThe number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS.)r®   r7   r	   ÚDEFAULT_CHARSETrM   ZDATA_UPLOAD_MAX_NUMBER_FIELDSÚ
isinstanceÚbytesÚdecodeÚUnicodeDecodeErrorr   Ú
appendlistr{   r   Ú_mutable)r6   Zquery_stringr*   rM   Zparse_qsl_kwargsrj   rl   r™   )r9   r%   r&   r7   É  s&    


zQueryDict.__init__r+   c             C   s6   | dd|d�}x|D ]}|  ||¡ qW |s2d|_|S )zt
        Return a new QueryDict with keys (may be repeated) from an iterable and
        values from value.
        r+   T)r*   rM   F)rÂ   rÃ   )r¹   Úiterablerl   r*   rM   Úqrj   r%   r%   r&   Úfromkeysç  s    
zQueryDict.fromkeysc             C   s   | j d krtj| _ | j S )N)r‚   r	   r½   )r6   r%   r%   r&   rM   ô  s    
zQueryDict.encodingc             C   s
   || _ d S )N)r‚   )r6   rl   r%   r%   r&   rM   ú  s    c             C   s   | j stdƒ‚d S )Nz$This QueryDict instance is immutable)rÃ   rŒ   )r6   r%   r%   r&   Ú_assert_mutableþ  s    zQueryDict._assert_mutablec                s2   |   ¡  t|| jƒ}t|| jƒ}tƒ  ||¡ d S )N)rÇ   Úbytes_to_textrM   r®   Ú__setitem__)r6   rj   rl   )r9   r%   r&   rÉ     s    zQueryDict.__setitem__c                s   |   ¡  tƒ  |¡ d S )N)rÇ   r®   Ú__delitem__)r6   rj   )r9   r%   r&   rÊ     s    zQueryDict.__delitem__c             C   s8   | j dd| jd�}x |  ¡ D ]\}}| ||¡ qW |S )Nr+   T)r*   rM   )r9   rM   r    Úsetlist)r6   Úresultrj   rl   r%   r%   r&   Ú__copy__  s    zQueryDict.__copy__c             C   sT   | j dd| jd�}||t| ƒ< x0|  ¡ D ]$\}}| t ||¡t ||¡¡ q(W |S )Nr+   T)r*   rM   )r9   rM   Úidr    rË   ÚcopyÚdeepcopy)r6   ÚmemorÌ   rj   rl   r%   r%   r&   Ú__deepcopy__  s
     zQueryDict.__deepcopy__c                s8   ˆ   ¡  t|ˆ jƒ}‡ fdd„|D ƒ}tƒ  ||¡ d S )Nc                s   g | ]}t |ˆ jƒ‘qS r%   )rÈ   rM   )rB   Úelt)r6   r%   r&   r‡     s    z%QueryDict.setlist.<locals>.<listcomp>)rÇ   rÈ   rM   r®   rË   )r6   rj   rž   )r9   )r6   r&   rË     s    zQueryDict.setlistc                s   |   ¡  tƒ  ||¡S )N)rÇ   r®   Úsetlistdefault)r6   rj   Zdefault_list)r9   r%   r&   rÔ     s    zQueryDict.setlistdefaultc                s2   |   ¡  t|| jƒ}t|| jƒ}tƒ  ||¡ d S )N)rÇ   rÈ   rM   r®   rÂ   )r6   rj   rl   )r9   r%   r&   rÂ   #  s    zQueryDict.appendlistc                s   |   ¡  tƒ j|f|žŽ S )N)rÇ   r®   Úpop)r6   rj   r—   )r9   r%   r&   rÕ   )  s    zQueryDict.popc                s   |   ¡  tƒ  ¡ S )N)rÇ   r®   Úpopitem)r6   )r9   r%   r&   rÖ   -  s    zQueryDict.popitemc                s   |   ¡  tƒ  ¡  d S )N)rÇ   r®   Úclear)r6   )r9   r%   r&   r×   1  s    zQueryDict.clearc                s.   |   ¡  t|| jƒ}t|| jƒ}tƒ  ||¡S )N)rÇ   rÈ   rM   r®   Ú
setdefault)r6   rj   rk   )r9   r%   r&   rØ   5  s    zQueryDict.setdefaultc             C   s
   |   i ¡S )z%Return a mutable copy of this object.)rÒ   )r6   r%   r%   r&   rÏ   ;  s    zQueryDict.copyc                sf   g }ˆr"ˆ  ˆj¡‰‡fdd„‰ ndd„ ‰ x0ˆ ¡ D ]$\‰}| ‡ ‡‡fdd„|D ƒ¡ q4W d |¡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&   ÚencodeP  s    z#QueryDict.urlencode.<locals>.encodec             S   s   t | |iƒS )N)r   )rÙ   rÚ   r%   r%   r&   rÜ   S  s    c             3   s,   | ]$}ˆ ˆ  ˆj¡t|ƒ  ˆj¡ƒV  qd S )N)rÜ   rM   r^   )rB   rÚ   )rÜ   rÙ   r6   r%   r&   rD   W  s   z&QueryDict.urlencode.<locals>.<genexpr>ú&)rÜ   rM   r    ÚextendÚjoin)r6   rÛ   Úoutputrž   r%   )rÜ   rÙ   rÛ   r6   r&   r   ?  s    zQueryDict.urlencode)NFN)r+   FN)N)N)N)r"   r#   r$   r(   rÃ   r‚   r7   rº   rÆ   rª   rM   r«   rÇ   rÉ   rÊ   rÍ   rÒ   rË   rÔ   rÂ   rÕ   rÖ   r×   rØ   rÏ   r   r»   r%   r%   )r9   r&   r,   µ  s,   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   s4   t |r| d¡ndƒ\}| _| d¡\| _}| _d S )NÚasciir¥   rb   )r   rÜ   ÚparamsÚ	partitionÚ	main_typeÚsub_type)r6   Zmedia_type_raw_lineZ	full_typer±   r%   r%   r&   r7   ^  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 ||  d¡f V  qdS )z; %s=%srâ   N)rÀ   )rB   rÙ   rÚ   r%   r%   r&   rD   f  s   z$MediaType.__str__.<locals>.<genexpr>z%s%s%sz/%s)rß   rã   r¬   rå   ræ   )r6   Z
params_strr%   r%   r&   Ú__str__d  s    zMediaType.__str__c             C   s   d| j j| f S )Nz<%s: %s>)r9   r$   )r6   r%   r%   r&   r:   o  s    zMediaType.__repr__c             C   s   | j dko| jdkS )NÚ*)rå   ræ   )r6   r%   r%   r&   Úis_all_typesr  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æ   )r6   Úotherr%   r%   r&   rA   v  s    zMediaType.matchN)	r"   r#   r$   r7   rç   r:   rª   ré   rA   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¿   r^   )ÚsrM   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   rq   r   Ú.N)ÚlowerÚhost_validation_rerA   Úrsplitr¶   re   )rT   rv   rZ   r[   r%   r%   r&   rW   �  s    
 rW   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   )rB   Úpattern)rT   r%   r&   rD   µ  s    z validate_host.<locals>.<genexpr>)rE   )rT   rY   r%   )rT   r&   rX   ¦  s    rX   c             C   s   dd„ |   d¡D ƒS )Nc             S   s   g | ]}|  ¡ rt|ƒ‘qS r%   )Ústriprá   )rB   Útokenr%   r%   r&   r‡   ¹  s    z'parse_accept_header.<locals>.<listcomp>ú,)Úsplit)r|   r%   r%   r&   r>   ¸  s    r>   )?rI   rJ   rÏ   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.deprecationr   Zdjango.utils.encodingr   r   Zdjango.utils.functionalr   Zdjango.utils.httpr   Zdjango.utils.inspectr   Zdjango.utils.regex_helperr   Zmultipartparserr   Úobjectri   rñ   r–   r!   Ú	Exceptionr'   r)   r;   r,   rá   rÈ   rW   rX   r>   r%   r%   r%   r&   Ú<module>   sJ   	  c )%