o
    ;ivU                     @   s  d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZmZmZmZmZmZmZmZmZmZmZ ddlmZmZ ejdkrTddlmZ nddlmZ G d	d
 d
eZG dd deZG dd deZG dd deZeeef Z eeeef Z!G dd deZ"G dd deZ#G dd deZ$G dd deZ%G dd deZ&G dd deZ'G dd deZ(G dd  d eZ)G d!d" d"eZ*G d#d$ d$eZ+G d%d& d&eZ,G d'd( d(eZ-G d)d* d*eZ.G d+d, d,eZ/G d-d. d.eZ0G d/d0 d0eZ1ee"e%e&e(e*e,e-f Z2ee#e$e%e'e)e+e.e/e0e1f
 Z3eg ee2 f Z4ee3ged f Z5ee!e4e5ged f Z6G d1d2 d2eZ7G d3d4 d4ed5d6Z8G d7d8 d8eZ9G d9d: d:eZ:ed;e;e<e<f e=e9e:e>e>e>d<Z?G d=d> d>e7e8e?Z@e;eAeB eBee
 f ZCeeDgdf ZEG d?d@ d@eZFeeD ZGee@eFgeGf ZHG dAdB dBZIeJ dCZKZLdDdE ZMdFedGeIdHe@fdIdJZNG dKdL dLZOG dMdN dNZPdS )Oa  
Vendored version of a2wsgi v1.10.2.

We vendor only a2wsgi/wsgi.py, plus type annotations, to convert WSGI apps into ASGI protocol
versions using the `WSGIMiddleware` class.

This is a well-tested library marked as an optional dependency of uvicorn. It doesn't have the
issues with buffering request streams that asgiref has, and it also is simpler, only requiring a
standard `concurrent.futures.ThreadPoolExecutor`.

---

   Copyright 2022 abersheeran

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
    N)ThreadPoolExecutor)TracebackType)AnyCallableDictListLiteralOptionalProtocolTupleType	TypedDictUnion)	AwaitableIterable)      )NotRequiredc                   @   s"   e Zd ZU eed< ed ed< dS )ASGIVersionsspec_versionz3.0versionN)__name__
__module____qualname__str__annotations__r    r   r   M/home/ubuntu/.local/lib/python3.10/site-packages/modal/_vendor/a2wsgi_wsgi.pyr   <   s   
 r   c                   @   s   e Zd ZU ed ed< eed< eed< eed< eed< eed< ee ed< eed	< eed
< e	e
eef  ed< ee
eef  ed< ee
eee f  ed< eeeef  ed< eeeeeef f  ed< dS )	HTTPScopehttptypeasgihttp_versionmethodschemepathraw_pathquery_string	root_pathheadersclientserverstate
extensionsN)r   r   r   r   r   r   r   r   bytesr   tupleintr	   dictr   objectr   r   r   r   r   A   s   
  r   c                   @   s   e Zd ZU ed ed< eed< eed< eed< eed< eed< eed< eed	< ee	eef  ed
< e
e	eef  ed< e
e	eee f  ed< ee ed< e
eeef  ed< e
eeeeef f  ed< dS )WebSocketScope	websocketr    r!   r"   r$   r%   r&   r'   r(   r)   r*   r+   subprotocolsr,   r-   N)r   r   r   r   r   r   r   r.   r   r/   r   r0   r	   r1   r   r2   r   r   r   r   r3   R   s   
  r3   c                   @   s6   e Zd ZU ed ed< eed< eeee	f  ed< dS )LifespanScopelifespanr    r!   r,   N)
r   r   r   r   r   r   r   r1   r   r   r   r   r   r   r6   c   s   
 r6   c                   @   s.   e Zd ZU ed ed< eed< ee ed< dS )HTTPRequestEventzhttp.requestr    body	more_bodyN)r   r   r   r   r   r.   r   boolr   r   r   r   r8   m   s   
 r8   c                   @   sF   e Zd ZU ed ed< eed< eeee	e	f   ed< ee
 ed< dS )HTTPResponseStartEventhttp.response.startr    statusr)   trailersN)r   r   r   r   r   r0   r   r   r/   r.   r;   r   r   r   r   r<   s   s
   
 r<   c                   @   2   e Zd ZU ed ed< ee ed< ee ed< dS )HTTPResponseBodyEventhttp.response.bodyr    r9   r:   N)r   r   r   r   r   r   r.   r;   r   r   r   r   rA   z      
 rA   c                   @      e Zd ZU ed ed< dS )HTTPDisconnectEventzhttp.disconnectr    Nr   r   r   r   r   r   r   r   r   rE         
 rE   c                   @   rD   )WebSocketConnectEventzwebsocket.connectr    NrF   r   r   r   r   rH      rG   rH   c                   @   s>   e Zd ZU ed ed< ee ed< eeee	e	f   ed< dS )WebSocketAcceptEventzwebsocket.acceptr    subprotocolr)   N)
