a
    ’éi‹u  ã                   @   sV  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ƒoŽejZW n ey¬   dZdZY n0 d	d
lmZmZmZ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 )zFModule 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é   )ÚConnectionTimeoutErrorÚInterfaceErrorÚNotSupportedErrorÚOperationalErrorÚProgrammingErrorÚReadTimeoutErrorÚWriteTimeoutErroré2   iÿÿÿ é   é   )ÚerrÚreturnc                 C   s"   | j st| ƒS d| j › d| j› �S )z`Reformat the IOError error message.

    This function reformats the IOError error message.
    zErrno z: )ÚerrnoÚstrÚstrerror)r   © r    úG/home/Claro/venv/lib/python3.9/site-packages/mysql/connector/network.pyÚ_strioerrorI   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!   Úsendi   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#   Q   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   é   Nr;   r=   r    r    r!   Ú_set_next_pktnrž   s    z"NetworkBrokerPlain._set_next_pktnr©r%   r&   Úpktr   c              
   C   s°   z|  |¡ W nœ tjtfyD } ztdd�|‚W Y d}~npd}~0  ty| } z"td|t|ƒfd�|‚W Y d}~n8d}~0  tyª } ztdd�|‚W Y d}~n
d}~0 0 dS )z!Write packet to the comm channel.éÐ  ©r   Né  ©r   ÚvaluesiÖ  )	Úsendallr2   ÚtimeoutÚTimeoutErrorr   ÚIOErrorr   r"   ÚAttributeError)r*   r%   r&   rC   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)r5   Ú
memoryviewÚ	recv_intor   )r*   r%   rO   rC   Zpkt_viewÚreadr    r    r!   Ú_recv_chunk¯   s    

zNetworkBrokerPlain._recv_chunkr$   c              
   C   s¾   |du r|   ¡  n|| _t|ƒtkr†d}tt|ƒt ƒD ]@}|  ||dt d| j¡ |||t …  ¡ |   ¡  |t7 }q8||d… }|  ||t dt|ƒ¡dd… t d| j¡ | ¡ dS )z¤Send 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é   )rA   r<   ÚlenÚMAX_PAYLOAD_LENGTHÚrangerN   Ú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jtfy„ } ztd|j	d�|‚W Y d}~nBd}~0  t
y¼ } z"td	|t|ƒfd
�|‚W Y d}~n
d}~0 0 dS )z+Receive `one` packet from the MySQL server.©rO   rV   r   rW   ó    rD   )r   ÚmsgNrF   rG   )rS   ÚPACKET_HEADER_LENGTHr[   Úunpackr<   r2   rJ   rK   r   r   rL   r   r"   )r*   r%   r&   ÚheaderZpayload_lenr   r    r    r!   r-   ç   s    þ$ÿþzNetworkBrokerPlain.recv)r   )NN)r.   r/   r0   r1   r>   rA   r2   r   r3   rN   r4   r5   rS   r   r+   r-   r    r    r    r!   r6   ˜   s      úù,r6   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 )ÚNetworkBrokerCompressedr7   Nr8   c                    s   t ƒ  ¡  d| _tƒ | _d S r9   )Ú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   rT   rU   r   r@   NrV   rW   )rX   rY   rZ   Úappendr[   r\   )r'   rk   Zpktsr]   r^   r    r    r!   Ú_prepare_packets  s$    
ÿþÿ
&ÿz(NetworkBrokerCompressed._prepare_packetsc                 C   s   | j d d | _ dS r?   )rg   r=   r    r    r!   Ú_set_next_compressed_pktnr  s    z2NetworkBrokerCompressed._set_next_compressed_pktnrrB   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.rV   r   rW   rU   )ÚzlibÚcompressr[   r\   rX   rg   rf   rN   )r*   r%   r&   rC   Úcompressed_pktri   r    r!   rN   #  s    
ÿþýÿz!NetworkBrokerCompressed._send_pktr$   c           	   	      s  |du r|   ¡  n|| _|du r*|  ¡  n|| _tdƒ |  || j¡¡}t|ƒtt	 kr´d}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 )z¼Send `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   rV   rW   rU   )rA   r<   rn   rg   r5   Újoinrm   rX   rY   rb   rZ   rN   ÚMIN_COMPRESS_LENGTHrf   r[   r\   )	r*   r%   r&   r'   r(   r)   Zpayload_prepr]   r^   ri   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rôt ƒ 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.r_   r   rV   r   r`   rW   r   r   N)rf   rS   r5   ro   Ú
decompressrX   r[   rc   rb   ÚCOMPRESSED_PACKET_HEADER_LENGTHrg   rh   rl   )	r*   r%   ru   rv   rq   rC   r]   Zpllrd   ri   r    r!   Ú_recv_compressed_pktk  s<    ÿýÿþýüÿýz,NetworkBrokerCompressed._recv_compressed_pktr,   c              
      s   | j sÞzhtƒ j|td�}t d|dd… d ¡d |d t d|dd… d ¡d   }| _}|  |||¡ W nn tj	t
