U
    dRf'3                     @   s   d dl mZmZ d dlZd dl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 d dlmZmZmZ e	jdkp|e	jdZG dd deZG d	d
 d
eZG dd deZdS )    )absolute_importdivisionN)TTransportException)create_thriftpy_contextRESTRICTED_SERVER_CIPHERSDEFAULT_CIPHERSdarwinZfreebsdc                   @   s   e Zd ZdZddddejddddddddef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 Zdd ZdS )TAsyncSocketz&Socket implementation for client side.N  Tc                 C   s   |r|| _ nF|r2|| _d| _d| _d| _ tj| _n d| _|| _|| _d| _ tj| _|| _|rd|d nd| _	|rv|d n| j	| _
|r|| _|| _nl|s|r|| _td|d| _|
s|r| jj|
|d |r| jj||d |	sd| j_tj| j_nd| _d| _dS )u  Initialize a TSocket

        TSocket can be initialized in 3 ways:
        * host + port. can configure to use AF_INET/AF_INET6
        * unix_socket
        * socket. should pass already opened socket here.

        @param host(str)    The host to connect to.
        @param port(int)    The (TCP) port to connect to.
        @param unix_socket(str) The filename of a unix socket to connect to.
        @param sock(socket)     Initialize with opened socket directly.
            If this param used, the host, port and unix_socket params will
            be ignored.
        @param socket_family(str) socket.AF_INET or socket.AF_INET6. only
            take effect when using host/port
        @param socket_timeout   socket timeout in ms
        @param connect_timeout  connect timeout in ms, only used in
            connection, will be set to socket_timeout if not set.
        @param validate(bool)       Set to False to disable SSL certificate
            validation and hostname validation. Default enabled.
        @param cafile(str)          Path to a file of concatenated CA
            certificates in PEM format.
        @param capath(str)           path to a directory containing several CA
            certificates in PEM format, following an OpenSSL specific layout.
        @param certfile(str)        The certfile string must be the path to a
            single file in PEM format containing the certificate as well as
            any number of CA certificates needed to establish the
            certificate’s authenticity.
        @param keyfile(str)         The keyfile string, if not present,
            the private key will be taken from certfile as well.
        @param ciphers(list<str>)   The cipher suites to allow
        @param ssl_context(SSLContext)  Customize the SSLContext, can be used
            to persist SSLContext object. Caution it's easy to get wrong, only
            use if you know what you're doing.
        N  Fserver_sideciphers)cafilecapathkeyfile)raw_sockunix_sockethostportasyncioZopen_unix_connectionsock_factoryZopen_connectionsocket_familysocket_timeoutconnect_timeoutssl_contextserver_hostnamer   load_verify_locationsload_cert_chaincheck_hostnamessl	CERT_NONEverify_mode)selfr   r   r   sockr   r   r   r   validater   r   certfiler   r    r(   @/tmp/pip-unpacked-wheel-jqs7l_7o/thriftpy2/contrib/aio/socket.py__init__   sJ    )
zTAsyncSocket.__init__c                 C   sv   | j rttjtj}n"t| jtj}|tjtjd t	ddd}|tj
tj| |tj
tjd || _d S )N   iir   )r   socketAF_UNIXSOCK_STREAMr   
setsockoptIPPROTO_TCPTCP_NODELAYstructpack
SOL_SOCKET	SO_LINGERSO_KEEPALIVEr   )r$   _sockZlingerr(   r(   r)   
_init_sockm   s    zTAsyncSocket._init_sockc                 C   s
   || _ d S N)r   )r$   r%   r(   r(   r)   
set_handle{   s    zTAsyncSocket.set_handlec                 C   s>   |r|dkr|d nd| _ | j | _| jdk	r:| j| j  dS )zgBackward compat api, will bind the timeout to both connect_timeout
        and socket_timeout.
        r   r   N)r   r   r   
settimeout)r$   msr(   r(   r)   set_timeout~   s    
zTAsyncSocket.set_timeoutc                 C   s
   t | jS r:   )boolr   r$   r(   r(   r)   is_open   s    zTAsyncSocket.is_openc              	      s   |    | jp| j| jf}zz| jr0| j| j | j| | jrP| j| j | j| j	d}| j
rn| j
|d< t| jf || jI d H \| _| _W n0 tjtfk
r   ttjdt| dY nX d S )Nr%   r!   r   zCould not connect to %stypemessage)r9   r   r   r   r   r   r<   connectr   r   r   r   wait_forr   readerwriterr-   errorOSErrorr   ZNOT_OPENstr)r$   addrkwargsr(   r(   r)   open   s(    


zTAsyncSocket.openc              
      s   z t | j|| jI d H }W nD tjk
rd } z$|jtjkrRt	rR| 
  d}n W 5 d }~X Y nX t|dkrttjdd|S N r   zTSocket read 0 bytesrC   )r   rG   rH   readr   r-   rJ   errno
