Your IP : 216.73.216.213


Current Path : /opt/alt/python37/lib/python3.7/site-packages/webob/__pycache__/
Upload File :
Current File : //opt/alt/python37/lib/python3.7/site-packages/webob/__pycache__/response.cpython-37.pyc

B

��vP��@s�ddlmZddlmZmZddlmZddlZddlZddlZyddl	Z
Wnek
rhddl
Z
YnXddlm
Z
ddlmZmZddlmZmZmZmZmZmZddlmZmZdd	lmZmZmZdd
lm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.ddl/m0Z0ddl1m2Z2dd
l3m4Z4m5Z5dgZ6e�7dej8�Z9e�7dej8�Z:dZ;Gdd�de<�Z=d'dd�Z>d(dd�Z?Gdd�de<�Z@Gdd�de<�ZAGdd�de<�ZBdd �ZCd!d"�ZDd#d$�ZEd%d&�ZFdS))�)�	b64encode)�datetime�	timedelta)�md5N)�ContentRange)�CacheControl�serialize_cache_control)�PY3�bytes_�native_�	text_type�	url_quote�urlparse)�Cookie�Morsel)�parse_date_delta�serialize_date_delta�timedelta_to_seconds)�
CHARSET_RE�	SCHEME_RE�	converter�date_header�
header_getter�list_header�
parse_auth�parse_content_range�parse_etag_response�	parse_int�parse_int_safe�serialize_auth�serialize_content_range�serialize_etag_response�
serialize_int)�ResponseHeaders)�BaseRequest)�status_reasons�status_generic_reasons�Responsez(([a-z0-9]+)=(?:"([^"]*)"|([a-z0-9_.-]*))z^[a-z0-9_.-]+$s
��c	@seZdZdZdZdZdZdZdZdZ	d�dd�Z
ed	d
��Zdd�Z
d
d�Zd�dd�Zdd�Zdd�Zeeeejd�Zdd�Zdd�Zeeeejd�ZZdd�Zdd�Zdd�Zeeeeejd�Zd d!�Zd"d#�Zeeeejd�Zd$d%�Zd�d'd(�Z eee e �Z!d)d*�Z"d+d,�Z#d-d.�Z$ee"e#e$�Z%Z&d/d0�Z'd1d2�Z(d3d4�Z)ee'e(e)e'jd�Z*ee'e(e)d5�Z+Z,d6d7�Z-d8d9�Z.d:d;�Z/ee-e.e/e-jd�Z0d<d=�Z1d>d?�Z2d@dA�Z3dBdC�Z4ee2e3e4e2jd�Z5e6dDdE�Z7e6dFdG�Z8e9e:dHdI�e;e<dJ�Z=e:dKdL�Z>e6dMdN�Z?e:dOdP�Z@e:dQdP�ZAe:dRdS�ZBe:dTdU�ZCe9e:dVdW�eDeEdX�ZFeGdYdZ�ZHeGd[d\�ZIeGd]d^�ZJe:d_d`�ZKe9eKeLeMda�ZNedbdc��ZOe:ddde�ZPe:dfdg�ZQe9e:dhdi�eRe<dJ�ZSe9e:djdk�eTeUdl�ZVe:dmdn�ZWe9e:dodp�eXeY�ZZdqdr�Z[dsdt�Z\dudv�Z]ee[e\e]e[jd�Z^dwdx�Z_dydz�Z`d{d|�Zaee_e`eae_jd�Zbd}d~�Zcdd��Zdd�d��Zeeecedeeecj�Zfd�d�d��Zgd�d�d��Zhd�d�d��Zid�d��ZjdZkd�d��Zld�d��Zmd�d��Znd�d��Zoeelemeneljd�Zpd�d�d��Zqed�d��eq�Zrd�d�d��Zsd�d��Ztd�d�d��Zud�d��Zvd�d��Zwd�Zxd�d��Zyd�d��ZzdS)�r'z(
        Represents a WSGI response
    z	text/htmlzUTF-8�strictFNcKsj|dkrX|dkrXd|ks d|krXd|kr4|�d�}n