fy¤ } ztdd	�|‚W Y d
}~nBd
}~0  tyÜ } z"td|t|ƒfd�|‚W Y d
}~n
d
}~0 0 | j sèd
S | j  ¡ }|d | _|S )z{Receive `one` or `several` packets from the MySQL server, enqueue them, and
        return the packet at the head.
        r_   rV   r   rW   r`   r   r   rD   rE   NrF   rG   )rh   rf   rS   rx   r[   rc   rg   ry   r2   rJ   rK   r   rL   r   r"   Úpopleftr<   )r*   r%   r&   rd   ru   rv   r   rC   ri   r    r!   r-   ›  s2    ýü ÿþ

zNetworkBrokerCompressed.recv)NN)r.   r/   r0   r1   r>   Ústaticmethodr3   r4   r   rm   rn   r2   r   rN   r   r+   ry   r5   r-   Ú__classcell__r    r    ri   r!   re   ý   s(     úù>þ0re   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
 e	e
 ddœdd„Zd$e	e
 edœdd„Zeddœdd„ƒZeeedœd d!„ƒƒZdS )%ÚMySQLSocketz�MySQL socket communication interface.

    Examples:
        Subclasses: network.MySQLTCPSocket and network.MySQLUnixSocket.
    Nr8   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_hostr6   Ú
_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)re   r€   r=   r    r    r!   Úswitch_to_compressed_modeÐ  s    z%MySQLSocket.switch_to_compressed_modec              	   C   s8   z| j  tj¡ | j  ¡  W n ttfy2   Y n0 dS )z'Shut down the socket before closing it.N)r%   Úshutdownr2   Ú	SHUT_RDWRÚcloserM   ÚOSErrorr=   r    r    r!   r‚   Ô  s
    zMySQLSocket.shutdownc              	   C   s*   z| j  ¡  W n ttfy$   Y n0 dS )zClose the socket.N)r%   r„   rM   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__)rJ   r   c                 C   s   || _ | jr| j |¡ dS )zSet the connection timeout.N)r~   r%   Ú
settimeout)r*   rJ   r    r    r!   Úset_connection_timeoutæ  s    z"MySQLSocket.set_connection_timeout)Ússl_contextÚhostr   c              
   C   s   | j dusJ ‚| j jdkr"tdƒ‚tdu r2tdƒ‚z|j| j |d�| _ W nÒ tyv } ztdƒ|‚W Y d}~n®d}~0  tjtfy¶ } z$t	d| j
t|ƒfd�|‚W Y d}~nnd}~0  tjyè } zt	t|ƒƒ|‚W Y d}~n<d}~0  t�y } zt	t|ƒƒ|‚W Y d}~n
d}~0 0 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_hostnamerF   rG   )r%   Úfamilyr   Ússlr   Úwrap_socketÚ	NameErrorÚSSLErrorrL   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   s4  d}| j stdd�‚tdu r$tdƒ‚|du r0g }|du r<g }�z‚|r¼|jdd� |d }t| }	t |	¡}
|dkrÄd	|vrŠ|
 jtjO  _d
|vr¢|
 jtj	O  _d|vrÄ|
 jtj
O  _nt ¡ }
||
_|rØtj|
_n|rætj|
_ntj|
_|
 ¡  |�rHz|
 |¡ W n< ttjf�yF } ztd|› �ƒ|‚W Y d}~n
d}~0 0 |�rœz|
 ||¡ W n< ttjf�yš } ztd|› �ƒ|‚W Y d}~n
d}~0 0 |�r¼|d	k�r¼|
 d |¡¡ |
W S  t�yð } ztdƒ|‚W Y d}~nHd}~0  tttjtjf�y. } ztt|ƒƒ|‚W Y d}~n
d}~0 0 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.
        Ni   rE   r�   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_locationsrL   r“   Úload_cert_chainÚset_ciphersrs   r’   r•   r”   r   )r*   r—   r˜   r™   rš   r›   rœ   r�   Ztls_versionZssl_protocolÚcontextr   r    r    r!   Úbuild_ssl_context  sh    



&&üzMySQLSocket.build_ssl_context)r'   r(   r)   Úwrite_timeoutr   c              
   C   sp   z,| j s*| jdur*| j |r$t|ƒnd¡ W n$ tyP } zW Y d}~n
d}~0 0 | jj| j| j|||d� 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`.
        N)r(   r)   )r~   r%   r‰   Úfloatr…   r€   r+   r&   )r*   r'   r(   r)   r³   r^   r    r    r!   r+   r  s    ÿÿûzMySQLSocket.send)Úread_timeoutr   c              
   C   sd   z,| j s*| jdur*| j |r$t|ƒnd¡ W n$ tyP } zW Y d}~n