r   r   r   r   r   r   r   r   r/   r.   r   r   r   r   rI      s   
 rI   c                   @   r@   )WebSocketReceiveEventzwebsocket.receiver    r.   textNr   r   r   r   r   r   r.   r   r   r   r   r   rK      rC   rK   c                   @   r@   )WebSocketSendEventzwebsocket.sendr    r.   rL   NrM   r   r   r   r   rN      rC   rN   c                   @   "   e Zd ZU ed ed< eed< dS )WebSocketDisconnectEventzwebsocket.disconnectr    codeN)r   r   r   r   r   r0   r   r   r   r   rP         
 rP   c                   @   r@   )WebSocketCloseEventwebsocket.closer    rQ   reasonN)r   r   r   r   r   r   r0   r   r   r   r   r   rS      rC   rS   c                   @   rD   )LifespanStartupEventlifespan.startupr    NrF   r   r   r   r   rV      rG   rV   c                   @   rD   )LifespanShutdownEventlifespan.shutdownr    NrF   r   r   r   r   rX      rG   rX   c                   @   rD   )LifespanStartupCompleteEventlifespan.startup.completer    NrF   r   r   r   r   rZ      rG   rZ   c                   @   rO   )LifespanStartupFailedEventzlifespan.startup.failedr    messageNr   r   r   r   r   r   r   r   r   r   r\      rR   r\   c                   @   rD   )LifespanShutdownCompleteEventlifespan.shutdown.completer    NrF   r   r   r   r   r_      rG   r_   c                   @   rO   )LifespanShutdownFailedEventzlifespan.shutdown.failedr    r]   Nr^   r   r   r   r   ra      rR   ra   c                   @   s.   e Zd ZU eed< eed< eed< eed< dS )CGIRequiredDefinedREQUEST_METHODSERVER_NAMESERVER_PORTSERVER_PROTOCOLNr   r   r   r   r   r   r   r   r   rb      s
   
 rb   c                   @   sN   e Zd ZU eed< eed< eed< eed< eed< eed< eed< eed< d	S )
CGIOptionalDefinedREQUEST_URIREMOTE_ADDRREMOTE_PORTSCRIPT_NAME	PATH_INFOQUERY_STRINGCONTENT_TYPECONTENT_LENGTHNrg   r   r   r   r   rh      s   
 rh   F)totalc                   @   sP   e Zd ZdZddedefddZddedefdd	Zdd
edee fddZ	dS )InputStreamas  
    An input stream (file-like object) from which the HTTP request body bytes can be
    read. (The server or gateway may perform reads on-demand as requested by the
    application, or it may pre- read the client's request body and buffer it in-memory
    or on disk, or use any other technique for providing such an input stream, according
    to its preference.)
    sizereturnc                C      t )aB  
        The server is not required to read past the client's specified Content-Length,
        and should simulate an end-of-file condition if the application attempts to read
        past that point. The application should not attempt to read more data than is
        specified by the CONTENT_LENGTH variable.
        A server should allow read() to be called without an argument, and return the
        remainder of the client's input stream.
        A server should return empty bytestrings from any attempt to read from an empty
        or exhausted input stream.
        NotImplementedError)selfrt   r   r   r   read  s   zInputStream.readlimitc                C   rv   )a  
        Servers should support the optional "size" argument to readline(), but as in
        WSGI 1.0, they are allowed to omit support for it.
        (In WSGI 1.0, the size argument was not supported, on the grounds that it might
        have been complex to implement, and was not often used in practice... but then
        the cgi module started using it, and so practical servers had to start
        supporting it anyway!)
        rw   )ry   r{   r   r   r   readline"  s   	zInputStream.readlinehintc                C   rv   )z
        Note that the hint argument to readlines() is optional for both caller and
        implementer. The application is free not to supply it, and the server or gateway
        is free to ignore it.
        rw   )ry   r}   r   r   r   	readlines-  s   zInputStream.readlinesNrs   )
r   r   r   __doc__r0   r.   rz   r|   listr~   r   r   r   r   rr     s
    rr   c                   @   sB   e Zd ZdZdddZdedefddZd	ee defd
dZ	dS )ErrorStreama  
    An output stream (file-like object) to which error output can be written,
    for the purpose of recording program or other errors in a standardized and
    possibly centralized location. This should be a "text mode" stream;
    i.e., applications should use "
