o
    Óó·i<Q  ã                   @   s  d Z ddlmZ ddlmZ ddlmZ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eeef defdd„Zdedefdd„ZG dd„ dƒZG dd„ dƒZG dd„ dƒZeeƒG d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)ÚListÚUnion)Úwarn)Úimplementer)ÚblockingCallFromThread)ÚLogger)ÚFailure)ÚINTERNAL_SERVER_ERROR)Ú	IResource)ÚNOT_DONE_YETÚstringÚreturnc                 C   s$   t | tƒr|  d¡ d¡S |  d¡S )aW  
    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.
    ú
iso-8859-1N)Ú
isinstanceÚstrÚencodeÚdecode©r   © r   úVC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/web/wsgi.pyÚ_wsgiString%   s   

r   c                 C   s
   |   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   N)r   r   r   r   r   Ú_wsgiStringToBytes7   s   

r   c                   @   sF   e Zd ZdZeƒ Zdeddfdd„Zdee ddfdd	„Z	d
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.
    Údatar   Nc                 C   s:   t |tƒstd|t|ƒjf ƒ‚| jj|dd|fd� dS )a  
        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: if C{data} is not a native string.
        z)write() argument must be str, not %r (%s)ZwsgiT)ÚsystemZisErrorÚmessageN)r   r   Ú	TypeErrorÚtypeÚ__name__Ú_logÚerror)Úselfr   r   r   r   ÚwriteR   s   
ÿÿz_ErrorStream.writeÚiovecc                 C   s   |   d |¡¡ dS )aZ  
        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: if C{iovec} contains any non-native strings.
        Ú N)r$   Újoin)r#   r%   r   r   r   Ú
writelinesg   s   z_ErrorStream.writelinesc                 C   s   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#   r   r   r   Úflushu   s    z_ErrorStream.flush)r    Ú
__module__Ú__qualname__Ú__doc__r	   r!   r   r$   r   r(   r*   r   r   r   r   r   D   s    r   c                   @   s>   e Zd ZdZdd„ Zddd„Zddd„Zdd	d
„Zd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                 C   s
   || _ dS )zt
        Initialize the instance.

        This is called in the I/O thread, not a WSGI application thread.
        N)Ú_wrapped)r#   Úinputr   r   r   Ú__init__‰   ó   
z_InputStream.__init__Nc                 C   ó   |du r	| 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.
        N)r/   Úread©r#   Úsizer   r   r   r4   ‘   ó   
z_InputStream.readc                 C   s&   |dks|du r| 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.
        éÿÿÿÿN)r/   Úreadliner5   r   r   r   r9   œ   s   	
z_InputStream.readlinec                 C   r3   )zˆ
        Pass through to the underlying C{readlines}.

        This is called in a WSGI application thread, not the I/O thread.
        N)r/   Ú	readlinesr5   r   r   r   r:   ©   r7   z_InputStream.readlinesc                 C   s
   t | jƒS )z‡
        Pass through to the underlying C{__iter__}.

        This is called in a WSGI application thread, not the I/O thread.
        N)Úiterr/   r)   r   r   r   Ú__iter__´   r2   z_InputStream.__iter__©N)	r    r+   r,   r-   r1   r4   r9   r:   r<   r   r   r   r   r.   ~   s    