|�d�}tj|dd�}|dkrXd}|dkrn|dkr~d}n|dk	r~td��|dkr�d|_n||_|dkr�g|_n||_d|_|dkr�|j}d}	d	|kr�|�d	�}	np|j	�rF|�rFd
|k�rF|dk�s@|�
d��s@|�
d
��s@|�
d��s@|�
d��rF|�d��s@|�d��rF|j	}	|�r`|	�r`|d|	7}n|j�rt|	�rt|	|_|j�s�|�r�|j�
d|f�|dk�r�|j|_n
t|�|_|dk�rt|t��r�|	dk�r�td��|�|	�}|g}|dk�r|j�
dtt|��f�ntt|��|jd<||_x@|��D]4\}
}t|j|
��sTtd|
|f��t||
|��q.WdS)N�	json_body�json)�,�:)�
separatorszapplication/json�z8You may only give one of the body and app_iter argumentsz200 OK�charsetzcharset=z	text/htmlztext/zapplication/xmlzapplication/z+xmlz+jsonz
; charset=zContent-Typez9You cannot set the body to a text value without a charsetzContent-LengthzUnexpected keyword: %s=%r)�popr*�dumps�	TypeError�_status�status�_headerlist�_headers�default_content_type�default_charset�
startswith�endswithr/�append�default_conditional_response�conditional_response�bool�
isinstancer�encode�str�len�headers�	_app_iter�items�hasattr�	__class__�setattr)�self�bodyr4�
headerlist�app_iter�content_typer=�kwr)r/�name�value�rQ�?/opt/alt/python37/lib/python3.7/site-packages/webob/response.py�__init__Wsx 









zResponse.__init__cCs�g}|����}t|t�}|r$d}nd}xz|����}|s<Py|�|d�\}}Wn tk
rptd|��YnX|��}|s�|�d�}|�d�}|�||f�q*W|||dd�}	|�|	j	p�d�}
|r�|
|	_
n|
|	_|	S)	aoReads a response from a file-like object (it must implement
        ``.read(size)`` and ``.readline()``).

        It will read up to the end of the response, not the end of the
        file.

        This reads the response as represented by ``str(resp)``; it
        may not read every valid HTTP response properly.  Responses
        must have a ``Content-Length``r,�:�zBad header line: %rzutf-8rQ)r4rKrLr)�readline�stripr?r�split�
ValueError�decoder;�read�content_length�textrJ)�cls�fprKr4Zis_textZ_colon�line�header_namerP�rrJrQrQrR�	from_file�s8


zResponse.from_filecCs@t|j�}t|j�t|�|_|jd|j|jdd�||jd�S)zMakes a copy of the responseFN)rMr4rKrLr=)�listrD�
iter_closerGr3r5r=)rIrLrQrQrR�copy�s


z
Response.copycCsd|jjtt|��|jfS)Nz<%s at 0x%x %s>)rG�__name__�abs�idr4)rIrQrQrR�__repr__�szResponse.__repr__cCsP|jg}|s|j|tdj|j�7}|sF|jrF|dtr<|jn|jg7}d�|�S)Nz%s: %s��
)r4rJ�map�__mod__rKr	r]�join)rIZ	skip_body�partsrQrQrR�__str__�s
zResponse.__str__cCs|jS)z#
        The status string
        )r3)rIrQrQrR�_status__get�szResponse._status__getcCs�t|t�r||_dStr.t|t�rB|�d�}nt|t�rB|�d�}t|t�s\t	dt
|���d|kr�y|dtt|�7}Wn,tk
r�|dt
t|�d7}YnX||_dS)N�asciiz3You must set status to a string or integer (not %s)� �d)r?�int�status_coder	�bytesrZrr@rAr2�typer%�KeyErrorr&r3)rIrPrQrQrR�_status__set�s$




zResponse._status__set)�doccCst|j��d�S)z*
        The status as an integer
        r)rvr3rX)rIrQrQrR�_status_code__getszResponse._status_code__getcCsFyd|t|f|_Wn*tk
r@d|t|df|_YnXdS)Nz%d %sru)r%r3rzr&)rI�coderQrQrR�_status_code__setszResponse._status_code__setcCs|jS)z.
        The list of response headers
        )r5)rIrQrQrR�_headerlist__get szResponse._headerlist__getcCs4d|_t|t�s*t|d�r"|��}t|�}||_dS)NrE)r6r?rdrFrEr5)rIrPrQrQrR�_headerlist__set&s

