o
    g1v                     @   sX  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 zddlZejejejejdZeedoGejZW n eyV   dZdZY nw 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&de'de(f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   )ConnectionTimeoutErrorInterfaceErrorNotSupportedErrorOperationalErrorProgrammingErrorReadTimeoutErrorWriteTimeoutError2   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    Q/var/www/html/api-tag/env/lib/python3.10/site-packages/mysql/connector/network.py_strioerrorJ   s   "r"   c                   @   sb   e Zd ZdZe		ddejdededee	 dee	 ddfd	d
Z
edejdedef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      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!   sendj       zNetworkBroker.sendc                 C   r)   )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   r,   zNetworkBroker.recvNN)__name__
__module____qualname____doc__r   socketr   bytesr   intr+   	bytearrayr-   r    r    r    r!   r#   R   s(    r#   c                   @   s   e Zd ZdZdddZdddZdejd	ed
eddfddZ	ddejde
defddZ		ddejd	ededee
 dee
 ddfddZdejd	edefddZdS )NetworkBrokerPlain,Broker class for MySQL socket communication.r   Nc                 C   s
   d| _ d S N_pktnrr*   r    r    r!   __init__   s   
zNetworkBrokerPlain.__init__c                 C      | j d d | _ dS zIncrement packet id.r      Nr;   r=   r    r    r!   _set_next_pktnr      z"NetworkBrokerPlain._set_next_pktnrr$   r%   pktc              
   C   s   z| | W dS  tjtfy } ztdd|d}~w ty3 } ztd|t|fd|d}~w tyD } ztdd|d}~ww )z!Write packet to the comm channel.  r   N  r   valuesi  )	sendallr3   timeoutTimeoutErrorr   IOErrorr   r"   AttributeError)r*   r$   r%   rD   r   r    r    r!   	_send_pkt   s    zNetworkBrokerPlain._send_pktr   sizec                 C   sV   t |}t|}|r)|||}|dkr|dkrtdd||d }||8 }|s
|S )z(Read `size` bytes from the comm channel.r   i  rF   N)r6   
memoryview	recv_intor   )r*   r$   rP   rD   pkt_viewreadr    r    r!   _recv_chunk   s   
zNetworkBrokerPlain._recv_chunkr&   r'   r(   c              
   C   s   |du r	|    n|| _t|tkrCd}tt|t D ] }| ||dtd| j |||t    |    |t7 }q||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   )rB   r<   lenMAX_PAYLOAD_LENGTHrangerO   structpack)r*   r$   r%   r&   r'   r(   offset_r    r    r!   r+      s6   

zNetworkBrokerPlain.sendc              
   C   s   z%| j |td}td|dd d d |d }| _|| j ||d W S  tjtfy< } ztd|j	d|d}~w t
yR } ztd	|t|fd
|d}~ww )z+Receive `one` packet from the MySQL server.rP   rX   r   rY       rE   )r   msgNrG   rH   )rU   PACKET_HEADER_LENGTHr]   unpackr<   r3   rK   rL   r   r   rM   r   r"   )r*   r$   r%   headerpayload_lenr   r    r    r!   r-      s"   zNetworkBrokerPlain.recvr   N)r   r.   )r/   r0   r1   r2   r>   rB   r3   r   r4   rO   r5   r6   rU   r   r+   r-   r    r    r    r!   r7      s,    


,r7   c                       s   e Zd ZdZd fddZedededee fdd	Z	dd
dZ
dejdededdf fddZ		ddejdededee dee ddf fddZdejdededdf fddZdejdedef fddZ  ZS )NetworkBrokerCompressedr8   r   Nc                    s   t    d| _t | _d S r9   )superr>   _compressed_pktnrr   _queue_readr=   	__class__r    r!   r>     s   
z NetworkBrokerCompressed.__init__r&   pktnrc                 C   s   g }t | tkr8d}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   rV   rW   r   rA   NrX   rY   )rZ   r[   r\   appendr]   r^   )r&   ro   pktsr_   r`   r    r    r!   _prepare_packets  s$   

&z(NetworkBrokerCompressed._prepare_packetsc                 C   r?   r@   )rk   r=   r    r    r!   _set_next_compressed_pktnr   rC   z2NetworkBrokerCompressed._set_next_compressed_pktnrr$   r%   rD   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.rX   r   rY   rW   )zlibcompressr]   r^   rZ   rk   rj   rO   )r*   r$   r%   rD   compressed_pktrm   r    r!   rO   $  s   
z!NetworkBrokerCompressed._send_pktr'   r(   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 }q6| ||||d  dS t|tkrj| ||| dS t ||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   rX   rY   rW   )rB   r<   rs   rk   r6   joinrr   rZ   r[   rd   r\   rO   MIN_COMPRESS_LENGTHrj   r]   r^   )	r*   r$   r%   r&   r'   r(   payload_prepr_   r`   rm   r    r!   r+   /  s:   


