o
    vvXjÍH  ã                   @   s$  d Z ddlmZmZ ddlZ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 ddlmZ dd	lmZmZmZmZ dd
lmZmZ ejejejejhZdZeƒ ZdZ d !d¡Z"e #d¡Z$ddddddœZ%efdd„Z&G dd„ de'ƒZ(G dd„ de(ƒZ)G dd„ de(ƒZ*d dd„Z+dS )!zTransport implementation.é    )Úabsolute_importÚunicode_literalsN)ÚSSLError)Úcontextmanageré   )ÚUnexpectedFrame)Úitems)ÚKNOWN_TCP_OPTSÚSOL_TCPÚpackÚunpack)Ú	get_errnoÚset_cloexeci(  iÿÿÿzAMQP  	Úlatin_1z\[([\.0-9a-f:]+)\](?::(\d+))?iè  é<   é
   é	   )ÚTCP_NODELAYÚTCP_USER_TIMEOUTÚTCP_KEEPIDLEÚTCP_KEEPINTVLÚTCP_KEEPCNTc                 C   sd   |}t  | ¡}|r| d¡} | d¡rt| d¡ƒ}| |fS d| v r.|  dd¡\} }t|ƒ}| |fS )z1Convert hostname:port string to host, port tuple.r   é   ú:)ÚIPV6_LITERALÚmatchÚgroupÚintÚrsplit)ÚhostÚdefaultÚportÚm© r#   úK/var/www/html/myproject/venv/lib/python3.10/site-packages/amqp/transport.pyÚto_host_port*   s   


ýr%   c                   @   s’   e Zd ZdZ			d!dd„Zdd„ Zed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efdd„Zdd „ ZdS )#Ú_AbstractTransportz-Common superclass for TCP and SSL transports.NTc                 K   sD   d| _ d | _|| _t| _t|ƒ\| _| _|| _|| _	|| _
|| _d S ©NF)Ú	connectedÚsockÚraise_on_initial_eintrÚEMPTY_BUFFERÚ_read_bufferr%   r   r!   Úconnect_timeoutÚread_timeoutÚwrite_timeoutÚsocket_settings)Úselfr   r-   r.   r/   r0   r*   Úkwargsr#   r#   r$   Ú__init__<   s   
z_AbstractTransport.__init__c              
   C   st   z | j rW d S |  | j| j| j¡ |  | j| j| j¡ d| _ W d S  t	t
tfy9   | jr8| j s8| j ¡  d | _‚ w )NT)r(   Ú_connectr   r!   r-   Ú_init_socketr0   r.   r/   ÚOSErrorÚIOErrorr   r)   Úclose©r1   r#   r#   r$   ÚconnectI   s   ÿ
ûz_AbstractTransport.connectc              
   c   sê   � |d u r| j V  d S | j }| ¡ }||kr| |¡ zNz| j V  W n9 tyC } zdt|ƒv r4t ¡ ‚dt|ƒv r>t ¡ ‚‚ d }~w tjy[ } zt|ƒt	j
krVt ¡ ‚‚ d }~ww W ||krh| |¡ d S d S ||krt| |¡ w w )Nú	timed outzThe operation did not complete)r)   Ú
gettimeoutÚ
settimeoutr   ÚstrÚsocketÚtimeoutÚerrorr   ÚerrnoÚEWOULDBLOCK)r1   r@   r)   ÚprevÚexcr#   r#   r$   Úhaving_timeout]   s8   €
€€ý÷ÿÿz!_AbstractTransport.having_timeoutc                 C   sZ  d }t jt jf}t|ƒ}t|ƒD ]š\}}zt  |||t jt¡}	t|	ƒ}
W n t jy?   |d |kr=|d ur8|‚t  	d¡‚Y qw t|	ƒD ]e\}}|\}}}}}z+t   |||¡| _
zt| j
dƒ W n	 tyi   Y nw | j
 |¡ | j
 |¡ W   d S  t j	y© } z"|}| j
