3
(h[              
   @   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yXd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mZ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)TLSv1zTLSv1.1zTLSv1.2PROTOCOL_TLSzTLSv1.3HAS_TLSv1_3TF   )	constantserrors)InterfaceError)PY2init_bytearraystruct_unpackc             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   K/tmp/pip-install-q3hcpn_q/mysql-connector-python/mysql/connector/network.py_strioerror@   s    r   c             C   s   g }t | }tj}xJ||kr\|jdtjd| | d|   | |d } t | }|d }qW |jtjd|dd tjd| |   |S )z0Prepare a packet for sending to the MySQL servers   z<BNr   z<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 )Nr   i    r"   )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)NotImplementedError)r(   r   r   r   open_connection{   s    zBaseMySQLSocket.open_connectionc             C   s   t dS )zGet the location of the socketN)r-   )r(   r   r   r   get_address   s    zBaseMySQLSocket.get_addressc             C   s@   y | j jtj | 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AttributeError)r(   r   r   r   r0      s    
zBaseMySQLSocket.shutdownc             C   s2   y| j j  | `W n tjtfk
r,   Y nX dS )zClose the socketN)r#   r3   r'   r1   r4   r5   )r(   r   r   r   close_connection   s
    
z BaseMySQLSocket.close_connectionc             C   s   | j   d S )N)r0   )r(   r   r   r   __del__   s    zBaseMySQLSocket.__del__Nc             C   s   |dkr| j  n|| _t|| j}x|D ]}y&trD| jjt| n| jj| W q( tk
r } z tj	d| j
 t|fdW Y dd}~X q( tk
r   tj	ddY q(X q(W dS )z Send packets to the MySQL serverNi  )r   valuesi  )r   )r+   r%   r    r
   r#   sendallbufferIOErrorr   OperationalErrorr/   r   r5   )r(   r   packet_numbercompressed_packet_numberpacketspacketr   r   r   r   
send_plain   s    
&zBaseMySQLSocket.send_plainc             C   sV  |dkr| j  n|| _|dkr&| j n|| _| j}t|}g }tj}||krt||}trt	 }	x|D ]}
|	|
7 }	qhW t
|	}	n
dj|}	~tj|	dd }tjdt|dd tjd| j d }trt
|}|j||  |	dd }	t|	}| j x||krtj|	d| }tjdt|dd tjd| j d	 }trTt
|}|j||  |	|d }	t|	}| j q W |	rtj|	}tjdt|dd tjd| j tjd|dd  }trt
|}|j||  ~	ntjd|dd tjd| | }
trt
|
}
t|
}|d
krtj|
}|jtjdt|dd tjd| j tjd|dd  |  nRtjd|dd tjd| j tjdddd  }trt
|}|j||
  x~|D ]v}y| jj| W n^ tk
r* } z tjd| j t|fdW Y dd}~X n" tk
rJ   tjddY nX qW dS )z+Send compressed packets to the MySQL serverN    i @  z<Ir   r   z<Bs    @ s   2   i  )r   r8   i  )r   )r+   r%   r,   r&   r   r   r   r    r
   	bytearrayr:   joinzlibcompressr   r   r   r#   r9   r;   r   r<   r/   r   r5   )r(   r   r=   r>   r   r   Zzpktsr   r   ZtmpbufpktZzbufheaderZ
zip_packetr   r   r   r   send_compressed   s~    




**
:$

B6
&zBaseMySQLSocket.send_compressedc       	      C   sP  y
t d}d}x<|dk rL| jjd| }|s:tjdd||7 }t|}qW |d | _tr~tj	dt
|dd d d }ntjd|dd d d }|}|jt | t|}|dd	 }xH|r| jj||}|dkr|dkrtjdd||d	 }||8 }qW |S  tk
rJ } z tjd
| j t|fdW Y d	d	}~X nX d	S )z%Receive packets from the MySQL serverrB   r      i  )r   r   z<I    Ni  )r   r8   )rD   r#   recvr   r	   r   r%   r
   r   unpack_fromr:   unpackextend
memoryview	recv_intor;   r<   r/   r   )	r(   r@   Z
packet_lenchunkpayload_lenrestZpacket_viewreadr   r   r   r   
recv_plain  s:    

zBaseMySQLSocket.recv_plainc             C   s  yt d}d}x<|dk rJ| jjd| }|s8tjdd||7 }t|}qW |d | _td|dd d d }|}td}x<|dkr| jj|}|stjdd||7 }|t| }q~W || S  t	k
 r } z tj
d	| j t|fd
W Y dd}~X nX dS )z%Receive packets from the MySQL serverrB   r   rK   i  )r   r   z<IrL   i  )r   r8   N)rD   r#   rM   r   r	   r   r%   r   r   r;   r<   r/   r   )r(   rI   Z
header_lenrS   rT   rU   payloadr   r   r   r   recv_py26_plain(  s.    


zBaseMySQLSocket.recv_py26_plainr         c             C   st   xn|rnt r(tjd|dd d d }ntjd|dd d d }| jj|d|d   ||d d }qW dS )zSplit compressed payloadz<Ir   r   rL   rK   N)r
   r   rN   rO   r'   r   )r(   Zpacket_bunchpayload_lengthr   r   r   _split_zipped_payloadM  s    z%BaseMySQLSocket._split_zipped_payloadc          !   C   sr  y| j j }|d | _|S  tk
r,   Y nX td}g }yr| jjd}x(|rrt|dk rr||7 }| jjd}qLW x4|rt|dk rtj	ddt
d|dd d	 d }|d | _t
d|d
d d	 d }t|}x@t||k r| jj|t| }|stj	dd|| }qW |dkrJ| j| | j j }|d | _|S |j||f |dkrdP td}| jjd}x.|rt|dk r||7 }| jjd}qzW qxW W n> tk
r }	 z tjd| j t|	fdW Y dd}	~	X nX td}
x:|D ]2\}}tr|
tjt|7 }
n|
tj|7 }
qW | j|
 ~
y| j j }|d | _|S  tk
rl   Y nX dS )z0Receive compressed packets from the MySQL serverr   rB   r      i  )r   z<Ir   rL   rK   i @  i  )r   r8   N)r'   popleftr%   
IndexErrorrD   r#   rM   r   r   r	   r   r&   r   r]   r   r;   r<   r/   r   r
   rF   
decompressr:   )r(   rH   rI   r?   ZabyteZzip_payload_lengthr\   Zzip_payloadrS   r   tmprX   r   r   r   recv_compressedZ  sp    








(


zBaseMySQLSocket.recv_compressedc             C   s   || _ | jr| jj| dS )zSet the connection timeoutN)r$   r#   
settimeout)r(   timeoutr   r   r   set_connection_timeout  s    z&BaseMySQLSocket.set_connection_timeoutFc          3   C   s  | j stjddy|r"tj}n|r.tj}ntj}|dksB| rVtj }	|sd|	_n|j	dd |d }
t
 r|
dkrt|d	kr|d	 }
t|
 }tj|}	|
dkrd
|kr|	 jtjO  _d|kr|	 jtjO  _d|kr|	 jtjO  _d|	_||	_|	j  |rZy|	j| W nB ttjfk
rX } z| j j  tdj|W Y dd}~X nX |ry|	j|| W nB ttjfk
r } z| j j  tdj|W Y dd}~X nX |r|	j| t| dr|	j| j | jd| _ n|	j| j | _ |rd|	_| jg}tjdkrL| jdkrLddg}t j!| j}|j"|d g|d	   d}g }x`|D ]X}ytj#| j j$ | W n4 tj%k
r } z|j&t'| W Y dd}~X nX d}P qZW |s| j j  tdjdj(|W n t)k
r   tj*dY n tjtfk
r> } z tjd| j+ t,|fdW Y dd}~X nd tj%k
rp } ztjt'|W Y dd}~X n2 t-k
r } ztjt'|W Y dd}~X nX dS )zSwitch the socket to use SSLi   )r   NFT)reverser   zTLSv1.3r   zTLSv1.2zTLSv1.1r   zInvalid CA Certificate: {}zInvalid Certificate/Key: {}server_host)server_hostnament	localhostz	127.0.0.1z$Unable to verify server identity: {}z, z&Python installation has no SSL supporti  )r   r8   ).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_locationsr;   SSLErrorr3   r   load_cert_chainset_ciphershasattrwrap_socketrh   osnamer1   gethostbyaddrrP   match_hostnamegetpeercertCertificateErrorr   r   rE   	NameErrorZNotSupportedErrorr/   r   r-   )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)rZ   r[   )FFNN)__name__
__module____qualname____doc__r)   propertyr+   r,   r.   r/   r0   r6   r7   rA   sendrJ   rW   rY   sysversion_inforM   r]   rc   rf   r   r   r   r   r   r!   Z   s4   	 
 
