o
    .j4                     @  s   d dl mZ d dlmZ d dlZd dlmZmZ ddlm	Z	 ddl
mZ ddlmZmZmZmZmZ d	d
lmZ eejejhZedddddZd ddZd!ddZG dd deZG dd deZdS )"    )annotations)	lru_cacheN)_SWITCH_UPGRADEConnectionState   )StreamMatrix)HeadersType)ConnectionTerminatedDataReceivedEarlyHeadersReceivedEventHeadersReceived   )HTTP1Protocol@   )maxsizenamebytesreturnc                 C  s   d dd | dD S )a1  
    Take a header name and capitalize it.
    >>> capitalize_header_name(b"x-hEllo-wORLD")
    'X-Hello-World'
    >>> capitalize_header_name(b"server")
    'Server'
    >>> capitalize_header_name(b"contEnt-TYPE")
    'Content-Type'
    >>> capitalize_header_name(b"content_type")
    'Content-Type'
       -c                 s  s    | ]}|  V  qd S N)
capitalize).0el r   _/home/thesage/.local/lib/python3.10/site-packages/urllib3/contrib/hface/protocols/http1/_h11.py	<genexpr>3   s    z)capitalize_header_name.<locals>.<genexpr>)joinsplit)r   r   r   r   capitalize_header_name&   s   r   headersr   	h11.Eventc           	      C  s   d  } } }}g }| D ]>\}}| dr7|dkr|}q|dkr!q|dkr(|}q|dkr/|}qtd|  |d u rA|dkrA|}|t||f q|d u rStd|d	kr^|d u r^|}n|}|d u rm|d
d|f n||krutdtj|||dS )N   :s   :methods   :schemes
   :authoritys   :pathzUnexpected request header: s   hostz"Missing request header: :authoritys   CONNECTr   s   Hostz&Host header does not match :authority.)methodr    target)
startswith
ValueErrordecodeappendr   inserth11Request)	r    r#   	authoritypathhostregular_headersr   valuer$   r   r   r   headers_to_request6   s@   
r1   response(h11.InformationalResponse | h11.Responsec                 C  s    dt | jdfg| j  S )z
    Converts an HTTP/1.0 or HTTP/1.1 response to HTTP/2-like headers.

    Generates from pseudo (colon) headers from a response line.
    s   :statusascii)strstatus_codeencoder    	raw_items)r2   r   r   r   headers_from_responsee   s   	r9   c                      s"   e Zd Z	dd fddZ  ZS )RelaxConnectionStateNr   Nonec                   s6   |d ur|| j vr|tu r| j t t |||S r   )pending_switch_proposalsr   addsuperprocess_event)selfrole
event_typeserver_switch_event	__class__r   r   r?   s   s
   
z"RelaxConnectionState.process_eventr   r   r;   )__name__
__module____qualname__r?   __classcell__r   r   rD   r   r:   r   s    r:   c                   @  s6  e Zd ZU dZded< dPddZedQd	d
ZdRddZe	dSddZ
dRddZdRddZdSddZdTdUddZ	dVdWd d!Z	dVdXd$d%ZdTdYd&d'ZdPd(d)ZdPd*d+ZdZd,d-Zd[d.d/Zd\d]d3d4Zd0d0d5d^d8d9Zd_d<d=ZdZd>d?ZdPd@dAZ	0d`dadEdFZdPdGdHZdbdJdKZdPdLdMZdRdNdOZd0S )cHTTP1ProtocolHyperImplr*   r5   implementationr   r;   c                 C  s<   t t j| _t | j_g | _t | _d| _	d| _
d| _d S )NF   )r*   
ConnectionCLIENT_connectionr:   _cstate_data_bufferr   _events_terminated	_switched_current_stream_idr@   r   r   r   __init__   s   

zHTTP1ProtocolHyperImpl.__init__tuple[type[BaseException], ...]c                   C  s   t jt jt jfS r   )r*   LocalProtocolErrorProtocolErrorRemoteProtocolErrorr   r   r   r   
exceptions   s   z!HTTP1ProtocolHyperImpl.exceptionsboolc                 C  s.   | j jrdS | jj| jj  kotjkS   S NF)rS   stream_countrP   	our_statetheir_stater*   IDLErW   r   r   r   is_available   s   "z#HTTP1ProtocolHyperImpl.is_availableintc                 C     dS )NrM   r   rW   r   r   r   max_stream_count   s   z'HTTP1ProtocolHyperImpl.max_stream_countc                 C  s   | j jtv S r   )rP   rb   _IDLE_STATESrW   r   r   r   is_idle   s   zHTTP1ProtocolHyperImpl.is_idlec                 C  s   | j o| jj S r   )rT   rS   r`   rW   r   r   r   has_expired   s   z"HTTP1ProtocolHyperImpl.has_expiredc                 C  s   |   std| jS )NzCannot generate a new stream ID because the connection is not idle. HTTP/1.1 is not multiplexed and we do not support HTTP pipelining.)rd   RuntimeErrorrV   rW   r   r   r   get_available_stream_id   s
   z.HTTP1ProtocolHyperImpl.get_available_stream_idr   