d ur’| j
 ¡  d | _
|d |
krŸ|d |krŸ‚ W Y d }~qDd }~ww qd S )Nr   z!failed to resolve broker hostnameT)r?   ÚAF_INETÚAF_INET6ÚlenÚ	enumerateÚgetaddrinfoÚSOCK_STREAMr
   ÚgaierrorrA   r)   r   ÚNotImplementedErrorr=   r:   r8   )r1   r   r!   r@   ÚeÚ
addr_typesÚaddr_types_numÚnÚfamilyÚentriesÚentries_numÚiÚresÚafÚsocktypeÚprotoÚ_ÚsaÚexr#   r#   r$   r4   x   sT   ÿÿÿþöÿö

€ùöíz_AbstractTransport._connectc              	   C   s˜   | j  d ¡ | j  tjtjd¡ |  |¡ tj|ftj|ffD ]!\}}|d ur@t	|ƒ}t	|| d ƒ}| j  tj|t
d||ƒ¡ q|  ¡  |  t¡ d S )Nr   i@B Úll)r)   r=   Ú
setsockoptr?   Ú
SOL_SOCKETÚSO_KEEPALIVEÚ_set_socket_optionsÚSO_SNDTIMEOÚSO_RCVTIMEOr   r   Ú_setup_transportÚ_writeÚAMQP_PROTOCOL_HEADER)r1   r0   r.   r/   r@   ÚintervalÚsecÚusecr#   r#   r$   r5   ¯   s    
ÿ
þ€z_AbstractTransport._init_socketc              	   C   s”   i }t D ]C}d }|dkr zddlm} W n ty   d}Y nw tt|ƒr*tt|ƒ}|rG|tv r7t| ||< qtt|ƒrG| ttt|ƒ¡||< q|S )Nr   r   )r   é   )	r	   r?   r   ÚImportErrorÚhasattrÚgetattrÚDEFAULT_SOCKET_SETTINGSÚ
getsockoptr
   )r1   r)   Útcp_optsÚoptÚenumr#   r#   r$   Ú_get_tcp_socket_defaultsÂ   s(   þ



ÿ€z+_AbstractTransport._get_tcp_socket_defaultsc                 C   s@   |   | j¡}|r| |¡ t|ƒD ]\}}| j t||¡ qd S ©N)rt   r)   Úupdater   r_   r
   )r1   r0   rq   rr   Úvalr#   r#   r$   rb   ×   s   
ÿz&_AbstractTransport._set_socket_optionsFc                 C   ó   t dƒ‚)z#Read exactly n bytes from the peer.úMust be overriden in subclass©rN   )r1   rR   Úinitialr#   r#   r$   Ú_readÞ   ó   z_AbstractTransport._readc                 C   ó   dS )z.Do any additional initialization of the class.Nr#   r9   r#   r#   r$   re   â   ó   z#_AbstractTransport._setup_transportc                 C   r~   )z8Do any preliminary work in shutting down the connection.Nr#   r9   r#   r#   r$   Ú_shutdown_transportæ   r   z&_AbstractTransport._shutdown_transportc                 C   rx   )z&Completely write a string to the peer.ry   rz   )r1   Úsr#   r#   r$   rf   ê   r}   z_AbstractTransport._writec                 C   s:   | j d ur|  ¡  | j  tj¡ | j  ¡  d | _ d| _d S r'   )r)   r€   Úshutdownr?   Ú	SHUT_RDWRr8   r(   r9   r#   r#   r$   r8   î   s   