zResponse._headerlist__setcCs
g|_dS)N)rK)rIrQrQrR�_headerlist__del.szResponse._headerlist__delcCs|jdkrt�|j�|_|jS)z9
        The headers in a dictionary-like object
        N)r6r#Z	view_listrK)rIrQrQrR�
_headers__get4s
zResponse._headers__getcCs"t|d�r|��}||_d|_dS)NrE)rFrErKr6)rIrPrQrQrR�
_headers__set<s
zResponse._headers__setcCs�|j}t|t�r$t|�dkr$|dS|dkr4td��zd�|�}Wdt|�Xt|t�rbt||��|g|_t|�dkrxn:|j	dkr�t|�|_	n$|j	t|�kr�t
d|j	t|�f��|S)zv
        The body of the response, as a ``str``.  This will read in the
        entire app_iter if necessary.
        rUrNzNo body has been setr.z@Content-Length is different from actual app_iter length (%r!=%r))rDr?rdrB�AttributeErrorrorer�_error_unicode_in_app_iterr\�AssertionError)rIrLrJrQrQrR�
_body__getIs(



zResponse._body__getr.cCsTt|t�s.t|t�rd}ndt|�}t|��|jdk	r>d|_|g|_t|�|_dS)NzAYou cannot set Response.body to a text object (use Response.text)z3You can only set the body to a binary type (not %s))	r?rxrryr2rD�content_md5rBr\)rIrP�msgrQrQrR�
_body__setms



zResponse._body__setcCst�|j�|jpd��S)z'Access the body of the response as JSONzUTF-8)r*�loadsrJrZr/)rIrQrQrR�_json_body__get�szResponse._json_body__getcCs tj|dd��|jpd�|_dS)N)r+r,)r-zUTF-8)r*r1r@r/rJ)rIrPrQrQrR�_json_body__set�szResponse._json_body__setcCs|`dS)N)rJ)rIrQrQrR�_json_body__del�szResponse._json_body__delcCs$|jstd��|j}|�|j|j�S)zd
        Get/set the text value of the body (using the charset of the
        Content-Type)
        z5You cannot access Response.text unless charset is set)r/r�rJrZ�unicode_errors)rIrJrQrQrR�
_text__get�s
zResponse._text__getcCs:|jstd��t|t�s(tdt|���|�|j�|_dS)Nz5You cannot access Response.text unless charset is setz;You can only set Response.text to a unicode string (not %s))r/r�r?rr2ryr@rJ)rIrPrQrQrR�
_text__set�s
zResponse._text__setcCs|`dS)N)rJ)rIrQrQrR�
_text__del�szResponse._text__delzDeprecated alias for .textcCst|�S)z�
        A file-like object that can be used to write to the
        body.  If you passed in a list app_iter, that app_iter will be
        modified by writes.
        )�ResponseBodyFile)rIrQrQrR�_body_file__get�szResponse._body_file__getcCst|�|_dS)N)�	iter_filerL)rI�filerQrQrR�_body_file__set�szResponse._body_file__setcCs|`dS)N)rJ)rIrQrQrR�_body_file__del�szResponse._body_file__delcCs�t|t�sFt|t�s(d}t|t|���|js:d}t|��|�|j�}|j}t|t�s�zt|�}|_Wdt	|�X|}t
dd�|D��|_|�|�|jdk	r�|jt
|�7_dS)Nz6You can only write str to a Response.body_file, not %sz;You can only write text to Response if charset has been setcss|]}t|�VqdS)N)rB)�.0�chunkrQrQrR�	<genexpr>�sz!Response.write.<locals>.<genexpr>)r?rxrr2ryr/r@rDrdre�sumr\r;rB)rIr]r�rLZnew_app_iterrQrQrR�write�s$





zResponse.writecCs|jS)z�
        Returns the app_iter of the response.

        If body was set, this will create an app_iter from that body
        (a single-item list)
        )rD)rIrQrQrR�_app_iter__get�szResponse._app_iter__getcCs |jdk	rd|_d|_||_dS)N)rDr\r�)rIrPrQrQrR�_app_iter__set�s
