
    \dU                     4   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ eeu rd Zd Znd Zd Z G d d          Z G d d          Z G d d          Z ee           G d d                      ZdgZdS )zo
An implementation of
U{Python Web Server Gateway Interface v1.0.1<http://www.python.org/dev/peps/pep-3333/>}.
    )Sequence)exc_info)warn)implementer)blockingCallFromThread)Logger)Failure)INTERNAL_SERVER_ERROR)	IResource)NOT_DONE_YETc                 Z    t          | t                    r| S |                     d          S )z
        Convert C{string} to an ISO-8859-1 byte string, if it is not already.

        @type string: C{str}/C{bytes} or C{unicode}
        @rtype: C{str}/C{bytes}

        @raise UnicodeEncodeError: If C{string} contains non-ISO-8859-1 chars.
        
iso-8859-1)
isinstancestrencodestrings    0lib/python3.11/site-packages/twisted/web/wsgi.py_wsgiStringr   *   s-     fc"" 	/M==...    c                     | S )z
        Return C{string} as is; a WSGI string is a byte string in Python 2.

        @type string: C{str}/C{bytes}
        @rtype: C{str}/C{bytes}
         r   s    r   _wsgiStringToBytesr   8   s	     r   c                     t          | t                    r(|                     d                              d          S |                     d          S )as  
        Convert C{string} to a WSGI "bytes-as-unicode" string.

        If it's a byte string, decode as ISO-8859-1. If it's a Unicode string,
        round-trip it to bytes and back using ISO-8859-1 as the encoding.

        @type string: C{str} or C{bytes}
        @rtype: C{str}

        @raise UnicodeEncodeError: If C{string} contains non-ISO-8859-1 chars.
        r   )r   r   r   decoder   s    r   r   r   D   sH     fc"" 	/==..55lCCC==...r   c                 ,    |                      d          S )z
        Convert C{string} from a WSGI "bytes-as-unicode" string to an
        ISO-8859-1 byte string.

        @type string: C{str}
        @rtype: C{bytes}

        @raise UnicodeEncodeError: If C{string} contains non-ISO-8859-1 chars.
        r   )r   r   s    r   r   r   U   s     }}\***r   c                   8    e Zd ZdZ e            Zd Zd Zd ZdS )_ErrorStreama  
    File-like object instances of which are used as the value for the
    C{'wsgi.errors'} key in the C{environ} dictionary passed to the application
    object.

    This simply passes writes on to L{logging<twisted.logger>} system as
    error events from the C{'wsgi'} system.  In the future, it may be desirable
    to expose more information in the events it logs, such as the application
    object which generated the message.
    c                 :   t          |t                    sft          t          u r0t          d|dt	          |          j        dt                     n(t          d|dt	          |          j        d          | j        	                    |dd|f           d	S )
aG  
        Generate an event for the logging system with the given bytes as the
        message.

        This is called in a WSGI application thread, not the I/O thread.

        @type data: str

        @raise TypeError: On Python 3, if C{data} is not a native string. On
            Python 2 a warning will be issued.
        z$write() argument should be str, not  ()categoryz"write() argument must be str, not wsgiT)systemisErrormessageN)
r   r   bytesr   type__name__UnicodeWarning	TypeError_logerror)selfdatas     r   writez_ErrorStream.writep   s     $$$ 	e||ttT$ZZ0002+      ittT$ZZ0002   		VTD7KKKKKr   c                 V    |                      d                    |                     dS )a  
        Join the given lines and pass them to C{write} to be handled in the
        usual way.

        This is called in a WSGI application thread, not the I/O thread.

        @param iovec: A C{list} of C{'\n'}-terminated C{str} which will be
            logged.

        @raise TypeError: On Python 3, if C{iovec} contains any non-native
            strings. On Python 2 a warning will be issued.
         N)r1   join)r/   iovecs     r   
writelinesz_ErrorStream.writelines   s&     	