" as a line ending, and assume that it will
    be converted to the correct line ending by the server/gateway.
    (On platforms where the str type is unicode, the error stream should accept
    and log arbitrary unicode without raising an error; it is allowed, however,
    to substitute characters that cannot be rendered in the stream's encoding.)
    For many servers, wsgi.errors will be the server's main error log. Alternatively,
    this may be sys.stderr, or a log file of some sort. The server's documentation
    should include an explanation of how to configure this or where to find the
    recorded output. A server or gateway may supply different error streams to
    different applications, if this is desired.
    ru   Nc                 C   rv   )a  
        Since the errors stream may not be rewound, servers and gateways are free to
        forward write operations immediately, without buffering. In this case, the
        flush() method may be a no-op. Portable applications, however, cannot assume
        that output is unbuffered or that flush() is a no-op. They must call flush()
        if they need to ensure that output has in fact been written.
        (For example, to minimize intermingling of data from multiple processes writing
        to the same error log.)
        rw   ry   r   r   r   flushG  s   
zErrorStream.flushsc                C   rv   Nrw   )ry   r   r   r   r   writeS     zErrorStream.writeseqc                C   rv   r   rw   )ry   r   r   r   r   
writelinesV  r   zErrorStream.writelines)ru   N)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   6  s
    
r   WSGIDefined)wsgi.versionwsgi.url_scheme
wsgi.inputwsgi.errorswsgi.multithreadwsgi.multiprocesswsgi.run_oncec                   @   s   e Zd ZdZdS )Environz
    WSGI Environ
    N)r   r   r   r   r   r   r   r   r   p  s    r   c                	   @   s:   e Zd Z	ddedeeeef  dee defddZ	dS )	StartResponseNr>   response_headersexc_inforu   c                C   rv   r   rw   )ry   r>   r   r   r   r   r   __call__}  s   zStartResponse.__call__r   )
r   r   r   r   r   r/   r	   ExceptionInfoWriteCallabler   r   r   r   r   r   |  s    r   c                   @   s   e Zd ZdejdeddfddZedefddZ	de
fd	d
Zddede
fddZddede
fddZddedee
 fddZdeje
ddf fddZdS )Bodyloopreceiveru   Nc                 C   s   t  | _|| _|| _d| _d S )NT)	bytearraybufferr   r   	_has_more)ry   r   r   r   r   r   __init__  s   
zBody.__init__c                 C   s   | j s| jrdS dS )NTF)r   r   r   r   r   r   has_more  s   zBody.has_morec                 C   s@   | j sdS tj|  | jd}| }|dd| _ |ddS )N    r   r:   Fr9   )r   asynciorun_coroutine_threadsafer   r   resultget)ry   futurer]   r   r   r   _receive_more_data  s   zBody._receive_more_datars   rt   c                 C   s   |dks|t | jkr"| j|   | jsn|dks|t | jks|dkr2t| j}| j  |S t| jd | }| jd |= |S )Nrs   )lenr   extendr   r   r.   clear)ry   rt   r   r   r   r   rz     s   

z	Body.readr{   c                 C   s   	 | j dd|dkr|nd }|dkr(t| j d |d  }| j d |d = |S |dkr=t| j d | }| j d |= |S | jsAn	| j |   qt| j }| j   |S )NT   
r   rs      )r   findr.   r   r   r   r   )ry   r{   lf_indexr   r   r   r   r|     s"   

zBody.readliner}   c                    sh    j sg S |dkr) d}|d}|d dkr"|t|d  dd |D S  fddt|D S )Nrs   r   
   r   c                 S   s   g | ]}|d  qS )r   r   ).0liner   r   r   
<listcomp>      z"Body.readlines.<locals>.<listcomp>c                    s   g | ]}   qS r   )r|   )r   _r   r   r   r     r   )r   rz   splitpopr   range)ry   r}   raw_databytelistr   r   r   r~     s   

zBody.readlinesc                 c   s     | j r|  V  | j sd S d S r   )r   r|   r   r   r   r   __iter__  s   
zBody.__iter__r   )r   r   r   r   AbstractEventLoopReceiver   propertyr;   r   r.   r   r0   rz   r|   r   r~   typing	Generatorr   r   r   r   r   r     s    r   surrogateescapec                 C   s   |  ttdS )zCConvert an environment variable to a WSGI "bytes-as-unicode" stringz
iso-8859-1)encodeENCESCdecode)ur   r   r   unicode_to_wsgi  s   r   scoper9   ru   c                 C   sz  |  dddd}| d dd}||r#|t|d }tj dd}|r0t|}| | d ||| d	 d
d| d  d|  dd|tj	dddd}|  dpWd\}}||d< t
|pbd|d< |  d}|dur}|\}	}
|	|d< t
|
|d< |  dg D ]7\}}|d}|dkrd}n|dkrd}nd |  d!d"}|d}||v r|| d# | }|||< q|S )$zE
    Builds a scope and request body into a WSGI environ object.
    r(    utf8latin1r%   Nrl   r#   r'   asciizHTTP/r"   )r   r   r$   r   TF)z
asgi.scoperc   rl   rm   rn   rf   r   r   r   r   r   r   r   r+   )	localhostP   rd   r   re   r*   rj   rk   r)   zcontent-lengthrp   zcontent-typero   HTTP_-r   ,)r   r   r   
startswithr   osenvironr   sysstdoutr   upperreplace)r   r9   script_name	path_infoscript_name_environ_varr   server_addrserver_portr*   addrportnamevaluecorrected_namer   r   r   build_environ  sR   