zResponse._app_iter__setcCsg|_d|_dS)N)rDr\)rIrQrQrR�_app_iter__del�szResponse._app_iter__delZAllowz14.7ZVaryz14.44zContent-Lengthz14.17rvzContent-Encodingz14.11zContent-Languagez14.12zContent-Locationz14.14zContent-MD5zContent-Dispositionz19.5.1z
Accept-Rangesz14.5z
Content-Rangez14.16zContentRange objectZDatez14.18ZExpiresz14.21z
Last-Modifiedz14.29ZETagz14.19z
Entity tagcCst|jdd�S)NT)Zstrong)r�	_etag_raw)rIrQrQrR�etag_strongszResponse.etag_strongZLocationz14.30ZPragmaz14.32ZAgez14.6zRetry-Afterz14.37zHTTP date or delta secondsZServerz14.38zWWW-Authenticatez14.47cCs0|j�d�}|sdSt�|�}|r,|�d�SdS)z;
        Get/set the charset (in the Content-Type)
        zContent-TypeNrU)rC�getr�search�group)rI�header�matchrQrQrR�
_charset__get6s

zResponse._charset__getcCsv|dkr|`dS|j�dd�}|dkr.td��t�|�}|r\|d|���||��d�}|d|7}||jd<dS)NzContent-Typez:You cannot set the charset when no content-type is definedz; charset=%s)r/rCr0r�rr��start�end)rIr/r�r�rQrQrR�
_charset__setBs
 zResponse._charset__setcCsV|j�dd�}|dkrdSt�|�}|rH|d|���||��d�}||jd<dS)NzContent-Type)rCr0rr�r�r�)rIr�r�rQrQrR�
_charset__delPs
 zResponse._charset__delcCs$|j�d�}|sdS|�dd�dS)a
        Get/set the Content-Type header (or None), *without* the
        charset or any parameters.

        If you include parameters (or ``;`` at all) when setting the
        content_type, any existing parameters will be deleted;
        otherwise they will be preserved.
        zContent-TypeN�;rUr)rCr�rX)rIr�rQrQrR�_content_type__getbs	zResponse._content_type__getcCsX|s|��dSd|krJ|j�dd�}d|krJ|�dd�d}|d|7}||jd<dS)Nr�zContent-TyperkrU)�_content_type__delrCr�rX)rIrPr��paramsrQrQrR�_content_type__setpszResponse._content_type__setcCs|j�dd�dS)NzContent-Type)rCr0)rIrQrQrRr�{szResponse._content_type__delcCsh|j�dd�}d|kriS|�dd�d}i}x4t�|�D]&}|�d�pT|�d�pTd||�d�<q:W|S)z�
        A dictionary of all the parameters in the content type.

        (This is not a view, set to change, modifications of the dict would not
        be applied otherwise)
        zContent-Typerkr�rU��)rCr�rX�	_PARAM_RE�finditerr�)rIr��resultr�rQrQrR�_content_type_params__get�s&z"Response._content_type_params__getcCs�|s|`dSg}xDt|���D]4\}}t�|�s@d|�dd�}|�d||f�qW|j�dd��	dd�d	}|d�
