B
    `7                 @   s  d dl mZ d dlmZmZmZmZmZ d dlZ	d dl
Z	d dlmZ d dlmZ d dlmZmZ ddlmZmZmZmZ dd	lmZmZ dd
lmZ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& ddl'm(Z( e"e)Z*G dd de(Z+G dd dZ,dS )    )
SSLContext)IteratorDictListTuplecastN)H2Configuration)NoAvailableStreamIDError)SettingCodesSettings   )SyncBackendSyncLockSyncSemaphoreSyncSocketStream)IteratorByteStreamPlainByteStream)PoolTimeoutRemoteProtocolError)URLHeadersTimeoutDict)
get_logger   )SyncByteStreamConnectionStateNewConnectionRequired)SyncBaseHTTPConnectionc               @   s  e Zd ZdZeddZd;eeedddZ	e
dd	d
Ze
dddZeedddZeedddZeedddZd<eeedddZedddZddddZd=eeeeeeeeeef dddZeddddZ ee!dd d!Z"e!dd"d#Z#ddd$d%Z$eeed&d'd(Z%eee&j'j(d&d)d*Z)eddd+d,Z*eee!edd-d.d/Z+eeedd0d1d2Z,eedd&d3d4Z-eeedd5d6d7Z.edd8d9d:Z/dS )>SyncHTTP2Connectioni   F)Zvalidate_inbound_headersN)socketbackendssl_contextc             C   sP   || _ |d krt n|| _|| _tjj| jd| _d| _	i | _
i | _tj| _d S )N)configF)r   r   r!   r    h2
connectionZH2ConnectionCONFIGh2_statesent_connection_initstreamseventsr   ACTIVEstate)selfr   r    r!    r-   C/home/dcms/DCMS/lib/python3.7/site-packages/httpcore/_sync/http2.py__init__   s    zSyncHTTP2Connection.__init__)returnc             C   s   d| j  dS )Nz<SyncHTTP2Connection state=>)r+   )r,   r-   r-   r.   __repr__+   s    zSyncHTTP2Connection.__repr__c             C   s   d| j j dt| j dS )NzHTTP/2, z, z streams)r+   namelenr(   )r,   r-   r-   r.   info.   s    zSyncHTTP2Connection.infoc             C   s   t | ds| j | _| jS )N_initialization_lock)hasattrr    create_lockr6   )r,   r-   r-   r.   	init_lock1   s    
zSyncHTTP2Connection.init_lockc             C   s   t | ds| j | _| jS )N
_read_lock)r7   r    r8   r:   )r,   r-   r-   r.   	read_lock9   s    
zSyncHTTP2Connection.read_lockc             C   s,   t | ds&| jjj}| jj|td| _| jS )N_max_streams_semaphore)	exc_class)r7   r&   local_settingsZmax_concurrent_streamsr    Zcreate_semaphorer   r<   )r,   Zmax_streamsr-   r-   r.   max_streams_semaphoreA   s
    

z)SyncHTTP2Connection.max_streams_semaphore)hostnametimeoutr0   c             C   s   t dd S )Nz0TLS upgrade not supported on HTTP/2 connections.)NotImplementedError)r,   r@   rA   r-   r-   r.   	start_tlsL   s    zSyncHTTP2Connection.start_tlsc             C   s   | j S )N)r+   )r,   r-   r-   r.   	get_stateQ   s    zSyncHTTP2Connection.get_statec             C   s   | j tjkrtj| _ d S )N)r+   r   IDLEZREADY)r,   r-   r-   r.   mark_as_readyT   s    z!SyncHTTP2Connection.mark_as_ready)methodurlheadersstreamextr0   c       	   	   C   s   |d kri n|}t t|di }| j$ | jsHtj| _| | d| _W d Q R X | j	
  yly| j }W n" tk
r   tj| _t Y n
X tj| _t|| d}|| j|< g | j|< ||||||S  tk
r   | j	   Y nX d S )NrA   T)	stream_idr$   )r   r   getr9   r'   r   r*   r+   send_connection_initr?   acquirer&   Zget_next_available_stream_idr	   FULLr   SyncHTTP2Streamr(   r)   request	Exceptionrelease)	r,   rG   rH   rI   rJ   rK   rA   rL   Z	h2_streamr-   r-   r.   rR   X   s,    




zSyncHTTP2Connection.request)rA   r0   c             C   sp   t dtjdtjdtjdid| j_| jjtjjj	= t
d|  | j  | jd | j }| j|| dS )	z
        The HTTP/2 connection requires some initial setup before we can start
        using individual request/response streams on it.
        Tr   d   i   )clientZinitial_valueszinitiate_connection=%ri   N)r   r
   ZENABLE_PUSHZMAX_CONCURRENT_STREAMSZMAX_HEADER_LIST_SIZEr&   r>   r#   settingsZENABLE_CONNECT_PROTOCOLloggertraceZinitiate_connectionincrement_flow_control_windowdata_to_sendr   write)r,   rA   r[   r-   r-   r.   rN   |   s    


z(SyncHTTP2Connection.send_connection_initc             C   s   dS )NFr-   )r,   r-   r-   r.   	is_closed   s    zSyncHTTP2Connection.is_closedc             C   s
   | j  S )N)r   is_connection_dropped)r,   r-   r-   r.   r^      s    z)SyncHTTP2Connection.is_connection_droppedc             C   s.   t d|  | jtjkr*tj| _| j  d S )Nzclose_connection=%r)rX   rY   r+   r   ZCLOSEDr   close)r,   r-   r-   r.   r_      s    zSyncHTTP2Connection.close)rL   rA   r0   c             C   sX   | j |}| j j}t||}x4|dkrR| | | j |}| j j}t||}q W |S )a  
        Returns the maximum allowable outgoing flow for a given stream.
        If the allowable flow is zero, then waits on the network until
        WindowUpdated frames have increased the flow rate.
        https://tools.ietf.org/html/rfc7540#section-6.9
        r   )r&   Zlocal_flow_control_windowZmax_outbound_frame_sizeminreceive_events)r,   rL   rA   Z
local_flowZconnection_flowZflowr-   r-   r.   wait_for_outgoing_flow   s    


z*SyncHTTP2Connection.wait_for_outgoing_flowc          	   C   s<   | j   x| j| s | | q
W W dQ R X | j| dS )z
        Returns the next event for a given stream.
        If no events are available yet, then waits on the network until
        an event is available.
        Nr   )r;   r)   ra   pop)r,   rL   rA   r-   r-   r.   wait_for_event   s    z"SyncHTTP2Connection.wait_for_eventc             C   s   | j | j|}|dkr td| j|}xR|D ]J}t|dd}td|| t	|drbt||| j
kr2| j
| | q2W | j }| j || dS )zK
        Read some data from the network, and update the H2 state.
            zServer disconnectedrL   r   z#receive_event stream_id=%r event=%sZ
error_codeN)r   readREAD_NUM_BYTESr   r&   Zreceive_datagetattrrX   rY   r7   r)   appendr[   r\   )r,   rA   datar)   eventZevent_stream_idr[   r-   r-   r.   ra      s    



z"SyncHTTP2Connection.receive_events)rL   rI   
end_streamrA   r0   c             C   sL   t d|| | jj|||d | jjd|d | j }| j|| d S )Nz$send_headers stream_id=%r headers=%r)rl   i   )rL   )rX   rY   r&   send_headersrZ   r[   r   r\   )r,   rL   rI   rl   rA   r[   r-   r-   r.   rm      s
    
z SyncHTTP2Connection.send_headers)rL   chunkrA   r0   c             C   s8   t d|| | j|| | j }| j|| d S )Nzsend_data stream_id=%r chunk=%r)rX   rY   r&   	send_datar[   r   r\   )r,   rL   rn   rA   r[   r-   r-   r.   ro      s    
zSyncHTTP2Connection.send_datac             C   s4   t d| | j| | j }| j|| d S )Nzend_stream stream_id=%r)rX   rY   r&   rl   r[   r   r\   )r,   rL   rA   r[   r-   r-   r.   rl      s    
zSyncHTTP2Connection.end_stream)rL   amountrA   r0   c             C   s*   | j || | j  }| j|| d S )N)r&   acknowledge_received_datar[   r   r\   )r,   rL   rp   rA   r[   r-   r-   r.   rq      s    
z-SyncHTTP2Connection.acknowledge_received_data)rL   r0   c             C   sb   zPt d| | j|= | j|= | jsN| jtjkr:tj| _n| jtjkrN| 	  W d | j
  X d S )Nzclose_stream stream_id=%r)rX   rY   r(   r)   r+   r   r*   rE   rP   r_   r?   rT   )r,   rL   r-   r-   r.   close_stream   s    
z SyncHTTP2Connection.close_stream)N)N)NNN)0__name__
__module____qualname__rg   r   r%   r   r   r   r/   strr2   r5   propertyr   r9   r;   r   r?   bytesr   rC   r   rD   rF   r   r   r   dictr   intrR   rN   boolr]   r^   r_   rb   r#   r)   Eventrd   ra   rm   ro   rl   rq   rr   r-   r-   r-   r.   r      sH   
  !r   c               @   s   e Zd ZeeddddZdeeee	e
eeee	e
f dddZeeeeeddd	d
Ze	eddddZeeeeeeef  f dddZeee dddZddddZdS )rQ   N)rL   r$   r0   c             C   s   || _ || _d S )N)rL   r$   )r,   rL   r$   r-   r-   r.   r/     s    zSyncHTTP2Stream.__init__)rG   rH   rI   rJ   rK   r0   c             C   s   |d krg ndd |D }|d kr*t dn|}|d kr:i n|}tt|di }tdd |D }d|kppd|k}| ||||| |r| || | |\}	}t| 	|| j
d	}
d
di}|	||
|fS )Nc             S   s   g | ]\}}|  |fqS r-   )lower).0kvr-   r-   r.   
<listcomp>  s    z+SyncHTTP2Stream.request.<locals>.<listcomp>re   rA   c             s   s   | ]\}}|V  qd S )Nr-   )r~   keyvaluer-   r-   r.   	<genexpr>  s    z*SyncHTTP2Stream.request.<locals>.<genexpr>s   content-lengths   transfer-encoding)iteratorZ
close_funchttp_versionzHTTP/2)r   r   r   rM   setrm   	send_bodyreceive_responser   	body_iter_response_closed)r,   rG   rH   rI   rJ   rK   rA   Zseen_headershas_bodystatus_codeZresponse_streamr-   r-   r.   rR     s    zSyncHTTP2Stream.request)rG   rH   rI   r   rA   r0   c             C   s   |\}}}}	ddd |}
|d ks,||
kr2|}nd||f }d|fd|fd|fd|	fgd	d
 |D  }| }| j| j||| d S )NP   i  )s   https   httpss   %s:%ds   :methods
   :authoritys   :schemes   :pathc             S   s    g | ]\}}|d kr||fqS ))s   hosts   transfer-encodingr-   )r~   r   r   r-   r-   r.   r   G  s    z0SyncHTTP2Stream.send_headers.<locals>.<listcomp>)rM   r$   rm   rL   )r,   rG   rH   rI   r   rA   schemer@   portpathdefault_port	authorityrl   r-   r-   r.   rm   3  s    zSyncHTTP2Stream.send_headers)rJ   rA   r0   c             C   sv   x`|D ]X}xR|r\| j | j|}tt||}|d | ||d   }}| j | j|| qW qW | j | j| d S )N)r$   rb   rL   r`   r4   ro   rl   )r,   rJ   rA   rj   Zmax_flow
chunk_sizern   r-   r-   r.   r   L  s    

zSyncHTTP2Stream.send_body)rA   r0   c             C   s~   x$| j | j|}t|tjjrP qW d}g }xF|jD ]<\}}|dkrZt|j	ddd}q6|
ds6|||f q6W ||fS )zH
        Read the response status and headers from the network.
           s   :statusasciiignore)errors   :)r$   rd   rL   
isinstancer#   r)   ZResponseReceivedrI   rz   decode
startswithri   )r,   rA   rk   r   rI   r   r   r-   r-   r.   r   X  s    
z SyncHTTP2Stream.receive_responsec             c   sb   x\| j | j|}t|tjjrB|j}| j | j|| |j	V  qt|tjj
tjjfrP qW d S )N)r$   rd   rL   r   r#   r)   ZDataReceivedZflow_controlled_lengthrq   rj   ZStreamEndedZStreamReset)r,   rA   rk   rp   r-   r-   r.   r   m  s    
zSyncHTTP2Stream.body_iter)r0   c             C   s   | j | j d S )N)r$   rr   rL   )r,   r-   r-   r.   r   y  s    z SyncHTTP2Stream._response_closed)NNN)rs   rt   ru   rz   r   r/   rx   r   r   r   ry   r   rR   r{   r   rm   r   r   r   r   r   r   r-   r-   r-   r.   rQ     s      "rQ   )-sslr   typingr   r   r   r   r   Zh2.connectionr#   Z	h2.eventsZ	h2.configr   Zh2.exceptionsr	   Zh2.settingsr
   r   Z_backends.syncr   r   r   r   Z_bytestreamsr   r   _exceptionsr   r   _typesr   r   r   _utilsr   baser   r   r   httpr   rs   rX   r   rQ   r-   r-   r-   r.   <module>   s"    x