z_AbstractTransport.closec                 C   sv  | j }t}zK|ddƒ}||7 }|d|ƒ\}}}|tkrA|tƒ}z||t ƒ}	W n tjtjtfy8   ||7 }‚ w d ||	g¡}
n||ƒ}
||
7 }t|dƒƒ}W nZ tjy_   || j	 | _	‚  t
tttjfyª } z;t|tjƒr‡tjdkr‡t|ƒtjkr‡|| j	 | _	t ¡ ‚t|tƒrœdt|ƒv rœ|| j	 | _	t ¡ ‚t|ƒtvr¥d| _‚ d }~ww |d	kr´|||
fS td
 |¡ƒ‚)Né   Tz>BHIó    r   Úntr;   FéÎ   z&Received {0:#04x} while expecting 0xce)r|   r+   ÚSIGNED_INT_MAXr?   r@   rA   r   ÚjoinÚordr,   r6   r7   Ú
isinstanceÚosÚnamer   rB   rC   r>   Ú_UNAVAILr(   r   Úformat)r1   r   ÚreadÚread_frame_bufferÚframe_headerÚ
frame_typeÚchannelÚsizeÚpart1Úpart2ÚpayloadÚchrE   r#   r#   r$   Ú
read_frameù   sR   
ü
ÿ
€í
ÿz_AbstractTransport.read_framec              
   C   sV   z|   |¡ W d S  tjy   ‚  tttjfy* } z
t|ƒtvr%d| _‚ d }~ww r'   )	rf   r?   r@   r6   r7   rA   r   rŽ   r(   )r1   r�   rE   r#   r#   r$   Úwrite/  s   €ýz_AbstractTransport.write)NNNNT)F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r3   r:   r   rF   r4   r5   rt   rb   r|   re   r€   rf   r8   r   rš   r›   r#   r#   r#   r$   r&   9   s(    
þ
7
6r&   c                
       sˆ   e Zd ZdZd‡ fdd„	Zdd„ Zddd„Zdd	d
„Zdddej	ddddddf
dd„Z
dd„ Zdejejejffdd„Zdd„ Z‡  ZS )ÚSSLTransportzTransport that works over SSL.Nc                    s:   t |tƒr|ni | _t| _tt| ƒj|fd|i|¤Ž d S )Nr-   )r‹   ÚdictÚssloptsr+   r,   Úsuperr    r3   )r1   r   r-   Ússlr2   ©Ú	__class__r#   r$   r3   =  s   
ÿÿ
ÿzSSLTransport.__init__c                 C   s0   | j | jfi | j¤Ž| _| j ¡  | jj| _dS )z!Wrap the socket in an SSL object.N)Ú_wrap_socketr)   r¢   Údo_handshaker�   Ú_quick_recvr9   r#   r#   r$   re   C  s   
zSSLTransport._setup_transportc                 K   s*   |r| j ||fi |¤ŽS | j|fi |¤ŽS ru   )Ú_wrap_contextÚ_wrap_socket_sni)r1   r)   Úcontextr¢   r#   r#   r$   r§   I  s   zSSLTransport._wrap_socketc                 K   s(   t jdi |¤Ž}||_|j|fi |¤ŽS )Nr#   )r¤   Úcreate_default_contextÚcheck_hostnameÚwrap_socket)r1   r)   r¢   r®   Úctx_optionsÚctxr#   r#   r$   rª   N  s   zSSLTransport._wrap_contextFTc                 C   s¾   |du rt tdƒrtj}ntj}|||||||||
|dœ
}tjd	i |¤Ž}|	dur]t tdƒr]tjr]t tdƒr]t |d ¡}||_|tjkrHd|_	|durV|durV| 
||¡ |j||	d�}|S )
z¶Socket wrap with SNI headers.

        Default `ssl.wrap_socket` method augmented with support for
        setting the server_hostname field required for SNI hostname header
        NÚPROTOCOL_TLS)
