U
    fm                     @   sL  d Z ddlZddlZddlZddlZ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mZ z2ddlZejejejejdZeedoejZW n ek
r   dZdZY nX d	d
lmZmZmZmZ dZ dZ!dZ"d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 )zGModule implementing low-level socket communication with MySQL servers.
    N)ABCabstractmethod)deque)AnyDequeListOptionalTupleUnion)TLSv1TLSv1.1TLSv1.2TLSv1.3HAS_TLSv1_3F   )InterfaceErrorNotSupportedErrorOperationalErrorProgrammingError2   i       )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   V/var/www/html/api-medvista/venv/lib/python3.8/site-packages/mysql/connector/network.py_strioerrorE   s    r    c                	   @   sP   e Zd ZdZed	ej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sockaddresspayloadpacket_numbercompressed_packet_numberr   c                 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   sende   s    	zNetworkBroker.sendr#   r$   r   c                 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   recv   s    zNetworkBroker.recv)NN)__name__
__module____qualname____doc__r   socketr   bytesr   intr)   	bytearrayr+   r   r   r   r   r!   M   s     r!   c                   @   s   e Zd ZdZddddZddddZejeeddd	d
Z	deje
edddZdej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__c                 C   s   | j d d | _ dS zIncrement packet id.r      Nr9   r;   r   r   r   _set_next_pktnr   s    z"NetworkBrokerPlain._set_next_pktnrr#   r$   pktr   c              
   C   sx   z| | W nd tk
rF } ztd|t|fd|W 5 d}~X Y n. tk
rr } ztdd|W 5 d}~X Y nX dS )z!Write packet to the comm channel.  r   valuesNi  r   )sendallIOErrorr   r    AttributeError)r(   r#   r$   rA   r   r   r   r   	_send_pkt   s     
zNetworkBrokerPlain._send_pktr   )r#   sizer   c                 C   sT   t |}t|}|rP|||}|dkr:|dkr:tdd||d }||8 }q|S )z(Read `size` bytes from the comm channel.r   i  rE   N)r3   
memoryview	recv_intor   )r(   r#   rJ   rA   Zpkt_viewreadr   r   r   _recv_chunk   s    

zNetworkBrokerPlain._recv_chunkr"   c              
   C   s   |dkr|    n|| _t|tkrd}tt|t D ]@}| ||dtd| j |||t    |    |t7 }q8||d }| ||tdt|dd td| j |  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.
        Nr      <B<I   )r?   r:   lenMAX_PAYLOAD_LENGTHrangerI   structpack)r(   r#   r$   r%   r&   r'   offset_r   r   r   r)      s6    

zNetworkBrokerPlain.sendr*   c              
   C   s   zJ| j |td}td|dd d d |d  }| _|| j ||d W S  tk
r } ztd|t|fd|W 5 d}~X Y nX dS )	z+Receive `one` packet from the MySQL server.rJ   rQ   r   rR       rB   rC   N)rN   PACKET_HEADER_LENGTHrV   unpackr:   rG   r   r    )r(   r#   r$   headerZpayload_lenr   r   r   r   r+      s     
zNetworkBrokerPlain.recv)r   )NN)r,   r-   r.   r/   r<   r?   r0   r   r1   rI   r2   r3   rN   r   r)   r+   r   r   r   r   r4      s      ,r4   c                       s   e Zd ZdZdd fddZeeeee dddZ	ddd	d
Z
ejeedd fddZdejeeee ee dd fddZejeedd fddZejeed fddZ  ZS )NetworkBrokerCompressedr5   Nr6   c                    s   t    d| _t | _d S r7   )superr<   _compressed_pktnrr   _queue_readr;   	__class__r   r   r<      s    
z NetworkBrokerCompressed.__init__)r%   pktnrr   c                 C   s   g }t | tkrpd}tt | t D ]>}|dtd| | ||t    |d d }|t7 }q$| |d } |tdt | dd td| |   |S )	z2Prepare a payload for sending to the MySQL server.r   rO   rP   r   r>   NrQ   rR   )rS   rT   rU   appendrV   rW   )r%   re   ZpktsrX   rY   r   r   r   _prepare_packets   s$    