|�7}||jd<dS)
Nz"%s"�"z\"z; %s=%szContent-Typerkr�rUr)�content_type_params�sortedrE�_OK_PARAM_REr��replacer;rCr0rXro)rIZ
value_dictr��k�vZctrQrQrR�_content_type_params__set�s
z"Response._content_type_params__setcCs$|j�dd��dd�d|jd<dS)NzContent-Typerkr�rUr)rCr�rX)rIrQrQrR�_content_type_params__del�sz"Response._content_type_params__delrk�/cCs�|
r|j|dd�|dkr.d}d}tdd�}	nN|	dkr`|dk	r`t|t�rRt|d�}t��|}	n|dkr||	dk	r||	t��}t|d	�}t|d	�}t||�}t|d	�|_t|d	�|_	t|d	�|_
|	|_||_||_
||_|j�d
|��f�dS)a�	
        Set (add) a cookie for the response.

        Arguments are:

        ``key``

           The cookie name.

        ``value``

           The cookie value, which should be a string or ``None``.  If
           ``value`` is ``None``, it's equivalent to calling the
           :meth:`webob.response.Response.unset_cookie` method for this
           cookie key (it effectively deletes the cookie on the client).

        ``max_age``

           An integer representing a number of seconds or ``None``.  If this
           value is an integer, it is used as the ``Max-Age`` of the
           generated cookie.  If ``expires`` is not passed and this value is
           an integer, the ``max_age`` value will also influence the
           ``Expires`` value of the cookie (``Expires`` will be set to now +
           max_age).  If this value is ``None``, the cookie will not have a
           ``Max-Age`` value (unless ``expires`` is also sent).

        ``path``

           A string representing the cookie ``Path`` value.  It defaults to
           ``/``.

        ``domain``

           A string representing the cookie ``Domain``, or ``None``.  If
           domain is ``None``, no ``Domain`` value will be sent in the
           cookie.

        ``secure``

           A boolean.  If it's ``True``, the ``secure`` flag will be sent in
           the cookie, if it's ``False``, the ``secure`` flag will not be
           sent in the cookie.

        ``httponly``

           A boolean.  If it's ``True``, the ``HttpOnly`` flag will be sent
           in the cookie, if it's ``False``, the ``HttpOnly`` flag will not
           be sent in the cookie.

        ``comment``

           A string representing the cookie ``Comment`` value, or ``None``.
           If ``comment`` is ``None``, no ``Comment`` value will be sent in
           the cookie.

        ``expires``

           A ``datetime.timedelta`` object representing an amount of time or
           the value ``None``.  A non-``None`` value is used to generate the
           ``Expires`` value of the generated cookie.  If ``max_age`` is not
           passed, but this value is not ``None``, it will influence the
           ``Max-Age`` header (``Max-Age`` will be 'expires_value -
           datetime.utcnow()').  If this value is ``None``, the ``Expires``
           cookie value will be unset (unless ``max_age`` is also passed).

        ``overwrite``

           If this key is ``True``, before setting the cookie, unset any
           existing cookie.

        F)r(Nrkr���)�days)�seconds�utf8z
Set-Cookie)�unset_cookierr?rvr�utcnowr
r�path�domain�comment�expires�max_age�secure�httponlyrKr;�	serialize)rI�keyrPr�r�r�r�r�r�r�Z	overwrite�mrQrQrR�
set_cookie�s.J




zResponse.set_cookiecCs|j|d||d�dS)z�
        Delete a cookie from the client.  Note that path and domain must match
        how the cookie was originally set.

        This sets the cookie to the empty string, and max_age=0 so
        that it should expire immediately.
        N)r�r�)r�)rIr�r�r�rQrQrR�
delete_cookieszResponse.delete_cookieTcCs�|j�d�}|s|sdSt�}x|D]}|�|�q$Wt|t�rJ|�d�}||kr�||=|jd=x6|��D]}|j�	d|�
�f�qjWn|r�td|��dS)z[
        Unset a cookie with the given name (remove it from the
        response).
        z
Set-CookieNr�z'No cookie has been set with the name %r)rC�getallr�loadr?rr@�valuesrKr;r�rz)rIr�r(�existingZcookiesr�r�rQrQrRr�!s


zResponse.unset_cookiecsh|j�d�s�St�t�rBx"|j�d�D]}�j�d|�q(W�Sdd�|jD����fdd�}|SdS)z�Merge the cookies that were set on this response with the
        given `resp` object (which can be any WSGI application).

        If the `resp` is a :class:`webob.Response` object, then the
        other object will be modified in-place.
        z
Set-CookiecSs g|]}|d��dkr|�qS)rz
set-cookie)�lower)r��hrQrQrR�
<listcomp>Esz*Response.merge_cookies.<locals>.<listcomp>csd��fdd�	}�||�S)Ncs�||�|d�S)N)�exc_inforQ)r4rCr�)�	c_headers�start_responserQrR�repl_start_responseHs
zEResponse.merge_cookies.<locals>.repl_app.<locals>.repl_start_response)NrQ)�environr�r�)r��resp)r�rR�repl_appGsz(Response.merge_cookies.<locals>.repl_appN)rCr�r?r'r��addrK)rIr�r�r�rQ)r�r�rR�
merge_cookies7s
zResponse.merge_cookiescCsx|j�dd�}|jdkr4tj||jdd�|_||j_|jj|krrtj|dd�}|jj��|jj�	|j�||j_|jS)z�
        Get/set/modify the Cache-Control header (`HTTP spec section 14.9
        <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9>`_)
        z
