U
    kufJ%                     @  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mZ ddlmZmZ dd	lmZ dd
lmZ ddlmZ ejrddlmZmZ eeZe	G dd dZG dd deZ dS )    )annotationsN)contextmanager)	dataclass)HTTPException)BytesIOIOBase   )InvalidHeaderTimeoutError)BaseHTTPResponse)Retry   )EmscriptenRequest)BaseHTTPConnectionBaseHTTPSConnectionc                   @  s.   e Zd ZU ded< ded< ded< ded< d	S )
EmscriptenResponseintstatus_codezdict[str, str]headerszIOBase | bytesbodyr   requestN)__name__
__module____qualname____annotations__ r   r   G/tmp/pip-unpacked-wheel-5in6dhvn/urllib3/contrib/emscripten/response.pyr      s   
r   c                      s4  e Zd Zd5dddd fddZeddd	d
Zejddddd
ZeddddZeddddZejdddddZd6ddddddZ	dddddZ
d7ddd d!d"d#d$Zd8ddddd%d&Zddd'd(Zddd)d*Zed!dd+d,Zd-dd.d/Zddd0d1Zed2dd3d4Z  ZS )9EmscriptenHttpResponseWrapperNr   z
str | Nonez/BaseHTTPConnection | BaseHTTPSConnection | None)internal_responseurl
connectionc                   s\   d | _ d | _|| _|| _|| _d| _t j|j|j	|dddd | 
| jjj| _d| _d S )NFr    T)r   statusrequest_urlversionreasondecode_content)_pool_body	_response_url_connection_closedsuper__init__r   r   _init_lengthr   methodlength_remaininglength_is_certain)selfr   r   r    	__class__r   r   r.      s     z&EmscriptenHttpResponseWrapper.__init__)returnc                 C  s   | j S Nr*   r3   r   r   r   r   6   s    z!EmscriptenHttpResponseWrapper.urlNone)r   r6   c                 C  s
   || _ d S r7   r8   )r3   r   r   r   r   r   :   s    c                 C  s   | j S r7   )r+   r9   r   r   r   r    >   s    z(EmscriptenHttpResponseWrapper.connectionzRetry | Nonec                 C  s   | j S r7   Z_retriesr9   r   r   r   retriesB   s    z%EmscriptenHttpResponseWrapper.retries)r<   r6   c                 C  s
   || _ d S r7   r;   )r3   r<   r   r   r   r<   F   s       z
int | Nonezbool | Nonez#typing.Generator[bytes, None, None])amtr&   r6   c                 c  s"   | j ||d}|r|V  q qq dS )a_  
        A generator wrapper for the read() method. A call will block until
        ``amt`` bytes have been read from the connection or until the
        connection is closed.

        :param amt:
            How much of the content to read. The generator will return up to
            much data per iteration, but may return less. This is particularly
            likely when using compressed data. However, the empty string will
            never be returned.

        :param decode_content:
            If True, will attempt to decode the body based on the
            'content-encoding' header.
        )r>   r&   Nread)r3   r>   r&   datar   r   r   streamK   s    z$EmscriptenHttpResponseWrapper.stream)request_methodr6   c                 C  s   | j d}|d k	rtz8dd |dD }t|dkrBtd| | }W n tk
rd   d }Y qxX |dk rxd }nd }| jdksd	| j  krd
k sn |dkrd}|S )Nzcontent-lengthc                 S  s   h | ]}t |qS r   )r   ).0valr   r   r   	<setcomp>p   s     z=EmscriptenHttpResponseWrapper._init_length.<locals>.<setcomp>,r   z8Content-Length contained multiple unmatching values (%s)r   )   i0  d      HEAD)r   getsplitlenr	   pop
ValueErrorr"   )r3   rC   content_lengthlengthslengthr   r   r   r/   e   s6    
 z*EmscriptenHttpResponseWrapper._init_lengthFboolbytes)r>   r&   cache_contentr6   c              
   C  sp  | j s(| jd ks(t| jjtr,| jjjr,dS |  0 t| jjtsjt| jj| _d| _	t
| jj| j_|d k	rd}| jj|}| jd k	rt| jt| d| _| j	r| jdkst||k r| jj  tt|W  5 Q R  S | jj }|r|| _| jd k	rt| jt| d| _t|dks>| j	rJ| jdkrJ| jj  tt|W  5 Q R  S W 5 Q R X d S )N    TFr   )r,   r)   
isinstancer   r   closed_error_catcherrN   r1   r2   r   r@   maxclosetypingcastrU   r(   )r3   r>   r&   rV   rA   r   r   r   r@      sL    
z"EmscriptenHttpResponseWrapper.readc                 c  s   |  ||}|sq|V  q d S r7   r?   )r3   r>   r&   rU   r   r   r   read_chunked   s    z*EmscriptenHttpResponseWrapper.read_chunkedc                 C  s(   | j r| jsd S | j | j d | _d S r7   )r'   r+   	_put_connr9   r   r   r   release_conn   s    z*EmscriptenHttpResponseWrapper.release_connc                 C  s   |    d S r7   )r\   r9   r   r   r   
drain_conn   s    z(EmscriptenHttpResponseWrapper.drain_connc                 C  s   | j r| j S | jddS d S )NT)rV   )r(   r@   r9   r   r   r   rA      s    z"EmscriptenHttpResponseWrapper.dataz
typing.Anyc                 C  s   | j d}t|S )a  
        Parses the body of the HTTP response as JSON.

        To use a custom JSON decoder pass the result of :attr:`HTTPResponse.data` to the decoder.

        This method can raise either `UnicodeDecodeError` or `json.JSONDecodeError`.

        Read more :ref:`here <json>`.
        zutf-8)rA   decode_jsonloads)r3   rA   r   r   r   json   s    
z"EmscriptenHttpResponseWrapper.jsonc                 C  s@   | j s<t| jjtr | jj  | jr6| j  d | _d| _ d S )NT)r,   rX   r)   r   r   r\   r+   r9   r   r   r   r\      s    
z#EmscriptenHttpResponseWrapper.closez$typing.Generator[(None, None, None)]c              
   c  s   ddl m}m} d}znzdV  d}W nZ |k
rR } zt
t|W 5 d}~X Y n. |k
r~ } ztt|W 5 d}~X Y nX W 5 |st| jjtr| jjjs| jj  | 	  n t| jjtr| jjjr| 	  X dS )z
        Catch Emscripten specific exceptions thrown by fetch.py,
        instead re-raising urllib3 variants, so that low-level exceptions
        are not leaked in the high-level api.

        On exit, release the connection back to the pool.
        r   )_RequestError_TimeoutErrorFNT)fetchrg   rh   rX   r)   r   r   rY   r\   ra   r
   strr   )r3   rg   rh   
clean_exiter   r   r   rZ      s*    	"
z,EmscriptenHttpResponseWrapper._error_catcher)NN)r=   N)NNF)NN)r   r   r   r.   propertyr   setterr    r<   rB   r/   r@   r_   ra   rb   rA   rf   r\   r   rZ   __classcell__r   r   r4   r   r      s@        '   /  	r   )!
__future__r   rf   rd   loggingr]   
contextlibr   Zdataclassesr   http.clientr   ior   r   
exceptionsr	   r
   responser   Z
util.retryr   r   r   TYPE_CHECKINGZ_base_connectionr   r   	getLoggerr   logr   r   r   r   r   r   <module>   s"   
