U
    gf`a                     @   sL  d Z ddgZddlZddlZddlZz"ddlZejejejej	dZ
W n ek
r^   dZY nX ddlmZmZ ddlmZ ddlmZmZmZmZmZ d	d
lmZmZmZmZ d	dlmZmZmZm Z  ddl!m"Z"m#Z# e$e%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e*Z,dS )zFModule implementing low-level socket communication with MySQL servers.MySQLTcpSocketMySQLUnixSocket    N)TLSv1TLSv1.1TLSv1.2TLSv1.3)ABCabstractmethod)deque)AnyDequeListOptionalTuple   )InterfaceErrorNotSupportedErrorOperationalErrorProgrammingError)COMPRESSED_PACKET_HEADER_LENGTHMAX_PAYLOAD_LENGTHMIN_COMPRESS_LENGTHPACKET_HEADER_LENGTH   )StreamWriteropen_connection)errreturnc                 C   s    | j st| S | j  d| j S )z`Reformat the IOError error message.

    This function reformats the IOError error message.
     )errnostrstrerror)r    r"   Z/var/www/html/api-medvista/venv/lib/python3.8/site-packages/mysql/connector/aio/network.py_strioerrorG   s    r$   c                	   @   sN   e Zd ZdZed	eeeee	 ee	 ddddZ
eejeedddZdS )
NetworkBrokeraP  Broker class interface.

    The network object is a broker used as a delegate by a socket object. Whenever the
    socket wants to deliver or get packets to or from the MySQL server it needs to rely
    on its network broker (netbroker).

    The netbroker sends `payloads` and receives `packets`.

    A packet is a bytes sequence, it has a header and body (referred to as payload).
    The first `PACKET_HEADER_LENGTH` or `COMPRESSED_PACKET_HEADER_LENGTH`
    (as appropriate) bytes correspond to the `header`, the remaining ones represent the
    `payload`.

    The maximum payload length allowed to be sent per packet to the server is
    `MAX_PAYLOAD_LENGTH`. When  `send` is called with a payload whose length is greater
    than `MAX_PAYLOAD_LENGTH` the netbroker breaks it down into packets, so the caller
    of `send` can provide payloads of arbitrary length.

    Finally, data received by the netbroker comes directly from the server, expect to
    get a packet for each call to `recv`. The received packet contains a header and
    payload, the latter respecting `MAX_PAYLOAD_LENGTH`.
    Nwriteraddresspayloadpacket_numbercompressed_packet_numberr   c                    s   dS )a  Send `payload` to the MySQL server.

        If provided a payload whose length is greater than `MAX_PAYLOAD_LENGTH`, it is
        broken down into packets.

        Args:
            sock: Object holding the socket connection.
            address: Socket's location.
            payload: Packet's body to send.
            packet_number: Sequence id (packet ID) to attach to the header when sending
                           plain packets.
            compressed_packet_number: Same as `packet_number` but used when sending
                                      compressed packets.

        Raises:
            :class:`OperationalError`: If something goes wrong while sending packets to
                                       the MySQL server.
        Nr"   )selfr'   r(   r)   r*   r+   r"   r"   r#   writeg   s    	zNetworkBroker.writereaderr(   r   c                    s   dS )a)  Get the next available packet from the MySQL server.

        Args:
            sock: Object holding the socket connection.
            address: Socket's location.

        Returns:
            packet: A packet from the MySQL server.

        Raises:
            :class:`OperationalError`: If something goes wrong while receiving packets
                                       from the MySQL server.
            :class:`InterfaceError`: If something goes wrong while receiving packets
                                     from the MySQL server.
        Nr"   )r,   r/   r(   r"   r"   r#   read   s    zNetworkBroker.read)NN)__name__
__module____qualname____doc__r	   r   r    bytesr   intr-   asyncioStreamReader	bytearrayr0   r"   r"   r"   r#   r%   O   s     r%   c                   @   s   e Zd ZdZddddZeeeeef dddZ	de
e dd	d
dZeeeddddZdejeedddZdeeee
e e
e ddddZejeedddZdS )NetworkBrokerPlain,Broker class for MySQL socket communication.Nr   c                 C   s
   d| _ d S N_pktnrr,   r"   r"   r#   __init__   s    zNetworkBrokerPlain.__init__pktr   c                 C   sB   t | tk rtdtd| dd d d | d  }}||fS )-Recover the header information from a packet.3Can't recover header info from an incomplete packet<Ir          )lenr   