cache-controlrkN�response)Z
updates_tory)ry)
rCr��_cache_control_objr�parse�_update_cache_controlZheader_value�
properties�clear�update)rIrPZnew_objrQrQrR�_cache_control__getUs
zResponse._cache_control__getcCs~|sd}t|t�rt|d�}t|t�r.t|�}t|t�r\|jdkrP||jd<dSt�|d�}|j}|j	�
�|j	�|j	�dS)Nrkr�z
Cache-Control)r?�dictrrrAr�rCr��
cache_controlr�r�r�)rIrP�cacherQrQrR�_cache_control__setfs






zResponse._cache_control__setcCs
i|_dS)N)r�)rIrQrQrR�_cache_control__delwszResponse._cache_control__delcCs.t|�}|s d|jkr*|jd=n
||jd<dS)Nz
Cache-Control)rrC)rIZ	prop_dictrPrQrQrRr�zs


zResponse._update_cache_controlrcKs�|dkrd}nt|t�r t|�}|j}|dkr0nx|s~d|_d|_d|_d|_d|_d|_	t
��|_d|j
krvt
��|_d|_n*|j��||_t
��t|d�|_d|_x |��D]\}}t|||�q�WdS)z�
            Set expiration on this request.  This sets the response to
            expire in the given seconds, and any other attributes are used
            for cache_control (e.g., private=True, etc).
        TrNz
last-modifiedzno-cache)r�)r?rrr�Zno_storeZno_cacheZmust_revalidater�Z
post_checkZ	pre_checkrr�r�rC�
last_modified�pragmar�r�rErH)rIr�rNr�rOrPrQrQrR�_cache_expires�s0




zResponse._cache_expirescCs|jS)N)r�)rIrQrQrR�<lambda>�r.zResponse.<lambda>�gzipcCsz|dkstd|��|dkr(|��dS|jdkr6dS|rNt|j�|_d|_n"tt|j��|_tt	t
|j��|_d|_dS)zl
        Encode the content with the given encoding (only gzip and
        identity are supported).
        )�identityr�zUnknown encoding: %rr�Nr�)r��decode_content�content_encoding�
gzip_app_iterrDrLr\rdr�rmrB)rI�encodingZlazyrQrQrR�encode_content�s


zResponse.encode_contentcCs�|jpd}|dkrdS|dkr*td|��|dkrxddlm}ddlm}|dd	||j�d
�}|��|_d|_|��nt	�
|jd�|_d|_dS)Nr�)r��deflatez)I don't know how to decode the content %sr�r)�GzipFile)�BytesIOrkrb)�filename�mode�fileobji�)r�rYr�r��ior�rJr[�close�zlib�
decompress)rIr�r�r�Zgzip_frQrQrRr��s



zResponse.decode_contentcCsP|dkr|j}t|���}t|�}|�dd�}t|�}|�d�|_|rL||_dS)z�
        Generate an etag for the response object using an MD5 hash of
        the body (the body parameter, or ``self.body`` if not given)

        Sets ``self.etag``
        If ``set_content_md5`` is True sets ``self.content_md5`` as well
        N�
r.�=)	rJr�digestrr�rrW�etagr�)rIrJZset_content_md5Z
md5_digestrQrQrR�md5_etag�szResponse.md5_etagcCsD|jr|�||�S|�|�}||j|�|ddkr>t|j�S|jS)z,
        WSGI application interface
        �REQUEST_METHOD�HEAD)r=�conditional_response_app�_abs_headerlistr4�
EmptyResponserD)rIr�r�rKrQrQrR�__call__�s

zResponse.__call__cCs^t|j�}xNt|�D]B\}\}}|��dkrt�|�r8Pt�t|�|�}||f||<PqW|S)zqReturns a headerlist, with the Location header possibly
        made absolute given the request environ.
        �location)	rdrK�	enumerater�rr�r�urljoin�_request_uri)rIr�rK�irOrPZnew_locationrQrQrRrs