2775>>"""""r   c                     dS )z
        Nothing is buffered, so flushing does nothing.  This method is required
        to exist by PEP 333, though.

        This is called in a WSGI application thread, not the I/O thread.
        Nr   r/   s    r   flushz_ErrorStream.flush   s      r   N)	r*   
__module____qualname____doc__r   r-   r1   r6   r9   r   r   r   r   r   b   s[        	 	 688DL L L:# # #    r   r   c                   6    e Zd ZdZd ZddZddZddZd ZdS )	_InputStreama  
    File-like object instances of which are used as the value for the
    C{'wsgi.input'} key in the C{environ} dictionary passed to the application
    object.

    This only exists to make the handling of C{readline(-1)} consistent across
    different possible underlying file-like object implementations.  The other
    supported methods pass through directly to the wrapped object.
    c                     || _         dS )zt
        Initialize the instance.

        This is called in the I/O thread, not a WSGI application thread.
        N)_wrapped)r/   inputs     r   __init__z_InputStream.__init__   s     r   Nc                 l    || j                                         S | j                             |          S )z
        Pass through to the underlying C{read}.

        This is called in a WSGI application thread, not the I/O thread.
        )r@   readr/   sizes     r   rD   z_InputStream.read   s3     <=%%'''}!!$'''r   c                 x    |dk    s|| j                                         S | j                             |          S )z
        Pass through to the underlying C{readline}, with a size of C{-1} replaced
        with a size of L{None}.

        This is called in a WSGI application thread, not the I/O thread.
        )r@   readlinerE   s     r   rI   z_InputStream.readline   s;     2::=))+++}%%d+++r   c                 l    || j                                         S | j                             |          S )z
        Pass through to the underlying C{readlines}.

        This is called in a WSGI application thread, not the I/O thread.
        )r@   	readlinesrE   s     r   rK   z_InputStream.readlines   s3     <=**,,,}&&t,,,r   c                 *    t          | j                  S )z
        Pass through to the underlying C{__iter__}.

        This is called in a WSGI application thread, not the I/O thread.
        )iterr@   r8   s    r   __iter__z_InputStream.__iter__   s     DM"""r   N)	r*   r:   r;   r<   rB   rD   rI   rK   rN   r   r   r   r>   r>      sx           	( 	( 	( 	(, , , ,	- 	- 	- 	-# # # # #r   r>   c                   V    e Zd ZdZdZ e            Zd Zd ZddZ	d Z
d Zd	 Zd
 ZdS )_WSGIResponsea$  
    Helper for L{WSGIResource} which drives the WSGI application using a
    threadpool and hooks it up to the L{http.Request}.

    @ivar started: A L{bool} indicating whether or not the response status and
        headers have been written to the request yet.  This may only be read or
        written in the WSGI application thread.

    @ivar reactor: An L{IReactorThreads} provider which is used to call methods
        on the request in the I/O thread.

    @ivar threadpool: A L{ThreadPool} which is used to call the WSGI
        application object in a non-I/O thread.

    @ivar application: The WSGI application object.

    @ivar request: The L{http.Request} upon which the WSGI environment is
        based and to which the application's output will be sent.

    @ivar environ: The WSGI environment L{dict}.

    @ivar status: The HTTP response status L{str} supplied to the WSGI
        I{start_response} callable by the application.

    @ivar headers: A list of HTTP response headers supplied to the WSGI
        I{start_response} callable by the application.

    @ivar _requestFinished: A flag which indicates whether it is possible to
        generate more response data or not.  This is L{False} until
        L{http.Request.notifyFinish} tells us the request is done,
        then L{True}.
    Fc                    d| _         || _        || _        || _        || _        | j                                                            | j                   |j        rdd	                    |j                  z   }nd}|j
        rdd	                    |j
                  z   }nd}|j                            dd          }t          |          dk    rd}n|d         }t          |j                  t          |                                j                  t          |          t          |          t          |          t          |                    d          pd          t          |                    d          pd          t          |                                          t          t)          |                                j                            t          |j                  d	
| _        d | j        _        |j                                        D ]x\  }	}
d
t          |	                                                              dd          z   }	d	                    d |
D                                           dd          | j        |	<   y| j                            d|                                rdpddddtA                      tC          |j"                  d           d S )NF   /r      ?   s   content-typer3   s   content-length)
REQUEST_METHODREMOTE_ADDRSCRIPT_NAME	PATH_INFOQUERY_STRINGCONTENT_TYPECONTENT_LENGTHSERVER_NAMESERVER_PORTSERVER_PROTOCOLHTTP_-_,c              3   4   K   | ]}t          |          V  d S rO   )r   ).0vs     r   	<genexpr>z)_WSGIResponse.__init__.<locals>.<genexpr>9  s(      )I)IQ+a..)I)I)I)I)I)Ir   
 )rU   r   httpshttpT)zwsgi.versionzwsgi.url_schemezwsgi.run_oncezwsgi.multithreadzwsgi.multiprocesszwsgi.errorsz