ValueErrorstructunpack)rD   pllseqidr"   r"   r#   
get_header   s    zNetworkBrokerPlain.get_headernext_idr   c                 C   s0   |dkr|  j d7  _ n|| _ |  j d;  _ dS z:Set the given packet id, if any, else increment packet id.Nr      r?   r,   rR   r"   r"   r#   _set_next_pktnr   s    z"NetworkBrokerPlain._set_next_pktnrr'   r(   rD   r   c              
      s   z| | | I dH  W nd tk
rT } ztd|t|fd|W 5 d}~X Y n. tk
r } ztdd|W 5 d}~X Y nX dS )z!Write packet to the comm channel.N  r   valuesi  r   )r-   drainIOErrorr   r$   AttributeError)r,   r'   r(   rD   r   r"   r"   r#   
_write_pkt   s    
 
zNetworkBrokerPlain._write_pktr   )r/   sizer   c                    sH   t d}t||k rD||t| I dH }|s:tdd||7 }q|S )z(Read `size` bytes from the comm channel.    Ni  r[   )r9   rJ   r0   r   )r,   r/   r`   rD   chunkr"   r"   r#   _read_chunk   s    

zNetworkBrokerPlain._read_chunkr&   c              
      s   |  | d}tt|t D ]F}| ||dtd| j |||t   I dH  |    |t7 }q| ||tdt|| dd td| j ||d  I dH  dS )zSend payload to the MySQL server.

        If provided a payload whose length is greater than `MAX_PAYLOAD_LENGTH`, it is
        broken down into packets.
        r      <BNrG   rH   )rV   rangerJ   r   r_   rL   packr@   )r,   r'   r(   r)   r*   r+   offset_r"   r"   r#   r-      s.    



zNetworkBrokerPlain.writer.   c              
      s|   z>| j |tdI dH }| |\}| _|| j ||dI dH  W S  tk
rv } ztd|t|fd|W 5 d}~X Y nX dS )z+Receive `one` packet from the MySQL server.r`   NrX   rY   )rc   r   rP   r@   r]   r   r$   )r,   r/   r(   headerZpayload_lenr   r"   r"   r#   r0      s     
zNetworkBrokerPlain.read)N)r   )NN)r1   r2   r3   r4   rB   staticmethodr5   r   r6   rP   r   rV   r   r    r_   r7   r8   r9   rc   r-   r0   r"   r"   r"   r#   r:      s.       &r:   c                       s   e Zd ZdZdd fddZeeeee dddZ	eee
eeef d	d
dZdee ddddZeeedd fddZdeeeee ee dd fddZejedd fddZejeed fddZ  ZS )NetworkBrokerCompressedr;   Nr<   c                    s   t    d| _t | _d S r=   )superrB   _compressed_pktnrr
   _queue_readrA   	__class__r"   r#   rB     s    
z NetworkBrokerCompressed.__init__)r)   pktnrr   c                 C   s   d}g }t t| t D ]>}|dtd| | ||t    |d d }|t7 }q|tdt| | dd td| | |d   |S )	z2Prepare a payload for sending to the MySQL server.r   rd   re   r   rT   rG   rH   N)rf   rJ   r   appendrL   rg   )r)   rs   rh   Zpktsri   r"   r"   r#   _prepare_packets  s(    



z(NetworkBrokerCompressed._prepare_packetsrC   c                 C   sb   t | tk rtdtd| dd d d | d td| dd d d   }}}|||fS )rE   rF   rG   r   rH   rI         )rJ   r   rK   rL   rM   )rD   compressed_pllrO   uncompressed_pllr"   r"   r#   rP   !  s    
z"NetworkBrokerCompressed.get_headerrQ   c                 C   s0   |dkr|  j d7  _ n|| _ |  j d;  _ dS rS   )ro   rU   r"   r"   r#   _set_next_compressed_pktnr/  s    z2NetworkBrokerCompressed._set_next_compressed_pktnrrW   c                    sb   t |}tdt|dd td| j tdt|dd  | }t |||I dH S )z1Compress packet and write it to the comm channel.rG   r   rH   re   N)zlibcompressrL   rg   rJ   ro   rn   r_   )r,   r'   r(   rD   compressed_pktrq   r"   r#   r_   7  s    
z"NetworkBrokerCompressed._write_pktr&   c           	   	      s  |  | | | td| || j}t|tt krd}t	t|t D ]4}| 
|||||t  I dH  |   |t7 }qP| 
||||d I dH  nrt|tkr| 
|||I dH  nPt 
||tdt|dd td| j tdddd  | I dH  dS )zSend `payload` as compressed packets to the MySQL server.

        If provided a payload whose length is greater than `MAX_PAYLOAD_LENGTH`, it is
        broken down into packets.
        ra   r   NrG   rH   re   )rV   rz   r9   joinru   r@   rJ   r   r   rf   r_   r   rn   rL   rg   ro   )	r,   r'   r(   r)   r*   r+   Zpayload_preprh   ri   rq   r"   r#   r-   B  s6    

  