error_codec                 C  s   d S r   r   )r@   rm   r   r   r   submit_close      z#HTTP1ProtocolHyperImpl.submit_closeF	stream_idr    r   
end_streamc                 C  s:   || j kr	td| t| |r| t  d S d S NzInvalid stream ID.)rV   r&   _h11_submitr1   r*   EndOfMessage)r@   rp   r    rq   r   r   r   submit_headers   s   
z%HTTP1ProtocolHyperImpl.submit_headersdatar   c                 C  sn   || j kr	td| jjtjkr"| j| |r | j| 	  d S | 
t| |r5| 
t  d S d S rr   )rV   r&   rP   rb   r*   SWITCHED_PROTOCOLrR   r(   rS   _connection_terminatedrs   Datart   )r@   rp   rv   rq   r   r   r   submit_data   s   
z"HTTP1ProtocolHyperImpl.submit_datac                 C  s   |    d S r   )connection_lost)r@   rp   rm   r   r   r   submit_stream_reset   s   z*HTTP1ProtocolHyperImpl.submit_stream_resetc                 C  sJ   | j jtjkr| j|   d S | js#| j   | j|   d S d S r   )	rP   rb   r*   rw   rS   r(   rx   rT   send_failedrW   r   r   r   r{      s   

z&HTTP1ProtocolHyperImpl.connection_lostc                 C  s0   | j jtjkr| j|   d S | d d S N    )rP   rb   r*   rw   rS   r(   rx   _h11_data_receivedrW   r   r   r   eof_received   s   z#HTTP1ProtocolHyperImpl.eof_receivedc                 C  s<   |sd S | j jtjkr| jt| j| d S | | d S r   )	rP   rb   r*   rw   rS   r(   r
   rV   r   r@   rv   r   r   r   bytes_received   s   z%HTTP1ProtocolHyperImpl.bytes_receivedc                 C  s"   d | j}| j  |   |S r~   )r   rR   clear_maybe_start_next_cycler   r   r   r   bytes_to_send   s   
z$HTTP1ProtocolHyperImpl.bytes_to_sendN
int | NoneEvent | Nonec                 C  s   | j j|dS )N)rp   )rS   popleft)r@   rp   r   r   r   
next_event   s   z!HTTP1ProtocolHyperImpl.next_eventrp   
excl_eventr   tuple[type[Event], ...] | Nonec                C  s   | j j||dS )Nr   )rS   has)r@   rp   r   r   r   r   has_pending_event   s   z(HTTP1ProtocolHyperImpl.has_pending_event	h11_eventr!   c                 C  s$   | j |}|r| j| d S d S r   )rP   send_with_data_passthroughrR   extend)r@   r   chunksr   r   r   rs     s   z"HTTP1ProtocolHyperImpl._h11_submitc                 C  s   | j | |   d S r   )rP   receive_data_fetch_eventsr   r   r   r   r     s   z)HTTP1ProtocolHyperImpl._h11_data_receivedc              
   C  s  | j j}| j}| jsz| }W n tjy/ } z|| |jt	| W Y d }~d S d }~ww |j
}|tju s=|tju rLtj|jkrJ||   nqd S |tju r\|t| jt| n_|tju rm|t| jt|d nN|tju r|j}|t| j|j
tu rt|n| n4|tju r|jrt| j|j|jtjk}nt| jd|jtjk}|| |   n|tju r||   | jr
d S d S )N)rp   r    r   )rS   r(   rP   rT   r   r*   r\   rx   error_status_hintr5   rE   	NEED_DATAPAUSED
MUST_CLOSErb   Responser   rV   r9   InformationalResponser   ry   rv   r
   	bytearrayr   rt   r    MIGHT_SWITCH_PROTOCOLr   ConnectionClosed)r@   aconnr   eev_typepayload
last_eventr   r   r   r     sl   







z$HTTP1ProtocolHyperImpl._fetch_eventsmessage
str | Noner   c                 C  s   d| _ t||S )NT)rT   r	   )r@   rm   r   r   r   r   rx   L  s   
z-HTTP1ProtocolHyperImpl._connection_terminatedc                 C  s   t j| jj  kr| jjkrn n| j  |  jd7  _t j| jjkr>| js@| jj	\}}|r9| j
t| j| d| _d S d S d S )NrM   T)r*   DONErP   ra   rb   start_next_cyclerV   rw   rU   trailing_datarS   r(   r
   )r@   rv   closedr   r   r   r   R  s   "

z.HTTP1ProtocolHyperImpl._maybe_start_next_cycleeventsc                 G  s   t |D ]}| j| qd S r   )reversedrS   
appendleft)r@   r   evr   r   r   reshelve\  s   zHTTP1ProtocolHyperImpl.reshelvec                 C  s   t d)Nzhttp1 does not support PING)NotImplementedErrorrW   r   r   r   ping`  s   zHTTP1ProtocolHyperImpl.pingc                 C  rf   r_   r   rW   r   r   r   expect_pongc  ro   z"HTTP1ProtocolHyperImpl.expect_pongrF   )r   rY   )r   r^   )r   re   )r   )rm   re   r   r;   )F)rp   re   r    r   rq   r^   r   r;   )rp   re   rv   r   rq   r^   r   r;   )rp   re   rm   re   r   r;   )rv   r   r   r;   )r   r   r   )rp   r   r   r   )rp   r   r   r   r   r^   )r   r!   r   r;   )r   N)rm   re   r   r   r   r   )r   r   r   r;   ) rG   rH   rI   rL   __annotations__rX   staticmethodr]   rd   propertyrg   ri   rj   rl   rn   ru   rz   r|   r{   r   r   r   r   r   rs   r   r   rx   r   r   r   r   r   r   r   r   rK      sD   
 








	


>



rK   )r   r   r   r   )r    r   r   r!   )r2   r3   r   r   )
__future__r   	functoolsr   r*   
h11._stater   r   _stream_matrixr   _typingr   r   r	   r
   r   r   r   
_protocolsr   	frozensetrc   r   rh   r   r1   r9   r:   rK   r   r   r   r   <module>   s   

/