U
    nËjÙ  ã                   @  s¶   d dl mZ d dlZd dlZd dlZd dlZddlmZmZ ddl	m
Z
 ddlmZ ejrrd dlmZ d d	lmZ e d
¡ZdgZdddœdd„ZG dd„ de
ƒZG dd„ deƒZdS )é    )ÚannotationsNé   )ÚRequestÚResponse)ÚSyncByteStreamé   )ÚBaseTransport)Ú
OptExcInfo)ÚWSGIApplicationÚ_TÚWSGITransportztyping.Iterable[_T])ÚbodyÚreturnc                 C  s,   t | ƒ} | D ]}|rt |g| ¡  S qg S ©N)ÚiterÚ	itertoolsÚchain)r   Úchunk© r   ú:/tmp/pip-unpacked-wheel-7ig9zwdf/httpx/_transports/wsgi.pyÚ_skip_leading_empty_chunks   s
    r   c                   @  s8   e Zd Zdddœdd„Zddœdd	„Zddœd
d„ZdS )ÚWSGIByteStreamztyping.Iterable[bytes]ÚNone)Úresultr   c                 C  s   t |dd ƒ| _t|ƒ| _d S )NÚclose)ÚgetattrÚ_closer   Ú_result)Úselfr   r   r   r   Ú__init__   s    zWSGIByteStream.__init__ztyping.Iterator[bytes])r   c                 c  s   | j D ]
}|V  qd S r   )r   )r   Úpartr   r   r   Ú__iter__#   s    
zWSGIByteStream.__iter__c                 C  s   | j d k	r|   ¡  d S r   )r   )r   r   r   r   r   '   s    
zWSGIByteStream.closeN)Ú__name__Ú
__module__Ú__qualname__r   r!   r   r   r   r   r   r      s   r   c                   @  s:   e Zd ZdZdddddd	d
dœdd„Zdddœdd„ZdS )r   a  
    A custom transport that handles sending requests directly to an WSGI app.
    The simplest way to use this functionality is to use the `app` argument.

    ```
    client = httpx.Client(app=app)
    ```

    Alternatively, you can setup the transport instance explicitly.
    This allows you to include any additional configuration arguments specific
    to the WSGITransport class:

    ```
    transport = httpx.WSGITransport(
        app=app,
        script_name="/submount",
        remote_addr="1.2.3.4"
    )
    client = httpx.Client(transport=transport)
    ```

    Arguments:

    * `app` - The WSGI application.
    * `raise_app_exceptions` - Boolean indicating if exceptions in the application
       should be raised. Default to `True`. Can be set to `False` for use cases
       such as testing the content of a client 500 response.
    * `script_name` - The root path on which the WSGI application should be mounted.
    * `remote_addr` - A string indicating the client IP of incoming requests.
    ```
    TÚ ú	127.0.0.1Nr
   ÚboolÚstrztyping.TextIO | Noner   )ÚappÚraise_app_exceptionsÚscript_nameÚremote_addrÚwsgi_errorsr   c                 C  s"   || _ || _|| _|| _|| _d S r   )r)   r*   r+   r,   r-   )r   r)   r*   r+   r,   r-   r   r   r   r   M   s
    zWSGITransport.__init__r   r   )Úrequestr   c                   sf  |  ¡  t |j¡}|jjp,dddœ|jj }d|jj|| jpBtj	ddd|j
| j|jj|jj d¡|jjt|ƒd| jd	œ}|jjD ]<\}}| d¡ ¡  d
d¡}|dkr°d| }| d¡||< q‚d ‰d ‰d ‰ ddddddœ‡ ‡‡fdd„}|  ||¡}	t|	ƒ}
ˆd k	�st‚ˆd k	�st‚ˆ �r:ˆ d �r:| j�r:ˆ d ‚tˆ ¡ d ƒ}dd„ ˆD ƒ}t|||
d�S )NéP   i»  )ÚhttpÚhttps)r   r   TFÚasciizHTTP/1.1)zwsgi.versionzwsgi.url_schemez
wsgi.inputzwsgi.errorszwsgi.multithreadzwsgi.multiprocesszwsgi.run_onceÚREQUEST_METHODZSCRIPT_NAMEZ	PATH_INFOÚQUERY_STRINGZSERVER_NAMEZSERVER_PORTZSERVER_PROTOCOLZREMOTE_ADDRú-Ú_)ÚCONTENT_TYPEÚCONTENT_LENGTHZHTTP_r(   zlist[tuple[str, str]]zOptExcInfo | Nonez$typing.Callable[[bytes], typing.Any])ÚstatusÚresponse_headersÚexc_infor   c                   s   | ‰|‰|‰ dd„ S )Nc                 S  s   d S r   r   )r6   r   r   r   Ú<lambda>„   ó    zFWSGITransport.handle_request.<locals>.start_response.<locals>.<lambda>r   )r9   r:   r;   ©Zseen_exc_infoZseen_response_headersZseen_statusr   r   Ústart_response{   s    z4WSGITransport.handle_request.<locals>.start_responser   r   c                 S  s$   g | ]\}}|  d ¡|  d ¡f‘qS )r2   )Úencode)Ú.0ÚkeyÚvaluer   r   r   Ú
<listcomp>�   s   ÿz0WSGITransport.handle_request.<locals>.<listcomp>)ÚheadersÚstream)N)ÚreadÚioÚBytesIOÚcontentÚurlÚportÚschemer-   ÚsysÚstderrÚmethodr+   ÚpathÚqueryÚdecodeÚhostr(   r,   rE   ÚrawÚupperÚreplacer)   r   ÚAssertionErrorr*   ÚintÚsplitr   )r   r.   Z
wsgi_inputrL   ÚenvironZ
header_keyÚheader_valuerB   r?   r   rF   Ústatus_coderE   r   r>   r   Úhandle_request[   sP    
ñ ýþzWSGITransport.handle_request)Tr%   r&   N)r"   r#   r$   Ú__doc__r   r^   r   r   r   r   r   ,   s   #    ú)Ú
__future__r   rH   r   rN   ÚtypingZ_modelsr   r   Ú_typesr   Úbaser   ÚTYPE_CHECKINGZ	_typeshedr	   Z_typeshed.wsgir
   ÚTypeVarr   Ú__all__r   r   r   r   r   r   r   Ú<module>   s   
