
    YfY                     j   d 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
mZ ddlmZ ddlmZmZ dd	lmZ ej        ej        ej        ej        hZd
Z e            ZdZdZ ej        d          ZddddddZefdZ  G d d          Z! G d de!          Z" G d de!          Z#ddZ$dS )zTransport implementation.    N)contextmanager)SSLError)packunpack   )UnexpectedFrame)KNOWN_TCP_OPTSSOL_TCP)set_cloexeci(  is   AMQP  	z\[([\.0-9a-f:]+)\](?::(\d+))?i  <   
   	   )TCP_NODELAYTCP_USER_TIMEOUTTCP_KEEPIDLETCP_KEEPINTVLTCP_KEEPCNTc                 8   |}t                               |           }|rM|                    d          } |                    d          r"t          |                    d                    }n,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ms       @/var/www/html/env/lib/python3.11/site-packages/amqp/transport.pyto_host_portr!   (   s    D4  A wwqzz771:: 	#qwwqzz??D$;;S!,,JD$t99D:    c                       e Zd ZdZ	 	 	 ddZdZd Zd Zed             Z	d	 Z
d
 Zd Zd ZddZd Zd Zd Zd ZefdZd ZdS )_AbstractTransporta  Common superclass for TCP and SSL transports.

    PARAMETERS:
        host: str

            Broker address in format ``HOSTNAME:PORT``.

        connect_timeout: int

            Timeout of creating new connection.

        read_timeout: int

            sets ``SO_RCVTIMEO`` parameter of socket.

        write_timeout: int

            sets ``SO_SNDTIMEO`` parameter of socket.

        socket_settings: dict

            dictionary containing `optname` and ``optval`` passed to
            ``setsockopt(2)``.

        raise_on_initial_eintr: bool

            when True, ``socket.timeout`` is raised
            when exception is received during first read. See ``_read()`` for
            details.
    NTc                     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.   r/   r)   kwargss           r    __init__z_AbstractTransport.__init__W   s^     	&<#(+D11	49.(*.r"   )
connectionr(   r)   r+   r   r   r,   r-   r.   r/   __dict____weakref__c           
         | j         r| j                                         d          d| j                                         d          }| j                                         d          d| j                                         d          }dt          |           j         d| d| dt          |           dd		S dt          |           j         d