&z(NetworkBrokerCompressed._prepare_packetsc                 C   s   | j d d | _ dS r=   )ra   r;   r   r   r   _set_next_compressed_pktnr  s    z2NetworkBrokerCompressed._set_next_compressed_pktnrr@   c                    s\   t |}tdt|dd td| j tdt|dd  | }t |||S )z1Compress packet and write it to the comm channel.rQ   r   rR   rP   )zlibcompressrV   rW   rS   ra   r`   rI   )r(   r#   r$   rA   compressed_pktrc   r   r   rI     s    
z!NetworkBrokerCompressed._send_pktr"   c           	   	      s  |dkr|    n|| _|dkr*|   n|| _td| || j}t|tt	 krd}t
t|t D ].}| |||||t   |   |t7 }ql| ||||d  nft|tkr| ||| nJt ||tdt|dd td| j tdddd  |  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.
        N    r   rQ   rR   rP   )r?   r:   rh   ra   r3   joinrg   rS   rT   r\   rU   rI   MIN_COMPRESS_LENGTHr`   rV   rW   )	r(   r#   r$   r%   r&   r'   Zpayload_preprX   rY   rc   r   r   r)   &  s>    

  
zNetworkBrokerCompressed.send)r#   compressed_plluncompressed_pllr   c           	         s"  t  j||d}|dkr|ntt|}d}|t|k rtd|||t d  d d }t| t|| krt  j|t	d}td|dd d d |d td|dd d d   }| _
}t  j||d}||dkr|nt|7 }| j|||t |   |t| 7 }q.d	S )
z&Handle reading of a compressed packet.rZ   r   rQ   r   r[   rR   r   r   N)r`   rN   r3   ri   
decompressrS   rV   r]   r\   COMPRESSED_PACKET_HEADER_LENGTHra   rb   rf   )	r(   r#   ro   rp   rk   rA   rX   Zpllr^   rc   r   r   _recv_compressed_pktc  s>     z,NetworkBrokerCompressed._recv_compressed_pktr*   c              
      s   | j szht j|td}td|dd d d |d td|dd d d   }| _}| ||| 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.
        rZ   rQ   r   rR   r[   r   r   rB   rC   N)rb   r`   rN   rr   rV   r]   ra   rs   rG   r   r    popleftr:   )r(   r#   r$   r^   ro   rp   r   rA   rc   r   r   r+     s0     


zNetworkBrokerCompressed.recv)NN)r,   r-   r.   r/   r<   staticmethodr1   r2   r   rg   rh   r0   r   rI   r   r)   rs   r3   r+   __classcell__r   r   rc   r   r_      s,     >  0r_   c                
   @   s  e Zd ZdZddddZddddZdddd	Zddd
dZddddZe	e
 ddddZeeddddZd!e	e e	e e	e e	e e	e e	ee  e	ee  edddZd"ee	e
 e	e
 ddddZedddZeddddZeeeddd ZdS )#MySQLSocketzMySQL socket communication interface.

    Examples:
        Subclasses: network.MySQLTCPSocket and network.MySQLUnixSocket.
    Nr6   c                 C   s   d| _ d| _d| _t | _dS )zsNetwork layer where transactions are made with plain (uncompressed) packets
        is enabled by default.
        N)r#   _connection_timeoutserver_hostr4   
_netbrokerr;   r   r   r   r<     s    zMySQLSocket.__init__c                 C   s   t  | _dS )zIEnable network layer where transactions are made with compressed packets.N)r_   rz   r;   r   r   r   switch_to_compressed_mode  s    z%MySQLSocket.switch_to_compressed_modec              	   C   s:   z| j tj | j   W n ttfk
r4   Y nX dS )z'Shut down the socket before closing it.N)r#   shutdownr0   	SHUT_RDWRcloserH   OSErrorr;   r   r   r   r|     s
    zMySQLSocket.shutdownc              	   C   s,   z| j   W n ttfk
