o
    ߥi                     @   s   d dl Z d dlmZmZmZmZmZ d dlmZ d dl	m
Z
mZmZmZmZmZ d dlmZmZmZ d dlmZ d dlmZ d dlmZmZ d d	lmZ G d
d deeef eZG dd deZ dS )    N)AnyDictIteratorMappingOptional)	parse_qsl)URLAddressFormDataHeadersQueryParams
UploadFile)MalformedJSONMalformedMultipartUnsupportedMediaType)parse_stream)MoreInfoFromHeaderMixin)EnvironStartResponse)cached_propertyc                   @   s   e Zd ZdZ	ddedee ddfddZdede	fd	d
Z
dee fddZdefddZde	defddZedefddZedefddZedeee	f fddZedefddZedefddZdS )HTTPConnectionz
    A base class for incoming HTTP connections.

    It is a valid Mapping type that allows you to directly
    access the values in any WSGI `environ` dictionary.
    Nenvironstart_responsereturnc                 C   s   || _ || _d S N)_environ_start_responseselfr   r    r   G/home/ubuntu/.local/lib/python3.10/site-packages/baize/wsgi/requests.py__init__   s   
zHTTPConnection.__init__keyc                 C   s
   | j | S r   )r   )r   r"   r   r   r    __getitem__"      
zHTTPConnection.__getitem__c                 C   
   t | jS r   )iterr   r   r   r   r    __iter__%   r$   zHTTPConnection.__iter__c                 C   r%   r   )lenr   r'   r   r   r    __len__(   r$   zHTTPConnection.__len__otherc                 C   s(   t || jstS | j|jko| j|jkS r   )
isinstance	__class__NotImplementedr   r   )r   r+   r   r   r    __eq__+   s
   
zHTTPConnection.__eq__c                 C   s6   |  dr|  drt| d t| d S tdddS )z
        Client's IP and Port.

        Note that this depends on the `REMOTE_ADDR` and `REMOTE_PORT` values
        given by the WSGI Server, and is not necessarily accurate.
        REMOTE_ADDRREMOTE_PORTN)hostport)getr	   intr'   r   r   r    client3   s   zHTTPConnection.clientc                 C   s   t | jdS )z/
        The full URL of this request.
        )r   )r   r   r'   r   r   r    url?      zHTTPConnection.urlc                 C   s   |  di S )z>
        The path parameters parsed by the framework.
        PATH_PARAMS)r4   r'   r   r   r    path_paramsF   r8   zHTTPConnection.path_paramsc                 C   s   t | d S )z?
        Query parameter. It is a multi-value mapping.
        QUERY_STRING)r   r'   r   r   r    query_paramsM   r8   zHTTPConnection.query_paramsc                 C   s   t dd | j D S )z
        A read-only case-independent mapping.

        Note that in its internal storage, all keys are in lower case.
        c                 s   sP    | ]#\}}| d s|dv r| d r|dd n| dd|fV  qdS )HTTP_)CONTENT_TYPECONTENT_LENGTH   N_-)
startswithlowerreplace).0r"   valuer   r   r    	<genexpr>[   s    $z)HTTPConnection.headers.<locals>.<genexpr>)r   r   itemsr'   r   r   r    headersT   s   zHTTPConnection.headersr   )__name__
__module____qualname____doc__r   r   r   r!   strr   r#   r   r(   r5   r*   boolr/   r   r	   r6   r   r7   r   r:   r   r<   r   rJ   r   r   r   r    r      s0    
r   c                       s   e Zd Z	ddedee ddf fddZedefddZ	dd
e
dee fddZedefddZedefddZdededefddZedefddZdddZ  ZS )RequestNr   r   r   c                    s   t  || d| _d S )NF)superr!   _stream_consumedr   r-   r   r    r!   f   s   
zRequest.__init__c                 C   s   | d S )z0
        HTTP method. Uppercase string.
        REQUEST_METHODr   r'   r   r   r    methodl   s   zRequest.method   
chunk_sizec                 c   sR    d| j v r| jV  dS | jrtdd| _| jd }	 ||}|s%dS |V  q)a"  
        Streaming read request body. e.g. `for chunk in request.stream(): ...`

        If you access `.stream()` then the byte chunks are provided
        without storing the entire body to memory. Any subsequent
        calls to `.body`, `.form`, or `.json` will raise an error.
        bodyNzStream consumedTz
wsgi.input)__dict__rY   rS   RuntimeErrorr   read)r   rX   rY   chunkr   r   r    streams   s   


zRequest.streamc                 C   s   d dd |  D S )zZ
        Read all the contents of the request body into the memory and return it.
            c                 S   s   g | ]}|qS r   r   )rF   r]   r   r   r    
<listcomp>   s    z Request.body.<locals>.<listcomp>)joinr^   r'   r   r   r    rY      s   zRequest.bodyc              
   C   s\   | j dkr*zt| j| j jddW S  tjy) } ztt	|dd}~ww t
d)z
        Call `self.body` and use `json.loads` parse it.

        If `content_type` is not equal to `application/json`,
        an HTTPExcption exception will be thrown.
        zapplication/jsoncharsetutf8N)content_typejsonloadsrY   decodeoptionsr4   JSONDecodeErrorr   rO   r   )r   excr   r   r    re      s   
zRequest.jsonboundaryrb   c                 C   s   t t|  ||tdS )N)file_factory)r
   parse_multipartr^   r   )r   rk   rb   r   r   r    _parse_multipart   s   zRequest._parse_multipartc                 C   s   | j dkr&| j jdd}d| j jvrtd| j jd d}| ||S | j dkr@| jj| j jddd}tt	|d	d
S t
d)a  
        Parse the data in the form format and return it as a multi-value mapping.

        If `content_type` is equal to `multipart/form-data`, it will directly
        perform streaming analysis, and subsequent calls to `self.body`
        or `self.json` will raise errors.

        If `content_type` is not equal to `multipart/form-data` or
        `application/x-www-form-urlencoded`, an HTTPExcption exception will be thrown.
        zmultipart/form-datarb   rc   rk   z'Missing boundary in header content-typezlatin-1z!application/x-www-form-urlencoded)encodingT)keep_blank_valuesz6multipart/form-data, application/x-www-form-urlencoded)rd   rh   r4   r   encodern   rY   rg   r
   r   r   )r   rb   rk   rY   r   r   r    form   s   

zRequest.formc                 C   s   d| j v r| j  dS dS )z
        Close all temporary files in the `self.form`.

        This can always be called, regardless of whether you use form or not.
        rr   N)rZ   rr   closer'   r   r   r    rs      s   
zRequest.closer   )rW   )r   N)rK   rL   rM   r   r   r   r!   propertyrO   rV   r5   r   bytesr^   r   rY   r   re   r
   rn   rr   rs   __classcell__r   r   rT   r    rQ   e   s(    rQ   )!re   typingr   r   r   r   r   urllib.parser   baize.datastructuresr   r	   r
   r   r   r   baize.exceptionsr   r   r   baize.multipart_helperr   rm   baize.requestsr   baize.typingr   r   baize.utilsr   rO   r   rQ   r   r   r   r    <module>   s     Q