U
    ³.¬bü;  ã                   @   s–  d Z ddlZddlZddl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 ddlmZmZ e
r‚dd	lmZ ndZe e¡ZG d
d„ dƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ dƒZG dd„ deƒZ dd„ Z!d2dd„Z"dd„ Z#d d!„ Z$d"d#„ Z%d3d$d%„Z&d&d'„ Z'd(d)„ Z(d*d+„ Z)eeed,œZ*e
�rze* +eed-œ¡ e,e* -¡ ƒZ.d.d/d0d1gZ/dS )4aC   The interfaces in this module are not intended for public use.

This module defines interfaces for applying checksums to HTTP requests within
the context of botocore. This involves both resolving the checksum to be used
based on client configuration and environment, as well as application of the
checksum to the request.
é    N)Úcrc32)Úsha1Úsha256)ÚHAS_CRT)ÚAwsChunkedWrapperErrorÚFlexibleChecksumError)ÚStreamingBody)Úconditionally_calculate_md5Údetermine_content_length)Ú	checksumsc                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚBaseChecksumé   c                 C   s   d S ©N© ©ÚselfÚchunkr   r   ú9/tmp/pip-unpacked-wheel-7df6wvge/botocore/httpchecksum.pyÚupdate.   s    zBaseChecksum.updatec                 C   s   d S r   r   ©r   r   r   r   Údigest1   s    zBaseChecksum.digestc                 C   s   |   ¡ }t |¡ d¡S )NÚascii)r   Úbase64Ú	b64encodeÚdecode)r   Úbsr   r   r   Ú	b64digest4   s    zBaseChecksum.b64digestc                    s:   ˆ   ¡ }t‡ ‡fdd„dƒD ]}ˆ |¡ qˆ  |¡ d S )Nc                      s   ˆ   ˆj¡S r   )ÚreadÚ_CHUNK_SIZEr   ©Úfileobjr   r   r   Ú<lambda>:   ó    z.BaseChecksum._handle_fileobj.<locals>.<lambda>r"   )ÚtellÚiterr   Úseek)r   r    Zstart_positionr   r   r   r   Ú_handle_fileobj8   s    zBaseChecksum._handle_fileobjc                 C   s,   t |ttfƒr|  |¡ n
|  |¡ |  ¡ S r   )Ú
isinstanceÚbytesÚ	bytearrayr   r&   r   )r   Úbodyr   r   r   Úhandle>   s    
zBaseChecksum.handleN)	Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r&   r+   r   r   r   r   r   +   s   r   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚCrc32Checksumc                 C   s
   d| _ d S ©Nr   ©Ú