t          |           dd	S )Nr   r   r   <z: z -> z at z#x>z: (disconnected) at )r(   getsocknamegetpeernametype__name__id)r0   srcdsts      r    __repr__z_AbstractTransport.__repr__t   s    9 	OY**,,Q/NN$)2G2G2I2I!2LNNCY**,,Q/NN$)2G2G2I2I!2LNNCNtDzz*NNcNNsNN4NNNNNNtDzz*NN4NNNNNr"   c                 H   	 | j         rd S |                     | j        | j        | j                   |                     | j        | j        | j                   d| _         d S # t          t          f$ r0 | j        r'| j         s | j                                         d | _         w xY w)NT)r'   _connectr   r   r,   _init_socketr/   r-   r.   OSErrorr   r(   closer0   s    r    connectz_AbstractTransport.connect|   s    	~ MM$)TY0DEEE$d&79K   "DNNN" 	 	 	y ! !	!!! 		s   A  AA   AB!c              #   F  K   || j         V  d S | j         }|                                }||k    r|                    |           	 | j         V  n# t          $ rN}dt	          |          v rt          j                    dt	          |          v rt          j                     d }~wt          $ r.}|j        t          j	        k    rt          j                     d }~ww xY w	 ||k    r|                    |           d S d S # ||k    r|                    |           w w xY w)N	timed outzThe operation did not complete)
r(   
gettimeout
settimeoutr   strsockettimeoutrD   errnoEWOULDBLOCK)r0   rN   r(   prevexcs        r    having_timeoutz!_AbstractTransport.having_timeout   sI     ?)OOOOO9D??$$Dw(((*i   #c((** .***5SAA .***   9 111 .***   d??OOD))))) #?7d??OOD)))) #s7   	A D 
CA	B$$C1)CCD D c                 :   t          j        ||t           j        t           j        t                    }t          |          D ]\  }}|\  }}}	}
}	 t          j         |||	          | _        	 t          | j        d           n# t          $ r Y nw xY w| j        	                    |           | j        
                    |            d S # t           j        $ rA | j        r| j                                         d | _        |dz   t          |          k    r Y w xY wd S )NTr   )rM   getaddrinfo	AF_UNSPECSOCK_STREAMr
   	enumerater(   r   NotImplementedErrorrK   rG   errorrE   len)r0   r   r   rN   entriesiresafsocktypeproto	canonnamesas               r    rB   z_AbstractTransport._connect   sG   $$(&*<g
 
  (( 	 	FAs14.B%B"M"h>>		40000*   D	$$W---	!!"%%%  <   9 &IOO%%% 	q5CLL(( )(		 	s7   C+B C
BCB7CADDc           
         | j                             d            | j                             t          j        t          j        d           |                     |           t          j        |ft          j        |ffD ]`\  }}|Yt          |          }t          ||z
  dz            }| j                             t          j        |t          d||                     a|                                  |                     t                     d S )Nr   i@B ll)r(   rK   
setsockoptrM   
SOL_SOCKETSO_KEEPALIVE_set_socket_optionsSO_SNDTIMEOSO_RCVTIMEOr   r   _setup_transport_writeAMQP_PROTOCOL_HEADER)r0   r/   r-   r.   rN   intervalsecusecs           r    rC   z_AbstractTransport._init_socket   s   	T"""	V.0CQGGG  111 $*#5}"E#)#5|"D"F 	 	GX#(mmHsNg566	$$%wsD))   	()))))r"   c                 z   i }t           D ]}d }|dk    r	 ddlm} n<# t          $ r d}Y n.w xY wt	          t          |          rt          t          |          }|r`|t          v rt          |         ||<   jt	          t          |          r1|                    t          t          t          |                    ||<   |S )Nr   r   )r      )	r	   rM   r   ImportErrorhasattrgetattrDEFAULT_SOCKET_SETTINGS
getsockoptr
   )r0   r(   tcp_optsoptenums        r    _get_tcp_socket_defaultsz+_AbstractTransport._get_tcp_socket_defaults   s    ! 	7 	7CD(((???????"   DDD %% ,vs++ 7111%<S%AHTNNVS)) 7%)__!5!5&7 &7HTNs   ++c                     |                      | j                  }|r|                    |           |                                D ]&\  }}| j                            t
          ||           'd S N)r|   r(   updateitemsrf   r
   )r0   r/   ry   rz   vals        r    ri   z&_AbstractTransport._set_socket_options   su    00;; 	-OOO,,, (( 	4 	4HCI  #s3333	4 	4r"   Fc                      t          d          )z#Read exactly n bytes from the peer.Must be overridden in subclassrY   )r0   ninitials      r    _readz_AbstractTransport._read       !"BCCCr"   c                     dS )z.Do any additional initialization of the class.N rF   s    r    rl   z#_AbstractTransport._setup_transport       r"   c                     dS )z8Do any preliminary work in shutting down the connection.Nr   rF   s    r    _shutdown_transportz&_AbstractTransport._shutdown_transport   r   r"   c                      t          d          )z&Completely write a string to the peer.r   r   )r0   ss     r    rm   z_AbstractTransport._write   r   r"   c                 >   | j         	 |                                  n# t          $ r Y nw xY w	 | j                             t          j                   n# t          $ r Y nw xY w	 | j                                          n# t          $ r Y nw xY wd | _         d| _        d S r&   )r(   r   rD   shutdownrM   	SHUT_RDWRrE   r'   rF   s    r    rE   z_AbstractTransport.close  s    9 ((****   	""6#34444   	!!!!   DIs/    
++$A 
A! A!%A? ?
BBc                    | j         }t          }	  |dd          }||z  } |d|          \  }}}|t          k    rc |t                    }	  ||t          z
            }	n&# t          j        t
          t          f$ r ||z  } w xY wd                    ||	g          }