zNetworkBrokerCompressed.sendcompressed_plluncompressed_pllc           	         s.  t  j||d}|dkr|ntt|}d}|t|k rtd|||t d  d d }t| t|| kryt  j|t	d}td|dd d d |d td|dd d d }| _
}t  j||d}||dkrs|nt|7 }| j|||t |   |t| 7 }|t|k sd	S d	S )
z&Handle reading of a compressed packet.ra   r   rX   r   rb   rY   r   r   N)rj   rU   r6   rt   
decompressrZ   r]   re   rd   COMPRESSED_PACKET_HEADER_LENGTHrk   rl   rp   )	r*   r$   r{   r|   rv   rD   r_   pllrf   rm   r    r!   _recv_compressed_pktl  s>   z,NetworkBrokerCompressed._recv_compressed_pktc              
      s   | j scz4t j|td}td|dd d d |d td|dd d d }| _}| ||| W n+ tj	t
fyL } ztdd	|d
}~w tyb } ztd|t|fd|d
}~ww | j shd
S | j  }|d | _|S )z{Receive `one` or `several` packets from the MySQL server, enqueue them, and
        return the packet at the head.
        ra   rX   r   rY   rb   r   r   rE   rF   NrG   rH   )rl   rj   rU   r~   r]   re   rk   r   r3   rK   rL   r   rM   r   r"   popleftr<   )r*   r$   r%   rf   r{   r|   r   rD   rm   r    r!   r-     s8   

zNetworkBrokerCompressed.recvrh   r.   )r/   r0   r1   r2   r>   staticmethodr4   r5   r   rr   rs   r3   r   rO   r   r+   r   r6   r-   __classcell__r    r    rm   r!   ri      s@    
 =$0ri   c                   @   s:  e Zd ZdZd,ddZd,ddZd,dd	Zd,d
dZd,ddZde	e
 ddfddZdededdfddZ							d-de	e de	e de	e de	e de	e de	ee  de	ee  defddZ			d.ded e	e
 d!e	e
 d"e	e
 ddf
d#d$Zd/d%e	e
 defd&d'Zed,d(d)Zeedefd*d+ZdS )0MySQLSocketzMySQL socket communication interface.

    Examples:
        Subclasses: network.MySQLTCPSocket and network.MySQLUnixSocket.
    r   Nc                 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_hostr7   
_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)ri   r   r=   r    r    r!   switch_to_compressed_mode  s   z%MySQLSocket.switch_to_compressed_modec              	   C   s8   z| j tj | j   W dS  ttfy   Y dS w )z'Shut down the socket before closing it.N)r$   shutdownr3   	SHUT_RDWRcloserN   OSErrorr=   r    r    r!   r     s   zMySQLSocket.shutdownc              	   C   s*   z| j   W dS  ttfy   Y dS w )zClose the socket.N)r$   r   rN   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__rK   c                 C   s    || _ | jr| j| dS dS )zSet the connection timeout.N)r   r$   
settimeout)r*   rK   r    r    r!   set_connection_timeout  s   z"MySQLSocket.set_connection_timeoutssl_contexthostc              
   C   s   | j dusJ | j jdkrtdtdu rtdz|j| j |d| _ W dS  ty6 } ztd|d}~w tjtfyP } zt	d| j
t|fd|d}~w tjyc } zt	t||d}~w tyu } zt	t||d}~ww )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_hostnamerG   rH   )r$   familyr   sslr   wrap_socket	NameErrorSSLErrorrM   r   r%   r"   CertificateErrorr   NotImplementedError)r*   r   r   r   r    r    r!   switch_to_ssl  s0   
zMySQLSocket.switch_to_sslFssl_cassl_certssl_keyssl_verify_certssl_verify_identitytls_versionstls_cipher_suitesc                 C   s  d}| j s
tddtdu rtd|du rg }|du rg }z|r]|jdd |d }t| }	t|	}
|dkr\d	|vrD|
 jtjO  _d