r   c                	   @   sH   e Zd ZdZ	ddedededdfdd	Zd
edede	ddfddZ
dS )WSGIMiddlewarez%
    Convert WSGIApp to ASGIApp.
    r   appworkerssend_queue_sizeru   Nc                 C   s   || _ || _td|d| _d S )NWSGI)thread_name_prefixmax_workers)r   r   r   executor)ry   r   r   r   r   r   r   r     s
   zWSGIMiddleware.__init__r   r   sendc                    s   |d dkrt | j| j| j}||||I d H S |d dkr+|dddI d H  d S |d dkra| I d H }|d dks?J |dd	iI d H  | I d H }|d d
ksVJ |ddiI d H  d S d S )Nr    r   r4   rT   i  )r    rQ   r7   rW   r[   rY   r`   )WSGIResponderr   r   r   )ry   r   r   r   	responderr]   r   r   r   r   %  s    zWSGIMiddleware.__call__)r   r   )r   r   r   r   WSGIAppr0   r   Scoper   Sendr   r   r   r   r   r     s    
	r   c                	   @   s   e Zd ZdedededdfddZded	ed
e	ddfddZ
deje ddfddZd
e	ddfddZ	ddedeeeef  deje defddZdededdfddZdS )r   r   r   r   ru   Nc                 C   s2   || _ || _t | _t|| _d| _d | _d S )NF)	r   r   r   get_event_loopr   Queue
send_queueresponse_startedr   )ry   r   r   r   r   r   r   r   9  s   

zWSGIResponder.__init__r   r   r   c           	         s   t | j|}t||}d }zb| j| |}t }t|j	| j
}| j| j||| jI d H  | jd I d H  | j I d H  t|d I d H  | jd ur`| jd | jd | jd W |rm| so|  d S d S d S |r|| s}|  w w w )Nr   r      )r   r   r   create_tasksendercontextvarscopy_context	functoolspartialrunwsgirun_in_executorr   start_responser   putjoinr   wait_forr   with_tracebackdonecancel)	ry   r   r   r   r9   r   r   contextfuncr   r   r   r   C  s0   




zWSGIResponder.__call__r]   c                 C   s$   t j| j|| jd}|  d S )Nr   )r   r   r   r  r   r   )ry   r]   r   r   r   r   r   Y  s
   
zWSGIResponder.sendc                    s:   	 | j  I d H }| j   |d u rd S ||I d H  qr   )r   r   	task_done)ry   r   r]   r   r   r   r   `  s   
zWSGIResponder.senderr>   r   r   c                    sV   | _  js%d _|dd\}}t|}dd |D } d||d  fdd	S )
NT r   c                 S   s0   g | ]\}}|  d  |  d fqS )r   )stripr   lower)r   r   r   r   r   r   r   s  s    z0WSGIResponder.start_response.<locals>.<listcomp>r=   )r    r>   r)   c                    s     d| ddS )NrB   Tr    r9   r:   )r   )chunkr   r   r   <lambda>~  s    
z.WSGIResponder.start_response.<locals>.<lambda>)r   r   r   r0   r   )ry   r>   r   r   status_code_stringr   status_coder)   r   r   r   r  h  s   zWSGIResponder.start_responser   r  c                 C   sf   |  ||}z"|D ]}| d|dd q	| ddd W t|ddd   d S t|ddd   w )	NrB   Tr  r   )r    r9   closec                   S   s   d S r   r   r   r   r   r   r    s    z$WSGIResponder.wsgi.<locals>.<lambda>)r   r   getattr)ry   r   r  iterabler  r   r   r   r     s   
*zWSGIResponder.wsgir   )r   r   r   r   r   r0   r   r   r   r   r   r   r	   	SendEventr   r   r   r   r/   r   r   r  r   r   r   r   r   r   r   r   8  s0    


r   )Qr   r   r   r   r   r   r   concurrent.futuresr   typesr   r   r   r   r   r   r	   r
   r   r   r   r   collections.abcr   r   version_infor   typing_extensionsr   r   r3   r6   WWWScoper   r8   r<   rA   rE   rH   rI   rK   rN   rP   rS   rV   rX   rZ   r\   r_   ra   ReceiveEventr  r   r   ASGIApprb   rh   rr   r   r/   r0   r   r;   r   r   r    BaseExceptionr   r.   r   r   IterableChunksr   r   getfilesystemencodingr   r   r   r   r   r   r   r   r   r   <module>   s    4

*$
E:!