
    ϪfU                        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y)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                 H    t        | t              r| S | j                  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    2/usr/lib/python3/dist-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 | j                  d      j                  d      S | j                  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   C   s7     fc"==.55lCC==..r   c                 $    | j                  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   T   s     }}\**r   c                   0    e Zd ZdZ e       Zd Zd Zd Zy)_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              s]t        t        u r,t        d|dt	        |      j
                  dt               n%t        d|dt	        |      j
                  d      | j                  j                  |dd|f       y	)
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.writeo   ss     $$e|T$Z002+  T$Z002  			VTD7Kr   c                 D    | j                  dj                  |             y)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                      y)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   a   s     	 8DL:#r   r   c                   4    e Zd ZdZd ZddZddZddZd Zy)	_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                     || _         y)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                 p    || j                   j                         S | j                   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   s1     <==%%''}}!!$''r   c                 z    |dk(  s|| j                   j                         S | j                   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   s7     2:==))++}}%%d++r   c                 p    || j                   j                         S | j                   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   s1     <==**,,}}&&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     DMM""r   N)	r*   r:   r;   r<   rB   rD   rI   rK   rN   r   r   r   r>   r>      s     	(,	-#r   r>   c                   N    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y)_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                 r   d| _         || _        || _        || _        || _        | j                  j                         j                  | j                         |j                  rddj                  |j                        z   }nd}|j                  rddj                  |j                        z   }nd}|j                  j                  dd      }t        |      dk(  rd}n|d   }t        |j                        t        |j!                         j"                        t        |      t        |      t        |      t        |j%                  d      xs d      t        |j%                  d      xs d      t        |j'                               t        t)        |j+                         j,                              t        |j.                        d	
| _        d | j                  _        |j4                  j7                         D ]f  \  }	}
d
t        |	      j9                         j;                  dd      z   }	dj                  d |
D              j;                  dd      | j0                  |	<   h | j0                  j=                  d|j?                         xr dxs ddddtA               tC        |jD                        d       y )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   2   K   | ]  }t        |        y wrO   )r   ).0vs     r   	<genexpr>z)_WSGIResponse.__init__.<locals>.<genexpr>8  s     )IQ+a.)Is   
 )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__  sA   $&!!#++DNN;??		'// ::JJdii(8(899HH!!$*u:?K(K
 *'..9&w'?'?'A'F'FG&z2$X.'4'(9(9/(J(PbQ)'*;*;<M*N*TRTU&w'A'A'CD&s7??+<+A+A'BC*7+>+>?
  +/'#22CCE 	LD&[.446>>sCHHD "%)I&)I!I!Q!Qc"DLL		 	 &#*#3#3#5#A'#KV!&$(%*+~ +7??;+	
r   c                     d| _         y)zc
        Record the end of the response generation for the request being
        serviced.
        TN)_requestFinished)r/   ignoreds     r   rs   z_WSGIResponse._finishedV  s    
 !%r   Nc           	      T   | j                   r||d   j                  |d         t        |t              s.t	        dj                  |t        |      j                              t        |t              rnat        |t              r,t        d|dt        |      j                  dt               n%t	        d|dt        |      j                  d      |D ]  }t        |t              rnat        |t              r,t        d	|dt        |      j                  dt               n%t	        d
|dt        |      j                  d      t        |      dk7  rt	        d
|      |D ]   }t        |t              r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.
        rU      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]  s    <<G/!*++GAJ77
 &#&3::DL11  gt$*DM224' DM224   	XF&%(FH-tF|446+  tF|446  6{a"I& TUU
  X!$,#&KF:$VWWX-	X4 zzr   c                 |      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                 `    | sj                          j                  j                         y rO   )_sendResponseHeadersrp   r1   )rl   r0   r/   s    r   	wsgiWritez&_WSGIResponse.write.<locals>.wsgiWrite  s$    ))+LLt$r   T)r   rm   rl   )r/   r0   r   s   `` r   r1   z_WSGIResponse.write  s1    B	%
	 )$,,	4<<PDL4DLs    2 	;c                 `   | j                   j                  dd      \  }}t        |      }| j                  j	                  |t        |             | j                  D ]P  \  }}|j                         dvs| j                  j                  j                  t        |      t        |             R y)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g4y$$T+=g+FG<< 	KD%zz|#55,,99&t,.@.G	r   c                 N    | j                   j                  | j                         y)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     	$$TXX.r   c                     	  j                   j                   j                        }|D ]#  }|r j                  |        j                  s# n t        |dd      }| |         fd} j                  j                  | j                         d _        y# t        $ r?  fd}  j                  j                  | j                  gt                 Y d _        yw xY w)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                   s-| sj                          j                  j                          y y rO   )r   r   rp   finish)rl   r/   s    r   
wsgiFinishz%_WSGIResponse.run.<locals>.wsgiFinish
  s0    ,,"113LL'') -r   c                    j                   j                  dt        |||             | rj                  j	                          y j                  j                  t               j                  j                          y )NzWSGI application error)failure)r-   r   r	   rp   loseConnectionr   r
   r   )rl   r)   r   	tracebackr/   s       r   	wsgiErrorz$_WSGIResponse.run.<locals>.wsgiError  s`    		!!,geT96U "  LL//1LL001FGLL'')r   T)ro   r   r   r1   r   getattrrm   callFromThreadrl   BaseExceptionr   )r/   appIteratorr   r   r   r   s   `     r   r   z_WSGIResponse.run  s    	B**4<<9K9KLK# JJt$((	
 K$7E  * LL''
DLLA-  	N* (DLL''	4<<M(*M -	Ns   A
B B >C"!C"rO   )r*   r:   r;   r<   r   r   r-   rB   rs   r   r1   r   r   r   r   r   r   rQ   rQ      s?    B 8DL
\%DL) V(/'r   rQ   c                   ,    e Zd ZdZdZd Zd Zd Zd Zy)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                 .    || _         || _        || _        y rO   )_reactor_threadpool_application)r/   rm   rn   ro   s       r   rB   zWSGIResource.__init__'  s    %'r   c                     t        | j                  | 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,  s9     !MM4++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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.putChildD  s     MNNr   N)	r*   r:   r;   r<   isLeafrB   r   r   r   r   r   r   r   r     s$     F(
 N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 * +( %<//"
+@ @F<# <#~n nb	 Y5O 5O 5Op 
r   