mò "á¸Ec@s.dZdZdkZdkZdklZdklZdkl Z dk l Z dk l Z dklZd klZd klZd klZlZlZlZdkZd klZd klZdkZdkZdk Z dk!Z!dk"Z"dk#Z#dk$l%Z%dk&Z&e ƒZ'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6e6Z7e4gZ8dZ9dZ:dZ;dZ<dZ=dZ>dZ?dZ@dZAdfd„ƒYZBdeiCfd„ƒYZDd eiEfd!„ƒYZFd"efd#„ƒYZGd$fd%„ƒYZHdS(&s… ZServer/Medusa FastCGI server, by Robin Dunn. Accepts connections from a FastCGI enabled webserver, receives request info using the FastCGi protocol, and then hands the request off to ZPublisher for processing. The response is then handed back to the webserver to send down to the browser. See http://www.fastcgi.com/fcgi-devkit-2.1/doc/fcgi-spec.html for the protocol specificaition. s1.0N(slogger(scounter(scompute_timezone_for_log(srequestCloseOnExec(shandle(sWakeup(s HTTPResponse(s HTTPRequest(sShutdownProducersLoggingProducersfile_part_producersfile_close_producer(sStringIO(s TemporaryFile(s StringTypesi i2iiiiiiiiii i t FCGIRecordcBsbtZdZed„Zd„Zd„Zd„Zd„Zd„Z d„Z d„Z d „Z RS( s” This class represents the various record structures used in the FastCGI protocol. It knows how to read and build itself bits at a time as they are read from the FCGIChannel. There are really several different record types but in this case subclassing for each type is probably overkill. See the FastCGI spec for structure and other details for all these record types. cCs›|oltt|ƒ}|d|_|d|_|dd>|d|_|dd>|d|_|d|_ nt |_t |_t |_d |_ dS( Niiiiiiiit(theadertmaptordtvalstselftversiontrecTypetreqIdt contentLengtht paddingLengthtFCGI_VERSION_1tFCGI_UNKNOWN_TYPEtFCGI_NULL_REQUEST_IDtcontent(RRR((t1/data/zmath/zope/lib/python/ZServer/FCGIServer.pyt__init__us     cCs|io|i S(N(RR R(R((Rt needContent…scCs |idjS(Ni(RR (R((Rt needPaddingˆscCs#|iƒo |iSn|iSdS(N(RRR R (R((RtneedMore‹s  cCs d|_dS(Ni(RR (R((Rt gotPadding‘scCsh|}|_|itjo<t|dƒd>t|dƒ|_t|dƒ|_n |it jot|dƒ|_ nå|it jp|it joVh|_ d}x²|t|ƒjo,|i||ƒ\}}}||i ||dd>|dd>|d|_t|dƒ|_ndS( Niiiiiiii(tdatatcRRRtFCGI_BEGIN_REQUESTRtroletflagsR t unknownTypetFCGI_GET_VALUESt FCGI_PARAMStvaluestpostlentreadPairtnametvaluetFCGI_END_REQUESTRtbt appStatustprotocolStatus(RRRR"RR%R#((Rt parseContent•s" %  1cCs)t||ƒ}|d}|d@oVtt|||d!ƒ}|d}|d@d>|dd>|dd>|d }nt||ƒ}|d}|d@oVtt|||d!ƒ}|d}|d@d>|dd>|dd>|d }n||||!||||||!|||fS( s? Read the next name-value pair from st at pos. ii€iiiiiiiN(RtstRtnameLenRR%tvalueLen(RR)RR+R%R*((RR!¬s   2   2cCsút|ƒ}|djot|ƒ}nKtd|d?d@Bƒt|d?d@ƒt|d?d@ƒt|d@ƒ}t|ƒ}|djo|t|ƒ}nO|td|d?d@Bƒt|d?d@ƒt|d?d@ƒt|d@ƒ}|||S(s& Opposite of readPair i€iiÿiiN(R R"tltchrR)R#(R"R#R,R)((Rt writePairÄs  J  NcCsí|i}|itjo=t|id?ƒt|id@ƒt|iƒdd}n |itjot|iƒdd}nà|it jp|it joAd}x¶|i i ƒD]#}||i||i |ƒ}q·Wn|itjon|i}t|d?d@ƒt|d?d@ƒt|d?d@ƒt|d@ƒ}|t|iƒd d}nt|ƒ}|dd d@}||}|i|i|id?|id@|d?|d@|d g}titt|ƒdƒ}|||dS( sF Format the record to be sent back to the web server. iiÿitiRiiiiÿÿiN(RRRRR-RRR RRRRtkeystiR.R$R&tvR'R tcLenteLentpadLenRR thdrtstringtjoinR(RR6R1R5RR3R4R2((RtgetRecordAsStringÚs* = % F  :( t__name__t __module__t__doc__tNoneRRRRRR(R!R.R9(((RRjs         t FCGIChannelcBs›tZdZdZeZd„Zd„Zd„Zd„Z d„Z d„Z d„Z d „Z d „Zd „Zdd „Zd d„ZeZd„ZRS(sr Process a FastCGI connection. This class implements most of the Application Server side of the protocol defined in http://www.fastcgi.com/fcgi-devkit-2.1/doc/fcgi-spec.html (which is the FastCGI Specification 1.0 from Open Market, Inc.) in a manner that is compatible with the asyncore medusa engine of ZServer. The main ommission from the spec is support for multiplexing multiple requests on a single connection, but since none of the web servers support it (that I know of,) and since ZServer can easily multiplex multiple connections in the same process, it's no great loss. icCsp||_||_tii||ƒt|ƒ|iƒd|_ h|_ t ƒ|_ t ƒ|_ d|_dS(Nii(tserverRtaddrtasynchatt async_chatRtsocktrequestCloseOnExectsetInitialStatet remainingRecstenvtStringIOtstdint filterDatat requestId(RR?RCR@((RRs        cCs&tƒ|_d|_|idƒdS(Ni(RHRRR=tcurRectset_terminator(R((RRE!s  cCs |idjS(Ni(RRF(R((Rtreadable'scCs|ii|ƒdS(N(RRtwrite(RR((Rtcollect_incoming_data+scCs>|ipVt|iiƒƒ|_|iiƒo*|i|iiƒƒtƒ|_dSq`n|i}|i ƒoN|i |iiƒƒ|iƒo'|i|iƒƒtƒ|_dSqÄn|i ƒo|i ƒn|i tjo|i|ƒn¬|idjo8tƒ}t|_ |i |_|i|iƒdƒnd|i tjow|idjog|i|_|itjo d|_q«|itjo d|_q«|itjo d|_q«nÝ|i tjoÓ|idjo¬|ii dƒo|id}nd}|ii dƒo|id}nd}t#i$d t%|ƒd ||fƒ|id|_t&i'|ii(d d ƒƒ|_)q«|ii*|i+ƒnú|i t,jož|idjo|id|_q«t-|i.ƒ|i/i0ƒd jo@|i1 o5t2ƒ}|i4|i/iƒƒ||_/d|_1n|i/i4|i.ƒnL|i t5jo;|idjo|id|_q«|i6i4|i.ƒn|idjo|i7ƒnrt#i$dt%|ƒ|i/i0ƒƒ|ii dƒo"|id|id<|id=n|i/i8dƒ|i9ƒdS(NiiiitREQUEST_METHODtGETt PATH_INFORtBs%s %stCONTENT_LENGTHt0itIt AuthorizationtHTTP_AUTHORIZATION(:RRLRRtgetvalueRRMRHtrecRR(RRRtFCGI_ManagementTypesthandleManagementTypesR tr2R RtpushR9RRKRtFCGI_AUTHORIZERRFtFCGI_RESPONDERt FCGI_FILTERRR RGthas_keytmethodtpatht DebugLoggertlogtidR7tatoitgettcontent_lengthtupdateRt FCGI_STDINR RRIttelltusing_temp_stdint TemporaryFilettROt FCGI_DATARJREtseekt send_response(RReR[RdR^Rq((Rtfound_terminator/s~                #%.   "cCs`tdt|tƒdtƒƒ}|i|ƒt|i|i |ƒ}t |i i ||ƒdS(sv Create output pipes, request, and response objects. Give them to ZPublisher for processing. tstdouttstderrN(t FCGIResponsetFCGIPipeRt FCGI_STDOUTRHtresponset setChannelt HTTPRequestRIRGtrequestthandleR?tmodule(RR~R{((RRtªs  c CsFtidt|ƒƒ|iidƒo|id}nd}|iidƒo|id}nd}|iidƒo|id}nd}|iidƒo|id}nd}|iidƒo¤|id}t i |d ƒd joyyt i|d ƒ}Wnt iij o d}nXt i|d d ƒ} t| ƒd jo d}qq| d}q{nd}|ioi|iii|idd|id |tidtitiƒƒƒt|||i|||f ƒnU|iiidd|tidtitiƒƒƒt|||i|||fƒdS(NtEtHTTP_USER_AGENTRt HTTP_REFERERRSRQRRRYisbasic t:iit-is$%s - %s [%s] "%s %s" %d %d "%s" "%s"s%d/%b/%Y:%H:%M:%S s 127.0.0.1 s!- %s [%s] "%s %s" %d %d "%s" "%s"(RfRgRhRRGRct user_agenttrefererReRdthttp_authorizationR7tlowertbase64t decodestringtdecodedtbinasciitErrortsplitRqR t user_nameR@R?tloggerttimetstrftimet localtimet tz_for_logt reply_codetbytes( RR—RˆRŒRdR‡R†ReRRq((Rt log_request¶s@    :cCsa|itjoMt|_hdt<dt<dt<}||_|i |i ƒdƒndS(sI The web server has asked us what features we support... tFCGI_MAX_CONNSt FCGI_MAX_REQStFCGI_MPXS_CONNSiN( R[RRtFCGI_GET_VALUES_RESULTR™RšR›tvarsRRR_R9(RR[R((RR]õs  ! c Cs2tƒ} || _|i| _t|ƒtdƒjoFxô|o7|d }|d}|| _ |i | i ƒdƒq:Wn²|\}}|ddd@}||}| i| i| id?| id@|d?|d@|dg}titt|ƒdƒ}|i |dƒ|i |dƒ|i |ddƒdS( NRi iiiÿÿiiÿR/(RR[RRRKR ttypeRtchunkRR_R9tpR3R4R5RR6R7R8RR-( RRRR6RŸR4R R5R3R[((RtsendDataRecords$        :cCsAtƒ}||_|i|_d|_|i|iƒdƒdS(NRi( RR[RRRKR RR_R9(RRR[((RtsendStreamTerminator!s     cCsStƒ}t|_|i|_t|_||_ |i |i ƒdƒd|_dS(Ni( RR[R$RRRKR tFCGI_REQUEST_COMPLETER'R&R_R9(RR&R[((Rt sendEndRecord(s     icCs;|iodSn|ii|ƒ|o|iƒndS(N(Rtclosedt producer_fifoR_tproducertsendt initiate_send(RR§R¨((RR_1s  cCswd|_xW|ioL|iiƒ}|dj ot|tƒ o|iƒn|ii ƒq Wt i i |ƒdS(Ni( RR¥R¦tfirstR R=t isinstancet StringTypestmoretpoptasyncoret dispatchertclose(RR ((RR±<s  (R:R;R<R¥R=RoRRERNRPRuRtR˜R]R¡R¢R¤R_tpush_with_producerR±(((RR>s"     { ?   t FCGIServercBs\tZdZeZddeeeed„Zd„Zd„Zd„Z d„Z d„Z RS( sÕ Listens for and accepts FastCGI requests and hands them off to a FCGIChannel for handling. FCGIServer can be configured to listen on either a specific port (for inet sockets) or socket_file (for unix domain sockets.) For inet sockets, the ip argument specifies the address from which the server will accept connections, '' indicates all addresses. If you only want to accept connections from the localhost, set ip to '127.0.0.1'. tMains 127.0.0.1cCs¬||_tƒ|_tii|ƒ|pti t i ƒ}n|oti ||ƒ|_nti|ƒ|_||_||_||_|io=|ititiƒ|iƒ|i|i|ifƒnŽyti|iƒWntij onX|ititiƒ|iƒ|i|iƒyti|idƒWntij onX|idƒ|idtt i!t i ƒƒ|i|i|ifƒdS(NiÿisYFastCGI Server (V%s) started at %s IP : %s Port : %s Socket path : %s ("tipRtcountertcountR¯R°Rt logger_objectR‘t file_loggertsysRvtresolvertresolving_loggertunresolving_loggerR€tportt socket_filet create_sockettsockettAF_INETt SOCK_STREAMtset_reuse_addrtbindtostunlinkterrortAF_UNIXtchmodtlistentlog_infot __version__R’tctime(RR€RµR¾R¿R»R¸((RRWs8         cCsg|iiƒy|iƒ\}}Wn*tij o|iddƒdSnX|i |||ƒdS(Ns"Server accept() threw an exceptiontwarning( RR·t incrementtaccepttconnR@RÁRÈRÌt channel_class(RR@RÒ((Rt handle_accept‰s  cCs dkl}ttiƒ|jS(N(sCONNECTION_LIMIT(tZServertCONNECTION_LIMITR R¯t socket_map(RRÖ((RRN“s cCsdS(Ni((R((Rtwritable˜scCs'tii|||ƒt|iƒdS(N(R¯R°RÀRtfamilyRžRDRÁ(RRÙRž((RRÀ›scCsd|_|ii|ƒS(Ni(Rt acceptingRÁRËtnum(RRÛ((RRËŸs ( R:R;R<R>RÓR=RRÔRNRØRÀRË(((RR³Gs 2   RxcBs5tZdZdZdZd„Zd„Zd„ZRS(NicCs ||_dS(N(tchannelR(RRÜ((RR|¬scCsÎt|ƒtdƒjotdƒ‚n|i}|ip¬|iiddƒ}|dj ojy\t|ƒtdƒjot i |ƒ}n|djot ƒ|_ tiƒ|_nWqÈqÈXn|it|ƒƒd|_n|pdSn|i }|djo|i|ƒn­x©|o¡|d }|d}t|ƒ}|i}||}|iiƒz|i|ƒ|i|ƒWd|iiƒX||_|it||i||ƒ|fƒq!WdS(NRsValue must be a stringscontent-lengthiôii€(RžRt TypeErrorRRvt_wrotetheadersRjR=R,R7RiRpt _tempfiletthreadt allocate_lockt _templockROtstrRqRŸR t _tempstartR%tetacquireRstreleasetfile_part_producer(RRRæRvR,R%RqRŸ((RRO¯sH                cCsH|i|i_tidt|iƒd|i|iifƒ|i }|dj o |ii t |ƒdfƒnd|_ |iitƒ|iiƒ|iiƒ|iiƒ|iip,|iit|i|iidƒdƒn|iƒo'|iitƒdƒtd„ƒn|iiddƒtƒd|_dS(NtAs%d %diR˜cCs tiƒS(N(R¯t close_all(((Rtðs(RtstatusRÜR–RfRgRhRvtlengthRàRqR=ROtfile_close_producerR¢RzR¤R±RwR¥R²tLoggingProducert_shutdownRequestedR_tShutdownProducertWakeup(RRq((Rt_finishÚs*/           ( R:R;R=RàRãRåR|RORô(((RRx¦s   +RycBs)tZdZd„Zd„Zd„ZRS(s¯ This class acts like a file and is used to catch stdout/stderr from ZPublisher and create FCGI records out of the data stream to send back to the web server. cCs||_||_d|_dS(Ni(RÜRRRî(RRÜR((RRs  cCsjt|ƒtdƒjot|ƒ}n |\}}|o*|ii||iƒ|i ||_ ndS(NR( RžRR tdatalenR RRÜR¡RRî(RRR Rõ((RROs  cCs d|_dS(N(R=RRÜ(R((RR±s(R:R;R<RROR±(((RRyús   (IR<RÍRAR¯tmedusaR‘tmedusa.counterR¶tmedusa.http_servertcompute_timezone_for_logRÕRDtPubCoreRtPubCore.ZEventRótZPublisher.HTTPResponset HTTPResponsetZPublisher.HTTPRequestR}t ProducersRòRðRéRïRft cStringIORHttempfileRpRÁR7RÆRºR’RáttypesR¬RŠR•R™RšR R›RtFCGI_ABORT_REQUESTR$RRmRzt FCGI_STDERRRrRRœR t FCGI_MAXTYPER\RtFCGI_KEEP_CONNRaR`RbR£tFCGI_CANT_MPX_CONNtFCGI_OVERLOADEDtFCGI_UNKNOWN_ROLERRBR>R°R³RxRy(:R›R¯RRšRùRR\R³RRóRRRDRARmRéRfR™RŠRaRbRxR£RýR‘RÍR}R$RR7RðRïR•RRºRRR¬RRR RRpRœRòRÁRáRHR RzR¶R>RrR R’RyRÆR`((Rt?sf           -     ™ÿE_T