n ||          }
||
z  }t           |d                    }n# t          j        $ r || j	        z   | _	         t
          t          f$ r}t          |t          j                  rGt          j        dk    r7|j        t          j        k    r"|| j	        z   | _	        t          j                    t          |t                    r3dt!          |          v r"|| j	        z   | _	        t          j                    |j        t"          vrd| _         d	}~ww xY w|d
k    r|||
fS t'          d|dd          )a  Parse AMQP frame.

        Frame has following format::

            0      1         3         7                   size+7      size+8
            +------+---------+---------+   +-------------+   +-----------+
            | type | channel |  size   |   |   payload   |   | frame-end |
            +------+---------+---------+   +-------------+   +-----------+
             octet    short     long        'size' octets        octet

           Tz>BHIr"   r   ntrI   FN   zReceived frame_end z#04xz while expecting 0xce)r   r*   SIGNED_INT_MAXrM   rN   rD   r   joinordr+   
isinstancerZ   osnamerO   rP   rL   _UNAVAILr'   r   )r0   r   readread_frame_bufferframe_header
frame_typechannelsizepart1part2payload	frame_endrR   s                r    
read_framez_AbstractTransport.read_frame  s,    z(,	44==L-(.v|(D(D%J n$$^,, D!677EE:    &.%	 ((E5>22$t**(DDGGII~ 	 	 	 1D4E ED" 	 	 	3--'24'T//I!222
 %68I$I!n&&&#x(( '[CHH-D-D %68I$I!n&&&y((!&'	* w//!KiKKKKM M Ms1   <C A!  C !#BAC /F;7B?F66F;c                     	 |                      |           d S # t          j        $ r  t          $ r}|j        t
          vrd| _         d }~ww xY wr&   )rm   rM   rN   rD   rO   r   r'   )r0   r   rR   s      r    writez_AbstractTransport.writeY  sg    	KKNNNNN~ 	 	 	 	 	 	y((!&	s    AAA)NNNNT)F)r<   
__module____qualname____doc__r2   	__slots__r@   rG   r   rS   rB   rC   r|   ri   r   rl   r   rm   rE   r   r   r   r   r"   r    r$   r$   7   sD        > .226>B/ / / /
I O O O  ( * * ^*4  .* * *&  *4 4 4D D D D    D D D  , !' @M @M @M @MD    r"   r$   c                        e Zd ZdZd fd	ZdZd ZddZddZ	 	 	 	 	 dd
Z	d Z
dej        ej        ej        ffdZd Z xZS )SSLTransporta  Transport that works over SSL.

    PARAMETERS:
        host: str

            Broker address in format ``HOSTNAME:PORT``.

        connect_timeout: int

            Timeout of creating new connection.

        ssl: bool|dict

            parameters of TLS subsystem.
                - when ``ssl`` is not dictionary, defaults of TLS are used
                - otherwise:
                    - if ``ssl`` dictionary contains ``context`` key,
                      :attr:`~SSLTransport._wrap_context` is used for wrapping
                      socket. ``context`` is a dictionary passed to
                      :attr:`~SSLTransport._wrap_context` as context parameter.
                      All others items from ``ssl`` argument are passed as
                      ``sslopts``.
                    - if ``ssl`` dictionary does not contain ``context`` key,
                      :attr:`~SSLTransport._wrap_socket_sni` is used for
                      wrapping socket. All items in ``ssl`` argument are
                      passed to :attr:`~SSLTransport._wrap_socket_sni` as
                      parameters.

        kwargs:

            additional arguments of
            :class:`~amqp.transport._AbstractTransport` class
    Nc                     t          |t                    r|ni | _        t          | _         t                      j        |fd|i| d S )Nr,   )r   dictssloptsr*   r+   superr2   )r0   r   r,   sslr1   	__class__s        r    r2   zSSLTransport.__init__  sb    (d33;ss(	= 	="1	=5;	= 	= 	= 	= 	=r"   )r   c                      | j         | j        fi | j        | _        | j                            | j                   | j                                         | j        j        | _        dS )z!Wrap the socket in an SSL object.N)_wrap_socketr(   r   rK   r,   do_handshaker   _quick_recvrF   s    r    rl   zSSLTransport._setup_transport  sa    %D%di@@4<@@		T1222	   9>r"   c                 @    |r | j         ||fi |S  | j        |fi |S r~   )_wrap_context_wrap_socket_sni)r0   r(   contextr   s       r    r   zSSLTransport._wrap_socket  sC     	@%4%dG??w???$t$T55W555r"   c                 N    t          j        di |}||_         |j        |fi |S )u  Wrap socket without SNI headers.

        PARAMETERS:
            sock: socket.socket

            Socket to be wrapped.

            sslopts: dict

                Parameters of  :attr:`ssl.SSLContext.wrap_socket`.

            check_hostname

                Whether to match the peer cert’s hostname. See
                :attr:`ssl.SSLContext.check_hostname` for details.

            ctx_options

                Parameters of :attr:`ssl.create_default_context`.
        r   )r   create_default_contextcheck_hostnamewrap_socket)r0   r(   r   r   ctx_optionsctxs         r    r   zSSLTransport._wrap_context  s<    * (77;77+st//w///r"   FTc                    |||||	d}||rt           j        nt           j        }t          j        |          }||                    ||           ||                    |           |
|                    |
           	 t           j        o|	du|_        n# t          $ r Y nw xY w|||_
        |N|j
        t           j        k    r9|rt           j        j        nt           j        j        }|                    |            |j        di |}|S )u  Socket wrap with SNI headers.

        stdlib :attr:`ssl.SSLContext.wrap_socket` method augmented with support
        for setting the server_hostname field required for SNI hostname header.

        PARAMETERS:
            sock: socket.socket

                Socket to be wrapped.

            keyfile: str

                Path to the private key

            certfile: str

                Path to the certificate

            server_side: bool

                Identifies whether server-side or client-side
                behavior is desired from this socket. See
                :attr:`~ssl.SSLContext.wrap_socket` for details.

            cert_reqs: ssl.VerifyMode

                When set to other than :attr:`ssl.CERT_NONE`, peers certificate
                is checked. Possible values are :attr:`ssl.CERT_NONE`,
                :attr:`ssl.CERT_OPTIONAL` and :attr:`ssl.CERT_REQUIRED`.

            ca_certs: str

                Path to “certification authority” (CA) certificates
                used to validate other peers’ certificates when ``cert_reqs``
                is other than :attr:`ssl.CERT_NONE`.

            do_handshake_on_connect: bool

                Specifies whether to do the SSL
                handshake automatically. See
                :attr:`~ssl.SSLContext.wrap_socket` for details.

            suppress_ragged_eofs (bool):

                See :attr:`~ssl.SSLContext.wrap_socket` for details.

            server_hostname: str

                Specifies the hostname of the service which
                we are connecting to. See :attr:`~ssl.SSLContext.wrap_socket`
                for details.

            ciphers: str

                Available ciphers for sockets created with this
                context. See :attr:`ssl.SSLContext.set_ciphers`

            ssl_version:

                Protocol of the SSL Context. The value is one of
                ``ssl.PROTOCOL_*`` constants.
        )r(   server_sidedo_handshake_on_connectsuppress_ragged_eofsserver_hostnameNr   )r   PROTOCOL_TLS_SERVERPROTOCOL_TLS_CLIENT