|vrP|
 jtj	O  _d|vr\|
 jtj
O  _nt }
||
_|rktj|
_n|rrtj|
_ntj|
_|
  |rz|
| W n ttjfy } ztd| |d}~ww |rz|
|| W n ttjfy } ztd| |d}~ww |r|d	kr|
d| |
W S  ty } ztd|d}~w tttjtjfy } ztt||d}~ww )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   rF   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_locationsrM   r   load_cert_chainset_ciphersrx   r   r   r   r   )r*   r   r   r   r   r   r   r   tls_versionssl_protocolcontextr   r    r    r!   build_ssl_context  sx   




zMySQLSocket.build_ssl_contextr&   r'   r(   write_timeoutc              
   C   sp   z| j s| jdur| j|rt|nd W n ty( } zW Y d}~nd}~ww | 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+   s  s"   

zMySQLSocket.sendread_timeoutc              
   C   sd   z| j s| jdur| j|rt|nd W n ty( } zW Y d}~nd}~ww | 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   r)   )zOpen the socket.Nr    r=   r    r    r!   open_connection  r,   zMySQLSocket.open_connectionc                 C   r)   )zGet the location of the socket.Nr    r=   r    r    r!   r%     r,   zMySQLSocket.addressrh   )NNNFFNN)NNNr   )r/   r0   r1   r2   r>   r   r   r   r   r   r5   r   r   r   r   boolr   r   r4   r+   r6   r-   r   r   propertyr%   r    r    r    r!   r     sj    





&

	
e
 r   c                       s^   e Zd ZdZddeddf fddZedefdd	Zdd
dZde	de	ddfddZ
  ZS )MySQLUnixSocketzpMySQL socket class using UNIX sockets.

    Opens a connection through the UNIX socket of the MySQL Server.
    /tmp/mysql.sockunix_socketr   Nc                    s   t    || _|| _d S r   )rj   r>   r   _address)r*   r   rm   r    r!   r>     s   

zMySQLUnixSocket.__init__c                 C      | j S r   r   r=   r    r    r!   r%        zMySQLUnixSocket.addressc              
   C   s   zt  t jt j| _| j| j | j| j W d S  t jt	fy5 } zt
d| jt|fd|d }~w tyL } ztd| jt|fd|d }~w ty^ } ztt||d }~ww )N  rH   )r3   AF_UNIXSOCK_STREAMr$   r   r   connectr   rK   rL   r   r%   r"   rM   r   	Exceptionr   )r*   r   r    r    r!   r     s8   zMySQLUnixSocket.open_connectionargskwargsc                 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   rh   )r/   r0   r1   r2   r   r>   r   r%   r   r   r   r   r    r    rm   r!   r     s    
r   c                	       sV   e Zd ZdZ			ddedededd	f fd
dZedefddZ	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  Fr   port
force_ipv6r   Nc                    s6   t    || _|| _|| _d| _| d| | _d S )Nr   r   )rj   r>   r   server_portr   _familyr   )r*   r   r   r   rm   r    r!   r>     s   
zMySQLTCPSocket.__init__c                 C   r   r   r   r=   r    r    r!   r%     r   zMySQLTCPSocket.addressc           	   
   C   s  d}zHt | j| jdt jt j}|D ]}| jr"|d t jkr"|} n|d t jkr-|} nq| jr?|d du r?t	d| j |d du rI|d }W n t
yd } zt	d| j| jt|fd|d}~ww |\| _}}}}zt  | j||| _| j| j | j| W dS  t jtfy } ztd| j| jt|fd|d}~w t
y } zt	d| j| jt|fd|d}~w ty } ztt||d}~ww )z/Open the TCP/IP connection to the MySQL server.)NNNNNr   NzNo IPv6 address found for i  rH   r   )r3   getaddrinfor   r   r   SOL_TCPr   AF_INET6AF_INETr   rM   r"   r   r$   r   r   r   rK   rL   r   r   r   r   )	r*   addrinfo	addrinfosinfor   socktypeprotor`   sockaddrr    r    r!   r     s~   
zMySQLTCPSocket.open_connection)r   r   Frh   )r/   r0   r1   r2   r   r5   r   r>   r   r%   r   r   r    r    rm   r!   r     s"    r   )0r2   r3   r]   r   rt   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   r   r   r   ry   r[   rd   r~   rM   r   r"   r#   r7   ri   r   r   r   r    r    r    r!   <module>   sD    $
Ge C j1