U
    f<V                     @   s  d Z ddlmZ ddlZddlZddlZddlZddlZzXddlZej	ej
ejdZeedrjejed< n
ejed< eedrejrdZnd	ZW n   d	ZY nX d
dlmZmZ d
dlmZ d
dlmZ dd Zdd 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.
    )dequeN)TLSv1TLSv1.1TLSv1.2PROTOCOL_TLSTLSv1.3HAS_TLSv1_3TF   )	constantserrors)InterfaceError)init_bytearrayc                 C   s    | j st| S dj| j | jdS )z_Reformat the IOError error message

    This function reformats the IOError error message.
    z{errno} {strerr})errnoZstrerr)r   strformatstrerror)err r   ;/tmp/pip-unpacked-wheel-mzf9r1ws/mysql/connector/network.py_strioerror@   s    r   c                 C   s   g }t | }tj}||krZ|dtd| | d|   | |d } t | }|d }q|td|dd td| |   |S )z0Prepare a packet for sending to the MySQL server   <BNr	   <Ir      )lenr
   MAX_PACKET_LENGTHappendstructpack)bufpktnrpktspllen	maxpktlenr   r   r   _prepare_packetsJ   s     


r$   c                   @   s   e Zd ZdZdd Zedd Zedd Zdd	 Zd
d Z	dd Z
dd Zdd Zd'ddZeZd(ddZdd Zdd Zejdd dkreZeZneZdd Zd d! Zd"d# Zd)d%d&ZdS )*BaseMySQLSocketa  Base class for MySQL socket communication

    This class should not be used directly but overloaded, changing the
    at least the open_connection()-method. Examples of subclasses are
      mysql.connector.network.MySQLTCPSocket
      mysql.connector.network.MySQLUnixSocket
    c                 C   s*   d | _ d | _d| _d| _t | _d| _d S )Ni    )sock_connection_timeout_packet_number_compressed_packet_numberr   _packet_queueZrecvsizeselfr   r   r   __init__c   s    zBaseMySQLSocket.__init__c                 C   s"   | j d | _ | j dkrd| _ | j S )zIncrements the packet numberr	      r   )r)   r,   r   r   r   next_packet_numberk   s    
z"BaseMySQLSocket.next_packet_numberc                 C   s"   | j d | _ | j dkrd| _ | j S )z'Increments the compressed packet numberr	   r/   r   )r*   r,   r   r   r   next_compressed_packet_numbers   s    
z-BaseMySQLSocket.next_compressed_packet_numberc                 C   s   t dS )zOpen the socketNNotImplementedErrorr,   r   r   r   open_connection{   s    zBaseMySQLSocket.open_connectionc                 C   s   t dS )zGet the location of the socketNr2   r,   r   r   r   get_address   s    zBaseMySQLSocket.get_addressc              	   C   s@   z | j tj | j   | `W n tjtfk
r:   Y nX dS )z&Shut down the socket before closing itN)r'   shutdownsocket	SHUT_RDWRcloser+   errorAttributeErrorr,   r   r   r   r6      s    
zBaseMySQLSocket.shutdownc              	   C   s2   z| j   | `W n tjtfk
r,   Y nX dS )zClose the socketN)r'   r9   r+   r7   r:   r;   r,   r   r   r   close_connection   s
    
z BaseMySQLSocket.close_connectionc                 C   s   |    d S N)r6   r,   r   r   r   __del__   s    zBaseMySQLSocket.__del__Nc                 C   s   |dkr| j  n|| _t|| j}|D ]p}z| j| W q& tk
rv } ztjd|  t	|fdW 5 d}~X Y q& t
k
r   tjddY q&X q&dS )z Send packets to the MySQL serverN  r   values  r   )r0   r)   r$   r'   sendallIOErrorr   OperationalErrorr5   r   r;   )r-   r   packet_numbercompressed_packet_numberpacketspacketr   r   r   r   
send_plain   s     zBaseMySQLSocket.send_plainc                 C   s  |dkr| j  n|| _|dkr&| j n|| _| j}t|}g }tj}||krt||}d|}	~t	
|	dd }
tdt|
dd td| j d }|||
  |	dd }	t|	}| j ||kr8t	
|	d| }
tdt|
dd td| j d	 }|||
  |	|d }	t|	}| j q|	rt	
|	}
tdt|
dd td| j td|dd  }|||
  ~	ntd|dd td| | }t|}|d
krt	
|}
|tdt|
dd td| j td|dd  |
  nDtd|dd td| j tdddd  }|||  |D ]v}z| j| W n^ tk