SSLContextload_cert_chainload_verify_locationsset_ciphersHAS_SNIr   AttributeErrorverify_mode	CERT_NONEPurposeCLIENT_AUTHSERVER_AUTHload_default_certsr   )r0   r(   keyfilecertfiler   	cert_reqsca_certsr   r   r   ciphersssl_versionoptsr   purposes                  r    r   zSSLTransport._wrap_socket_sni  s`   H &'>$8.
 
  -'',  .--##Hg666))(333(((	;t ; ""  	 	 	D	
  "+G 3s} D D -''[, 
 &&w///"w"**T**s    B 
B#"B#c                 T    | j          | j                                         | _         dS dS )z/Unwrap a SSL socket, so we can call shutdown().N)r(   unwraprF   s    r    r   z SSLTransport._shutdown_transport/  s+    9 	((**DIII ! r"   c                    | j         }| j        }	 t          |          |k     r	  ||t          |          z
            }n=# t          $ r0}|j        |v r!|r| j        rt          j                    Y d }~d d }~ww xY w|st          d          ||z  }t          |          |k     n#  || _         xY w|d |         ||d          c}| _        |S )N%Server unexpectedly closed connectionr   r+   r[   rD   rO   r)   rM   rN   	r0   r   r   _errnosrecvrbufr   rR   results	            r    r   zSSLTransport._read4  s   
  	d))a--	QT]++AA    yG++" 3t'B 3"(."2"22   K!"IJJJ	 d))a--	 $D$(!Hd122h!!9   B' A  B'  
A:
%A5/B' 4A55A::,B' '
B1c                     | j         j        }|r>	  ||          }n# t          $ r d}Y nw xY w|st          d          ||d         }|<dS dS )z+Write a string out to the SSL socket fully.r   zSocket closedN)r(   r   
ValueErrorrD   )r0   r   r   r   s       r    rm   zSSLTransport._writeP  s    	 	E!HH   
   /o...!""A  	 	 	 	 	s    ++)NNr~   )
NNFNNFTNNN)r<   r   r   r   r2   r   rl   r   r   r   r   rO   ENOENTEAGAINEINTRr   rm   __classcell__)r   s   @r    r   r   d  s           D= = = = = =
I* * *6 6 6 6
0 0 0 02 =A6:@EDH37	v v v vp+ + +
  %|U\5;?   8      r"   r   c                   <    e Zd ZdZd Zdej        ej        ffdZdS )TCPTransportz~Transport that deals directly with TCP socket.

    All parameters are :class:`~amqp.transport._AbstractTransport` class.
    c                 b    | j         j        | _        t          | _        | j         j        | _        d S r~   )r(   sendallrm   r*   r+   r   r   rF   s    r    rl   zTCPTransport._setup_transportg  s*     i'(9>r"   Fc                    | j         }| j        }	 t          |          |k     r	  ||t          |          z
            }n=# t          $ r0}|j        |v r!|r| j        rt          j                    Y d}~d d}~ww xY w|st          d          ||z  }t          |          |k     n#  || _         xY w|d|         ||d         c}| _        |S )z%Read exactly n bytes from the socket.Nr   r   r   s	            r    r   zTCPTransport._readn  s    	d))a--QT]++AA   yG++" 3t'B 3"(."2"22   K!"IJJJ	 d))a--	 $D$(!Hd122h!!r   N)	r<   r   r   r   rl   rO   r   r   r   r   r"   r    r   r   a  sQ         
* * *  %u|U[.I      r"   r   Fc                 :    |rt           nt          } || f||d|S )a  Create transport.

    Given a few parameters from the Connection constructor,
    select and create a subclass of
    :class:`~amqp.transport._AbstractTransport`.

    PARAMETERS:

        host: str

            Broker address in format ``HOSTNAME:PORT``.

        connect_timeout: int

            Timeout of creating new connection.

        ssl: bool|dict

            If set, :class:`~amqp.transport.SSLTransport` is used
            and ``ssl`` parameter is passed to it. Otherwise
            :class:`~amqp.transport.TCPTransport` is used.

        kwargs:

            additional arguments of :class:`~amqp.transport._AbstractTransport`
            class
    )r,   r   )r   r   )r   r,   r   r1   	transports        r    	Transportr     s1    8 !$5I9TN?NNvNNNr"   r&   )%r   rO   r   rerM   r   
contextlibr   r   structr   r   
exceptionsr   platformr	   r
   utilsr   r   r   r   rP   r   	AMQP_PORTbytesr*   r   rn   compiler   rw   r!   r$   r   r   r   r   r"   r    <module>r     s      				 				  



 % % % % % %               ' ' ' ' ' ' - - - - - - - -      L%+u|U5FG	uww /  rz:;;     )    j j j j j j j jZ	z z z z z% z z zz# # # # #% # # #LO O O O O Or"   