wsgi.input)#startedreactor
threadpoolapplicationrequestnotifyFinishaddBoth	_finishedprepathr4   postpathurisplitlenr   methodgetClientAddresshost	getHeadergetRequestHostnamer   getHostportclientprotoenvirondefaultContentTyperequestHeadersgetAllRawHeadersupperreplaceupdateisSecurer   r>   content)r/   rm   rn   ro   rp   
scriptNamepathInfopartsqueryStringnamevaluess              r   rB   z_WSGIResponse.__init__	  s   $&!!##++DN;;;? 			'/ : ::JJJ 	dii(8999HHH!!$**u::??KK(K
 *'.99&w'?'?'A'A'FGG&z22$X..'44'(9(9/(J(J(PbQQ)'*;*;<M*N*N*TRTUU&w'A'A'C'CDD&s7??+<+<+A'B'BCC*7+>??
 
  +/'#2CCEE 	 	LD&[..4466>>sCHHHD "%)I)I&)I)I)I!I!I!Q!Qc" "DL 	 &#*#3#3#5#5#A'#KV!&$(%*+~~ +7?;;+ 	
 	
 	
 	
 	
r   c                     d| _         dS )zc
        Record the end of the response generation for the request being
        serviced.
        TN)_requestFinished)r/   ignoreds     r   rs   z_WSGIResponse._finishedW  s    
 !%r   Nc           	         | j         r#|!|d                             |d                   t          |t                    s5t	          d                    |t          |          j                            t          |t                    rnmt          |t                    r0t          d|dt          |          j        dt                     n(t	          d	|dt          |          j        d          |D ]}t          |t                    rnmt          |t                    r0t          d
|dt          |          j        dt                     n(t	          d|dt          |          j        d          t          |          dk    rt	          d|          |D ])}t          |t                    st	          d|          *|| _        || _        | j        S )z
        The WSGI I{start_response} callable.  The given values are saved until
        they are needed to generate the response.

        This will be called in a non-I/O thread.
        NrU      z!status must be str, not {!r} ({})zheaders should be a list, not r    r!   r"   zheaders must be a list, not z)header should be a (str, str) tuple, not z'header must be a (str, str) tuple, not z%header must be (str, str) tuple, not )rl   with_tracebackr   r   r,   formatr)   r*   listr   r   RuntimeWarningtuplerx   statusheadersr1   )r/   r   r   excInfoheaderelems         r   startResponsez_WSGIResponse.startResponse^  sF    < 	8G/!*++GAJ777
 &#&& 	3::DLL1    gt$$ 	** 
	D77DMM2224'     )77DMM2224    	X 	XF&%(( FH-- 
vvtF||4446+      ivvtF||4446   6{{a T& T TUUU
  X X!$,, X#$VF$V$VWWWXX zr   c                 p      fd}	 t           j        | j                  d _        S # d _        w xY w)a   
        The WSGI I{write} callable returned by the I{start_response} callable.
        The given bytes will be written to the response body, possibly flushing
        the status and headers first.

        This will be called in a non-I/O thread.
        c                 h    | s                                  j                                       d S rO   )_sendResponseHeadersrp   r1   )rl   r0   r/   s    r   	wsgiWritez&_WSGIResponse.write.<locals>.wsgiWrite  s9     ,))+++Lt$$$$$r   T)r   rm   rl   )r/   r0   r   s   `` r   r1   z_WSGIResponse.write  sW    B	% 	% 	% 	% 	% 	%
	 )$,	4<PPDLL4DLs   , 	5c                 j   | j                             dd          \  }}t          |          }| j                            |t          |                     | j        D ]U\  }}|                                dvr:| j        j        	                    t          |          t          |                     VdS )a,  
        Set the response code and response headers on the request object, but
        do not flush them.  The caller is responsible for doing a write in
        order for anything to actually be written out in response to the
        request.

        This must be called in the I/O thread.
        NrU   )serverdate)
r   rw   intrp   setResponseCoder   r   lowerresponseHeadersaddRawHeader)r/   coder'   r   values        r   r   z"_WSGIResponse._sendResponseHeaders  s     ))$22g4yy$$T+=g+F+FGGG< 	 	KD%zz||#555,99&t,,.@.G.G  	 	r   c                 D    | j                             | j                   dS )zo
        Start the WSGI application in the threadpool.

        This must be called in the I/O thread.
        N)rn   callInThreadrunr8   s    r   startz_WSGIResponse.start  s"     	$$TX.....r   c                     	                        j         j                  }|D ]"}|r                     |            j        r n#t          |dd          }|
 |              fd} j                            | j                   n:# t          $ r-  fd}  j        j        | j        gt                      R   Y nw xY wd _        dS )z
        Call the WSGI application object, iterate it, and handle its output.

        This must be called in a non-I/O thread (ie, a WSGI application
        thread).
        closeNc                 x    j         s1| s                                 j                                         d S d S rO   )r   r   rp   finish)rl   r/   s    r   