zResponse._abs_headerlist)�GETr
c
Cs�t|�}|�|�}|�dd�}||jkrzd}|jrF|jrF|j|jk}n|jr^|jr^|j|jk}|rz|dt|��t	|j
�S|j�r�||jk�r�|j
dk�r�|dk�r�|jdk�r�|jdk	�r�|j�
|j�}|dk�r:t|j
�td|j�}d	tt|��fd
ttdd|j��fdgt|�}|d|�|d
k�r4dS|gS|�|j|j�}	|	dk	�r�|jdk	�sdt�d	t|j|j�fd
t|�fgt|d�}|d|�|d
k�r�t	|	�S|	S||j|�|d
k�r�t	|j
�S|j
S)a%
        Like the normal __call__ interface, but checks conditional headers:

        * If-Modified-Since   (304 Not Modified; only on GET, HEAD)
        * If-None-Match       (304 Not Modified; only on GET, HEAD)
        * Range               (406 Partial Content; only on GET, HEAD)
        rrFz304 Not ModifiedN)r
r��z#Requested range not satisfiable: %szContent-Lengthz
Content-Range)zContent-Typez
text/plainz#416 Requested Range Not Satisfiabler
rQ)zcontent-lengthz206 Partial Content)r$rr��
_safe_methodsZ
if_none_matchr
Zif_modified_sincer��filter_headersrrD�rangeZif_range�
content_rangerwr\rer
rArBr�app_iter_ranger��stopr�r4)
rIr�r��reqrK�methodZ	status304rrJrLrQrQrRrs^














z!Response.conditional_response_appcCs(|j}t|d�r|�||�St|||�S)z�
        Return a new app_iter built from the response app_iter, that
        serves up only the given ``start:stop`` range.
        r)rDrFr�AppIterRange)rIr�rrLrQrQrRrRs
zResponse.app_iter_range)NNNNNN)F)r.)	rkNr�NFFNNF)r�N)T)r)r�F)NF){rg�
__module__�__qualname__�__doc__r7r8r�r<�requestr�rS�classmethodrcrfrjrqrrr{�propertyr4r}rrwZ
status_intr�r�r�rKr�r�rCr�r�rJr�r�r�r*r)r�r�r�r]Zunicode_bodyZubodyr�r�r�Z	body_filer�r�r�r�rLrZallowZvaryrrrr"r\r�Zcontent_languageZcontent_locationr��content_dispositionZ
accept_rangesrr rr�dater�r�r�rr!r
r�rr�rZagerrZretry_after�serverrrZwww_authenticater�r�r�r/r�r�r�rMr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�Z
cache_expiresr�r�rrrrrrrQrQrQrRr'Gs
G,
$



	
