r } ztjd|  t|fdW 5 d}~X Y n" tk
r   tjddY nX qbdS )z+Send compressed packets to the MySQL serverN     @  r   r   r   r   s    @ r   2   r?   r@   rB   rC   )r0   r)   r1   r*   r   r
   r   r$   joinzlibcompressr   r   r   r'   rD   rE   r   rF   r5   r   r;   )r-   r   rG   rH   r    r"   Zzpktsr#   r!   ZtmpbufZzbufheaderpktZ
zip_packetr   r   r   r   send_compressed   s    







 zBaseMySQLSocket.send_compressedc           	   
   C   s   zt d}d}|dk rH| jd| }|s6tjdd||7 }t|}q|d | _td|dd d d }|}|	t | t
|}|dd	 }|r| j||}|dkr|dkrtjdd||d	 }||8 }q|W S  tk
r } ztjd
|  t|fdW 5 d	}~X Y nX d	S )%Receive packets from the MySQL serverrL   r        rC   r   r       Nr?   r@   )	bytearrayr'   recvr   r   r   r)   r   unpackextend
memoryview	recv_intorE   rF   r5   r   )	r-   rJ   Z
packet_lenchunkpayload_lenrestZpacket_viewreadr   r   r   r   
recv_plain   s6    


 zBaseMySQLSocket.recv_plainc              
   C   s   zt d}d}|dk rH| jd| }|s6tjdd||7 }t|}q|d | _td|dd d d }|}t	d}|dkr| j|}|stjdd||7 }|t| }qz|| W S  t
