B
    `6                 @   s  d dl Z d dlmZ d dlmZmZmZmZmZm	Z	m
Z
mZ ddlmZmZ ddlmZ ddlmZmZmZ ddlmZ dd	lmZmZmZmZ dd
lmZmZmZ ddl m!Z!m"Z"m#Z#m$Z$ ddl%m&Z& ee'Z(G dd deZ)G dd de!Z*G dd de"Z+dS )    N)
SSLContext)IteratorCallableDictListOptionalSetTuplecast   )SyncLockSyncSemaphore)lookup_sync_backend)LocalProtocolErrorPoolTimeoutUnsupportedProtocol)
ThreadLock)URLHeadersOriginTimeoutDict)
get_loggerorigin_to_url_stringurl_to_origin   )SyncByteStreamSyncHTTPTransportConnectionStateNewConnectionRequired)SyncHTTPConnectionc               @   s:   e Zd ZddddZd
eddddZdddd	ZdS )NullSemaphoreN)returnc             C   s   d S )N )selfr"   r"   M/home/dcms/DCMS/lib/python3.7/site-packages/httpcore/_sync/connection_pool.py__init__   s    zNullSemaphore.__init__)timeoutr!   c             C   s   d S )Nr"   )r#   r&   r"   r"   r$   acquire   s    zNullSemaphore.acquirec             C   s   d S )Nr"   )r#   r"   r"   r$   release   s    zNullSemaphore.release)N)__name__
__module____qualname__r%   floatr'   r(   r"   r"   r"   r$   r       s   r    c               @   s@   e Zd ZeeeddddZee dddZ	dddd	Z
dS )
ResponseByteStreamN)stream
connectioncallbackr!   c             C   s   || _ || _|| _dS )z
        A wrapper around the response stream that we return from `.request()`.

        Ensures that when `stream.close()` is called, the connection pool
        is notified via a callback.
        N)r.   r/   r0   )r#   r.   r/   r0   r"   r"   r$   r%   "   s    zResponseByteStream.__init__)r!   c             c   s   x| j D ]
}|V  qW d S )N)r.   )r#   chunkr"   r"   r$   __iter__2   s    zResponseByteStream.__iter__c          	   C   s"   z| j   W d | | j X d S )N)r.   closer0   r/   )r#   r"   r"   r$   r3   6   s    zResponseByteStream.close)r)   r*   r+   r   r   r   r%   r   bytesr2   r3   r"   r"   r"   r$   r-   !   s   r-   c               @   s6  e Zd ZdZd'eeeeeeeeed	ddZ	e
edd	d
Ze
edddZeeeef edddZd(eeeeeeeeeef dddZeee dddZeddddZddddZeeddddZeddddZee e ddd Z!e e dd!d"Z"ddd#d$Z#e$ee%e f dd%d&Z&dS ))SyncConnectionPoola1  
    A connection pool for making HTTP requests.

    **Parameters:**

    * **ssl_context** - `Optional[SSLContext]` - An SSL context to use for
    verifying connections.
    * **max_connections** - `Optional[int]` - The maximum number of concurrent
    connections to allow.
    * **max_keepalive_connections** - `Optional[int]` - The maximum number of
    connections to allow before closing keep-alive connections.
    * **keepalive_expiry** - `Optional[float]` - The maximum time to allow
    before closing a keep-alive connection.
    * **http2** - `bool` - Enable HTTP/2 support.
    * **uds** - `str` - Path to a Unix Domain Socket to use instead of TCP sockets.
    * **local_address** - `Optional[str]` - Local address to connect from. Can
    also be used to connect using a particular address family. Using
    `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4),
    while using `local_address="::"` will connect using an `AF_INET6` address
    (IPv6).
    * **backend** - `str` - A name indicating which concurrency backend to use.
    NFsync)	ssl_contextmax_connectionsmax_keepalive_connectionskeepalive_expiryhttp2udslocal_addressmax_keepalivebackendc
             C   s   |d k	rt dt |}|d kr&t n|| _|| _|| _|| _|| _|| _	|| _
i | _t | _t|	| _d| _|rydd l}
W n tk
r   tdY nX d S )Nz?'max_keepalive' is deprecated. Use 'max_keepalive_connections'.g        r   zfAttempted to use http2=True, but the 'h2' package is not installed. Use 'pip install httpcore[http2]'.)warningswarnDeprecationWarningr   _ssl_context_max_connections_max_keepalive_connections_keepalive_expiry_http2_uds_local_address_connectionsr   _thread_lockr   _backend_next_keepalive_checkh2ImportError)r#   r7   r8   r9   r:   r;   r<   r=   r>   r?   rN   r"   r"   r$   r%   Z   s,    
zSyncConnectionPool.__init__)r!   c             C   s8   t | ds2| jd k	r*| jj| jtd| _nt | _| jS )N_internal_semaphore)	exc_class)hasattrrD   rL   Zcreate_semaphorer   rP   r    )r#   r"   r"   r$   _connection_semaphore   s    

