Ic.@sdZddkZddkZddkZddkZeidZddkZddkZyddk Z Wne j oddk Z nXe ei eieZddkZddkZddkZddkZddklZddklZddkZy$ddklZddklZWne j o eZnXddkZdZed d Zed d d ddddddddddddddZ e i!dedddZ"d d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6gZ#d7e$fd8YZ%d9e&fd:YZ'd;e$fd<YZ(d=e$fd>YZ)d?e&fd@YZ*dAe&fdBYZ+e odCei fdDYZ,ndCei fdEYZ,dFe,fdGYZ-dHe$fdIYZ.edJZ/eZ0dKei1fdLYZ2dMe$fdNYZ3dOfdPYZ4yddk5Z5WnUe j oIyddQk6l7Z7l8Z8Wne j odRZ9n XdSZ9n XdTZ9dUe$fdVYZ:dS(Ws A high-speed, production ready, thread pooled, generic WSGI server. Simplest example on how to use this module directly (without using CherryPy's application machinery): from cherrypy import wsgiserver def my_crazy_app(environ, start_response): status = '200 OK' response_headers = [('Content-type','text/plain')] start_response(status, response_headers) return ['Hello world! '] server = wsgiserver.CherryPyWSGIServer( ('0.0.0.0', 8070), my_crazy_app, server_name='www.cherrypy.example') The CherryPy WSGI server can serve as many WSGI applications as you want in one instance by using a WSGIPathInfoDispatcher: d = WSGIPathInfoDispatcher({'/': my_crazy_app, '/blog': my_blog_app}) server = wsgiserver.CherryPyWSGIServer(('0.0.0.0', 80), d) Want SSL support? Just set these attributes: server.ssl_certificate = server.ssl_private_key = if __name__ == '__main__': try: server.start() except KeyboardInterrupt: server.stop() This won't call the CherryPy engine (application side) at all, only the WSGI server, which is independant from the rest of CherryPy. Don't let the name "CherryPyWSGIServer" throw you; the name merely reflects its origin, not its coupling. For those of you wanting to understand internals of this module, here's the basic call flow. The server's listening thread runs a very tight loop, sticking incoming connections onto a Queue: server = CherryPyWSGIServer(...) server.start() while True: tick() # This blocks until a request comes in: child = socket.accept() conn = HTTPConnection(child, ...) server.requests.put(conn) Worker threads are kept in a pool and poll the Queue, popping off and then handling each connection in turn. Each connection can consist of an arbitrary number of requests and their responses, so we run a nested loop: while True: conn = server.requests.get() conn.communicate() -> while True: req = HTTPRequest(...) req.parse_request() -> # Read the Request-Line, e.g. "GET /page HTTP/1.1" req.rfile.readline() req.read_headers() req.respond() -> response = wsgi_app(...) try: for chunk in response: if chunk: req.write(chunk) finally: if hasattr(response, "close"): response.close() if req.close_connection: return iNs(?i)%2F(tunquote(turlparse(tSSL(tcryptocGsZtt}g}|D]'}||jo|tt|qq~}ti|iS(sReturn error numbers for all errors in errnames on this platform. The 'errno' module contains different global constants depending on the specific platform (OS). This function will return the list of numeric values for a given list of potential names. (tdirterrnotgetattrtdicttfromkeystkeys(terrnamest errno_namest_[1]tktnums((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pytplat_specific_errorsns ;tEINTRtWSAEINTRtEPIPEtEBADFtWSAEBADFtENOTSOCKt WSAENOTSOCKt ETIMEDOUTt WSAETIMEDOUTt ECONNREFUSEDtWSAECONNREFUSEDt ECONNRESETt WSAECONNRESETt ECONNABORTEDtWSAECONNABORTEDt ENETRESETt WSAENETRESETt EHOSTDOWNt EHOSTUNREACHs timed outtEAGAINt EWOULDBLOCKtWSAEWOULDBLOCKtACCEPTsACCEPT-CHARSETsACCEPT-ENCODINGsACCEPT-LANGUAGEs ACCEPT-RANGEStALLOWs CACHE-CONTROLt CONNECTIONsCONTENT-ENCODINGsCONTENT-LANGUAGEtEXPECTsIF-MATCHs IF-NONE-MATCHtPRAGMAsPROXY-AUTHENTICATEtTEtTRAILERsTRANSFER-ENCODINGtUPGRADEtVARYtVIAtWARNINGsWWW-AUTHENTICATEtWSGIPathInfoDispatchercBs eZdZdZdZRS(svA WSGI dispatcher for dispatch based on the PATH_INFO. apps: a dict or list of (path_prefix, app) pairs. cCswy|i}Wntj onX|i|ig}|D]"\}}||id|fqE~|_dS(Nt/(titemstAttributeErrortsorttreversetrstriptapps(tselfR8R tpta((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt__init__s  cCs|dpd}xx|iD]m\}}|i|dp ||jo@|i}|d||d<|t||d<|||SqW|dd d gd gS( Nt PATH_INFOR2t SCRIPT_NAMEs 404 Not Founds Content-Types text/plainsContent-Lengtht0t(s Content-Types text/plain(sContent-LengthR?(R8t startswithtcopytlen(R9tenvirontstart_responsetpathR:tapp((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt__call__s !   (t__name__t __module__t__doc__R<RH(((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR1s tMaxSizeExceededcBseZRS((RIRJ(((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRLstSizeCheckWrappercBs_eZdZdZdZd dZd dZddZdZ dZ d Z RS( s?Wraps a file-like object, raising MaxSizeExceeded if too large.cCs||_||_d|_dS(Ni(trfiletmaxlent bytes_read(R9RNRO((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR<s  cCs.|io |i|ijo tndS(N(RORPRL(R9((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt _check_lengthscCs5|ii|}|it|7_|i|S(N(RNtreadRPRCRQ(R9tsizetdata((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRRs cCs|dj o6|ii|}|it|7_|i|Sg}x|tot|iid}|it|7_|i|i|t|djp|ddjodi|SqLWdS(Niis R@( tNoneRNtreadlineRPRCRQtTruetappendtjoin(R9RSRTtres((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRVs    $icCswd}g}|i}xX|oP|i||t|7}d|jo |jnoPn|i}qW|S(Ni(RVRXRC(R9tsizehintttotaltlinestline((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt readliness  cCs|iidS(N(RNtclose(R9((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR`scCs|S(N((R9((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt__iter__scCs2|ii}|it|7_|i|S(N(RNtnextRPRCRQ(R9RT((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRbs N( RIRJRKR<RQRURRRVR_R`RaRb(((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRMs      t HTTPRequestcBseZdZdZdZdZdZdZdZdZ dZ dZ d d Z dd Zd Zd ZRS(sAn HTTP Request (and response). A single HTTP connection may consist of multiple request/response pairs. send: the 'send' method from the connection's socket object. wsgi_app: the WSGI application to call. environ: a partial WSGI environ (server and connection entries). The caller MUST set the following entries: * All wsgi.* entries, including .input * SERVER_NAME and SERVER_PORT * Any SSL_* entries * Any custom entries like REMOTE_ADDR and REMOTE_PORT * SERVER_SOFTWARE: the value to write in the "Server" response header. * ACTUAL_SERVER_PROTOCOL: the value to write in the Status-Line of the response. From RFC 2145: "An HTTP server SHOULD send a response version equal to the highest version for which the server is at least conditionally compliant, and whose major version is less than or equal to the one received in the request. An HTTP server MUST NOT send a version for which it is not at least conditionally compliant." outheaders: a list of header tuples to write in the response. ready: when True, the request has been parsed and is ready to begin generating the response. When False, signals the calling Connection that the response should not be generated and the connection should close. close_connection: signals the calling Connection that the request should close. This does not imply an error! The client and/or server may each request that the connection be closed. chunked_write: if True, output will be encoded with the "chunked" transfer-coding. This value is set automatically inside send_headers. icCsq|d|_||_|i|_||_t|_t|_d|_g|_ t|_ t|_ t|_ dS(Ns wsgi.inputR@( RNtwfileRBRDtwsgi_apptFalsetreadytstarted_responsetstatust outheaderst sent_headerstclose_connectiont chunked_write(R9RdRDRe((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR<s         cCsQ|i|i_d|i_y|iWn!tj o|iddSXdS(s;Parse the next HTTP request start-line and message-headers.is413 Request Entity Too LargeN(tmax_request_header_sizeRNRORPt_parse_requestRLtsimple_response(R9((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt parse_request-s  cCs|ii}|pt|_dS|djo(|ii}|pt|_dSn|i}y%|iidd\}}}Wn$tj o|idddSX||d~ } d i | }||d<| |ds%2FR=t QUERY_STRINGiitACTUAL_SERVER_PROTOCOLis505 HTTP Version Not SupportedtSERVER_PROTOCOLs HTTP/%s.%st SERVER_NAMEtCONTENT_LENGTHs413 Request Entity Too LargesHTTP/1.1tHTTP_CONNECTIONR`s Keep-AlivetHTTP_TRANSFER_ENCODINGt,tchunkeds501 Unimplementedt HTTP_EXPECTs 100-continueid(RNRVRfRgRDtstriptsplitt ValueErrorRpRt quoted_slashRRYtinttmintresponse_protocolt read_headerstreprtargstmax_request_body_sizetgetRWRlRUtlowert chunked_read(R9t request_lineRDtmethodRFt req_protocoltschemetlocationtparamstqstfragR txtatomstrptserver_protocoltsptextmrbsttet_[2]tenc((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRo8s     %   0        &  O      c Csf|i}xto|ii}|ptdn|djoPn|ddjo|i}nN|idd\}}|ii|i}}d|idd }|t jo3|i |}|od i ||f}qn||||g}|iD]\} } || d| dq~7}WnVtj oJt| tptdnt| tptdqnX|i d|iidi|dS(#s<Assert, process, and send the HTTP response message-headers.iiscontent-lengthiiii0sHTTP/1.1RstHEADsTransfer-EncodingR}t connectiont ConnectionR`s Keep-AliveitdatetDatetservertServertSERVER_SOFTWARERvRrs s: s,WSGI response header key %r is not a string.s.WSGI response header value %r is not a string.R@N(iii0(sTransfer-Encodingschunked(s Connectionsclose(s Connections Keep-Alive(RjRRRiRWRlRRDRmRXRRNRORPRRtrfc822t formatdatet TypeErrort isinstanceRRdRRY( R9R tkeytvaluethkeysRiRSRRR R((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRsJ0             !> N(RIRJRKRnRR<RqRoRRRRRpRURERR(((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRcs!  #      t NoSSLErrorcBseZdZRS(s>Exception raised when a client speaks HTTP to an HTTPS socket.(RIRJRK(((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRst FatalSSLAlertcBseZdZRS(sCException raised when the SSL implementation signals a fatal alert.(RIRJRK(((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRst CP_fileobjectcBsJeZdZdZdZdZdZddZddZRS(s-Faux file object attached to a socket object.cCsfx_|oWy|i|}||}Wqtij o$}|idtjoq]qXqWdS(s!Sendall for non-blocking sockets.iN(tsendRRRtsocket_errors_nonblocking(R9RTt bytes_sentte((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRscCs|ii|S(N(t_sockR(R9RT((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRscCs:|io,di|i}g|_|i|ndS(NR@(t_wbufRYR(R9tbuffer((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pytflushs  cCsqxjtoby|ii|SWqtij o8}|idtjo|idtjoqhqXqWdS(Ni(RWRtrecvRRRRtsocket_error_eintr(R9RSR((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRsic Cst|i|i}|i}|idd|djoQti|_x4to,|i|}|pPn|i|qMW|i S|i }||joF|id|i |}ti|_|ii|i |Sti|_xto||}|i|}|pPnt |}||jo | o|S||jo|i|~Pn||jpt d||f|i|||7}~qW|i SdS(Niisrecv(%d) returned %d bytes(tmaxt _rbufsizetdefault_bufsizet_rbufRRRWRRtgetvaluettellRRRCR( R9RStrbufsizeRRTtbuf_lentrvtlefttn((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRRsL          !  c Cs|i}|idd|idjop|id|i|}|idpt||jo*ti|_|ii|i|S~n|djoI|i djo|id|ig}ti|_d}|i }x7|djo)|d}|pPn|i |qWdi |S|iddti|_xto|i |i }|pPn|id}|djo7|d7}|i|| |ii||~Pn|i|q]W|iS|idd|i}||joF|id|i|} ti|_|ii|i| Sti|_xto |i |i }|pPn||} |idd| }|djoG|d7}|ii|||o|i|| Pq || Snt|} | |jo | o|S| | jo*|i|| |ii|| Pn|i||| 7}qsW|iSdS(Niis iR@(RRRRVtendswithRCRRRRRRURRXRYRWtfindR( R9RSRtblinetbuffersRTRtnlRRRR((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRV-s  #                  ( RIRJRKRRRRRRRV(((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRs   eZdZdZdZdZdZdZdZRS(s,SSL file object attached to a socket object.ig{Gz?c Osti}xtoy|||SWnMtij oti|in)tij oti|intij oZ}|o|id jodS|id}|o|t jodSt i |nti j o}|o|id jodSd}y|iddd}Wntj onX|djo tnt|in nXti||ijot idqqWdS( sWrap the given call with SSL error-trapping. is_reader: if False EOF errors will be raised. If True, EOF errors will return "" (to emulate normal sockets). isUnexpected EOFR@iis http requests timed outN(isUnexpected EOF(isUnexpected EOF(ttimeRWRt WantReadErrortsleept ssl_retrytWantWriteErrort SysCallErrorRRRRtErrorRUt IndexErrorRRt ssl_timeoutttimeout( R9t is_readertcallRtkwargststartRterrnumtthirdarg((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt _safe_calls>    cOstg}tt|i}xUtoM|it|||}|i||ii}|pdi|SqWdS(NR@( tsuperRRRWRRXRtpendingRY(R9RRRtrRTR:((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRHs cOs"|ittt|i||S(N(RRfRRR(R9RR((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRRscOs"|ittt|i||S(N(RRfRRR(R9RR((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRUs( RIRJRKRRRRRR(((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRs . tHTTPConnectioncBsheZdZdZeZhdd6dd6ed6ed6ed 6ei d 6Z d Z d Z d Z RS(sqAn HTTP connection (active socket). socket: the raw socket object (usually TCP) for this connection. wsgi_app: the WSGI application for this server/connection. environ: a WSGI environ template. This will be copied for each request. rfile: a fileobject for reading from the socket. send: a function for writing (+ flush) to the socket. iiis wsgi.versionthttpswsgi.url_schemeswsgi.multithreadswsgi.multiprocesss wsgi.run_onces wsgi.errorscCs||_||_|ii|_|ii|toht|tioU|i}t |d|i |_ ||i _ t |dd|_ ||i _ n.t|d|i |_ t|dd|_ t|i d|idLike print_exc() but return a string. Backport for Python 2.3.R@N(RRRYt tracebacktformat_exceptionRU(tlimittetypeRttb((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRs#t WorkerThreadcBs&eZdZdZdZdZRS(s@Thread which continuously polls a Queue for Connection objects. server: the HTTP Server which spawned this thread, and which owns the Queue and is placing active connections into it. ready: a simple flag for the calling server to know when this thread has begun polling the Queue. Due to the timing issues of polling a Queue, a WorkerThread does not check its own 'ready' flag after it has started. To stop the thread, it is necessary to stick a _SHUTDOWNREQUEST object onto the Queue (one for each running WorkerThread). cCs&t|_||_tii|dS(N(RfRgRt threadingtThreadR<(R9R((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR<s  c Csynt|_x^toV|iii}|tjodS||_z|iWd|id|_XqWWn't t fj o}||i_ nXdS(N( RWRgRtrequestsRt_SHUTDOWNREQUESTtconnRR`RURRt interrupt(R9R%texc((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pytruns    N(RIRJRKRUR%R<R((((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR s  t ThreadPoolcBskeZdZdddZdZdZeedeiZdZdZ d Z d d Z RS( sA Request Queue for the CherryPyWSGIServer which pools threads. ThreadPool objects must provide min, get(), put(obj), start() and stop(timeout) attributes. i icCsF||_||_||_g|_ti|_|ii|_dS(N(RRRt_threadstQueuet_queueR(R9RRR((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR<s     cCsx0t|iD]}|iit|iqWx2|iD]'}|id|i|iq=Wx0|iD]%}x|i pt i dq{WqrWdS(sStart the pool of threads.sCP WSGIServer g?N( txrangeRR*RXR RtsetNametgetNameRRgRR(R9titworker((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRs   cCs<tg}|iD]!}|idjo ||qq~S(s3Number of worker threads which are idle. Read-only.N(RCR*R%RU(R9R tt((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt _get_idlestdoccCs&|ii||tjodSdS(N(R,tputR$(R9tobj((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR5s cCsxt|D]t}|idjot|i|ijoPnt|i}|id|i|ii||i q WdS(s.Spawn new worker threads (not above self.max).isCP WSGIServer N( R-RRCR*R RR.R/RXR(R9tamountR0R1((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pytgrows )cCsx<|iD]1}|ip|ii||d8}q q W|djoDxAtt|t|i|iD]}|iitqrWndS(s-Kill off worker threads (not below self.min).iiN( R*tisAlivetremoveR-RRCR,R5R$(R9R7R2R0((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pytshrink"s   &icCsHx!|iD]}|iitq Wti}x|io|ii}||j o|ioy|djp |djo|i n|i ||ioq|i }|oS|i i oEt o't|it io|iiq|iitin|i nWq?ttfj o }q?Xq3q3WdS(Ni(R*R,R5R$R!t currentThreadRR9RURYR%RNtclosedRRRRtshutdowntSHUT_RDRR(R9RR1tcurrenttctexc1((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pytstop3s,      ( RIRJRKR<RR3tpropertytidleR5R8R;RC(((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR)s   t SSLConnectionc!Bs:eZdZdZx d%D]Zd#eefd$UqWRS(&s|A thread-safe wrapper for an SSL.Connection. *args: the arguments to create the wrapped SSL.Connection(*args). cGs%ti||_ti|_dS(N(RRt _ssl_connR!tRLockt_lock(R9R((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR<\st get_contextRRRRRRt renegotiatetbindtlistentconnecttacceptt setblockingtfilenoR>R`tget_cipher_listt getpeernamet getsocknamet getsockoptt setsockopttmakefilet get_app_datat set_app_datat state_stringt sock_shutdowntget_peer_certificatet want_readt want_writetset_connect_statetset_accept_statet connect_exRt settimeoutsdef %s(self, *args): self._lock.acquire() try: return self._ssl_conn.%s(*args) finally: self._lock.release() N(!RJspendingssendswritesrecvsreadRKsbindslistensconnectsacceptRPsfilenosshutdownscloseRRRSs getsocknameRUs setsockoptRWRXRYRZR[R\R]R^R_R`Rassendalls settimeout(RIRJRKR<tf(((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRFVs (twindlltWinErrorcCsdS(s=Dummy function, since neither fcntl nor ctypes are available.N((R((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pytprevent_socket_inheritancewscCs0tii|iddp tndS(s6Mark the given socket fd as non-inheritable (Windows).iiN(Rdtkernel32tSetHandleInformationRQRe(R((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRf{scCsB|i}ti|ti}ti|ti|tiBdS(s4Mark the given socket fd as non-inheritable (POSIX).N(RQtfcntltF_GETFDtF_SETFDt FD_CLOEXEC(Rtfdt old_flags((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRfs tCherryPyWSGIServercBs eZdZdZdZdZeZdZ e Z e Z hZdZdZdddddddZdZd ZeeeZd Zd Zd Zeeed dZdZddZdZdZdZeeed dZdZ dZ!RS(sAn HTTP server for WSGI. bind_addr: The interface on which to listen for connections. For TCP sockets, a (host, port) tuple. Host values may be any IPv4 or IPv6 address, or any valid hostname. The string 'localhost' is a synonym for '127.0.0.1' (or '::1', if your hosts file prefers IPv6). The string '0.0.0.0' is a special IPv4 entry meaning "any active interface" (INADDR_ANY), and '::' is the similar IN6ADDR_ANY for IPv6. The empty string or None are not allowed. For UNIX sockets, supply the filename as a string. wsgi_app: the WSGI 'application callable'; multiple WSGI applications may be passed as (path_prefix, app) pairs. numthreads: the number of worker threads to create (default 10). server_name: the string to set for WSGI's SERVER_NAME environ entry. Defaults to socket.gethostname(). max: the maximum number of queued requests (defaults to -1 = no limit). request_queue_size: the 'backlog' argument to socket.listen(); specifies the maximum number of queued connections (default 5). timeout: the timeout in seconds for accepted connections (default 10). nodelay: if True (the default since 3.1), sets the TCP_NODELAY socket option. protocol: the version string to write in the Status-Line of all HTTP responses. For example, "HTTP/1.1" (the default). This also limits the supported features used in the response. SSL/HTTPS --------- The OpenSSL module must be importable for SSL functionality. You can obtain it from http://pyopenssl.sourceforge.net/ ssl_certificate: the filename of the server SSL certificate. ssl_privatekey: the filename of the server's private key file. If either of these is None (both are None by default), this server will not use SSL. If both are given and are valid, they will be read on server start and used in the SSL context for the listening socket. sHTTP/1.1s 127.0.0.1sCherryPy/3.1.1i iic Cst|d|pdd||_t|o ||_n tidtt||_||_|pt i }n||_ ||_ ||_ ||_dS(NRiRsThe ability to pass multiple apps is deprecated and will be removed in 3.2. You should explicitly include a WSGIPathInfoDispatcher instead.(R)R#tcallableRetwarningstwarntDeprecationWarningR1t bind_addrRt gethostnamet server_nametrequest_queue_sizeRtshutdown_timeout( R9RtRet numthreadsRvRRwRRx((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyR<s"       cCs |iiS(N(R#R(R9((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt_get_numthreadsscCs||i_dS(N(R#R(R9R((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt_set_numthreadsscCsd|i|ii|ifS(Ns %s.%s(%r)(RJt __class__RIRt(R9((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt__str__scCs|iS(N(t _bind_addr(R9((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt_get_bind_addrscCs>t|to!|ddjotdn||_dS(NiR@szHost values of '' or None are not allowed. Use '0.0.0.0' (IPv4) or '::' (IPv6) instead to listen on all active interfaces.(R@N(RttupleRURR~(R9R((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyt_set_bind_addrs! R4s,The interface on which to listen for connections. For TCP sockets, a (host, port) tuple. Host values may be any IPv4 or IPv6 address, or any valid hostname. The string 'localhost' is a synonym for '127.0.0.1' (or '::1', if your hosts file prefers IPv6). The string '0.0.0.0' is a special IPv4 entry meaning "any active interface" (INADDR_ANY), and '::' is the similar IN6ADDR_ANY for IPv6. The empty string or None are not allowed. For UNIX sockets, supply the filename as a string.c Cs@d|_t|itodyti|iWnnXyti|idWnnXti ti dd|ifg}nu|i\}}y+ti ||ti ti dti }Wn7tij o(titi dd|ifg}nXd|_d}x}|D]u}|\}}}} } y|i|||Wn?tij o0}|io|iind|_q nXPq W|ipti|n|iid|ii|i|iit|_xc|ioX|i|io@x"|itjotidqW|io |iq7qqWdS(sRun the server forever.iiR@sNo socket could be createdig?N(RUt _interruptRRtt basestringtostunlinktchmodRtAF_UNIXt SOCK_STREAMt getaddrinfot AF_UNSPECt AI_PASSIVEtgaierrortAF_INETRLRR`RbRMRwR#RRWRgttickR&RR( R9tinfothosttportRRZtaftsocktypetprotot canonnametsa((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRsZ %&          icCsti||||_t|i|iititid|io |iititidn|io|i ot djot dnt i t i}|i|i |i|it||i|_|it|it og|iddjoS|tijoCy |iititidWqhttifj oqhXqln|ii|idS(s.Create (or recreate) the actual socket object.is(You must install pyOpenSSL to use HTTPS.is::N(RRfRVt SOL_SOCKETt SO_REUSEADDRtnodelayt IPPROTO_TCPt TCP_NODELAYtssl_certificatetssl_private_keyRRUt ImportErrortContextt SSLv23_METHODtuse_privatekey_filetuse_certificate_fileRFtpopulate_ssl_environRRtRtAF_INET6t IPPROTO_IPV6t IPV6_V6ONLYR4RRL(R9tfamilyttypeRtctx((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRLDs(     $  cCsy,|ii\}}t||ipdSt|do|i|in|ii}|i ddjod|i |dXxti ||ti ti D]}|\}}}} } d} yCti|||} | id| i||f| iWqti j o| o| iq6qXqWnt|do|ind|_n|ii|idS(s5Gracefully shutdown a server that is serving forever.RiisBad file descriptorg?R`N(RfRgRRURRtRRTRRRRRRRbRNR`RR#RCRx( R9RRRRRZRRRRRR((sD/usr/lib/python2.6/site-packages/paste/script/wsgiserver/__init__.pyRCs4     c Csct|idi}titi|}hdd6dd6}|ih|id6|id6xd|i fd |i fgD]\}}t |d d !}d |}|||Ms                    #?Ei 'b