ECONNRESET
MAC_OR_BSDcloselenr   END_OF_FILEr$   szbuffer(   r(   r)   rR      s    
zTAsyncSocket.readc                 C   s   | j | d S r:   rI   writer$   r[   r(   r(   r)   r^      s    zTAsyncSocket.writec                    s   t | j | jI d H  d S r:   )r   rG   rI   drainr   r@   r(   r(   r)   flush   s    zTAsyncSocket.flushc              	   C   sH   | j s
d S z| j  | j   d | _ W n tjtfk
rB   Y nX d S r:   )r   rI   rV   r-   rJ   rK   r@   r(   r(   r)   rV      s    


zTAsyncSocket.close)__name__
__module____qualname____doc__r-   AF_INETr   r*   r9   r;   r>   rA   rO   rR   r^   ra   rV   r(   r(   r(   r)   r	      s.         
S
r	   c                
   @   sX   e Zd ZdZdddejdddddef
ddZdd Zd	d
 Z	dd Z
dd Zdd ZdS )TAsyncServerSocketz&Socket implementation for server side.Nr
      c                 C   s   |r || _ d| _d| _tj| _nd| _ || _|| _tj| _|| _|rL|d nd| _|| _	|rd|| _
nD|rt|tjstd| td|
d| _
| j
j||	d nd| _
dS )a  Initialize a TServerSocket

        TSocket can be initialized in 2 ways:
        * host + port. can configure to use AF_INET/AF_INET6
        * unix_socket

        @param host(str)    The host to connect to
        @param port(int)    The (TCP) port to connect to
        @param unix_socket(str) The filename of a unix socket to connect to
        @param socket_family(str) socket.AF_INET or socket.AF_INET6. only
            take effect when using host/port
        @param client_timeout   client socket timeout
        @param backlog          backlog for server socket
        @param certfile(str)        The server cert pem filename
        @param keyfile(str)         The server cert key filename
        @param ciphers(list<str>)   The cipher suites to allow
        @param ssl_context(SSLContext)  Customize the SSLContext, can be used
            to persist SSLContext object. Caution it's easy to get wrong, only
            use if you know what you're doing.
        Nr   zNo such certfile found: %sTr   r   )r   r   r   r   Zstart_unix_serverr   Zstart_serverr   client_timeoutbacklogr   osaccessR_OKIOErrorr   r   )r$   r   r   r   r   ri   rj   r   r'   r   r   r(   r(   r)   r*      s,    
zTAsyncServerSocket.__init__c              
   C   s   | j rjttjtj}z|| j  W qz tjtfk
rf } z|jtjkrVt	
| j  W 5 d }~X Y qzX nt| jtj}|tjtjd ttdrz|tjtjd W n< tjk
r } z|d tjtjfkrn W 5 d }~X Y nX |d  || _d S )Nr+   SO_REUSEPORTr   )r   r-   r.   r/   rF   rJ   rK   rS   ZECONNREFUSEDrk   unlinkr   r0   r5   SO_REUSEADDRhasattrro   ZENOPROTOOPTEINVALr<   r   )r$   r8   errr(   r(   r)   r9     s$     

zTAsyncServerSocket._init_sockc                 C   s8   |    | jp| j| jf}| j| | j| j d S r:   )r9   r   r   r   r   bindlistenrj   )r$   rM   r(   r(   r)   rv     s    zTAsyncServerSocket.listenc                    s$   | j | || j| jdI d H }|S )NrB   )r   _create_client_connected_cbr   r   )r$   callbackserverr(   r(   r)   accept%  s    zTAsyncServerSocket.acceptc                    s    fdd}|S )Nc                    sH   z"t  t| |jI d H  W n  t jjk
rB   |  Y nX d S r:   )r   rG   StreamHandlerri   
exceptionsTimeoutErrorrV   rH   rI   rx   r$   r(   r)   client_connected_cb/  s    zKTAsyncServerSocket._create_client_connected_cb.<locals>.client_connected_cbr(   )r$   rx   r   r(   r   r)   rw   -  s    	z.TAsyncServerSocket._create_client_connected_cbc              	   C   sF   | j s
d S z| j tj | j   W n tjtfk
r@   Y nX d S r:   )r   shutdownr-   	SHUT_RDWRrV   rJ   rK   r@   r(   r(   r)   rV   :  s    zTAsyncServerSocket.close)rb   rc   rd   re   r-   rf   r   r*   r9   rv   rz   rw   rV   r(   r(   r(   r)   rg      s       
3rg   c                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )r{   c                 C   s   || | _ | _d S r:   r~   )r$   rH   rI   r(   r(   r)   r*   F  s    zStreamHandler.__init__c              
      sz   z| j |I d H }W nD tjk
rZ } z$|jtjkrHtrH|   d}n W 5 d }~X Y nX t|dkrvt	t	j
dd|S rP   )rH   rR   r-   rJ   rS   rT   rU   rV   rW   r   rX   rY   r(   r(   r)   rR   I  s    zStreamHandler.readc                 C   s   | j | d S r:   r]   r_   r(   r(   r)   r^   ]  s    zStreamHandler.writec                    s   | j  I d H  d S r:   )rI   r`   r@   r(   r(   r)   ra   `  s    zStreamHandler.flushc              	   C   s.   z| j   W n tjtfk
r(   Y nX d S r:   )rI   rV   r-   rJ   rK   r@   r(   r(   r)   rV   c  s    zStreamHandler.closec                    s   d S r:   r(   r@   r(   r(   r)   rO   i  s    zStreamHandler.openN)	rb   rc   rd   r*   rR   r^   ra   rV   rO   r(   r(   r(   r)   r{   E  s   r{   )
__future__r   r   r!   r   rS   rk   r-   r3   sysZthriftpy2.transportr   Zthriftpy2.transport._sslr   r   r   platform
startswithrU   objectr	   rg   r{   r(   r(   r(   r)   <module>   s    :u