z(SyncConnectionPool._connection_semaphorec             C   s   t | ds| j | _| jS )N!_internal_connection_acquiry_lock)rR   rL   Zcreate_lockrT   )r#   r"   r"   r$   _connection_acquiry_lock   s    
z+SyncConnectionPool._connection_acquiry_lock)originr!   c             C   s   t || j| j| j| j| jdS )N)rV   r;   r<   r7   r=   r?   )r   rG   rH   rC   rI   rL   )r#   rV   r"   r"   r$   _create_connection   s    z%SyncConnectionPool._create_connection)methodurlheadersr.   extr!   c          	   C   sj  |d dkr(|d  d}td||d s8tdt|}|d krLi n|}tt|di }|   d }	x|	d kr@| jX t	
d| | |}	|	d kr| j|d	}	t	
d
|	 | j|	|d nt	
d|	 W d Q R X y|	j|||||d}
W qp tk
r   d }	Y qp tk
r<   t	
d|	 | |	  Y qpX qpW |
\}}}}t||	| jd}||||fS )Nr   )s   https   httpszlatin-1zUnsupported URL protocol r   zMissing hostname in URL.r&   zget_connection_from_pool=%r)rV   zcreated connection=%r)r&   zreuse connection=%r)rZ   r.   r[   zremove from pool connection=%r)r/   r0   )decoder   r   r   r
   r   get_keepalive_sweeprU   loggertrace_get_connection_from_poolrW   _add_to_poolrequestr   	Exception_remove_from_poolr-   _response_closed)r#   rX   rY   rZ   r.   r[   schemerV   r&   r/   responsestatus_codeZwrapped_streamr"   r"   r$   rc      s@    

zSyncConnectionPool.requestc             C   s   d}d }d }t  }x| |D ]}|jr,d}|jtjkrt| rbtd| |	| | 
| qtd| |}q|jtjkr|jrtd| |}q|jtjkr|}qW |d k	r|  d |_n"| jr|d k	r|std| |}x|D ]}|  qW |S )NFTz#removing dropped idle connection=%rz!reusing idle http11 connection=%rz"reusing active http2 connection=%rzreusing pending connection=%r)set_connections_for_originZ	is_http11stater   IDLEis_connection_droppedr_   r`   addre   ZACTIVEZis_http2ZPENDINGZmark_as_ready
expires_atrG   r3   )r#   rV   Zseen_http11Zpending_connectionZreuse_connectionconnections_to_closer/   r"   r"   r$   ra      s8    

z,SyncConnectionPool._get_connection_from_pool)r/   r!   c             C   s   d}d}|j tjkrd}nV|j tjkrpt|  }| jd k	rP|| jkrPd}d}n | jd k	rp| j	 }|| j |_
|r~| | |r|  d S )NFT)rl   r   ZCLOSEDrm   len_get_all_connectionsrE   rF   rL   timerp   re   r3   )r#   r/   Zremove_from_poolZclose_connectionnum_connectionsnowr"   r"   r$   rf   
  s"    




z#SyncConnectionPool._response_closedc             C   s   | j dkrdS | j }|| jk r&dS |td| j  | _t }xD|  D ]8}|jtj	krH|j
dk	rH||j
krH|| | | qHW x|D ]}|  qW dS )z[
        Remove any IDLE connections that have expired past their keep-alive time.
        Ng      ?)rF   rL   rt   rM   minrj   rs   rl   r   rm   rp   ro   re   r3   )r#   rv   rq   r/   r"   r"   r$   r^   "  s    






z#SyncConnectionPool._keepalive_sweep)r/   r&   r!   c          	   C   s\   t d| | jj|dd d | j* | j|jt	  | j|j 
| W d Q R X d S )Nzadding connection to pool=%rpool)r&   )r_   r`   rS   r'   r]   rK   rJ   
setdefaultrV   rj   ro   )r#   r/   r&   r"   r"   r$   rb   <  s
    zSyncConnectionPool._add_to_poolc          	   C   sj   t d| | jN || j|jt kr\| j  | j|j 	| | j|j s\| j|j= W d Q R X d S )Nz removing connection from pool=%r)
r_   r`   rK   rJ   r]   rV   rj   rS   r(   remove)r#   r/   r"   r"   r$   re   E  s    
z$SyncConnectionPool._remove_from_poolc             C   s   t | j|t  S )N)rj   rJ   r]   )r#   rV   r"   r"   r$   rk   N  s    z*SyncConnectionPool._connections_for_originc             C   s&   t  }x| j D ]}||O }qW |S )N)rj   rJ   values)r#   connectionsZconnection_setr"   r"   r$   rs   Q  s    z'SyncConnectionPool._get_all_connectionsc             C   s:   |   }x|D ]}| | qW x|D ]}|  q&W d S )N)rs   re   r3   )r#   r|   r/   r"   r"   r$   r3   W  s
    

zSyncConnectionPool.closec             C   sB   |    i }x0| j D ]"\}}tdd |D |t|< qW |S )za
        Returns a dict of origin URLs to a list of summary strings for each connection.
        c             S   s   g | ]}|  qS r"   )info).0r/   r"   r"   r$   
<listcomp>i  s    z:SyncConnectionPool.get_connection_info.<locals>.<listcomp>)r^   rJ   itemssortedr   )r#   statsrV   r|   r"   r"   r$   get_connection_info`  s    z&SyncConnectionPool.get_connection_info)	NNNNFNNNr6   )NNN)'r)   r*   r+   __doc__r   intr,   boolstrr%   propertyr   rS   r   rU   r	   r4   r   rW   r   r   r   dictrc   r   r   ra   rf   r^   r   rb   re   r   rk   rs   r3   r   r   r   r"   r"   r"   r$   r5   B   s>              /0		r5   ),r@   sslr   typingr   r   r   r   r   r   r	   r
   Z_backends.syncr   r   Z_backends.baser   _exceptionsr   r   r   Z_threadlockr   _typesr   r   r   r   _utilsr   r   r   baser   r   r   r   r/   r   r)   r_   r    r-   r5   r"   r"   r"   r$   <module>   s   (!