r.   c                   @   sT   e Zd ZdZdZeƒ Zdd„ Zdd„ Zddd	„Z	d
d„ Z
dd„ Zdd„ Zd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                 C   sš  d| _ || _|| _|| _|| _| j ¡  | j¡ |jr$dd 	|j¡ }nd}|j
r2dd 	|j
¡ }nd}|j dd¡}t|ƒdkrDd}n|d }| ¡ }	t|jƒt|	jƒtt|	jƒƒt|ƒt|ƒt|ƒt| d¡pjdƒt| d¡prdƒt| ¡ ƒtt| ¡ jƒƒt|jƒd	œ| _d | j_|j ¡ D ]!\}
}d
t|
ƒ ¡  dd¡ }
d 	dd„ |D ƒ¡ dd¡| j|
< q‘| j d| ¡ r½dp¾ddddt ƒ t!|j"ƒdœ¡ d S )NFó   /ó    ó   ?é   s   content-typer&   s   content-length)ÚREQUEST_METHODZREMOTE_ADDRZREMOTE_PORTZSCRIPT_NAMEZ	PATH_INFOÚQUERY_STRINGÚCONTENT_TYPEÚCONTENT_LENGTHZSERVER_NAMEZSERVER_PORTZSERVER_PROTOCOLZHTTP_ú-Ú_ú,c                 s   s   � | ]}t |ƒV  qd S r=   )r   )Ú.0Úvr   r   r   Ú	<genexpr>  s   € z)_WSGIResponse.__init__.<locals>.<genexpr>Ú
ú )rB   r   ÚhttpsÚhttpT)zwsgi.versionzwsgi.url_schemezwsgi.run_oncezwsgi.multithreadzwsgi.multiprocesszwsgi.errorsz
wsgi.input)#ÚstartedÚreactorÚ
threadpoolÚapplicationÚrequestZnotifyFinishZaddBothÚ	_finishedZprepathr'   ZpostpathÚuriÚsplitÚlenZgetClientAddressr   ÚmethodÚhostr   ÚportZ	getHeaderZgetRequestHostnameZgetHostZclientprotoÚenvironZdefaultContentTypeZrequestHeadersZgetAllRawHeadersÚupperÚreplaceÚupdateZisSecurer   r.   Úcontent)r#   rR   rS   rT   rU   Z
scriptNameZpathInfoÚpartsZqueryStringZ
remotePeerÚnameÚvaluesr   r   r   r1   â   sZ   
õÿëÿz_WSGIResponse.__init__c                 C   s
   d| _ dS )zc
        Record the end of the response generation for the request being
        serviced.
        TN)Ú_requestFinished)r#   Zignoredr   r   r   rV   2  s   
z_WSGIResponse._finishedNc                 C   s(  | j r|dur|d  |d ¡‚t|tƒs td |t|ƒj¡ƒ‚t|tƒr&nt|t	ƒr9t
d|t|ƒjf td� ntd|t|ƒjf ƒ‚|D ]D}t|tƒrNnt|t	ƒrat
d|t|ƒjf td� ntd	|t|ƒjf ƒ‚t|ƒdkrytd
|›�ƒ‚|D ]}t|tƒs‰td|›�ƒ‚q{qF|| _|| _| 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.
        NrB   é   z!status must be str, not {!r} ({})z%headers should be a list, not %r (%s))Úcategoryz#headers must be a list, not %r (%s)z0header should be a (str, str) tuple, not %r (%s)z.header must be a (str, str) tuple, not %r (%s)z'header must be a (str, str) tuple, not z%header must be (str, str) tuple, not )rQ   Úwith_tracebackr   r   r   Úformatr   r    Úlistr   r   ÚRuntimeWarningÚtuplerY   ÚstatusÚheadersr$   )r#   rm   rn   ZexcInfoÚheaderÚelemr   r   r   ÚstartResponse9  s^   

ÿÿ
	
ÿýÿÿ

ÿýÿÿ
ÿÿz_WSGIResponse.startResponsec                    s0   ‡ ‡fdd„}zt ˆj|ˆjƒW dˆ_S dˆ_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   | sˆ  ¡  ˆj ˆ ¡ d S r=   )Ú_sendResponseHeadersrU   r$   ©rQ   ©r   r#   r   r   Ú	wsgiWriteŸ  s   z&_WSGIResponse.write.<locals>.wsgiWriteTN)r   rR   rQ   )r#   r   ru   r   rt   r   r$   ~  s   !z_WSGIResponse.writec                 C   sd   | j  dd¡\}}t|ƒ}| j |t|ƒ¡ | jD ]\}}| ¡ dvr/| jj 	t|ƒt|ƒ¡ qd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.
        NrB   )ÚserverÚdate)