_int_crc32r   r   r   r   Ú__init__G   s    zCrc32Checksum.__init__c                 C   s   t || jƒd@ | _d S ©Nl   ÿÿ )r   r2   r   r   r   r   r   J   s    zCrc32Checksum.updatec                 C   s   | j jddd�S ©Né   Úbig)Ú	byteorder©r2   Úto_bytesr   r   r   r   r   M   s    zCrc32Checksum.digestN©r,   r-   r.   r3   r   r   r   r   r   r   r/   F   s   r/   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚCrtCrc32Checksumc                 C   s
   d| _ d S r0   r1   r   r   r   r   r3   S   s    zCrtCrc32Checksum.__init__c                 C   s   t  || j¡}|d@ | _d S r4   )Úcrt_checksumsr   r2   ©r   r   Znew_checksumr   r   r   r   V   s    zCrtCrc32Checksum.updatec                 C   s   | j jddd�S r5   r9   r   r   r   r   r   Z   s    zCrtCrc32Checksum.digestNr;   r   r   r   r   r<   Q   s   r<   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚCrtCrc32cChecksumc                 C   s
   d| _ d S r0   )Ú_int_crc32cr   r   r   r   r3   `   s    zCrtCrc32cChecksum.__init__c                 C   s   t  || j¡}|d@ | _d S r4   )r=   Úcrc32cr@   r>   r   r   r   r   c   s    zCrtCrc32cChecksum.updatec                 C   s   | j jddd�S r5   )r@   r:   r   r   r   r   r   g   s    zCrtCrc32cChecksum.digestNr;   r   r   r   r   r?   ^   s   r?   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚSha1Checksumc                 C   s   t ƒ | _d S r   )r   Ú	_checksumr   r   r   r   r3   l   s    zSha1Checksum.__init__c                 C   s   | j  |¡ d S r   ©rC   r   r   r   r   r   r   o   s    zSha1Checksum.updatec                 C   s
   | j  ¡ S r   ©rC   r   r   r   r   r   r   r   s    zSha1Checksum.digestNr;   r   r   r   r   rB   k   s   rB   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚSha256Checksumc                 C   s   t ƒ | _d S r   )r   rC   r   r   r   r   r3   w   s    zSha256Checksum.__init__c                 C   s   | j  |¡ d S r   rD   r   r   r   r   r   z   s    zSha256Checksum.updatec                 C   s
   | j  ¡ S r   rE   r   r   r   r   r   }   s    zSha256Checksum.digestNr;   r   r   r   r   rF   v   s   rF   c                   @   sF   e Zd ZdZddd„Zdd„ Zdd	d
„Zddd„Zdd„ Zdd„ Z	dS )ÚAwsChunkedWrapperr   Núx-amz-checksumc                 C   s2   || _ || _|| _|  ¡  |d kr(| j}|| _d S r   )Ú_rawÚ_checksum_nameÚ_checksum_clsÚ_resetÚ_DEFAULT_CHUNK_SIZEÚ_chunk_size)r   ÚrawÚchecksum_clsÚchecksum_nameÚ
chunk_sizer   r   r   r3   „   s    zAwsChunkedWrapper.__init__c                 C   s&   d| _ d| _d | _| jr"|  ¡ | _d S )Nr"   F)Ú
_remainingÚ	_completerC   rK   r   r   r   r   rL   ”   s
    zAwsChunkedWrapper._resetr   c                 C   s2   |dks|dkrt dd�‚|  ¡  | j d¡ d S )Nr   z Can only seek to start of stream©Ú	error_msg)r   rL   rI   r%   )r   ÚoffsetÚwhencer   r   r   r%   ›   s    ÿzAwsChunkedWrapper.seekc                 C   s¢   |d k	r|dkrd }| j r$| js$dS |d kp8|t| jƒk}| j sn|rn|  j|  ¡ 7  _|d kpj|t| jƒk}q:|d kr€t| jƒ}| jd |… }| j|d … | _|S )Nr   r"   )rT   rS   ÚlenÚ_make_chunk)r   ÚsizeZwant_more_bytesZ	to_returnr   r   r   r   £   s    

zAwsChunkedWrapper.readc                 C   s‚   | j  | j¡}tt|ƒƒdd …  d¡}| | _| jrB| j |¡ | jrv| jrv| j	 d¡}| j 
¡  d¡}d||f S d||f S )Né   r   s   0
%s:%s

s   %s
%s
)rI   r   rN   ÚhexrY   ÚencoderT   rC   r   rJ   r   )r   Z	raw_chunkZhex_lenÚnameÚchecksumr   r   r   rZ   ¼   s    zAwsChunkedWrapper._make_chunkc                 c   s   | j s|  ¡ V  q d S r   )rT   rZ   r   r   r   r   Ú__iter__Î   s    zAwsChunkedWrapper.__iter__)NrH   N)r   )N)
r,   r-   r.   rM   r3   rL   r%   r   rZ   ra   r   r   r   r   rG   �   s      û


rG   c                       s2   e Zd Z‡ fdd„Zd‡ fdd„	Zdd„ Z‡  ZS )	ÚStreamingChecksumBodyc                    s   t ƒ  ||¡ || _|| _d S r   )Úsuperr3   rC   Ú	_expected)r   Z
raw_streamÚcontent_lengthr`   Úexpected©Ú	__class__r   r   r3   Ô   s    zStreamingChecksumBody.__init__Nc                    s:   t ƒ j|d�}| j |¡ |d ks.|s6|dkr6|  ¡  |S )N)Úamtr   )rc   r   rC   r   Ú_validate_checksum)r   ri   r   rg   r   r   r   Ù   s
    zStreamingChecksumBody.readc                 C   s<   | j  ¡ t | j¡kr8d| j› d| j  ¡ › �}t|d�‚d S )NzExpected checksum z$ did not match calculated checksum: rU   )rC   r   r   Ú	b64decoderd   r   r   )r   rV   r   r   r   rj   à   s    ÿz(StreamingChecksumBody._validate_checksum)N)r,   r-   r.   r3   r   rj   Ú__classcell__r   r   rg   r   rb   Ó   s   rb   c                 C   s   t | ||ƒ t| ||ƒ d S r   )Ú"resolve_request_checksum_algorithmÚ$resolve_response_checksum_algorithms)ÚrequestÚoperation_modelÚparamsr   r   r   Úresolve_checksum_contexté   s    rr   c           
      C   sè   |j }| d¡}|r°||kr°|d kr(t}||  ¡ }||krJtd| d�‚d}|jrf| d  d¡rfd}||d| d	œ}|d
 | d krŠd S | d  di ¡}	||	d< |	| d d< n4|jsÀ| d¡rä| d  di ¡}	d|	d< |	| d d< d S )NZrequestAlgorithmMemberz"Unsupported checksum algorithm: %srU   ÚheaderÚurlzhttps:Útrailerúx-amz-checksum-%s)Ú	algorithmÚinr_   r_   ÚheadersÚcontextr`   Úrequest_algorithmZrequestChecksumRequiredúconditional-md5)Úhttp_checksumÚgetÚ_SUPPORTED_CHECKSUM_ALGORITHMSÚlowerr   Zhas_streaming_inputÚ
