U
    ec R                     @   s  d Z ddlZddlZddlZddlZddlZddlmZ zHddlZej	ej
ejdZeedrdejnejed< eedo|ejZW n ek
r   dZY nX d	d
lmZ d	dlmZmZmZ d	dlmZ dd Zdd ZG dd d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)deque)TLSv1TLSv1.1TLSv1.2PROTOCOL_TLSTLSv1.3HAS_TLSv1_3F   )MAX_PACKET_LENGTH)InterfaceErrorNotSupportedErrorOperationalError)init_bytearrayc                 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)err r   ;/tmp/pip-unpacked-wheel-ix8dg7li/mysql/connector/network.py_strioerror@   s    r   c                 C   s   g }t | }t}||krX|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
   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dd Z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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   s0   d | _ d | _d| _d| _t | _d | _d| _d S )Ni    )sock_connection_timeout_packet_number_compressed_packet_numberr   _packet_queueserver_hostZrecvsizeselfr   r   r   __init__a   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_numberj   s    
z"BaseMySQLSocket.next_packet_numberc                 C   s"   | j d | _ | j dkrd| _ | j S )z'Increments the compressed packet numberr	   r0   r   )r*   r-   r   r   r   next_compressed_packet_numberq   s    
z-BaseMySQLSocket.next_compressed_packet_numberc                 C   s   t dS )zOpen the socketNNotImplementedErrorr-   r   r   r   open_connectionx   s    zBaseMySQLSocket.open_connectionc                 C   s   t dS )zGet the location of the socketNr3   r-   r   r   r   get_address|   s    zBaseMySQLSocket.get_addressc              	   C   s>   z | j tj | j   | `W n ttfk
r8   Y nX dS )z&Shut down the socket before closing itN)r'   shutdownsocket	SHUT_RDWRcloser+   AttributeErrorOSErrorr-   r   r   r   r7      s    
zBaseMySQLSocket.shutdownc              	   C   s0   z| j   | `W n ttfk
r*   Y nX dS )zClose the socketN)r'   r:   r+   r;   r<   r-   r   r   r   close_connection   s
    
z BaseMySQLSocket.close_connectionc                 C   s   |    d S N)r7   r-   r   r   r   __del__   s    zBaseMySQLSocket.__del__Nc                 C   s   |}|dkr|    n|| _t|| j}|D ]~}z| j| W q, tk
r| } ztd|  t|fd|W 5 d}~X Y q, t	k
r } ztdd|W 5 d}~X Y q,X q,dS )z Send packets to the MySQL serverN  r   values  r   )
r1   r)   r$   r'   sendallIOErrorr   r6   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|    n|| _|dkr*|   n|| _| j}t|}g }t}||krt||}d|}	~t	|	dd }
t
dt|
dd t
d| j d }|||
  |	dd }	t|	}|   ||kr>t	|	d| }
t
dt|
dd t
d| j d	 }|||
  |	|d }	t|	}|   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 ]}z| j| W nl tk
r } ztd|  t|fd|W 5 d}~X Y n0 tk
r } ztdd|W 5 d}~X Y nX qhdS )z+Send compressed packets to the MySQL serverN     @  r   r   r   r   s    @ r   2   r@   rA   rC   rD   )r1   r)   r2   r*   r   r
   r$   joinzlibcompressr   r   r   r'   rE   rF   r   r6   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 rF| jd| }|s4tdd||7 }t|}q|d | _td|dd d d }|}|t | t	|}|dd	 }|r| j
||}|dkr|dkrtdd||d	 }||8 }q|W S  tk
r } ztd
|  t|fd|W 5 d	}~X Y nX d	S )z%Receive packets from the MySQL serverrM   r        rD   r   r       Nr@   rA   )	bytearrayr'   recvr   r   r)   r   unpackextend
memoryview	recv_intorF   r   r6   r   )	r.   rK   Z
packet_lenchunkZpayload_lenrestZpacket_viewreadr   r   r   r   
recv_plain   s:    




 zBaseMySQLSocket.recv_plainc                 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_payload  s    z%BaseMySQLSocket._split_zipped_payloadc              
   C   sF  z| j  }|d | _|W S  tk