T&O  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| j  || _d S )N)superr   r)   unix_socket)r(   r   )	__class__r   r   r)     s    zMySQLUnixSocket.__init__c             C   s   | j S )N)r   )r(   r   r   r   r/     s    zMySQLUnixSocket.get_addressc             C   s   y2t j t jt j| _| jj| j | jj| j W nj tk
rn } z t	j
d| j t|fdW Y d d }~X n0 tk
r } zt	j
t|W Y d d }~X nX d S )Ni  )r   r8   )r1   AF_UNIXSOCK_STREAMr#   rd   r$   connectr   r;   r   r	   r/   r   	Exceptionr   )r(   r   r   r   r   r.   !  s    
&zMySQLUnixSocket.open_connection)r   )r   r   r   r   r)   r/   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.
    	127.0.0.1  Fc                s*   t t| j  || _|| _|| _d| _d S )Nr   )r   r   r)   rh   server_port
force_ipv6_family)r(   hostportr   )r   r   r   r)   4  s
    zMySQLTCPSocket.__init__c             C   s   dj | j| jS )Nz{0}:{1})r   rh   r   )r(   r   r   r   r/   ;  s    zMySQLTCPSocket.get_addressc       	      C   s  dgd }yt j| j| jdt jt j}x<|D ]4}| jrL|d t jkrL|}P q,|d t jkr,|}P q,W | jr|d dkrt	j
dj| j|d dkr|d }W n< tk
r } z t	j
d| j t|fdW Y dd}~X nX |\| _}}}}y0t j | j||| _| jj| j | jj| W nn tk
rZ } z t	j
d| j t|fdW Y dd}~X n2 tk
r } zt	jt|W Y dd}~X nX dS )z7Open the TCP/IP connection to the MySQL server
        N   r   zNo IPv6 address found for {0}i  )r   r8   )r1   getaddrinforh   r   r   SOL_TCPr   AF_INET6AF_INETr   r	   r   r;   r/   r   r   r#   rd   r$   r   r   r<   r   )	r(   ZaddrinfoZ	addrinfosinfor   socktypeproto_Zsockaddrr   r   r   r.   >  s>    

(&zMySQLTCPSocket.open_connection)r   r   F)r   r   r   r   r)   r/   r.   r   r   r   )r   r   r   .  s   r   ) r   collectionsr   r   r1   r   r   rF   rl   PROTOCOL_TLSv1PROTOCOL_TLSv1_1PROTOCOL_TLSv1_2rt   r   r   PROTOCOL_SSLv23r   rs    r   r   r	   Zcatch23r
   r   r   r   r    objectr!   r   r   r   r   r   r   <module>   s>   



   =