Ë
    ojËU  ã                   ó  — 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"   € ô �fœcÔ"Øˆ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   € ô �fœcÔ"Ø—=‘= Ó.×5Ñ5°lÓ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óð ð 	�	‰	�‰˜ V°TÀDÀ7ˆÕ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   € ð 	�
‰
�2—7‘7˜5“>Õ"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    „ ñ	ñ ‹8€Dò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   € ô �D—M‘MÓ"Ð"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   è ø€ Ò)I¸Q¬+°a¯.Ñ)Iùs   ‚ú
ú )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  € ØˆŒØˆŒØ$ˆŒØ&ˆÔØˆŒØ�‰×!Ñ!Ó#×+Ñ+¨D¯N©NÔ;à�?Š?Ø §	¡	¨'¯/©/Ó :Ñ:‰JàˆJà×ÒØ˜dŸi™i¨×(8Ñ(8Ó9Ñ9‰HàˆHà—‘×!Ñ! $¨Ó*ˆÜˆu‹:˜Š?Ø‰Kà ™(ˆKô
 *¨'¯.©.Ó9Ü& w×'?Ñ'?Ó'A×'FÑ'FÓGÜ& zÓ2Ü$ XÓ.Ü'¨Ó4Ü'¨×(9Ñ(9¸/Ó(JÒ(PÈbÓQÜ)¨'×*;Ñ*;Ð<MÓ*NÒ*TÐRTÓUÜ& w×'AÑ'AÓ'CÓDÜ&¤s¨7¯?©?Ó+<×+AÑ+AÓ'BÓCÜ*¨7×+>Ñ+>Ó?ñ
ˆŒð  +/ˆ�‰Ô'à#×2Ñ2×CÑCÓEò 	‰LˆD�&Øœ[¨Ó.×4Ñ4Ó6×>Ñ>¸sÀCÓHÑHˆDð "%§¡Ñ)IÀ&Ô)IÓ!I×!QÑ!QØ�có"ˆD�L‰L˜Òð		ð 	�‰×Ñà &Ø#*×#3Ñ#3Ó#5Ò#A¸'Ò#KÀVØ!&Ø$(Ø%*Ü+›~ô +¨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Ð/Ø˜!‘*×+Ñ+¨G°A©JÓ7Ð7ô
 ˜&¤#Ô&ÜØ3×:Ñ:ØœD ›L×1Ñ1óóð ô �gœtÔ$ØÜ˜¤Ô*ÝâœD ›M×2Ó2ð4ä'öõ âœD ›M×2Ó2ð4óð ð ò 	XˆFÜ˜&¤%Ô(ØÜ˜F¤HÔ-Ýâœt F›|×4Ó4ð6ä+öõ  âœt F›|×4Ó4ð6óð ô �6‹{˜aÒÜÐ"IÈ&ÈÐ TÓUÐUð
 ò X�Ü! $¬Õ,Ü#Ð&KÈFÈ:Ð$VÓWÐWñXð-	Xð4 ˆŒØˆŒØ�z‰zÐ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$   ø€ ÙØ×)Ñ)Ô+Ø�L‰L×Ñ˜tÕ$r   T)r   rm   rl   )r/   r0   r£   s   `` r   r1   z_WSGIResponse.write£  s1   ù€ õB	%ð
	 Ü)¨$¯,©,¸	À4Ç<Á<ÓPàˆD�Lø˜4ˆD�Lús   Š 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Ü�4‹yˆØ�‰×$Ñ$ TÔ+=¸gÓ+FÔGàŸ<™<ò 	‰KˆD�%à�z‰z‹|Ð#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   € ð 	�‰×$Ñ$ T§X¡XÕ.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Ø—L‘L×'Ñ'Õ)ð -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`   ø€ Ø—	‘	×!Ñ!Ø,´g¸eÀTÈ9Ó6Uð "ô ñ Ø—L‘L×/Ñ/Õ1à—L‘L×0Ñ0Ô1FÔGØ—L‘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Ñ9KÓLˆKØ#ò �ÙØ—J‘J˜tÔ$Ø×(Ó(Ùð	ô
 ˜K¨°$Ó7ˆEØÐ Ù”ô *ð �L‰L×'Ñ'¨
°D·L±LÔAØˆ�øô- ò 	Nô*ð (ˆD�L‰L×'Ñ'¨	°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 ÐÙ‹8€Dò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   € ô !Ø�M‰M˜4×+Ñ+¨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   