d}~0 0 | j | j| j¡S )z.Get packet from the MySQL server comm channel.N)r~   r%   r‰   r´   r…   r€   r-   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)NNN)N)r.   r/   r0   r1   r>   r�   r‚   r†   rˆ   r   r4   rŠ   r   r   r–   Úboolr   r²   r3   r+   r5   r-   r   r¶   Úpropertyr&   r    r    r    r!   r}   ¿  sR   
&       ø

÷e   ûú r}   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‡   )rf   r>   r»   Ú_address)r*   r»   ri   r    r!   r>   ®  s    
zMySQLUnixSocket.__init__r8   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 n¬ t jt	fyt } z$t
d| jt|ƒfd�|‚W Y d }~ntd }~0  ty® } z$td| jt|ƒfd�|‚W Y d }~n:d }~0  tyÞ } ztt|ƒƒ|‚W Y d }~n
d }~0 0 d S )NiÒ  rG   )r2   ÚAF_UNIXÚSOCK_STREAMr%   r‰   r~   Úconnectr»   rJ   rK   r   r&   r"   rL   r   Ú	Exceptionr   )r*   r   r    r    r!   r¶   ·  s0    ýþþúÿþ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/   r0   r1   r   r>   r¸   r&   r¶   r   r–   r|   r    r    ri   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Ÿ   )rf   r>   r   Úserver_portrË   Ú_familyr¼   )r*   rŒ   rÊ   rË   ri   r    r!   r>   ß  s    
zMySQLTCPSocket.__init__r8   c                 C   s   | j S r‡   r½   r=   r    r    r!   r&   ì  s    zMySQLTCPSocket.addressc           	   
   C   sÖ  d}z�t  | 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u r~t	d| j› �ƒ‚|d du r’|d }W n@ t
yÔ } z(t	d| j| jt|ƒfd�|‚W Y d}~n
d}~0 0 |\| _}}}}z0t   | j||¡| _| j | j¡ | j |¡ W nº t jtf�y^ } z(td| j| jt|ƒfd�|‚W Y d}~n|d}~0  t
�yž } z(t	d| j| jt|ƒfd�|‚W Y d}~n<d}~0  t�yÐ } zt	t|ƒƒ|‚W Y d}~n
d}~0 0 dS )z/Open the TCP/IP connection to the MySQL server.)NNNNNr   NzNo IPv6 address found for iÓ  rG   )r2   Úgetaddrinfor   rÌ   r¿   ÚSOL_TCPrË   ÚAF_INET6ÚAF_INETr   rL   r"   rÍ   r%   r‰   r~   rÀ   rJ   rK   r   rÁ   r   )	r*   ZaddrinfoZ	addrinfosÚinfor   ÚsocktypeÚprotor^   Zsockaddrr    r    r!   r¶   ð  sh    
úûþýýþùþýzMySQLTCPSocket.open_connection)rÈ   rÉ   F)r.   r/   r0   r1   r   r4   r·   r>   r¸   r&   r¶   r|   r    r    ri   r!   rÇ   Ù  s      üûrÇ   )0r1   r2   r[   rÄ   ro   Úabcr   r   Úcollectionsr   Útypingr   r   r   r   r	   r
   r�   ÚPROTOCOL_TLSv1ÚPROTOCOL_TLSv1_1ÚPROTOCOL_TLSv1_2ÚPROTOCOL_TLSr¡   Úhasattrr   ZTLS_V1_3_SUPPORTEDÚImportErrorÚerrorsr   r   r   r   r   r   r   rt   rY   rb   rx   rL   r   r"   r#   r6   re   r}   r¹   rÇ   r    r    r    r!   Ú<module>   s@    ü
$
Ge C j1