rm   rX   ÚintrU   ÚsetResponseCoder   rn   ÚlowerZresponseHeadersZaddRawHeader)r#   Úcoder   rc   Úvaluer   r   r   rr   ©  s   	ÿ€ýz"_WSGIResponse._sendResponseHeadersc                 C   s   | j  | j¡ dS )zo
        Start the WSGI application in the threadpool.

        This must be called in the I/O thread.
        N)rS   ZcallInThreadÚrunr)   r   r   r   Ústart½  s   z_WSGIResponse.startc                    s°   z(ˆ   ˆ jˆ j¡}|D ]}|rˆ  |¡ ˆ jr qqt|ddƒ}|dur'|ƒ  W n tyD   ‡ fdd„}ˆ jj|ˆ j	gt
ƒ ¢R Ž  Y nw ‡ fdd„}ˆ j |ˆ j	¡ 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                    sD   ˆ j jdt|||ƒd� | rˆ j ¡  d S ˆ j t¡ ˆ j ¡  d S )NzWSGI application error)Úfailure)r!   r€   r
   rU   ZloseConnectionry   r   Úfinish)rQ   r   r|   Ú	tracebackr)   r   r   Ú	wsgiErrorØ  s   ÿz$_WSGIResponse.run.<locals>.wsgiErrorc                    s$   ˆ j s| s	ˆ  ¡  ˆ j ¡  d S d S r=   )re   rr   rU   r�   rs   r)   r   r   Ú
wsgiFinishå  s
   ýz%_WSGIResponse.run.<locals>.wsgiFinishT)rT   r]   rq   r$   re   ÚgetattrÚBaseExceptionrR   ZcallFromThreadrQ   r   )r#   ZappIteratorrp   r   rƒ   r„   r   r)   r   r}   Å  s&   
ÿ€
ô
z_WSGIResponse.runr=   )r    r+   r,   r-   re   r	   r!   r1   rV   rq   r$   rr   r~   r}   r   r   r   r   r>   ½   s    !P
E+r>   c                   @   s4   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚWSGIResourceaW  
    An L{IResource} implementation which delegates responsibility for all
    resources hierarchically inferior to it to a WSGI application.

    The C{environ} argument passed to the application, includes the
    C{REMOTE_PORT} key to complement the C{REMOTE_ADDR} key.

    @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                 C   s   || _ || _|| _d S r=   )Ú_reactorÚ_threadpoolÚ_application)r#   rR   rS   rT   r   r   r   r1     s   
zWSGIResource.__init__c                 C   s    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.
        N)r>   rˆ   r‰   rŠ   r~   r   )r#   rU   Úresponser   r   r   Úrender
  s
   
ÿzWSGIResource.renderc                 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 WSGIResourceN©ÚRuntimeError)r#   rc   rU   r   r   r   ÚgetChildWithDefault  ó   z WSGIResource.getChildWithDefaultc                 C   r�   )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 WSGIResourceNrŽ   )r#   ÚpathÚchildr   r   r   ÚputChild"  r‘   zWSGIResource.putChildN)	r    r+   r,   r-   ZisLeafr1   rŒ   r�   r”   r   r   r   r   r‡   ï  s    r‡   N)!r-   Úcollections.abcr   Úsysr   Útypingr   r   Úwarningsr   Zzope.interfacer   Ztwisted.internet.threadsr   Ztwisted.loggerr	   Ztwisted.python.failurer
   Ztwisted.web.httpr   Ztwisted.web.resourcer   Ztwisted.web.serverr   r   Úbytesr   r   r   r.   r>   r‡   Ú__all__r   r   r   r   Ú<module>   s,   :?  4
;