r)   ÚkeyfileÚcertfileÚserver_sideÚ	cert_reqsÚca_certsÚdo_handshake_on_connectÚsuppress_ragged_eofsÚciphersÚssl_versionÚHAS_SNIÚ
SSLContextr»   T)Úserver_hostnamer#   )rm   r¤   r²   ÚPROTOCOL_SSLv23r¯   r¼   r½   Úverify_modeÚ	CERT_NONEr®   Úload_cert_chain)r1   r)   r³   r´   rµ   r¶   r·   r¸   r¹   r¾   rº   r»   Úoptsr¬   r#   r#   r$   r«   S  s>   
öÿÿþ
zSSLTransport._wrap_socket_snic                 C   s   | j dur| j  ¡ | _ dS dS )z/Unwrap a SSL socket, so we can call shutdown().N)r)   Úunwrapr9   r#   r#   r$   r€   „  s   
ÿz SSLTransport._shutdown_transportc           	   
   C   sä   | j }| j}zTt|ƒ|k rYz
||t|ƒ ƒ}W n1 tjyH } z$t|tƒr/dt|ƒv r/t ¡ ‚|j	|v rC|r=| j
r=t ¡ ‚W Y d }~q‚ d }~ww |sOtdƒ‚||7 }t|ƒ|k sW n   || _‚ |d |… ||d … }| _|S )Nr;   ú%Server unexpectedly closed connection)r©   r,   rI   r?   rA   r‹   r   r>   r@   rB   r*   r7   ©	r1   rR   r{   Ú_errnosÚrecvÚrbufr�   rE   Úresultr#   r#   r$   r|   ‰  s4   

€õï€zSSLTransport._readc                 C   sT   | j j}|r(z||ƒ}W n ty   d}Y nw |stdƒ‚||d… }|sdS dS )z+Write a string out to the SSL socket fully.r   zSocket closedN)r)   r›   Ú
ValueErrorr7   )r1   r�   r›   rR   r#   r#   r$   rf   ©  s   ûõzSSLTransport._write)NNru   )rœ   r�   rž   rŸ   r3   re   r§   rª   r¤   rÁ   r«   r€   rB   ÚENOENTÚEAGAINÚEINTRr|   rf   Ú__classcell__r#   r#   r¥   r$   r    :  s"    


ü1
ÿ r    c                   @   s.   e Zd ZdZdd„ Zdejejffdd„ZdS )ÚTCPTransportz.Transport that deals directly with TCP socket.c                 C   s   | j j| _t| _| j j| _d S ru   )r)   Úsendallrf   r+   r,   rÈ   r©   r9   r#   r#   r$   re   ½  s   
zTCPTransport._setup_transportFc           	   
   C   sÆ   | j }| j}zEt|ƒ|k rJz
||t|ƒ ƒ}W n" tjy9 } z|j|v r4|r.| jr.t ¡ ‚W Y d}~q‚ d}~ww |s@tdƒ‚||7 }t|ƒ|k sW n   || _‚ |d|… ||d… }| _|S )z%Read exactly n bytes from the socket.NrÅ   )	r©   r,   rI   r?   rA   rB   r*   r@   r7   rÆ   r#   r#   r$   r|   Ä  s0   

€ûõ€zTCPTransport._readN)	rœ   r�   rž   rŸ   re   rB   rÍ   rÎ   r|   r#   r#   r#   r$   rÐ   º  s    rÐ   Fc                 K   s"   |rt nt}|| f||dœ|¤ŽS )z‹Create transport.

    Given a few parameters from the Connection constructor,
    select and create a subclass of _AbstractTransport.
    )r-   r¤   )r    rÐ   )r   r-   r¤   r2   Ú	transportr#   r#   r$   Ú	TransportÝ  s   rÓ   r'   ),rŸ   Ú
__future__r   r   rŒ   rB   Úrer?   r¤   r   Ú
contextlibr   Ú
exceptionsr   Úfiver   Úplatformr	   r
   r   r   Úutilsr   r   rÍ   rÎ   rÌ   rC   rŽ   Ú	AMQP_PORTÚbytesr+   rˆ   Úencoderg   Úcompiler   ro   r%   Úobjectr&   r    rÐ   rÓ   r#   r#   r#   r$   Ú<module>   sB    

û	   #