startswithZhttp_checksum_required)
ro   rp   rq   Úsupported_algorithmsr}   Zalgorithm_memberZalgorithm_nameZlocation_typerw   Úchecksum_contextr   r   r   rm   î   s:    
ÿý
ÿrm   c                 C   sz   |   di ¡  di ¡}|  d¡}|s&d S |dkr8t| ƒ n>|d dkrNt| ƒ n(|d dkrdt| ƒ ntd|d  d	�‚d S )
Nrz   r`   r{   r|   rx   rs   ru   zUnknown checksum variant: %srU   )r~   r	   Ú_apply_request_header_checksumÚ_apply_request_trailer_checksumr   )ro   rƒ   rw   r   r   r   Úapply_request_checksum   s    




ÿr†   c                 C   sd   |   di ¡  di ¡}|  d¡}|d }|| d kr6d S t  |d ¡}|ƒ  | d ¡}|| d |< d S )Nrz   r`   r{   r_   ry   rw   r*   )r~   Ú_CHECKSUM_CLSr+   )ro   rƒ   rw   Úlocation_namerP   r   r   r   r   r„   4  s    
r„   c                 C   s²   |   di ¡  di ¡}|  d¡}|d }t  |d ¡}| d }| d }||krPd S d|d	< d
|d< ||d< t|ƒ}|d k	r„t|ƒ|d< t|ttfƒrœt |¡}t	|||d�| d< d S )Nrz   r`   r{   r_   rw   ry   r*   ÚchunkedzTransfer-Encodingzaws-chunkedzContent-EncodingzX-Amz-TrailerzX-Amz-Decoded-Content-Length)rP   rQ   )
r~   r‡   r
   Ústrr'   r(   r)   ÚioÚBytesIOrG   )ro   rƒ   rw   rˆ   rP   ry   r*   re   r   r   r   r…   @  s*    

ýr…   c           
      C   s�   |j }| d¡}|rŒ||krŒ|d kr(t}dd„ | dg ¡D ƒ}g }tD ] }||krTqF||krF| |¡ qF| d  di ¡}	||	d< |	| d d< d S )NZrequestValidationModeMemberc                 S   s   h | ]}|  ¡ ’qS r   )r€   )Ú.0Úar   r   r   Ú	<setcomp>i  s    z7resolve_response_checksum_algorithms.<locals>.<setcomp>ZresponseAlgorithmsrz   r`   Úresponse_algorithms)r}   r~   r   Ú_ALGORITHMS_PRIORITY_LISTÚappend)
ro   rp   rq   r‚   r}   Zmode_memberr�   Zusable_algorithmsrw   rƒ   r   r   r   rn   a  s"    

ÿrn   c           	      C   s¶   |d }|  di ¡}|  d¡}|s&d S |D ]t}d| }||kr@q*d|| krNq*|jrft| ||ƒ|d< nt| ||ƒ|d< |d   di ¡}||d< ||d d<  d S t d	|› d
�¡ d S )Nry   r`   r�   rv   ú-r*   rz   Zresponse_algorithmzXSkipping checksum validation. Response did not contain one of the following algorithms: Ú.)r~   Zhas_streaming_outputÚ_handle_streaming_responseÚ_handle_bytes_responseÚloggerÚinfo)	Úhttp_responseÚresponserz   rp   ry   rƒ   Z
algorithmsrw   Úheader_namer   r   r   Úhandle_checksum_bodyy  s:    
  ÿ
  ÿ
ÿrœ   c                 C   s6   t  |¡}d| }t| j|d  d¡|ƒ |d | ƒS )Nrv   ry   zcontent-length)r‡   r~   rb   rO   )r™   rš   rw   rP   r›   r   r   r   r•   ¢  s    

ür•   c           	      C   sd   | j }d| }t |¡}|ƒ }| |¡ |d | }| ¡ t |¡kr`d|| ¡ f }t|d�‚|S )Nrv   ry   z:Expected checksum %s did not match calculated checksum: %srU   )	Úcontentr‡   r~   r   r   r   rk   r   r   )	r™   rš   rw   r*   r›   rP   r`   rf   rV   r   r   r   r–   ­  s    

þÿÿ
r–   )r   r   r   )r   rA   rA   r   r   r   )N)N)0Ú__doc__r   r‹   ÚloggingÚbinasciir   Úhashlibr   r   Zbotocore.compatr   Zbotocore.exceptionsr   r   Zbotocore.responser   Zbotocore.utilsr	   r
   Zawscrtr   r=   Ú	getLoggerr,   r—   r   r/   r<   r?   rB   rF   rG   rb   rr   rm   r†   r„   r…   rn   rœ   r•   r–   r‡   r   ÚlistÚkeysr   r‘   r   r   r   r   Ú<module>   sT   
R	 ü
2" ÿ
)ýÿ