U
    C]H                     @   s   d dl Z ddlmZ ddlmZ ddl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 eeZG d
d deZG dd dZdS )    N   )AsyncioBackend)ConcurrencyBackend)	CertTypesTimeoutTypesVerifyTypes)AsyncRequestAsyncResponse)MessageLoggerASGIMiddleware
get_logger   )AsyncDispatcherc                   @   sN   e Zd ZdZdejeeejee	f e
ddddZdeeeeed	d
dZdS )ASGIDispatcha  
    A custom dispatcher that handles sending requests directly to an ASGI app.

    The simplest way to use this functionality is to use the `app` argument.
    This will automatically infer if 'app' is a WSGI or an ASGI application,
    and will setup an appropriate dispatch class:

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

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

    ```
    dispatch = httpx.ASGIDispatch(
        app=app,
        root_path="/submount",
        client=("1.2.3.4", 123)
    )
    client = httpx.Client(dispatch=dispatch)
    ```

    Arguments:

    * `app` - The ASGI 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.
    * `root_path` - The root path on which the ASGI application should be mounted.
    * `client` - A two-tuple indicating the client IP and port of incoming requests.
    ```
    T z	127.0.0.1{   N)appraise_app_exceptions	root_pathclientbackendreturnc                 C   s0   || _ || _|| _|| _|d kr&t n|| _d S N)r   r   r   r   r   r   )selfr   r   r   r   r    r   s/var/www/html/staging.mfahmagazine.net/magazine_api/magazine_env/lib/python3.8/site-packages/httpx/dispatch/asgi.py__init__1   s
    zASGIDispatch.__init__)requestverifycerttimeoutr   c                    s\  dddidj jjjjjjjjdjj
j	
j
d	t
jtd d d d 
j t
j tdfd	d
td dfddd d 	fdd}
j| I d H  I d H  d k	r
jrI d H  d k	stdd k	s,td d
fdd}td |dS )Nhttpversionz3.0z1.1ascii)typeZasgihttp_versionmethodheadersschemepathZquery_stringserverr   r   )loggerr   c                     s@   z   I d H } W n  tk
r2   dddd Y S X d| ddS )Nzhttp.request    F)r$   body	more_bodyT)	__anext__StopAsyncIteration)r.   )request_streamr   r   receive\   s
    z"ASGIDispatch.send.<locals>.receive)messager   c                    s   | d dkr*| d |  dg    nT| d dkr~|  dd}|  dd	}|rljd
krl|I d H  |s~ I d H  d S )Nr$   zhttp.response.startstatusr'   zhttp.response.bodyr.   r-   r/   FZHEAD)getsetr&   putmark_as_done)r4   r.   r/   )r'   r   response_bodyresponse_started_or_failedstatus_coder   r   sendc   s    
zASGIDispatch.send.<locals>.sendc               
      s`   zBz I d H  W n& tk
r> }  z| W 5 d } ~ X Y nX W 5   I d H    X d S r   )r9   r7   	Exception)exc)r   app_excr3   r:   r;   scoper=   r   r   run_appu   s    z"ASGIDispatch.send.<locals>.run_appz&application did not return a response.c                      s4     I d H   I d H   d k	r0jr0 d S r   )draincloser   r   )r@   
backgroundr:   r   r   r   on_close   s    z#ASGIDispatch.send.<locals>.on_closezHTTP/1.1)r<   r%   r'   contentrF   r   )r&   r'   rawurlr(   r)   queryencodehostr   r   r
   r   r+   r   Zcreate_eventBodyIteratorstreamdictZbackground_manager
__aenter__waitr   rD   AssertionErrorr	   iterate)r   r   r   r   r    rB   rF   r   )r   r@   rE   r'   r3   r   r2   r:   r;   rA   r   r=   r<   r   r=   ?   sL    	

zASGIDispatch.send)Tr   r   N)NNN)__name__
__module____qualname____doc__typingCallableboolstrZTupleintr   r   r   r   r   r   r	   r=   r   r   r   r   r      s.   &       r   c                   @   s`   e Zd ZdZeddddZeje dddZ	ddd	d
Z
eddddZddddZdS )rM   zm
    Provides a byte-iterator interface that the client can use to
    ingest the response content from.
    N)r   r   c                 C   s   |j dd| _t | _d S )Nr   )max_size)Zcreate_queue_queueobject_done)r   r   r   r   r   r      s    zBodyIterator.__init__r,   c                 C  s6   | j  I dH }|| jkrq2t|ts*t|V  q dS )zS
        A byte-iterator, used by the client to consume the response body.
        N)r^   r6   r`   
isinstancebytesrR   r   datar   r   r   rS      s
    
zBodyIterator.iteratec                    s   |   2 z3 dH W }q6 dS )zl
        Drain any remaining body, in order to allow any blocked `put()` calls
        to complete.
        N)rS   )r   chunkr   r   r   rC      s    zBodyIterator.drain)rd   r   c                    s   | j |I dH  dS )zF
        Used by the server to add data to the response body.
        N)r^   r8   rc   r   r   r   r8      s    zBodyIterator.putc                    s   | j | jI dH  dS )zL
        Used by the server to signal the end of the response body.
        N)r^   r8   r`   )r   r   r   r   r9      s    zBodyIterator.mark_as_done)rT   rU   rV   rW   r   r   rX   AsyncIteratorrb   rS   rC   r8   r9   r   r   r   r   rM      s   rM   )rX   Zconcurrency.asyncior   Zconcurrency.baser   configr   r   r   Zmodelsr   r	   utilsr
   r   baser   rT   r+   r   rM   r   r   r   r   <module>   s    