k
r } ztjd	|  t|fd
W 5 d}~X Y nX dS )rU   rL   r   rV   rW   rC   r   r   rX   r?   r@   N)rY   r'   rZ   r   r   r   r)   r   r[   r   rE   rF   r5   r   )r-   rR   Z
header_lenr_   r`   ra   payloadr   r   r   r   recv_py26_plain  s2    


 zBaseMySQLSocket.recv_py26_plainr      )rf      c                 C   sN   |rJt d|dd d d }| j|d|d   ||d d }q dS )zSplit compressed payloadr   r   r   rX   rV   N)r   r[   r+   r   )r-   Zpacket_bunchpayload_lengthr   r   r   _split_zipped_payload5  s    z%BaseMySQLSocket._split_zipped_payloadc              
   C   sJ  z| j  }|d | _|W S  tk
r.   Y nX td}g }zd| jd}|rrt|dk rr||7 }| jd}qL|rt|dk rtj	ddt
d|dd d	 d }|d | _t
d|d
d d	 d }t|}t||k r| j|t| }|stj	dd|| }q|dkrF| | | j  }|d | _|W S |||f |dkrbqtd}| jd}|rrt|dk rr||7 }| jd}qvqrW n> tk
r }	 ztjd|  t|	fdW 5 d}	~	X Y nX td}
|D ]\}}|
t|7 }
q| |
 ~
z| j  }|d | _|W S  tk
rD   Y nX dS )z0Receive compressed packets from the MySQL serverr   rL   r	      rW   rC   r   r   rX   rV   rM   r?   r@   N)r+   popleftr)   
IndexErrorrY   r'   rZ   r   r   r   r   r[   r*   r   ri   r   rE   rF   r5   r   rP   
decompress)r-   rS   rR   rI   ZabyteZzip_payload_lengthrh   Zzip_payloadr_   r   tmprd   r   r   r   recv_compressed<  sx    








 


zBaseMySQLSocket.recv_compressedc                 C   s   || _ | jr| j| dS )zSet the connection timeoutN)r(   r'   
settimeout)r-   timeoutr   r   r   set_connection_timeout  s    z&BaseMySQLSocket.set_connection_timeoutFc                 C   s  | j stjddz|r"tj}n|r.tj}ntj}|dks@|sTt }	|sd|	_n|j	dd |d }
t
s|
dkrt|d	kr|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  _d|	_||	_|	  |rVz|	| W nB ttjfk
rT } z| j   td|W 5 d}~X Y nX |rz|	|| W nB ttjfk
r } z| j   td|W 5 d}~X Y nX |r|	| t| dr|	j| j | jd| _ n|	| j | _ |rd|	_| jg}tjdkrH| jdkrHddg}t !| j}|"|d g|d	   d}g }|D ]\}zt#| j $ | W n4 tj%k
r } z|&t'| W 5 d}~X Y nX d} qqT|s| j   tdd(|W n t)k
r   t*dY n tjtfk
r: } ztjd| + t,|fdW 5 d}~X Y nd tj%k
rl } ztt'|W 5 d}~X Y n2 t-k
r } ztt'|W 5 d}~X Y nX dS )zSwitch the socket to use SSLi   rC   NFT)reverser   r   r	   r   r   r   zInvalid CA Certificate: {}zInvalid Certificate/Key: {}server_host)server_hostnament	localhost	127.0.0.1z$Unable to verify server identity: {}z, z&Python installation has no SSL supportr?   r@   ).r'   r   r   sslCERT_REQUIREDCERT_OPTIONAL	CERT_NONEcreate_default_contextcheck_hostnamesortTLS_V1_3_SUPPORTEDr   TLS_VERSIONS
SSLContextoptionsOP_NO_TLSv1_2OP_NO_TLSv1_1OP_NO_TLSv1verify_modeload_default_certsload_verify_locationsrE   SSLErrorr9   r   load_cert_chainset_ciphershasattrwrap_socketrt   osnamer7   gethostbyaddrr\   match_hostnamegetpeercertCertificateErrorr   r   rO   	NameErrorZNotSupportedErrorr5   r   r3   )r-   cacertkeyZverify_certZverify_identityZcipher_suitesZtls_versions	cert_reqscontextZtls_versionZssl_protocolr   Z	hostnamesaliasesZmatch_foundZerrshostnamer   r   r   switch_to_ssl  s    




 
 


 zBaseMySQLSocket.switch_to_ssl)NN)NN)FFNN)__name__
__module____qualname____doc__r.   propertyr0   r1   r4   r5   r6   r<   r>   rK   sendrT   rc   re   sysversion_inforZ   ri   ro   rr   r   r   r   r   r   r%   Z   s@   

	  
  
E!L     r%   c                       s2   e Zd ZdZd	 fdd	Zdd Zdd Z  ZS )
MySQLUnixSocketzoMySQL socket class using UNIX sockets

    Opens a connection through the UNIX socket of the MySQL Server.
    /tmp/mysql.sockc                    s   t t|   || _d S r=   )superr   r.   unix_socket)r-   r   	__class__r   r   r.     s    zMySQLUnixSocket.__init__c                 C   s   | j S r=   )r   r,   r   r   r   r5     s    zMySQLUnixSocket.get_addressc              
   C   s   z2t  t jt j| _| j| j | j| j W nj tk
rn } zt	j
d|  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  r@   )r7   AF_UNIXSOCK_STREAMr'   rp   r(   connectr   rE   r   r   r5   r   	Exceptionr   )r-   r   r   r   r   r4      s     zMySQLUnixSocket.open_connection)r   r   r   r   r   r.   r5   r4   __classcell__r   r   r   r   r     s   r   c                       s2   e Zd ZdZd fdd	Zdd Zd	d
 Z  ZS )MySQLTCPSocketzXMySQL socket class using TCP/IP

    Opens a TCP/IP connection to the MySQL Server.
    rx     Fc                    s*   t t|   || _|| _|| _d| _d S )Nr   )r   r   r.   rt   server_port
force_ipv6_family)r-   hostportr   r   r   r   r.     s
    zMySQLTCPSocket.__init__c                 C   s   d | j| jS )Nz{0}:{1})r   rt   r   r,   r   r   r   r5     s    zMySQLTCPSocket.get_addressc           	   
   C   s  dgd }zt | j| jdt jt j}|D ]8}| jrL|d t jkrL|} qdq*|d t jkr*|} qdq*| jr|d dkrt	
d| j|d dkr|d }W n< tk
r } zt	j
d|  t|fdW 5 d}~X Y nX |\| _}}}}z0t  | j||| _| j| j | j| W np tk
r\ } z t	j
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 )z7Open the TCP/IP connection to the MySQL server
        N   r   zNo IPv6 address found for {0}i  r@   )r7   getaddrinfort   r   r   SOL_TCPr   AF_INET6AF_INETr   r   r   rE   r5   r   r   r'   rp   r(   r   r   rF   r   )	r-   ZaddrinfoZ	addrinfosinfor   socktypeproto_Zsockaddrr   r   r   r4     sR    
 
 zMySQLTCPSocket.open_connection)rx   r   Fr   r   r   r   r   r     s   r   )r   collectionsr   r   r7   r   r   rP   ry   PROTOCOL_TLSv1PROTOCOL_TLSv1_1PROTOCOL_TLSv1_2r   r   r   PROTOCOL_SSLv23r   r    r
   r   r   utilsr   r   r$   objectr%   r   r   r   r   r   r   <module>   s@   


   