wsgiFinishz%_WSGIResponse.run.<locals>.wsgiFinish  sL    , *" 411333L'')))))* *r   c                    j                             dt          |||                     | rj                                         d S j                            t                     j                                         d S )NzWSGI application error)failure)r-   r   r	   rp   loseConnectionr   r
   r   )rl   r)   r   	tracebackr/   s       r   	wsgiErrorz$_WSGIResponse.run.<locals>.wsgiError  s    	!!,geT96U6U "     *L//11111L001FGGGL'')))))r   T)ro   r   r   r1   r   getattrrm   callFromThreadrl   BaseExceptionr   )r/   appIteratorr   r   r   r   s   `     r   r   z_WSGIResponse.run  s/   	B**4<9KLLK#   %JJt$$$( EK$77E  * * * * * L''
DLAAAA+  	N 	N 	N* * * * * (DL'	4<M(**MMMMMM	N, s   A"B 4CCrO   )r*   r:   r;   r<   r   r   r-   rB   rs   r   r1   r   r   r   r   r   r   rQ   rQ      s         B 688DL
 L
 L
\% % %D D D DL)  )  ) V  (/ / /' ' ' ' 'r   rQ   c                   .    e Zd ZdZdZd Zd Zd Zd ZdS )WSGIResourcea  
    An L{IResource} implementation which delegates responsibility for all
    resources hierarchically inferior to it to a WSGI application.

    @ivar _reactor: An L{IReactorThreads} provider which will be passed on to
        L{_WSGIResponse} to schedule calls in the I/O thread.

    @ivar _threadpool: A L{ThreadPool} which will be passed on to
        L{_WSGIResponse} to run the WSGI application object.

    @ivar _application: The WSGI application object.
    Tc                 0    || _         || _        || _        d S rO   )_reactor_threadpool_application)r/   rm   rn   ro   s       r   rB   zWSGIResource.__init__(  s    %'r   c                 z    t          | j        | j        | j        |          }|                                 t
          S )a  
        Turn the request into the appropriate C{environ} C{dict} suitable to be
        passed to the WSGI application object and then pass it on.

        The WSGI application object is given almost complete control of the
        rendering process.  C{NOT_DONE_YET} will always be returned in order
        and response completion will be dictated by the application object, as
        will the status, headers, and the response body.
        )rQ   r   r   r   r   r   )r/   rp   responses      r   renderzWSGIResource.render-  s<     !M4+T->
 
 	r   c                      t          d          )z
        Reject attempts to retrieve a child resource.  All path segments beyond
        the one which refers to this resource are handled by the WSGI
        application object.
        z/Cannot get IResource children from WSGIResourceRuntimeError)r/   r   rp   s      r   getChildWithDefaultz WSGIResource.getChildWithDefault=  s     LMMMr   c                      t          d          )z
        Reject attempts to add a child resource to this resource.  The WSGI
        application object handles all path segments beneath this resource, so
        L{IResource} children can never be found.
        z0Cannot put IResource children under WSGIResourcer   )r/   pathchilds      r   putChildzWSGIResource.putChildE  s     MNNNr   N)	r*   r:   r;   r<   isLeafrB   r   r   r   r   r   r   r   r     si          F( ( (
   N N NO O O O Or   r   N)r<   collections.abcr   sysr   warningsr   zope.interfacer   twisted.internet.threadsr   twisted.loggerr   twisted.python.failurer	   twisted.web.httpr
   twisted.web.resourcer   twisted.web.serverr   r   r(   r   r   r   r>   rQ   r   __all__r   r   r   <module>r      s   
 % $ $ $ $ $             & & & & & & ; ; ; ; ; ; ! ! ! ! ! ! * * * * * * 2 2 2 2 2 2 * * * * * * + + + + + +( %<</ / /   / / /"
+ 
+ 
+@ @ @ @ @ @ @ @F<# <# <# <# <# <# <# <#~n n n n n n n nb	 Y5O 5O 5O 5O 5O 5O 5O 5Op 
r   