0Uc@sdZddlZddlZddlZddlZejdZddlZddlZyddl Z Wne k rddl Z nXe ej ejeZddlZddlZddlZddlZddlmZddlmZddlZy$ddlmZddlmZWne k rAeZnXddlZdZed d Zed d d ddddddddddddddZ e j!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 rdCej fdDYZ,ndCej fdEYZ,dFe,fdGYZ-dHe$fdIYZ.edJZ/eZ0dKej1fdLYZ2dMe$fdNYZ3dOfdPYZ4yddl5Z5WnQe k ryddQl6m7Z7m8Z8Wne k rdRZ9n 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(tcryptocGsMtt}g|D]!}||krtt|^q}tj|jS(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_namestktnums((sB/usr/lib/python2.7/vendor-packages/cherrypy/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. cCsmy|j}Wntk r#nX|j|jg|D]!\}}|jd|f^q?|_dS(Nt/(titemstAttributeErrortsorttreversetrstriptapps(tselfR7tpta((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt__init__s   cCs|dp d}xu|jD]j\}}|j|dsE||kr|j}|d||d<|t||d<|||SqW|dd d gd gS( Nt PATH_INFOR1t SCRIPT_NAMEs 404 Not Founds Content-Types text/plainsContent-Lengtht0t(s Content-Types text/plain(sContent-LengthR>(R7t startswithtcopytlen(R8tenvirontstart_responsetpathR9tapp((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt__call__s   (t__name__t __module__t__doc__R;RG(((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyR0s tMaxSizeExceededcBseZRS((RHRI(((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRKstSizeCheckWrappercBs_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(R8RMRN((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyR;s  cCs+|jr'|j|jkr'tndS(N(RNRORK(R8((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt _check_lengthscCs5|jj|}|jt|7_|j|S(N(RMtreadRORBRP(R8tsizetdata((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRQs cCs|dk rA|jj|}|jt|7_|j|Sg}xwtr|jjd}|jt|7_|j|j|t|dks|ddkrJdj|SqJWdS(Niis R?( tNoneRMtreadlineRORBRPtTruetappendtjoin(R8RRRStres((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRUs     "icCsrd}g}|j}xS|rm|j||t|7}d|koU|knr^Pn|j}qW|S(Ni(RURWRB(R8tsizehintttotaltlinestline((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt readliness   cCs|jjdS(N(RMtclose(R8((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyR_scCs|S(N((R8((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt__iter__scCs2|jj}|jt|7_|j|S(N(RMtnextRORBRP(R8RS((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRas N( RHRIRJR;RPRTRQRUR^R_R`Ra(((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRLs      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. icCsz|d|_||_|j|_||_t|_t|_t|_d|_ g|_ t|_ t|_ t|_ dS(Ns wsgi.inputR?(RMtwfileRARCtwsgi_apptFalsetreadytstarted_requesttstarted_responsetstatust outheaderst sent_headerstclose_connectiont chunked_write(R8RcRCRd((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyR;s          cCsO|j|j_d|j_y|jWntk rJ|jddSXdS(s;Parse the next HTTP request start-line and message-headers.is413 Request Entity Too LargeN(tmax_request_header_sizeRMRNROt_parse_requestRKtsimple_response(R8((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt parse_request.s   cCs|jj}t|_|s+t|_dS|dkr\|jj}|s\t|_dSn|j}y%|jjdd\}}}Wn"t k r|j dddSX||dException raised when a client speaks HTTP to an HTTPS socket.(RHRIRJ(((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRst FatalSSLAlertcBseZdZRS(sCException raised when the SSL implementation signals a fatal alert.(RHRIRJ(((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRst CP_fileobjectcBsJeZdZdZdZdZdZddZddZRS(s-Faux file object attached to a socket object.cCs`xY|r[y|j|}||}Wqtjk rW}|jdtkrXqXqXqWdS(s!Sendall for non-blocking sockets.iN(tsendRRRtsocket_errors_nonblocking(R8RSt bytes_sentte((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRs cCs|jj|S(N(t_sockR(R8RS((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRscCs8|jr4dj|j}g|_|j|ndS(NR?(t_wbufRXR(R8tbuffer((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pytflushs  cCsjxctrey|jj|SWqtjk ra}|jdtkrb|jdtkrbqbqXqWdS(Ni(RVRtrecvRRRRtsocket_error_eintr(R8RRR((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRs ic Cst|j|j}|j}|jdd|dkrtj|_x0tr{|j|}|skPn|j|qLW|j S|j }||kr|jd|j |}tj|_|jj|j |Stj|_xtr||}|j|}|sPnt |}||krA| rA|S||kra|j|~Pn||kst d||f|j|||7}~qW|j SdS(Niisrecv(%d) returned %d bytes(tmaxt _rbufsizetdefault_bufsizet_rbufRRRVRRtgetvaluettellRQRBR( R8RRtrbufsizeRRStbuf_lentrvtlefttn((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRQsH            "  c Csp|j}|jdd|jdkr|jd|j|}|jdsht||krtj|_|jj|j|S~n|dkr|j dkr/|jd|jg}tj|_d}|j }x3|dkr!|d}|sPn|j |qWdj |S|jddtj|_xtr|j |j }|ssPn|jd}|dkr|d7}|j|| |jj||~Pn|j|qQW|jS|jdd|j}||krL|jd|j|} tj|_|jj|j| Stj|_xtra|j |j }|sPn||} |jdd| }|dkr|d7}|jj|||r|j|| Pq|| Snt|} | |kr| r|S| | krG|j|| |jj|| Pn|j||| 7}q^W|jSdS(Niis iR?(RRRRUtendswithRBRRRQRRTRRWRXRVtfindR( R8RRRtblinetbuffersRSRtnlRRRR((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRU1s  !                    ( RHRIRJRRRRRQRU(((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRs   eZdZdZdZdZdZdZdZRS(s,SSL file object attached to a socket object.ig{Gz?c Ostj}xtry|||SWn8tjk rLtj|jntjk rotj|jntjk r}|r|jd krdS|jd}|r|t krdSt j |ntj k rW}|r|jd krdSd}y|jddd}Wntk r,nX|dkrEtnt|jn nXtj||jkrt jdqqWdS( 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(ttimeRVRt WantReadErrortsleept ssl_retrytWantWriteErrort SysCallErrorRRRRtErrorRTt IndexErrorRRt ssl_timeoutttimeout( R8t is_readertcallRtkwargststartRterrnumtthirdarg((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt _safe_calls<      cOspg}tt|j}xQtrk|jt|||}|j||jj}|sdj|SqWdS(NR?( tsuperRRRVRRWRtpendingRX(R8RRRtrRSR9((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRLs  cOs"|jttt|j||S(N(RReRRR(R8RR((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRVscOs"|jttt|j||S(N(RReRRR(R8RR((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRYs( RHRIRJRRRRRR(((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRs . tHTTPConnectioncBsneZdZdZeZidd6dd6ed6ed6ed 6ej d 6Z d Z d Z eZ d ZRS(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||_||_|jj|_|jj|trt|tjr|j}t |d|j |_ ||j _ t |dd|_ ||j _ n-t|d|j |_ t|dd|_ t|j d|jdLike print_exc() but return a string. Backport for Python 2.3.R?N(RRRXt tracebacktformat_exceptionRT(tlimittetypeRttb((sB/usr/lib/python2.7/vendor-packages/cherrypy/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|_||_tjj|dS(N(ReRfRt threadingtThreadR;(R8R((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyR;s  cCsyjt|_xZtrh|jjj}|tkr7dS||_z|jWd|jd|_XqWWn%t t fk r}||j_ nXdS(N( RVRfRtrequestsRt_SHUTDOWNREQUESTtconnRR_RTRRt interrupt(R8R%texc((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pytruns     N(RHRIRJRTR%R;R((((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyR s  t ThreadPoolcBskeZdZdddZdZdZeedejZdZdZ 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|_tj|_|jj|_dS(N(RRRt_threadstQueuet_queueR(R8RRR((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyR;s     cCsx0t|jD]}|jjt|jqWx2|jD]'}|jd|j|jq=Wx.|jD]#}x|j st j dq{WqrWdS(sStart the pool of threads.sCP WSGIServer g?N( txrangeRR*RWR RtsetNametgetNameRRfRR(R8titworker((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRs cCs/tg|jD]}|jdkr |^q S(s3Number of worker threads which are idle. Read-only.N(RBR*R%RT(R8tt((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt _get_idle#stdoccCs$|jj||tkr dSdS(N(R,tputR$(R8tobj((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyR5(s cCsxt|D]q}|jdkr>t|j|jkr>Pnt|j}|jd|j|jj||j q WdS(s.Spawn new worker threads (not above self.max).isCP WSGIServer N( R-RRBR*R RR.R/RWR(R8tamountR0R1((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pytgrow-s'cCsx:|jD]/}|js |jj||d8}q q W|dkrx@tt|t|j|jD]}|jjtqoWndS(s-Kill off worker threads (not below self.min).iiN( R*tisAlivetremoveR-RRBR,R5R$(R8R7R2R0((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pytshrink7s  ,icCs6x!|jD]}|jjtq Wtj}x|jr1|jj}||k r3|jr3y|dks~|dkr|j n|j ||jr|j }|r|j j rt rt|jt jr|jjq|jjtjn|j nWq.ttfk r*}q.Xq3q3WdS(Ni(R*R,R5R$R!t currentThreadRR9RTRXR%RMtclosedRRRRtshutdowntSHUT_RDRR(R8RR1tcurrenttctexc1((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pytstopHs(      ( RHRIRJR;RR3tpropertytidleR5R8R;RC(((sB/usr/lib/python2.7/vendor-packages/cherrypy/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%tj||_tj|_dS(N(RRt _ssl_connR!tRLockt_lock(R8R((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyR;qst get_contextRRRRRQt 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 setsockoptsmakefileRXRYRZR[R\R]R^R_R`Rassendalls settimeout(RHRIRJR;tf(((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRFks  (twindlltWinErrorcCsdS(s=Dummy function, since neither fcntl nor ctypes are available.N((R((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pytprevent_socket_inheritancescCs.tjj|jdds*tndS(s6Mark the given socket fd as non-inheritable (Windows).iiN(Rdtkernel32tSetHandleInformationRQRe(R((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRfscCsB|j}tj|tj}tj|tj|tjBdS(s4Mark the given socket fd as non-inheritable (POSIX).N(RQtfcntltF_GETFDtF_SETFDt FD_CLOEXEC(Rtfdt old_flags((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRfs tCherryPyWSGIServercBs eZdZdZdZdZeZdZ e Z e Z iZdZdZdddddddZdZd 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.2i iic Cst|d|pdd||_t|r9||_ntjdtt||_||_|svt j }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#tcallableRdtwarningstwarntDeprecationWarningR0t bind_addrRt gethostnamet server_nametrequest_queue_sizeRtshutdown_timeout( R8RtRdt numthreadsRvRRwRRx((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyR;s!       cCs |jjS(N(R#R(R8((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt_get_numthreadsscCs||j_dS(N(R#R(R8R((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt_set_numthreadsscCsd|j|jj|jfS(Ns %s.%s(%r)(RIt __class__RHRt(R8((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt__str__scCs|jS(N(t _bind_addr(R8((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyt_get_bind_addrscCs;t|tr.|ddkr.tdn||_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(RttupleRTRR~(R8R((sB/usr/lib/python2.7/vendor-packages/cherrypy/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|jtr~ytj|jWnnXytj|jdWnnXtj tj dd|jfg}nr|j\}}y+tj ||tj tj dtj }Wn5tjk rtjtj dd|jfg}nXd|_d}xy|D]q}|\}}}} } y|j|||Wn;tjk ru}|jrf|jjnd|_qnXPqW|jstj|n|jjd|jj|j|jjt|_x[|jr)|j|jrx |jtkr tjdqW|jr&|jq&qqWdS(sRun the server forever.iiR?sNo socket could be createdig?N(RTt _interruptRRtt basestringtostunlinktchmodRtAF_UNIXt SOCK_STREAMt getaddrinfot AF_UNSPECt AI_PASSIVEtgaierrortAF_INETRLRR_RbRMRwR#RRVRfttickR&RR( R8tinfothosttportRRYtaftsocktypetprotot canonnametsa((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRsT $%           icCsvtj||||_t|j|jjtjtjd|jri|jjtjtjdn|jr_|j r_t dkrt dnt j t j}|j|j |j|jt||j|_|jt|jt r_|jddkr_|tjkr_y |jjtjtjdWq\ttjfk rXq\Xq_n|jj|jdS(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_keyRRTt ImportErrortContextt SSLv23_METHODtuse_privatekey_filetuse_certificate_fileRFtpopulate_ssl_environRRtRtAF_INET6t IPPROTO_IPV6t IPV6_V6ONLYR3RRL(R8tfamilyttypeRtctx((sB/usr/lib/python2.7/vendor-packages/cherrypy/wsgiserver/__init__.pyRLYs(    "  cCsy$|jj\}}t||js/dSt|drQ|j|jn|jj}|j ddkrd|j |dMs                      #?Ez 'b