r&   Y nX dS )zClose the socket.N)r#   r~   rH   r   r;   r   r   r   close_connection  s    zMySQLSocket.close_connectionc                 C   s   |    d S N)r|   r;   r   r   r   __del__  s    zMySQLSocket.__del__)timeoutr   c                 C   s   || _ | jr| j| dS )zSet the connection timeout.N)rx   r#   
settimeout)r(   r   r   r   r   set_connection_timeout  s    z"MySQLSocket.set_connection_timeout)ssl_contexthostr   c              
   C   s  | j dk	st| j jdkr"tdtdkr2tdz|j| j |d| _ W n tk
rt } ztd|W 5 d}~X Y n tjt	fk
r } zt
d| jt|fd|W 5 d}~X Y nb tjk
r } zt
t||W 5 d}~X Y n2 tk
r } zt
t||W 5 d}~X Y nX dS )a  Upgrade an existing connection to TLS.

        Args:
            ssl_context (ssl.SSLContext): The SSL Context to be used.
            host (str): Server host name.

        Returns:
            None.

        Raises:
            ProgrammingError: If the transport does not expose the socket instance.
            NotSupportedError: If Python installation has no SSL support.
        Nr   z,SSL is not supported when using Unix sockets&Python installation has no SSL support)server_hostnamerB   rC   )r#   AssertionErrorfamilyr   sslr   wrap_socket	NameErrorSSLErrorrG   r   r$   r    CertificateErrorr   NotImplementedError)r(   r   r   r   r   r   r   switch_to_ssl  s(     zMySQLSocket.switch_to_sslF)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|dkr,g }|dkr8g }zt|r|jdd |d }t| }	t|	}
|dkrd	|kr|
 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|
_|
  |rBz|
| W n: ttjfk
r@ } ztd| |W 5 d}~X Y nX |rz|
|| W n: ttjfk
r } 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 )a  Build a SSLContext.

        Args:
            ssl_ca: Certificate authority, opptional.
            ssl_cert: SSL certificate, optional.
            ssl_key: Private key, optional.
            ssl_verify_cert: Verify the SSL certificate if `True`.
            ssl_verify_identity: Verify host identity if `True`.
            tls_versions: TLS protocol versions, optional.
            tls_cipher_suites: Set of steps that helps to establish a secure connection.

        Returns:
            ssl_context (ssl.SSLContext): An SSL Context ready be used.

        Raises:
            NotSupportedError: Python installation has no SSL support.
            InterfaceError: Socket undefined or invalid ssl data.
        i   rE   Nr   T)reverser   r   r   r   r   zInvalid CA Certificate: zInvalid Certificate/Key: :)r#   r   r   r   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_locationsrG   r   load_cert_chainset_ciphersrm   r   r   r   r   )r(   r   r   r   r   r   r   r   tls_versionZssl_protocolcontextr   r   r   r   build_ssl_context  sf    



""zMySQLSocket.build_ssl_context)r%   r&   r'   r   c                 C   s   | j j| j| j|||dS )at  Send `payload` to the MySQL server.

        NOTE: if `payload` is an instance of `bytearray`, then `payload` might be
        changed by this method - `bytearray` is similar to passing a variable by
        reference.

        If you're sure you won't read `payload` after invoking `send()`,
        then you can use `bytearray.` Otherwise, you must use `bytes`.
        )r&   r'   )rz   r)   r#   r$   )r(   r%   r&   r'   r   r   r   r)   d  s    zMySQLSocket.sendc                 C   s   | j | j| jS )z.Get packet from the MySQL server comm channel.)rz   r+   r#   r$   r;   r   r   r   r+   {  s    zMySQLSocket.recvc                 C   s   dS )zOpen the socket.Nr   r;   r   r   r   open_connection  s    zMySQLSocket.open_connectionc                 C   s   dS )zGet the location of the socket.Nr   r;   r   r   r   r$     s    zMySQLSocket.address)NNNFFNN)NN)r,   r-   r.   r/   r<   r{   r|   r   r   r   r2   r   r   r   r   boolr   r   r1   r)   r3   r+   r   r   propertyr$   r   r   r   r   rw     sN   