r.   Y nX td}g }z`| jd}|rrt|dk rr||7 }| jd}qL|rt|dk rtddt	
d|dd d	 d }|d | _t	
d|d
d d	 d }t|}t||k r| j|t| }|s
tdd|| }q|dkrB| | | j  }|d | _|W S |||f |dkr^qtd}| jd}|rrt|dk rr||7 }| jd}qrqrW n> tk
r }	 ztd|  t|	fd|	W 5 d}	~	X Y nX td}
|D ]\}}|
t|7 }
q| |
 ~
z| j  }|d | _|W S  tk
r@   Y nX dS )z0Receive compressed packets from the MySQL serverr   rM   r	      rW   rD   r   r   rX   rV   rN   r@   rA   N)r+   popleftr)   
IndexErrorrY   r'   rZ   r   r   r   r[   r*   r   rd   r   rF   r   r6   r   rQ   
decompress)r.   rT   rS   rJ   ZabyteZzip_payload_lengthrc   Zzip_payloadr_   r   tmppayloadr   r   r   recv_compressed"  sp    










 


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_timeoutm  s    z&BaseMySQLSocket.set_connection_timeoutFc                 C   s  | j stddz|r tj}n|r,tj}ntj}|dks>|sRt }	|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 nD ttjfk
rT } z| j   td| |W 5 d}~X Y nX |rz|	|| W nD 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rJ| jdkrJd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qV|s| j   tdd&| W n t'k
r } zt(d|W 5 d}~X Y n tjtfk
rJ } ztd| ) t*|fd|W 5 d}~X Y nd 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 )zSwitch the socket to use SSLi   rD   NFT)reverser   r   r	   r   r   r   zInvalid CA Certificate: zInvalid Certificate/Key: r,   )server_hostnament	localhost	127.0.0.1z"Unable to verify server identity: z, z&Python installation has no SSL supportr@   rA   ),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_locationsrF   SSLErrorr:   load_cert_chainset_ciphershasattrwrap_socketr,   osnamer8   gethostbyaddrr\   match_hostnamegetpeercertCertificateErrorr   r   rP   	NameErrorr   r6   r   r4   )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_ssls  s    



"
"
 
 

 zBaseMySQLSocket.switch_to_ssl)NN)NN)FFNN)__name__
__module____qualname____doc__r/   r1   r2   r5   r6   r7   r=   r?   rL   sendrU   rb   rZ   rd   rk   rn   r   r   r   r   r   r%   X   s,   		

N"K    r%   c                       s:   e Zd ZdZd fdd	Z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    || _d S r>   )superr/   unix_socket)r.   r   	__class__r   r   r/     s    
zMySQLUnixSocket.__init__c                 C   s   | j S r>   )r   r-   r   r   r   r6     s    zMySQLUnixSocket.get_addressc              
   C   s   z2t  t jt j| _| j| j | j| j W nj tk
rn } zt	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  rA   )r8   AF_UNIXSOCK_STREAMr'   rl   r(   connectr   rF   r   r6   r   	Exceptionr   )r.   r   r   r   r   r5     s     zMySQLUnixSocket.open_connectionc                 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.   argskwargsr   r   r   r     s    zMySQLUnixSocket.switch_to_ssl)r   )	r   r   r   r   r/   r6   r5   r   __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.
    rs     Fc                    s&   t    || _|| _|| _d| _d S )Nr   )r   r/   r,   server_port
force_ipv6_family)r.   hostportr   r   r   r   r/   
  s
    
zMySQLTCPSocket.__init__c                 C   s   | j  d| j S )N:)r,   r   r-   r   r   r   r6     s    zMySQLTCPSocket.get_addressc           	   
   C   s  dgd }zt | j| jdt jt j}|D ]6}| jrJ|d t jkrJ|} qb|d t jkr*|} qbq*| jr|d dkrt	d| j |d dkr|d }W n< t
k
r } zt	d|  t|fd|W 5 d}~X Y nX |\| _}}}}z0t  | j||| _| j| j | j| W np t
k
rX } 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 serverN   r   zNo IPv6 address found for i  rA   )r8   getaddrinfor,   r   r   SOL_TCPr   AF_INET6AF_INETr   rF   r6   r   r   r'   rl   r(   r   r   r   r   )	r.   ZaddrinfoZ	addrinfosinfor   socktypeprotorI   Zsockaddrr   r   r   r5     sX    
 zMySQLTCPSocket.open_connection)rs   r   F)r   r   r   r   r/   r6   r5   r   r   r   r   r   r     s   r   ) r   r   r8   r   r   rQ   collectionsr   rt   PROTOCOL_TLSv1PROTOCOL_TLSv1_1PROTOCOL_TLSv1_2r|   r   r   PROTOCOL_SSLv23r   r{   ImportError	constantsr
   errorsr   r   r   utilsr   r   r$   r%   r   r   r   r   r   r   <module>   s<   

   !