zNetworkBrokerCompressed.write)r/   rx   r   c           	         s   t tt j||dI dH }d}|t|k rtd|||t d  d d }t| t|| krt j|t	dI dH }| 
|\}| _}t j||dI dH }||dkr|nt|7 }| j|||t |   |t| 7 }q$dS )z&Handle reading of a compressed packet.rj   Nr   rG   r   rI   )r9   r{   
decompressrn   rc   rJ   rL   rM   r   r   rP   ro   rp   rt   )	r,   r/   rx   rD   rh   rN   rk   ry   r}   rq   r"   r#   _read_compressed_pkty  s:      	z,NetworkBrokerCompressed._read_compressed_pktr.   c              
      s   | j szft j|tdI dH }| |\}| _}|dkrX| j t j||dI dH  n| ||I dH  W n8 tk
r } zt	d|t
|fd|W 5 d}~X Y nX | j sdS | j  }|d | _|S )z{Receive `one` or `several` packets from the MySQL server, enqueue them, and
        return the packet at the head.
        rj   Nr   rX   rY   rH   )rp   rn   rc   r   rP   ro   rt   r   r]   r   r$   popleftr@   )r,   r/   r(   rk   rx   ry   r   rD   rq   r"   r#   r0     s8     	 


zNetworkBrokerCompressed.read)N)NN)r1   r2   r3   r4   rB   rl   r5   r6   r   ru   r   rP   r   rz   r   r    r_   r-   r7   r8   r   r9   r0   __classcell__r"   r"   rq   r#   rm      s.     8 (rm   c                
   @   s  e Zd ZdZddddZeedddZee	ddd	d
Z
ddddZedddZeddddZddddZejddddZd eee ee ddddZedddZdddddg g fee ee ee ee ee eee  eee  ejdddZdS )!MySQLSocketzMySQL socket communication interface.

    Examples:
        Subclasses: network.MySQLTCPSocket and network.MySQLUnixSocket.
    Nr<   c                 C   s*   d| _ d| _d| _d| _t | _d| _dS )zsNetwork layer where transactions are made with plain (uncompressed) packets
        is enabled by default.
        NF)_reader_writer_connection_timeout_addressr:   
_netbroker_is_connectedrA   r"   r"   r#   rB     s    zMySQLSocket.__init__c                 C   s   | j S )zSocket location.)r   rA   r"   r"   r#   r(     s    zMySQLSocket.addresskwargsr   c                    s   dS )zOpen the socket.Nr"   r,   r   r"   r"   r#   r     s    zMySQLSocket.open_connectionc                    sB   | j r8| j   | j jdk	r(| j j  | j  I dH  d| _dS )zClose the connection.NF)r   close	transportabortwait_closedr   rA   r"   r"   r#   close_connection  s    
zMySQLSocket.close_connectionc                 C   s   | j S )zCheck if the socket is connected.

        Return:
            bool: Returns `True` if the socket is connected to MySQL server.
        )r   rA   r"   r"   r#   is_connected  s    zMySQLSocket.is_connected)timeoutr   c                 C   s
   || _ dS )zSet the connection timeout.N)r   )r,   r   r"   r"   r#   set_connection_timeout  s    z"MySQLSocket.set_connection_timeoutc                 C   s   t  | _dS )zIEnable network layer where transactions are made with compressed packets.N)rm   r   rA   r"   r"   r#   switch_to_compressed_mode  s    z%MySQLSocket.switch_to_compressed_mode)ssl_contextr   c                    sD   | j dk	st| j jd}|jdkr.td| j |I dH  dS )a?  Upgrade an existing stream-based connection to TLS.

        The `start_tls()` method from `asyncio.streams.StreamWriter` is only available
        in Python 3.11. This method is used as a workaround.

        The MySQL TLS negotiation happens in the middle of the TCP connection.
        Therefore, passing a socket to open connection will cause it to negotiate
        TLS on an existing connection.

        Args:
            ssl_context: The SSL Context to be used.

        Raises:
            RuntimeError: If the transport does not expose the socket instance.
        Nsocketr   z,SSL is not supported when using Unix sockets)r   AssertionErrorr   get_extra_infofamilyr   	start_tls)r,   r   r   r"   r"   r#   switch_to_ssl  s
    