&       

a  rw   c                       s\   e Zd ZdZdedd fddZeeddd	Zddd
dZe	e	ddddZ
  ZS )MySQLUnixSocketzpMySQL socket class using UNIX sockets.

    Opens a connection through the UNIX socket of the MySQL Server.
    /tmp/mysql.sockN)unix_socketr   c                    s   t    || _|| _d S r   )r`   r<   r   _address)r(   r   rc   r   r   r<     s    
zMySQLUnixSocket.__init__r6   c                 C   s   | j S r   r   r;   r   r   r   r$     s    zMySQLUnixSocket.addressc              
   C   s   z2t  t jt j| _| j| j | j| j W nh tk
rl } zt	d| j
t|fd|W 5 d }~X Y n0 tk
r } zt	t||W 5 d }~X Y nX d S )Ni  rC   )r0   AF_UNIXSOCK_STREAMr#   r   rx   connectr   rG   r   r$   r    	Exceptionr   )r(   r   r   r   r   r     s      zMySQLUnixSocket.open_connection)argskwargsr   c                 O   s   t dt dS )zSwitch the socket to use SSL.z2SSL is disabled when using unix socket connectionsN)warningswarnWarning)r(   r   r   r   r   r   r     s    zMySQLUnixSocket.switch_to_ssl)r   )r,   r-   r.   r/   r   r<   r   r$   r   r   r   rv   r   r   rc   r   r     s    r   c                       sN   e Zd ZdZdeeedd fddZeed	d
dZ	dd	ddZ
  ZS )MySQLTCPSocketzYMySQL socket class using TCP/IP.

    Opens a TCP/IP connection to the MySQL Server.
    	127.0.0.1  FN)r   port
force_ipv6r   c                    s6   t    || _|| _|| _d| _| d| | _d S )Nr   r   )r`   r<   ry   server_portr   _familyr   )r(   r   r   r   rc   r   r   r<     s    
zMySQLTCPSocket.__init__r6   c                 C   s   | j S r   r   r;   r   r   r   r$     s    zMySQLTCPSocket.addressc           	   
   C   s  d}zt | j| jdt jt j}|D ]6}| jrD|d t jkrD|} q\|d t jkr$|} q\q$| jr~|d dkr~t	d| j |d dkr|d }W n: t
k
r } zt	d| jt|fd|W 5 d}~X Y nX |\| _}}}}z0t  | j||| _| j| j | j| W np t
k
rP } z t	d| j| jt|fd|W 5 d}~X Y n2 tk
r } ztt||W 5 d}~X Y nX dS )z/Open the TCP/IP connection to the MySQL server.)NNNNNr   NzNo IPv6 address found for i  rC   )r0   getaddrinfory   r   r   SOL_TCPr   AF_INET6AF_INETr   rG   r$   r    r   r#   r   rx   r   r   r   r   )	r(   ZaddrinfoZ	addrinfosinfor   socktypeprotorY   sockaddrr   r   r   r     sZ    
 zMySQLTCPSocket.open_connection)r   r   F)r,   r-   r.   r/   r   r2   r   r<   r   r$   r   rv   r   r   rc   r   r     s      r   )-r/   r0   rV   r   ri   abcr   r   collectionsr   typingr   r   r   r   r	   r
   r   PROTOCOL_TLSv1PROTOCOL_TLSv1_1PROTOCOL_TLSv1_2PROTOCOL_TLSr   hasattrr   TLS_V1_3_SUPPORTEDImportErrorerrorsr   r   r   r   rn   rT   r\   rr   rG   r   r    r!   r4   r_   rw   r   r   r   r   r   r   <module>   s@    
Ga A U)