o
    iX                     @   sD   d Z ddlmZ ddlmZ G dd dZG dd dZddgZdS )	zV
HTTP/2 request wrapper.

Provides a Request-compatible interface for HTTP/2 streams.
    )BytesIO)split_request_uric                   @   sN   e Zd ZdZdd ZdddZdddZdd	d
Zdd Zdd Z	dd Z
dS )	HTTP2BodyzBody wrapper for HTTP/2 request data.

    Provides a file-like interface to the request body,
    compatible with gunicorn's Body class expectations.
    c                 C   s   t || _t|| _dS )zfInitialize with body data.

        Args:
            data: bytes containing the request body
        N)r   _datalen_len)selfdata r
   J/home/ubuntu/.local/lib/python3.10/site-packages/gunicorn/http2/request.py__init__   s   
zHTTP2Body.__init__Nc                 C      |du r	| j  S | j |S )zRead data from the body.

        Args:
            size: Number of bytes to read, or None for all remaining

        Returns:
            bytes: The requested data
        N)r   readr   sizer
   r
   r   r   !      	
zHTTP2Body.readc                 C   r   )zRead a line from the body.

        Args:
            size: Maximum bytes to read

        Returns:
            bytes: A line of data
        N)r   readliner   r
   r
   r   r   .   r   zHTTP2Body.readlinec                 C   s   | j |S )zRead all lines from the body.

        Args:
            hint: Approximate byte count hint

        Returns:
            list: List of lines
        )r   	readlines)r   hintr
   r
   r   r   ;   s   	zHTTP2Body.readlinesc                 C   s
   t | jS )zIterate over lines in the body.)iterr   r   r
   r
   r   __iter__F      
zHTTP2Body.__iter__c                 C   s   | j S )zReturn the content length.)r   r   r
   r
   r   __len__J   s   zHTTP2Body.__len__c                 C   s   | j   dS )zClose the body stream.N)r   closer   r
   r
   r   r   N   s   zHTTP2Body.close)N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r
   r
   r
   r   r      s    
	

r   c                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zed
d Z	edd Z
dd ZdS )HTTP2RequestzHTTP/2 request wrapper compatible with gunicorn Request interface.

    Wraps an HTTP2Stream to provide the same interface as the HTTP/1.x
    Request class, allowing workers to handle HTTP/2 requests using
    existing code paths.
    c                 C   sl  || _ || _|| _|| _d| _| }|dd| _|dd| _|dd}|dd	}|| _	zt
|}|jp9d| _|jp?d| _|jpEd| _W n tyZ   || _d| _d| _Y nw || _g | _| D ]\}}	| j| |	f qe|rd
d | jD | _| jd|f g | _|jrdd |jD | _| }
t|
| _d| _d| _|j| _d| _|j| _|j| _dS )zInitialize from an HTTP/2 stream.

        Args:
            stream: HTTP2Stream instance with received headers/body
            cfg: Gunicorn configuration object
            peer_addr: Client address tuple (host, port)
        )   r   z:methodGETz:schemehttpsz
:authority z:path/c                 S   s    g | ]\}}|d kr||fqS )HOSTr
   ).0nvr
   r
   r   
<listcomp>   s     z)HTTP2Request.__init__.<locals>.<listcomp>r%   c                 S   s   g | ]
\}}|  |fqS r
   )upper)r&   namevaluer
   r
   r   r)      s    
FN)streamcfg	peer_addrremote_addrversionget_pseudo_headersgetmethodschemeurir   pathqueryfragment
ValueError
_authorityheadersget_regular_headersappendr*   trailersget_request_bodyr   body
must_close_expected_100_continue	stream_id
req_numberproxy_protocol_infopriority_weightpriority_depends_on)r   r-   r.   r/   pseudo	authorityr7   partsr+   r,   	body_datar
   r
   r   r   [   sR   

zHTTP2Request.__init__c                 C   s
   d| _ dS )z1Force the connection to close after this request.TNrB   r   r
   r
   r   force_close   r   zHTTP2Request.force_closec                 C   s   | j rdS dS )zCheck if connection should close after this request.

        HTTP/2 connections are persistent by design, but we may still
        need to close if explicitly requested.

        Returns:
            bool: True if connection should close
        TFrM   r   r
   r
   r   should_close   s   	zHTTP2Request.should_closec                 C   s,   |  }| jD ]\}}||kr|  S qdS )zGet a header value by name.

        Args:
            name: Header name (case-insensitive)

        Returns:
            str: Header value, or None if not found
        N)r*   r<   )r   r+   h_nameh_valuer
   r
   r   
get_header   s   	zHTTP2Request.get_headerc                 C   s6   |  d}|durzt|W S  ty   Y dS w dS )zsGet the Content-Length header value.

        Returns:
            int: Content length, or None if not set
        zCONTENT-LENGTHN)rR   intr:   )r   clr
   r
   r   content_length   s   

zHTTP2Request.content_lengthc                 C   s
   |  dS )zoGet the Content-Type header value.

        Returns:
            str: Content type, or None if not set
        zCONTENT-TYPE)rR   r   r
   r
   r   content_type   s   
zHTTP2Request.content_typec                 C   s    d| j  d| j d| jj dS )Nz<HTTP2Request method=z path=z stream_id=>)r4   r7   r-   rD   r   r
   r
   r   __repr__   s   zHTTP2Request.__repr__N)r   r   r   r   r   rN   rO   rR   propertyrU   rV   rX   r
   r
   r
   r   r   S   s    M

r   N)r   ior   gunicorn.utilr   r   r   __all__r
   r
   r
   r   <module>   s   B 