o b.@sdZddlZddlZddlmZddlmZddlmZddl m Z ddl m Z m Z mZmZGdd d e jejZGd d d e jZGd d d eZGdddeje jZdS)zH I hold resource classes and helper classes that deal with CGI scripts. N)protocol)Logger)filepath)pb)httpresourceserverstaticc@s$eZdZddZddZddZdS) CGIDirectorycCstj|tj||dSN)rResource__init__rFilePath)selfpathnamer3/usr/lib/python3/dist-packages/twisted/web/twcgi.pyr s zCGIDirectory.__init__cCs6||}|s tjjS|rt|jSt|jSr ) childexistsr File childNotFoundisdirr path CGIScript)rrrequestfnprrrgetChilds   zCGIDirectory.getChildcCstd}||S)Nz1CGI directories do not support directory listing.)r NoResourcerender)rrnotFoundrrrr$s zCGIDirectory.renderN)__name__ __module__ __qualname__r rrrrrrr s r c@s2eZdZdZdZd ddZddZgfdd ZdS) rz L{CGIScript} is a resource which runs child processes according to the CGI specification. The implementation is complex due to the fact that it requires asynchronous IPC with an external process with an unpleasant protocol. NcCs$||_|dur ddlm}||_dS)zA Initialize, with the name of a CGI script file. Nr)reactor)filenametwisted.internetr$_reactor)rr%registryr$rrrr 6s  zCGIScript.__init__c Csdd|j}|dd}tj|d|jt|j |j ||j |j d }| j}|dur4||d<|j}|rBdd||d <t|d r`|jdd |j}|jddt||d <z|j d }Wntywd|d<g} Ynw|j |dd} |d<d| vrg} n dd| dD} |D]\} } | dd} | dvrd| } | || <qtjD] \}}||vr|||<q|||| tjS)a Do various things to conform to the CGI specification. I will set up the usual slew of environment variables, then spin off a process. @type request: L{twisted.web.http.Request} @param request: An HTTP request. /:rzCGI/1.1) SERVER_SOFTWARE SERVER_NAMEGATEWAY_INTERFACESERVER_PROTOCOL SERVER_PORTREQUEST_METHOD SCRIPT_NAMESCRIPT_FILENAME REQUEST_URIN REMOTE_ADDR/ PATH_INFOcontentCONTENT_LENGTH? QUERY_STRINGr#=cSsg|] }tj|qSr)urllibparseunquotedecode).0xrrr ssz$CGIScript.render..+-_)s content-typescontent-lengthsproxysHTTP_)joinprepathgetRequestHostnamesplitrversion clientprotostrgetHostportmethodr%urigetClientAddresshostpostpathhasattrr7seektellindex ValueError getAllHeadersitemsreplaceupperosenviron runProcess NOT_DONE_YET)rr scriptName serverNameenvippplengthqindexqargsqstitleheaderenvnamekeyvaluerrrrBsX        zCGIScript.renderc Cs4t|}|j||j|jg||tj|jdS)aI Run the cgi script. @type env: A L{dict} of L{str}, or L{None} @param env: The environment variables to pass to the process that will get spawned. See L{twisted.internet.interfaces.IReactorProcess.spawnProcess} for more information about environments and process creation. @type request: L{twisted.web.http.Request} @param request: An HTTP request. @type qargs: A L{list} of L{str} @param qargs: The command line arguments to pass to the process that will get spawned. N)CGIProcessProtocolr' spawnProcessr%r_rdirnamerrerrjprrrras  zCGIScript.runProcess)NN)r r!r"__doc__isLeafr rrarrrrr+s   Arc@s eZdZdZdZgfddZdS)FilteredScripta I am a special version of a CGI script, that uses a specific executable. This is useful for interfacing with other scripting languages that adhere to the CGI standard. My C{filter} attribute specifies what executable to run, and my C{filename} init parameter describes which script to pass to the first argument of that script. To customize me for a particular location of a CGI interpreter, override C{filter}. @type filter: L{str} @ivar filter: The absolute path to the executable. z /usr/bin/catc Cs8t|}|j||j|j|jg||tj|jdS)ad Run a script through the C{filter} executable. @type env: A L{dict} of L{str}, or L{None} @param env: The environment variables to pass to the process that will get spawned. See L{twisted.internet.interfaces.IReactorProcess.spawnProcess} for more information about environments and process creation. @type request: L{twisted.web.http.Request} @param request: An HTTP request. @type qargs: A L{list} of L{str} @param qargs: The command line arguments to pass to the process that will get spawned. N)rqr'rrfilterr%r_rrsrtrrrras zFilteredScript.runProcessN)r r!r"rvryrarrrrrxsrxc@seZdZdZdZdZdZeZdZ ddZ ddZ d d Z d d Z d dZddZddZddZddZddZddZddZdS)rqr#rFcC |dSr )resumeProducingrissuerrrrview_resumeProducing z'CGIProcessProtocol.view_resumeProducingcCr{r )pauseProducingr}rrrview_pauseProducingrz&CGIProcessProtocol.view_pauseProducingcCr{r ) stopProducingr}rrrview_stopProducingrz%CGIProcessProtocol.view_stopProducingcC|jdSr ) transportr|rrrrr|z"CGIProcessProtocol.resumeProducingcCrr )rrrrrrrrz!CGIProcessProtocol.pauseProducingcCrr )rloseConnectionrrrrrrz CGIProcessProtocol.stopProducingcCs||_|j|jdSr )r notifyFinishaddBoth _finished)rrrrrr szCGIProcessProtocol.__init__cCsH|j|d|jjdd|jj}|r|j||jdS)Nr#r)rregisterProducerr7rWreadrwrite closeStdin)rr7rrrconnectionMades   z!CGIProcessProtocol.connectionMadecCs|j||_dSr ) errortext)rerrorrrr errReceivedszCGIProcessProtocol.errReceivedc Cs|jr|j|}g}dD]}||}|dkr|||fq |rd|j_||d\}}|d||_|dt|d}|j|}|D]b}|d} | dkr\|j j d|dqH|d|  } || dd} | d krw|j t j| d krz t| dd } Wnty|j d YqHw|j | qH| d vr|jj| | qH||t|d}d|_|jr||_|js|j|dSdS)z) Handle a chunk of input )s s s s Nrr8s: z)ignoring malformed CGI header: {header!r})rmslocationsstatuszmalformed status header)sserversdate)handling_headers headertextfindappendrdefaultContentTypesortlenrK_logrlowersetResponseCoderFOUNDint BaseExceptionresponseHeaders addRawHeaderr) routputtext headerEnds delimiter headerend linebreakheadersrmbr headerName headerText statusNumrrr outReceivedsX       zCGIProcessProtocol.outReceivedcCs|jjdkr|jjd|jj|jjd|jr"|jjd|jj|jd|jrD|jjd|jj|jd|j sD|j t t jdd |j|j sS|j|jdSdS) Nrz*CGI {uri} exited with exit code {exitCode})rRexitCodez"Errors from CGI {uri}: {errorText})rR errorTextz/Premature end of headers in {uri}: {headerText})rRrzCGI Script Errorz Premature end of script headers.)rprrrrrRrrr_requestFinishedrr ErrorPagerINTERNAL_SERVER_ERRORrunregisterProducerfinish)rreasonrrr processEnded0s>  zCGIProcessProtocol.processEndedcCs d|_dS)zc Record the end of the response generation for the request being serviced. TN)r)rignoredrrrrQs zCGIProcessProtocol._finishedN)r r!r"rheaders_writtenrrrrrrrrr|rrr rrrrrrrrrrqs&: !rq)rvr_r>r&rtwisted.loggerrtwisted.pythonrtwisted.spreadr twisted.webrrrr r rr rrxProcessProtocolViewablerqrrrrs    s-