o bU@sdZddlmZddlmZddlmZddlmZddl m Z ddl m Z ddl mZdd lmZdd lmZdd lmZeeurKd d ZddZndd ZddZGdddZGdddZGdddZeeGdddZdgZdS)zo An implementation of U{Python Web Server Gateway Interface v1.0.1}. )Sequence)exc_info)warn) implementer)blockingCallFromThread)Logger)Failure)INTERNAL_SERVER_ERROR) IResource) NOT_DONE_YETcCst|tr|S|dS)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) isinstancestrencodestringr2/usr/lib/python3/dist-packages/twisted/web/wsgi.py _wsgiString*s  rcCs|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} rrrrr_wsgiStringToBytes8srcCs$t|tr |ddS|dS)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 rrdecoderrrrrDs  cCs |dS)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 )rrrrrrUs c@s.eZdZdZeZddZddZddZdS) _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} 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. cCs^t|ts"tturtd|t|jftdn td|t|jf|jj |dd|fddS)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 %r (%s)categoryz)write() argument must be str, not %r (%s)wsgiT)systemisErrormessageN) r rbytesrtype__name__UnicodeWarning TypeError_logerror)selfdatarrrwriteps   z_ErrorStream.writecCs|d|dS)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)r'join)r%iovecrrr writeliness z_ErrorStream.writelinescCsdS)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. Nrr%rrrflushsz_ErrorStream.flushN) r __module__ __qualname____doc__rr#r'r+r-rrrrrbs   rc@s>eZdZdZddZd ddZd ddZd d d Zd d ZdS) _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. cCs ||_dS)zt Initialize the instance. This is called in the I/O thread, not a WSGI application thread. N)_wrapped)r%inputrrr__init__ z_InputStream.__init__NcC|dur |jS|j|S)z Pass through to the underlying C{read}. This is called in a WSGI application thread, not the I/O thread. N)r2readr%sizerrrr7  z_InputStream.readcCs&|dks|dur |jS|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)r2readliner8rrrr<s  z_InputStream.readlinecCr6)z Pass through to the underlying C{readlines}. This is called in a WSGI application thread, not the I/O thread. N)r2 readlinesr8rrrr=r:z_InputStream.readlinescCs t|jS)z Pass through to the underlying C{__iter__}. This is called in a WSGI application thread, not the I/O thread. )iterr2r,rrr__iter__r5z_InputStream.__iter__N) r r.r/r0r4r7r<r=r?rrrrr1s  r1c@sTeZdZdZdZeZddZddZddd Z d d Z d d Z ddZ ddZ dS) _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 Csd|_||_||_||_||_|j|j|jr$dd |j}nd}|j r2dd |j }nd}|j dd}t |dkrDd}n|d}t|jt|jt|t|t|t|dpbdt|dpjdt|tt|jt|jd |_d|j_|jD]!\} } d t| d d } d dd| Ddd|j| <q|jd|rdpddddt t!|j"ddS)NF/?s content-typer(scontent-length) REQUEST_METHOD REMOTE_ADDR SCRIPT_NAME PATH_INFO QUERY_STRING CONTENT_TYPECONTENT_LENGTH SERVER_NAME SERVER_PORTSERVER_PROTOCOLHTTP_-_,css|]}t|VqdSr@)r).0vrrr 9sz)_WSGIResponse.__init__..  )rErhttpshttpT)z wsgi.versionzwsgi.url_schemez wsgi.run_oncezwsgi.multithreadzwsgi.multiprocessz wsgi.errorsz wsgi.input)#startedreactor threadpool applicationrequest notifyFinishaddBoth _finishedprepathr)postpathurisplitlenrmethodgetClientAddresshost getHeadergetRequestHostnamergetHostport clientprotoenvirondefaultContentTyperequestHeadersgetAllRawHeadersupperreplaceupdateisSecurerr1content) r%r\r]r^r_ scriptNamepathInfoparts queryStringnamevaluesrrrr4 sV    z_WSGIResponse.__init__cCs d|_dS)zc Record the end of the response generation for the request being serviced. TN)_requestFinished)r%ignoredrrrrbWs z_WSGIResponse._finishedNcCs(|jr|dur|d|dt|ts td|t|jt|tr&nt|t r9t d|t|jft dn td|t|jf|D]D}t|t rNnt|t rat d|t|jft dn td |t|jft |dkrytd ||D]}t|tstd |q{qF||_||_|jS) 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. NrEz!status must be str, not {!r} ({})z%headers should be a list, not %r (%s)rz#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 )r[with_tracebackr rr"formatrr listrrRuntimeWarningtuplergstatusheadersr')r%rrexcInfoheaderelemrrr startResponse^s^            z_WSGIResponse.startResponsecs0fdd}z tj|jWd_Sd_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. cs|sjdSr@)_sendResponseHeadersr_r'r[r&r%rr wsgiWritesz&_WSGIResponse.write..wsgiWriteT)rr\r[)r%r&rrrrr's!z_WSGIResponse.writecCsd|jdd\}}t|}|j|t||jD]\}}|dvr/|jj t|t|qdS)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. NrE)serverdate) rrfintr_setResponseCoderrlowerresponseHeaders addRawHeader)r%coderr}valuerrrrs   z"_WSGIResponse._sendResponseHeaderscCs|j|jdS)zo Start the WSGI application in the threadpool. This must be called in the I/O thread. N)r] callInThreadrunr,rrrstartsz_WSGIResponse.startcsz(jj}|D]}|r|jrnq t|dd}|dur'|WntyDfdd}jj|j gt RYnwfdd}j|j d_ dS)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). closeNcsDjjdt|||d|rjdSjtjdS)NzWSGI application error)failure)r#rrr_loseConnectionrr finish)r[rr tracebackr,rr wsgiErrors  z$_WSGIResponse.run..wsgiErrorcs$js|s jdSdSr@)rrr_rrr,rr wsgiFinish s z%_WSGIResponse.run..wsgiFinishT) r^rprr'rgetattr BaseExceptionr\callFromThreadr[r)r% appIteratorrrrrrr,rrs&       z_WSGIResponse.runr@)r r.r/r0rrr#r4rbrr'rrrrrrrrAs!N F+ rAc@s4eZdZdZdZddZddZddZd d Zd 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. TcCs||_||_||_dSr@)_reactor _threadpool _application)r%r\r]r^rrrr4(s zWSGIResource.__init__cCs t|j|j|j|}|tS)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. )rArrrrr )r%r_responserrrrender-s  zWSGIResource.rendercCtd)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}r_rrrgetChildWithDefault=z WSGIResource.getChildWithDefaultcCr)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%pathchildrrrputChildErzWSGIResource.putChildN) r r.r/r0isLeafr4rrrrrrrrs rN)r0collections.abcrsysrwarningsrzope.interfacertwisted.internet.threadsrtwisted.loggerrtwisted.python.failurertwisted.web.httpr twisted.web.resourcer twisted.web.serverr rrrrrr1rAr__all__rrrrs0             C?3 8