U
    ³.¬b;  ã                   @   s¢   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 d dlmZmZmZ d dlmZ d d	l
mZ d d
lmZ e  e¡ZG dd„ deƒZdd„ ZdS )é    N)ÚIOBase)ÚProtocolError)ÚReadTimeoutError)Úparsers)Úset_socket_timeout)ÚIncompleteReadErrorr   ÚResponseStreamingError)ÚScalarTypes)ÚXMLParseError)Úfirst_non_none_responsec                   @   sœ   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Zd#dd„Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ ZeZedfdd„Zefdd„Zdd„ Zdd „ Zd!d"„ ZdS )$ÚStreamingBodyae  Wrapper class for an http response body.

    This provides a few additional conveniences that do not exist
    in the urllib3 model:

        * Set the timeout on the socket (i.e read() timeouts)
        * Auto validation of content length, if the amount of bytes
          we read does not match the content length, an exception
          is raised.

    i   c                 C   s   || _ || _d| _d S )Nr   )Ú_raw_streamÚ_content_lengthÚ_amount_read)ÚselfZ
raw_streamÚcontent_length© r   ú5/tmp/pip-unpacked-wheel-7df6wvge/botocore/response.pyÚ__init__5   s    zStreamingBody.__init__c                 C   s   d S ©Nr   ©r   r   r   r   Ú__del__:   s    zStreamingBody.__del__c                 C   s:   zt | j|ƒ W n$ tk
r4   tjddd� ‚ Y nX dS )z&Set the timeout seconds on the socket.zbCannot access the socket object of a streaming response.  It's possible the interface has changed.T)Úexc_infoN)r   r   ÚAttributeErrorÚloggerÚerror)r   Útimeoutr   r   r   r   @   s    üz StreamingBody.set_socket_timeoutc                 C   s(   z| j  ¡ W S  tk
r"   Y dS X d S )NF)r   Úreadabler   r   r   r   r   r   W   s    zStreamingBody.readableNc              
   C   sž   z| j  |¡}W nZ tk
r@ } zt|j|d�‚W 5 d}~X Y n, tk
rj } zt|d�‚W 5 d}~X Y nX |  jt|ƒ7  _|dks’|sš|dkrš|  	¡  |S )zhRead at most amt bytes from the stream.

        If the amt argument is omitted, read all data.
        )Zendpoint_urlr   N)r   r   )
r   ÚreadÚURLLib3ReadTimeoutErrorr   ÚurlÚURLLib3ProtocolErrorr   r   ÚlenÚ_verify_content_length)r   ÚamtÚchunkÚer   r   r   r   ]   s    zStreamingBody.readc                 C   s
   | j  ¡ S r   )r   Ú	readlinesr   r   r   r   r'   q   s    zStreamingBody.readlinesc                 C   s   |   | j¡S )z:Return an iterator to yield 1k chunks from the raw stream.)Úiter_chunksÚ_DEFAULT_CHUNK_SIZEr   r   r   r   Ú__iter__t   s    zStreamingBody.__iter__c                 C   s   |   | j¡}|r|S tƒ ‚dS )z-Return the next 1k chunk from the raw stream.N)r   r)   ÚStopIteration)r   Úcurrent_chunkr   r   r   Ú__next__x   s    zStreamingBody.__next__c                 C   s   | j S r   )r   r   r   r   r   Ú	__enter__   s    zStreamingBody.__enter__c                 C   s   | j  ¡  d S r   ©r   Úclose)r   ÚtypeÚvalueÚ	tracebackr   r   r   Ú__exit__‚   s    zStreamingBody.__exit__Fc                 c   sd   d}|   |¡D ]<}||  d¡}|dd… D ]}| |¡d V  q,|d }q|r`| |¡d V  dS )zÓReturn an iterator to yield lines from the raw stream.

        This is achieved by reading chunk of bytes (of size chunk_size) at a
        time from the raw stream, and then yielding lines from there.
        ó    TNéÿÿÿÿr   )r(   Ú
splitlines)r   Ú
chunk_sizeÚkeependsÚpendingr%   ÚlinesÚliner   r   r   Ú
iter_lines‡   s    
zStreamingBody.iter_linesc                 c   s    |   |¡}|dkrq|V  q dS )z\Return an iterator to yield chunks of chunk_size bytes from the raw
        stream.
        r5   N)r   )r   r8   r,   r   r   r   r(   –   s    
zStreamingBody.iter_chunksc                 C   s2   | j d k	r.| jt| j ƒkr.t| jt| j ƒd�‚d S )N)Zactual_bytesZexpected_bytes)r   r   Úintr   r   r   r   r   r#       s    ÿþz$StreamingBody._verify_content_lengthc                 C   s
   | j  ¡ S r   )r   Útellr   r   r   r   r?   ¬   s    zStreamingBody.tellc                 C   s   | j  ¡  dS )z*Close the underlying http response stream.Nr/   r   r   r   r   r0   ¯   s    zStreamingBody.close)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r)   r   r   r   r   r   r'   r*   r-   r.   r4   Únextr=   r(   r#   r?   r0   r   r   r   r   r   &   s$   

r   c                 C   sx   | j d }|j|jdœ}|d dkr0|j|d< n,| jrRt|j|d  d¡ƒ|d< n
|j|d< t 	|¡}|| 
|| j¡fS )NÚprotocol)ÚheadersÚstatus_coderG   i,  ÚbodyrF   zcontent-length)ÚmetadatarF   rG   ÚcontentZhas_streaming_outputr   ÚrawÚgetr   Úcreate_parserÚparseZoutput_shape)Zoperation_modelÚhttp_responserE   Zresponse_dictÚparserr   r   r   Úget_response´   s"    
þ ÿ


 ÿrQ   )ÚloggingÚior   Zurllib3.exceptionsr   r!   r   r   Zbotocorer   Zbotocore.compatr   Zbotocore.exceptionsr   r   r	   r
   Zbotocore.hooksr   Ú	getLoggerr@   r   r   rQ   r   r   r   r   Ú<module>   s   
 