`



$


?�zcontent-lengthzcontent-typecs�fdd�|D�S)Ncs g|]}|d���kr|�qS)r)r�)r�r�)�remove_headersrQrRr�^sz"filter_headers.<locals>.<listcomp>rQ)Zhlistr,rQ)r,rRr]sr�ccs x|�|�}|sP|VqWdS)N)r[)r��
block_size�datarQrQrRr�as

r�c@sLeZdZdZdZdd�Zdd�Zedd�d	d
�Zdd�Z	d
d�Z
dd�ZdS)r��wbFcCs||_|j|_dS)N)r�r�)rIr�rQrQrRrSlszResponseBodyFile.__init__cCs
d|jS)Nz<body_file for %r>)r�)rIrQrQrRrjpszResponseBodyFile.__repr__cCs|jjS)N)r�r/)rIrQrQrRr�tr.zResponseBodyFile.<lambda>z:The encoding of the file (inherited from response.charset))r|cCsx|D]}|�|�qWdS)N)r�)rI�seq�itemrQrQrR�
writelinesxs
zResponseBodyFile.writelinescCstd��dS)Nz Response bodies cannot be closed)�NotImplementedError)rIrQrQrRr|szResponseBodyFile.closecCsdS)NrQ)rIrQrQrR�flushszResponseBodyFile.flushN)rgr"r#r�closedrSrjr'r�r3rr5rQrQrQrRr�hsr�c@s<eZdZdZdd�Zdd�Zdd�Zdd	�ZeZd
d�Z	dS)
r!z<
    Wraps an app_iter, returning just a range of bytes
    cCsX|dkstd|��|dks8|dkr,||ks8td|��t|�|_d|_||_||_dS)Nrz
Bad start: %rzBad stop: %r)r��iterrL�_posr�r)rIrLr�rrQrQrRrS�s

zAppIterRange.__init__cCs|S)NrQ)rIrQrQrR�__iter__�szAppIterRange.__iter__cCs�|j|j}}x�|jD]�}|jt|�7_|j|kr:qq|j|krHdS|||jd�}|dk	r�|j|kr�|d||j�}t|�||ks�t�|SqWt��dS)Nr.)r�rrLr8rBr��
StopIteration)rIr�rr�rQrQrR�_skip_start�s

zAppIterRange._skip_startcCsx|j|jkr|��S|j}|dk	r0|j|kr0t�t|j�}|jt|�7_|dks^|j|krb|S|d||j�SdS)N)r8r�r;rr:�nextrLrB)rIrr�rQrQrRr<�s
zAppIterRange.nextcCst|j�dS)N)rerL)rIrQrQrRr�szAppIterRange.closeN)
rgr"r#r$rSr9r;r<�__next__rrQrQrQrRr!�s	r!c@s6eZdZdZddd�Zdd�Zdd�Zd	d
�ZeZdS)rz�An empty WSGI response.

    An iterator that immediately stops. Optionally provides a close
    method to close an underlying app_iter it replaces.
    NcCs|rt|d�r|j|_dS)Nr)rFr)rIrLrQrQrRrS�szEmptyResponse.__init__cCs|S)NrQ)rIrQrQrRr9�szEmptyResponse.__iter__cCsdS)NrrQ)rIrQrQrR�__len__�szEmptyResponse.__len__cCs
t��dS)N)r:)rIrQrQrRr<�szEmptyResponse.next)N)	rgr"r#r$rSr9r>r<r=rQrQrQrRr�s
rcCs�|dd}|�d�r$||d7}n||dd|d7}|�d�r`|ddkr`|d	d
�}n"|�d�r�|ddkr�|d	d
�}tr�t|�dd�d�}t|�dd�d�}n|�dd�}|�dd�}|t|�7}t|�}d|kr�||dd	�7}n||7}|S)zZLike wsgiref.url.request_uri, except eliminates :80 ports

    Return the full request URIzwsgi.url_schemez://Z	HTTP_HOSTZSERVER_NAMEr,ZSERVER_PORTz:80�httpN���z:443�https���ZSCRIPT_NAMEr�zlatin-1Z	PATH_INFOrkrU)r�r:r	r
r
)r��url�script_nameZ	path_infoZ
qpath_inforQrQrRr�s&
rcCst|d�r|��dS)Nr)rFr)r7rQrQrRre�s
reccs�d}t�d�d@}t�dtjtjtjd�}tVx4|D],}|t|�7}t�||�d@}|�|�Vq8W|�	�Vt
�d||d@�VdS)Nrr.l���	z<2L)r�crc32�compressobj�DEFLATED�	MAX_WBITS�
DEF_MEM_LEVEL�_gzip_headerrB�compressr5�struct�pack)rL�size�crcrLr2rQrQrRr��s


r�cCsDt|�}t|�dkr0|dd�d|dd�}td||f��dS)N�2�z...i����z>An item of the app_iter (%s) was text, causing a text body: %r)�reprrBr2)rLrJZ
app_iter_reprrQrQrRr�sr�)r+)r-)G�base64rrr�hashlibr�rerMrZ
simplejsonr*�ImportErrorZwebob.byterangerZwebob.cachecontrolrrZwebob.compatr	r
rrr
rZ
webob.cookiesrrZwebob.datetime_utilsrrrZwebob.descriptorsrrrrrrrrrrrrr r!r"Z
webob.headersr#Z
webob.requestr$Z
webob.utilr%r&�__all__�compile�Ir�r�rK�objectr'rr�r�r!rrrer�r�rQrQrQrR�<module>sP 	D

9