zMySQLSocket.switch_to_ssl)r)   r*   r+   r   c                    s$   | j j| j| j|||dI dH  dS )z!Send packets to the MySQL server.)r*   r+   N)r   r-   r   r(   )r,   r)   r*   r+   r"   r"   r#   r-     s    zMySQLSocket.writec                    s   | j | j| jI dH S )z#Read packets from the MySQL server.N)r   r0   r   r(   rA   r"   r"   r#   r0   &  s    zMySQLSocket.readF)ssl_cassl_certssl_keyssl_verify_certssl_verify_identitytls_versionstls_cipher_suitesr   c                 C   s  | j stddtdkr tdzt|r|jdd |d }t| }	t|	}
|dkrd	|krn|
 jtjO  _d
|kr|
 jtj	O  _d|kr|
 jtj
O  _nt }
||
_|rtj|
_n|rtj|
_ntj|
_|
  |r*z|
| W n: ttjfk
r( } ztd| |W 5 d}~X Y nX |r|z|
|| W n: ttjfk
rz } ztd| |W 5 d}~X Y nX |r|
d| |
W S  tk
r } ztd|W 5 d}~X Y n> tttjtjfk
r  } ztt||W 5 d}~X Y nX dS )zBuild a SSLContext.i   r[   Nz&Python installation has no SSL supportT)reverser   r   r   r   r   zInvalid CA Certificate: zInvalid Certificate/Key: :)r   r   sslRuntimeErrorsortTLS_VERSIONS
SSLContextoptionsOP_NO_TLSv1_2OP_NO_TLSv1_1OP_NO_TLSv1create_default_contextcheck_hostnameCERT_REQUIREDverify_modeCERT_OPTIONAL	CERT_NONEload_default_certsload_verify_locationsr]   SSLErrorload_cert_chainset_ciphersr~   	NameErrorr   NotImplementedErrorCertificateErrorr    )r,   r   r   r   r   r   r   r   Ztls_versionssl_protocolcontextr   r"   r"   r#   build_ssl_context*  s^    



""zMySQLSocket.build_ssl_context)NN)r1   r2   r3   r4   rB   propertyr    r(   r	   r   r   r   boolr   r6   r   r   r   r   r   r5   r   r-   r9   r0   r   r   r"   r"   r"   r#   r     sJ   
  

r   c                       s<   e Zd ZdZdeeed fddZedd	d
dZ	  Z
S )r   zMySQL socket class using TCP/IP.

    Args:
        host: MySQL host name.
        port: MySQL port.
        force_ipv6: Force IPv6 usage.
    	127.0.0.1  F)hostport
force_ipv6c                    s0   t    || _|| _|| _| d| | _d S )Nr   )rn   rB   _host_portZ_force_ipv6r   )r,   r   r   r   rq   r"   r#   rB   z  s
    
zMySQLTcpSocket.__init__Nr   c                    s0   t f | j| jd|I dH \| _| _d| _dS )zOpen TCP/IP connection.)r   r   NT)r   r   r   r   r   r   r   r"   r"   r#   r     s     zMySQLTcpSocket.open_connection)r   r   F)r1   r2   r3   r4   r    r6   r   rB   r   r   r   r"   r"   rq   r#   r   q  s   	       	c                       s8   e Zd ZdZd
ed fddZedddd	Z  ZS )r   zbMySQL socket class using UNIX sockets.

    Args:
        unix_socket: UNIX socket file path.
    /tmp/mysql.sock)unix_socketc                    s   t    || _d S )N)rn   rB   r   )r,   r   rq   r"   r#   rB     s    
zMySQLUnixSocket.__init__Nr   c                    s.   t jf d| ji|I dH \| _| _d| _dS )zOpen UNIX socket connection.pathNT)r7   open_unix_connectionr   r   r   r   r   r"   r"   r#   r     s    
zMySQLUnixSocket.open_connection)r   )	r1   r2   r3   r4   r    rB   r   r   r   r"   r"   rq   r#   r     s   )-r4   __all__r7   rL   r{   r   PROTOCOL_TLSv1PROTOCOL_TLSv1_1PROTOCOL_TLSv1_2PROTOCOL_TLSr   ImportErrorabcr   r	   collectionsr
   typingr   r   r   r   r   errorsr   r   r   r   networkr   r   r   r   utilsr   r   r]   r    r$   r%   r:   rm   r   r   r   r"   r"   r"   r#   <module>   s8   

Gj J )