<s> """<STR_LIT>""" <EOL> __author__ = '<STR_LIT>' <EOL> __version__ = '<STR_LIT>' <EOL> import sys <EOL> import os <EOL> import signal <EOL> import struct <EOL> import cStringIO as StringIO <EOL> import select <EOL> import socket <EOL> import errno <EOL> import traceback <EOL> try : <EOL> import thread <EOL> import threading <EOL> thread_available = True <EOL> except ImportError : <EOL> import dummy_thread as thread <EOL> import dummy_threading as threading <EOL> thread_available = False <EOL> if not hasattr ( socket , '<STR_LIT>' ) : <EOL> socket . SHUT_WR = <NUM_LIT:1> <EOL> __all__ = [ '<STR_LIT>' ] <EOL> FCGI_LISTENSOCK_FILENO = <NUM_LIT:0> <EOL> FCGI_HEADER_LEN = <NUM_LIT:8> <EOL> FCGI_VERSION_1 = <NUM_LIT:1> <EOL> FCGI_BEGIN_REQUEST = <NUM_LIT:1> <EOL> FCGI_ABORT_REQUEST = <NUM_LIT:2> <EOL> FCGI_END_REQUEST = <NUM_LIT:3> <EOL> FCGI_PARAMS = <NUM_LIT:4> <EOL> FCGI_STDIN = <NUM_LIT:5> <EOL> FCGI_STDOUT = <NUM_LIT:6> <EOL> FCGI_STDERR = <NUM_LIT:7> <EOL> FCGI_DATA = <NUM_LIT:8> <EOL> FCGI_GET_VALUES = <NUM_LIT:9> <EOL> FCGI_GET_VALUES_RESULT = <NUM_LIT:10> <EOL> FCGI_UNKNOWN_TYPE = <NUM_LIT:11> <EOL> FCGI_MAXTYPE = FCGI_UNKNOWN_TYPE <EOL> FCGI_NULL_REQUEST_ID = <NUM_LIT:0> <EOL> FCGI_KEEP_CONN = <NUM_LIT:1> <EOL> FCGI_RESPONDER = <NUM_LIT:1> <EOL> FCGI_AUTHORIZER = <NUM_LIT:2> <EOL> FCGI_FILTER = <NUM_LIT:3> <EOL> FCGI_REQUEST_COMPLETE = <NUM_LIT:0> <EOL> FCGI_CANT_MPX_CONN = <NUM_LIT:1> <EOL> FCGI_OVERLOADED = <NUM_LIT:2> <EOL> FCGI_UNKNOWN_ROLE = <NUM_LIT:3> <EOL> FCGI_MAX_CONNS = '<STR_LIT>' <EOL> FCGI_MAX_REQS = '<STR_LIT>' <EOL> FCGI_MPXS_CONNS = '<STR_LIT>' <EOL> FCGI_Header = '<STR_LIT>' <EOL> FCGI_BeginRequestBody = '<STR_LIT>' <EOL> FCGI_EndRequestBody = '<STR_LIT>' <EOL> FCGI_UnknownTypeBody = '<STR_LIT>' <EOL> FCGI_EndRequestBody_LEN = struct . calcsize ( FCGI_EndRequestBody ) <EOL> FCGI_UnknownTypeBody_LEN = struct . calcsize ( FCGI_UnknownTypeBody ) <EOL> if __debug__ : <EOL> import time <EOL> DEBUG = <NUM_LIT:0> <EOL> DEBUGLOG = '<STR_LIT>' <EOL> def _debug ( level , msg ) : <EOL> if DEBUG < level : <EOL> return <EOL> try : <EOL> f = open ( DEBUGLOG , '<STR_LIT:a>' ) <EOL> f . write ( '<STR_LIT>' % ( time . ctime ( ) [ <NUM_LIT:4> : - <NUM_LIT:4> ] , msg ) ) <EOL> f . close ( ) <EOL> except : <EOL> pass <EOL> class InputStream ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , conn ) : <EOL> self . _conn = conn <EOL> self . _shrinkThreshold = conn . server . inputStreamShrinkThreshold <EOL> self . _buf = '<STR_LIT>' <EOL> self . _bufList = [ ] <EOL> self . _pos = <NUM_LIT:0> <EOL> self . _avail = <NUM_LIT:0> <EOL> self . _eof = False <EOL> def _shrinkBuffer ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _pos >= self . _shrinkThreshold : <EOL> self . _buf = self . _buf [ self . _pos : ] <EOL> self . _avail -= self . _pos <EOL> self . _pos = <NUM_LIT:0> <EOL> assert self . _avail >= <NUM_LIT:0> <EOL> def _waitForData ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _conn . process_input ( ) <EOL> def read ( self , n = - <NUM_LIT:1> ) : <EOL> if self . _pos == self . _avail and self . _eof : <EOL> return '<STR_LIT>' <EOL> while True : <EOL> if n < <NUM_LIT:0> or ( self . _avail - self . _pos ) < n : <EOL> if self . _eof : <EOL> newPos = self . _avail <EOL> break <EOL> else : <EOL> self . _waitForData ( ) <EOL> continue <EOL> else : <EOL> newPos = self . _pos + n <EOL> break <EOL> if self . _bufList : <EOL> self . _buf += '<STR_LIT>' . join ( self . _bufList ) <EOL> self . _bufList = [ ] <EOL> r = self . _buf [ self . _pos : newPos ] <EOL> self . _pos = newPos <EOL> self . _shrinkBuffer ( ) <EOL> return r <EOL> def readline ( self , length = None ) : <EOL> if self . _pos == self . _avail and self . _eof : <EOL> return '<STR_LIT>' <EOL> while True : <EOL> if self . _bufList : <EOL> self . _buf += '<STR_LIT>' . join ( self . _bufList ) <EOL> self . _bufList = [ ] <EOL> i = self . _buf . find ( '<STR_LIT:\n>' , self . _pos ) <EOL> if i < <NUM_LIT:0> : <EOL> if self . _eof : <EOL> newPos = self . _avail <EOL> break <EOL> else : <EOL> self . _waitForData ( ) <EOL> continue <EOL> else : <EOL> newPos = i + <NUM_LIT:1> <EOL> break <EOL> if length is not None : <EOL> if self . _pos + length < newPos : <EOL> newPos = self . _pos + length <EOL> r = self . _buf [ self . _pos : newPos ] <EOL> self . _pos = newPos <EOL> self . _shrinkBuffer ( ) <EOL> return r <EOL> def readlines ( self , sizehint = <NUM_LIT:0> ) : <EOL> total = <NUM_LIT:0> <EOL> lines = [ ] <EOL> line = self . readline ( ) <EOL> while line : <EOL> lines . append ( line ) <EOL> total += len ( line ) <EOL> if <NUM_LIT:0> < sizehint <= total : <EOL> break <EOL> line = self . readline ( ) <EOL> return lines <EOL> def __iter__ ( self ) : <EOL> return self <EOL> def next ( self ) : <EOL> r = self . readline ( ) <EOL> if not r : <EOL> raise StopIteration <EOL> return r <EOL> def add_data ( self , data ) : <EOL> if not data : <EOL> self . _eof = True <EOL> else : <EOL> self . _bufList . append ( data ) <EOL> self . _avail += len ( data ) <EOL> class MultiplexedInputStream ( InputStream ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , conn ) : <EOL> super ( MultiplexedInputStream , self ) . __init__ ( conn ) <EOL> lock = threading . RLock ( ) <EOL> self . _lock = threading . Condition ( lock ) <EOL> def _waitForData ( self ) : <EOL> self . _lock . wait ( ) <EOL> def read ( self , n = - <NUM_LIT:1> ) : <EOL> self . _lock . acquire ( ) <EOL> try : <EOL> return super ( MultiplexedInputStream , self ) . read ( n ) <EOL> finally : <EOL> self . _lock . release ( ) <EOL> def readline ( self , length = None ) : <EOL> self . _lock . acquire ( ) <EOL> try : <EOL> return super ( MultiplexedInputStream , self ) . readline ( length ) <EOL> finally : <EOL> self . _lock . release ( ) <EOL> def add_data ( self , data ) : <EOL> self . _lock . acquire ( ) <EOL> try : <EOL> super ( MultiplexedInputStream , self ) . add_data ( data ) <EOL> self . _lock . notify ( ) <EOL> finally : <EOL> self . _lock . release ( ) <EOL> class OutputStream ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , conn , req , type , buffered = False ) : <EOL> self . _conn = conn <EOL> self . _req = req <EOL> self . _type = type <EOL> self . _buffered = buffered <EOL> self . _bufList = [ ] <EOL> self . dataWritten = False <EOL> self . closed = False <EOL> def _write ( self , data ) : <EOL> length = len ( data ) <EOL> while length : <EOL> toWrite = min ( length , self . _req . server . maxwrite - FCGI_HEADER_LEN ) <EOL> rec = Record ( self . _type , self . _req . requestId ) <EOL> rec . contentLength = toWrite <EOL> rec . contentData = data [ : toWrite ] <EOL> self . _conn . writeRecord ( rec ) <EOL> data = data [ toWrite : ] <EOL> length -= toWrite <EOL> def write ( self , data ) : <EOL> assert not self . closed <EOL> if not data : <EOL> return <EOL> self . dataWritten = True <EOL> if self . _buffered : <EOL> self . _bufList . append ( data ) <EOL> else : <EOL> self . _write ( data ) <EOL> def writelines ( self , lines ) : <EOL> assert not self . closed <EOL> for line in lines : <EOL> self . write ( line ) <EOL> def flush ( self ) : <EOL> if self . _buffered : <EOL> data = '<STR_LIT>' . join ( self . _bufList ) <EOL> self . _bufList = [ ] <EOL> self . _write ( data ) <EOL> def close ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . closed and self . dataWritten : <EOL> self . flush ( ) <EOL> rec = Record ( self . _type , self . _req . requestId ) <EOL> self . _conn . writeRecord ( rec ) <EOL> self . closed = True <EOL> class TeeOutputStream ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , streamList ) : <EOL> self . _streamList = streamList <EOL> def write ( self , data ) : <EOL> for f in self . _streamList : <EOL> f . write ( data ) <EOL> def writelines ( self , lines ) : <EOL> for line in lines : <EOL> self . write ( line ) <EOL> def flush ( self ) : <EOL> for f in self . _streamList : <EOL> f . flush ( ) <EOL> class StdoutWrapper ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , stdout ) : <EOL> self . _file = stdout <EOL> self . dataWritten = False <EOL> def write ( self , data ) : <EOL> if data : <EOL> self . dataWritten = True <EOL> self . _file . write ( data ) <EOL> def writelines ( self , lines ) : <EOL> for line in lines : <EOL> self . write ( line ) <EOL> def __getattr__ ( self , name ) : <EOL> return getattr ( self . _file , name ) <EOL> def decode_pair ( s , pos = <NUM_LIT:0> ) : <EOL> """<STR_LIT>""" <EOL> nameLength = ord ( s [ pos ] ) <EOL> if nameLength & <NUM_LIT> : <EOL> nameLength = struct . unpack ( '<STR_LIT>' , s [ pos : pos + <NUM_LIT:4> ] ) [ <NUM_LIT:0> ] & <NUM_LIT> <EOL> pos += <NUM_LIT:4> <EOL> else : <EOL> pos += <NUM_LIT:1> <EOL> valueLength = ord ( s [ pos ] ) <EOL> if valueLength & <NUM_LIT> : <EOL> valueLength = struct . unpack ( '<STR_LIT>' , s [ pos : pos + <NUM_LIT:4> ] ) [ <NUM_LIT:0> ] & <NUM_LIT> <EOL> pos += <NUM_LIT:4> <EOL> else : <EOL> pos += <NUM_LIT:1> <EOL> name = s [ pos : pos + nameLength ] <EOL> pos += nameLength <EOL> value = s [ pos : pos + valueLength ] <EOL> pos += valueLength <EOL> return ( pos , ( name , value ) ) <EOL> def encode_pair ( name , value ) : <EOL> """<STR_LIT>""" <EOL> nameLength = len ( name ) <EOL> if nameLength < <NUM_LIT> : <EOL> s = chr ( nameLength ) <EOL> else : <EOL> s = struct . pack ( '<STR_LIT>' , nameLength | <NUM_LIT> L ) <EOL> valueLength = len ( value ) <EOL> if valueLength < <NUM_LIT> : <EOL> s += chr ( valueLength ) <EOL> else : <EOL> s += struct . pack ( '<STR_LIT>' , valueLength | <NUM_LIT> L ) <EOL> return s + name + value <EOL> class Record ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , type = FCGI_UNKNOWN_TYPE , requestId = FCGI_NULL_REQUEST_ID ) : <EOL> self . version = FCGI_VERSION_1 <EOL> self . type = type <EOL> self . requestId = requestId <EOL> self . contentLength = <NUM_LIT:0> <EOL> self . paddingLength = <NUM_LIT:0> <EOL> self . contentData = '<STR_LIT>' <EOL> @ staticmethod <EOL> def _recvall ( sock , length ) : <EOL> """<STR_LIT>""" <EOL> dataList = [ ] <EOL> recvLen = <NUM_LIT:0> <EOL> while length : <EOL> try : <EOL> data = sock . recv ( length ) <EOL> except socket . error as e : <EOL> if e [ <NUM_LIT:0> ] == errno . EAGAIN : <EOL> select . select ( [ sock ] , [ ] , [ ] ) <EOL> continue <EOL> else : <EOL> raise <EOL> if not data : <EOL> break <EOL> dataList . append ( data ) <EOL> dataLen = len ( data ) <EOL> recvLen += dataLen <EOL> length -= dataLen <EOL> return '<STR_LIT>' . join ( dataList ) , recvLen <EOL> def read ( self , sock ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> header , length = self . _recvall ( sock , FCGI_HEADER_LEN ) <EOL> except : <EOL> raise EOFError <EOL> if length < FCGI_HEADER_LEN : <EOL> raise EOFError <EOL> self . version , self . type , self . requestId , self . contentLength , self . paddingLength = struct . unpack ( FCGI_Header , header ) <EOL> if __debug__ : _debug ( <NUM_LIT:9> , '<STR_LIT>' <EOL> '<STR_LIT>' % <EOL> ( sock . fileno ( ) , self . type , self . requestId , <EOL> self . contentLength ) ) <EOL> if self . contentLength : <EOL> try : <EOL> self . contentData , length = self . _recvall ( sock , <EOL> self . contentLength ) <EOL> except : <EOL> raise EOFError <EOL> if length < self . contentLength : <EOL> raise EOFError <EOL> if self . paddingLength : <EOL> try : <EOL> self . _recvall ( sock , self . paddingLength ) <EOL> except : <EOL> raise EOFError <EOL> @ staticmethod <EOL> def _sendall ( sock , data ) : <EOL> """<STR_LIT>""" <EOL> length = len ( data ) <EOL> while length : <EOL> try : <EOL> sent = sock . send ( data ) <EOL> except socket . error as e : <EOL> if e [ <NUM_LIT:0> ] == errno . EAGAIN : <EOL> select . select ( [ ] , [ sock ] , [ ] ) <EOL> continue <EOL> else : <EOL> raise <EOL> data = data [ sent : ] <EOL> length -= sent <EOL> def write ( self , sock ) : <EOL> """<STR_LIT>""" <EOL> self . paddingLength = - self . contentLength & <NUM_LIT:7> <EOL> if __debug__ : _debug ( <NUM_LIT:9> , '<STR_LIT>' <EOL> '<STR_LIT>' % <EOL> ( sock . fileno ( ) , self . type , self . requestId , <EOL> self . contentLength ) ) <EOL> header = struct . pack ( FCGI_Header , self . version , self . type , <EOL> self . requestId , self . contentLength , <EOL> self . paddingLength ) <EOL> self . _sendall ( sock , header ) <EOL> if self . contentLength : <EOL> self . _sendall ( sock , self . contentData ) <EOL> if self . paddingLength : <EOL> self . _sendall ( sock , '<STR_LIT:\x00>' * self . paddingLength ) <EOL> class Request ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , conn , inputStreamClass ) : <EOL> self . _conn = conn <EOL> self . server = conn . server <EOL> self . params = { } <EOL> self . stdin = inputStreamClass ( conn ) <EOL> self . stdout = OutputStream ( conn , self , FCGI_STDOUT ) <EOL> self . stderr = OutputStream ( conn , self , FCGI_STDERR , buffered = True ) <EOL> self . data = inputStreamClass ( conn ) <EOL> def run ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> protocolStatus , appStatus = self . server . handler ( self ) <EOL> except : <EOL> traceback . print_exc ( file = self . stderr ) <EOL> self . stderr . flush ( ) <EOL> if not self . stdout . dataWritten : <EOL> self . server . error ( self ) <EOL> protocolStatus , appStatus = FCGI_REQUEST_COMPLETE , <NUM_LIT:0> <EOL> if __debug__ : _debug ( <NUM_LIT:1> , '<STR_LIT>' % <EOL> ( protocolStatus , appStatus ) ) <EOL> try : <EOL> self . _flush ( ) <EOL> self . _end ( appStatus , protocolStatus ) <EOL> except socket . error as e : <EOL> if e [ <NUM_LIT:0> ] != errno . EPIPE : <EOL> raise <EOL> def _end ( self , appStatus = <NUM_LIT:0> L , protocolStatus = FCGI_REQUEST_COMPLETE ) : <EOL> self . _conn . end_request ( self , appStatus , protocolStatus ) <EOL> def _flush ( self ) : <EOL> self . stdout . close ( ) <EOL> self . stderr . close ( ) <EOL> class CGIRequest ( Request ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , server ) : <EOL> self . requestId = <NUM_LIT:1> <EOL> self . role = FCGI_RESPONDER <EOL> self . flags = <NUM_LIT:0> <EOL> self . aborted = False <EOL> self . server = server <EOL> self . params = dict ( os . environ ) <EOL> self . stdin = sys . stdin <EOL> self . stdout = StdoutWrapper ( sys . stdout ) <EOL> self . stderr = sys . stderr <EOL> self . data = StringIO . StringIO ( ) <EOL> def _end ( self , appStatus = <NUM_LIT:0> L , protocolStatus = FCGI_REQUEST_COMPLETE ) : <EOL> sys . exit ( appStatus ) <EOL> def _flush ( self ) : <EOL> pass <EOL> class Connection ( object ) : <EOL> """<STR_LIT>""" <EOL> _multiplexed = False <EOL> _inputStreamClass = InputStream <EOL> def __init__ ( self , sock , addr , server ) : <EOL> self . _sock = sock <EOL> self . _addr = addr <EOL> self . server = server <EOL> self . _requests = { } <EOL> def _cleanupSocket ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> self . _sock . shutdown ( socket . SHUT_WR ) <EOL> except : <EOL> return <EOL> try : <EOL> while True : <EOL> r , w , e = select . select ( [ self . _sock ] , [ ] , [ ] ) <EOL> if not r or not self . _sock . recv ( <NUM_LIT> ) : <EOL> break <EOL> except : <EOL> pass <EOL> self . _sock . close ( ) <EOL> def run ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _keepGoing = True <EOL> while self . _keepGoing : <EOL> try : <EOL> self . process_input ( ) <EOL> except EOFError : <EOL> break <EOL> except ( select . error , socket . error ) as e : <EOL> if e [ <NUM_LIT:0> ] == errno . EBADF : <EOL> break <EOL> raise <EOL> self . _cleanupSocket ( ) <EOL> def process_input ( self ) : <EOL> """<STR_LIT>""" <EOL> while self . _keepGoing : <EOL> try : <EOL> r , w , e = select . select ( [ self . _sock ] , [ ] , [ ] , <NUM_LIT:1.0> ) <EOL> except ValueError : <EOL> raise EOFError <EOL> if r : break <EOL> if not self . _keepGoing : <EOL> return <EOL> rec = Record ( ) <EOL> rec . read ( self . _sock ) <EOL> if rec . type == FCGI_GET_VALUES : <EOL> self . _do_get_values ( rec ) <EOL> elif rec . type == FCGI_BEGIN_REQUEST : <EOL> self . _do_begin_request ( rec ) <EOL> elif rec . type == FCGI_ABORT_REQUEST : <EOL> self . _do_abort_request ( rec ) <EOL> elif rec . type == FCGI_PARAMS : <EOL> self . _do_params ( rec ) <EOL> elif rec . type == FCGI_STDIN : <EOL> self . _do_stdin ( rec ) <EOL> elif rec . type == FCGI_DATA : <EOL> self . _do_data ( rec ) <EOL> elif rec . requestId == FCGI_NULL_REQUEST_ID : <EOL> self . _do_unknown_type ( rec ) <EOL> else : <EOL> pass <EOL> def writeRecord ( self , rec ) : <EOL> """<STR_LIT>""" <EOL> rec . write ( self . _sock ) <EOL> def end_request ( self , req , appStatus = <NUM_LIT:0> L , <EOL> protocolStatus = FCGI_REQUEST_COMPLETE , remove = True ) : <EOL> """<STR_LIT>""" <EOL> rec = Record ( FCGI_END_REQUEST , req . requestId ) <EOL> rec . contentData = struct . pack ( FCGI_EndRequestBody , appStatus , <EOL> protocolStatus ) <EOL> rec . contentLength = FCGI_EndRequestBody_LEN <EOL> self . writeRecord ( rec ) <EOL> if remove : <EOL> del self . _requests [ req . requestId ] <EOL> if __debug__ : _debug ( <NUM_LIT:2> , '<STR_LIT>' % req . flags ) <EOL> if not ( req . flags & FCGI_KEEP_CONN ) and not self . _requests : <EOL> self . _cleanupSocket ( ) <EOL> self . _keepGoing = False <EOL> def _do_get_values ( self , inrec ) : <EOL> """<STR_LIT>""" <EOL> outrec = Record ( FCGI_GET_VALUES_RESULT ) <EOL> pos = <NUM_LIT:0> <EOL> while pos < inrec . contentLength : <EOL> pos , ( name , value ) = decode_pair ( inrec . contentData , pos ) <EOL> cap = self . server . capability . get ( name ) <EOL> if cap is not None : <EOL> outrec . contentData += encode_pair ( name , str ( cap ) ) <EOL> outrec . contentLength = len ( outrec . contentData ) <EOL> self . writeRecord ( outrec ) <EOL> def _do_begin_request ( self , inrec ) : <EOL> """<STR_LIT>""" <EOL> role , flags = struct . unpack ( FCGI_BeginRequestBody , inrec . contentData ) <EOL> req = self . server . request_class ( self , self . _inputStreamClass ) <EOL> req . requestId , req . role , req . flags = inrec . requestId , role , flags <EOL> req . aborted = False <EOL> if not self . _multiplexed and self . _requests : <EOL> self . end_request ( req , <NUM_LIT:0> L , FCGI_CANT_MPX_CONN , remove = False ) <EOL> else : <EOL> self . _requests [ inrec . requestId ] = req <EOL> def _do_abort_request ( self , inrec ) : <EOL> """<STR_LIT>""" <EOL> req = self . _requests . get ( inrec . requestId ) <EOL> if req is not None : <EOL> req . aborted = True <EOL> def _start_request ( self , req ) : <EOL> """<STR_LIT>""" <EOL> req . run ( ) <EOL> def _do_params ( self , inrec ) : <EOL> """<STR_LIT>""" <EOL> req = self . _requests . get ( inrec . requestId ) <EOL> if req is not None : <EOL> if inrec . contentLength : <EOL> pos = <NUM_LIT:0> <EOL> while pos < inrec . contentLength : <EOL> pos , ( name , value ) = decode_pair ( inrec . contentData , pos ) <EOL> req . params [ name ] = value <EOL> else : <EOL> self . _start_request ( req ) <EOL> def _do_stdin ( self , inrec ) : <EOL> """<STR_LIT>""" <EOL> req = self . _requests . get ( inrec . requestId ) <EOL> if req is not None : <EOL> req . stdin . add_data ( inrec . contentData ) <EOL> def _do_data ( self , inrec ) : <EOL> """<STR_LIT>""" <EOL> req = self . _requests . get ( inrec . requestId ) <EOL> if req is not None : <EOL> req . data . add_data ( inrec . contentData ) <EOL> def _do_unknown_type ( self , inrec ) : <EOL> """<STR_LIT>""" <EOL> outrec = Record ( FCGI_UNKNOWN_TYPE ) <EOL> outrec . contentData = struct . pack ( FCGI_UnknownTypeBody , inrec . type ) <EOL> outrec . contentLength = FCGI_UnknownTypeBody_LEN <EOL> self . writeRecord ( outrec ) <EOL> class MultiplexedConnection ( Connection ) : <EOL> """<STR_LIT>""" <EOL> _multiplexed = True <EOL> _inputStreamClass = MultiplexedInputStream <EOL> def __init__ ( self , sock , addr , server ) : <EOL> super ( MultiplexedConnection , self ) . __init__ ( sock , addr , server ) <EOL> lock = threading . RLock ( ) <EOL> self . _lock = threading . Condition ( lock ) <EOL> def _cleanupSocket ( self ) : <EOL> self . _lock . acquire ( ) <EOL> while self . _requests : <EOL> self . _lock . wait ( ) <EOL> self . _lock . release ( ) <EOL> super ( MultiplexedConnection , self ) . _cleanupSocket ( ) <EOL> def writeRecord ( self , rec ) : <EOL> self . _lock . acquire ( ) <EOL> try : <EOL> rec . write ( self . _sock ) <EOL> finally : <EOL> self . _lock . release ( ) <EOL> def end_request ( self , req , appStatus = <NUM_LIT:0> L , <EOL> protocolStatus = FCGI_REQUEST_COMPLETE , remove = True ) : <EOL> self . _lock . acquire ( ) <EOL> try : <EOL> super ( MultiplexedConnection , self ) . end_request ( req , appStatus , <EOL> protocolStatus , <EOL> remove ) <EOL> self . _lock . notify ( ) <EOL> finally : <EOL> self . _lock . release ( ) <EOL> def _do_begin_request ( self , inrec ) : <EOL> self . _lock . acquire ( ) <EOL> try : <EOL> super ( MultiplexedConnection , self ) . _do_begin_request ( inrec ) <EOL> finally : <EOL> self . _lock . release ( ) <EOL> def _do_abort_request ( self , inrec ) : <EOL> self . _lock . acquire ( ) <EOL> try : <EOL> super ( MultiplexedConnection , self ) . _do_abort_request ( inrec ) <EOL> finally : <EOL> self . _lock . release ( ) <EOL> def _start_request ( self , req ) : <EOL> thread . start_new_thread ( req . run , ( ) ) <EOL> def _do_params ( self , inrec ) : <EOL> self . _lock . acquire ( ) <EOL> try : <EOL> super ( MultiplexedConnection , self ) . _do_params ( inrec ) <EOL> finally : <EOL> self . _lock . release ( ) <EOL> def _do_stdin ( self , inrec ) : <EOL> self . _lock . acquire ( ) <EOL> try : <EOL> super ( MultiplexedConnection , self ) . _do_stdin ( inrec ) <EOL> finally : <EOL> self . _lock . release ( ) <EOL> def _do_data ( self , inrec ) : <EOL> self . _lock . acquire ( ) <EOL> try : <EOL> super ( MultiplexedConnection , self ) . _do_data ( inrec ) <EOL> finally : <EOL> self . _lock . release ( ) <EOL> class Server ( object ) : <EOL> """<STR_LIT>""" <EOL> request_class = Request <EOL> cgirequest_class = CGIRequest <EOL> inputStreamShrinkThreshold = <NUM_LIT> - <NUM_LIT> <EOL> def __init__ ( self , handler = None , maxwrite = <NUM_LIT> , bindAddress = None , <EOL> umask = None , multiplexed = False ) : <EOL> """<STR_LIT>""" <EOL> if handler is not None : <EOL> self . handler = handler <EOL> self . maxwrite = maxwrite <EOL> if thread_available : <EOL> try : <EOL> import resource <EOL> maxConns = resource . getrlimit ( resource . RLIMIT_NOFILE ) [ <NUM_LIT:0> ] <EOL> except ( ImportError , AttributeError ) : <EOL> maxConns = <NUM_LIT:100> <EOL> maxReqs = maxConns <EOL> if multiplexed : <EOL> self . _connectionClass = MultiplexedConnection <EOL> maxReqs *= <NUM_LIT:5> <EOL> else : <EOL> self . _connectionClass = Connection <EOL> self . capability = { <EOL> FCGI_MAX_CONNS : maxConns , <EOL> FCGI_MAX_REQS : maxReqs , <EOL> FCGI_MPXS_CONNS : multiplexed and <NUM_LIT:1> or <NUM_LIT:0> <EOL> } <EOL> else : <EOL> self . _connectionClass = Connection <EOL> self . capability = { <EOL> FCGI_MAX_CONNS : <NUM_LIT:1> , <EOL> FCGI_MAX_REQS : <NUM_LIT:1> , <EOL> FCGI_MPXS_CONNS : <NUM_LIT:0> <EOL> } <EOL> self . _bindAddress = bindAddress <EOL> self . _umask = umask <EOL> def _setupSocket ( self ) : <EOL> if self . _bindAddress is None : <EOL> isFCGI = True <EOL> sock = socket . fromfd ( FCGI_LISTENSOCK_FILENO , socket . AF_INET , <EOL> socket . SOCK_STREAM ) <EOL> try : <EOL> sock . getpeername ( ) <EOL> except socket . error as e : <EOL> if e [ <NUM_LIT:0> ] == errno . ENOTSOCK : <EOL> isFCGI = False <EOL> elif e [ <NUM_LIT:0> ] != errno . ENOTCONN : <EOL> raise <EOL> if not isFCGI or os . environ . get ( '<STR_LIT>' , '<STR_LIT:N>' ) . upper ( ) . startswith ( '<STR_LIT:Y>' ) : <EOL> req = self . cgirequest_class ( self ) <EOL> req . run ( ) <EOL> sys . exit ( <NUM_LIT:0> ) <EOL> else : <EOL> oldUmask = None <EOL> if type ( self . _bindAddress ) is str : <EOL> sock = socket . socket ( socket . AF_UNIX , socket . SOCK_STREAM ) <EOL> try : <EOL> os . unlink ( self . _bindAddress ) <EOL> except OSError : <EOL> pass <EOL> if self . _umask is not None : <EOL> oldUmask = os . umask ( self . _umask ) <EOL> else : <EOL> assert type ( self . _bindAddress ) is tuple <EOL> assert len ( self . _bindAddress ) == <NUM_LIT:2> <EOL> sock = socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) <EOL> sock . setsockopt ( socket . SOL_SOCKET , socket . SO_REUSEADDR , <NUM_LIT:1> ) <EOL> sock . bind ( self . _bindAddress ) <EOL> sock . listen ( socket . SOMAXCONN ) <EOL> if oldUmask is not None : <EOL> os . umask ( oldUmask ) <EOL> return sock <EOL> def _cleanupSocket ( self , sock ) : <EOL> """<STR_LIT>""" <EOL> sock . close ( ) <EOL> def _installSignalHandlers ( self ) : <EOL> self . _oldSIGs = [ ( x , signal . getsignal ( x ) ) for x in <EOL> ( signal . SIGHUP , signal . SIGINT , signal . SIGTERM ) ] <EOL> signal . signal ( signal . SIGHUP , self . _hupHandler ) <EOL> signal . signal ( signal . SIGINT , self . _intHandler ) <EOL> signal . signal ( signal . SIGTERM , self . _intHandler ) <EOL> def _restoreSignalHandlers ( self ) : <EOL> for signum , handler in self . _oldSIGs : <EOL> signal . signal ( signum , handler ) <EOL> def _hupHandler ( self , signum , frame ) : <EOL> self . _hupReceived = True <EOL> self . _keepGoing = False <EOL> def _intHandler ( self , signum , frame ) : <EOL> self . _keepGoing = False <EOL> def run ( self , timeout = <NUM_LIT:1.0> ) : <EOL> """<STR_LIT>""" <EOL> web_server_addrs = os . environ . get ( '<STR_LIT>' ) <EOL> if web_server_addrs is not None : <EOL> web_server_addrs = map ( lambda x : x . strip ( ) , <EOL> web_server_addrs . split ( '<STR_LIT:U+002C>' ) ) <EOL> sock = self . _setupSocket ( ) <EOL> self . _keepGoing = True <EOL> self . _hupReceived = False <EOL> self . _installSignalHandlers ( ) <EOL> while self . _keepGoing : <EOL> try : <EOL> r , w , e = select . select ( [ sock ] , [ ] , [ ] , timeout ) <EOL> except select . error as e : <EOL> if e [ <NUM_LIT:0> ] == errno . EINTR : <EOL> continue <EOL> raise <EOL> if r : <EOL> try : <EOL> clientSock , addr = sock . accept ( ) <EOL> except socket . error as e : <EOL> if e [ <NUM_LIT:0> ] in ( errno . EINTR , errno . EAGAIN ) : <EOL> continue <EOL> raise <EOL> if web_server_addrs and ( len ( addr ) != <NUM_LIT:2> or addr [ <NUM_LIT:0> ] not in web_server_addrs ) : <EOL> clientSock . close ( ) <EOL> continue <EOL> conn = self . _connectionClass ( clientSock , addr , self ) <EOL> thread . start_new_thread ( conn . run , ( ) ) <EOL> self . _mainloopPeriodic ( ) <EOL> self . _restoreSignalHandlers ( ) <EOL> self . _cleanupSocket ( sock ) <EOL> return self . _hupReceived <EOL> def _mainloopPeriodic ( self ) : <EOL> """<STR_LIT>""" <EOL> pass <EOL> def _exit ( self , reload = False ) : <EOL> """<STR_LIT>""" <EOL> if self . _keepGoing : <EOL> self . _keepGoing = False <EOL> self . _hupReceived = reload <EOL> def handler ( self , req ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError , self . __class__ . __name__ + '<STR_LIT>' <EOL> def error ( self , req ) : <EOL> """<STR_LIT>""" <EOL> import cgitb <EOL> req . stdout . write ( '<STR_LIT>' + <EOL> cgitb . html ( sys . exc_info ( ) ) ) <EOL> class WSGIServer ( Server ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , application , environ = None , <EOL> multithreaded = True , ** kw ) : <EOL> """<STR_LIT>""" <EOL> if '<STR_LIT>' in kw : <EOL> del kw [ '<STR_LIT>' ] <EOL> super ( WSGIServer , self ) . __init__ ( ** kw ) <EOL> if environ is None : <EOL> environ = { } <EOL> self . application = application <EOL> self . environ = environ <EOL> self . multithreaded = multithreaded <EOL> self . _app_lock = thread . allocate_lock ( ) <EOL> def handler ( self , req ) : <EOL> """<STR_LIT>""" <EOL> if req . role != FCGI_RESPONDER : <EOL> return FCGI_UNKNOWN_ROLE , <NUM_LIT:0> <EOL> environ = req . params <EOL> environ . update ( self . environ ) <EOL> environ [ '<STR_LIT>' ] = ( <NUM_LIT:1> , <NUM_LIT:0> ) <EOL> environ [ '<STR_LIT>' ] = req . stdin <EOL> if self . _bindAddress is None : <EOL> stderr = req . stderr <EOL> else : <EOL> stderr = TeeOutputStream ( ( sys . stderr , req . stderr ) ) <EOL> environ [ '<STR_LIT>' ] = stderr <EOL> environ [ '<STR_LIT>' ] = not isinstance ( req , CGIRequest ) and thread_available and self . multithreaded <EOL> environ [ '<STR_LIT>' ] = True <EOL> environ [ '<STR_LIT>' ] = isinstance ( req , CGIRequest ) <EOL> if environ . get ( '<STR_LIT>' , '<STR_LIT>' ) . lower ( ) in ( '<STR_LIT:yes>' , '<STR_LIT>' , '<STR_LIT:1>' ) : <EOL> environ [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> elif environ . get ( '<STR_LIT>' , '<STR_LIT>' ) . lower ( ) == '<STR_LIT>' : <EOL> environ [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> else : <EOL> environ [ '<STR_LIT>' ] = '<STR_LIT:http>' <EOL> self . _sanitizeEnv ( environ ) <EOL> headers_set = [ ] <EOL> headers_sent = [ ] <EOL> result = None <EOL> def write ( data ) : <EOL> assert type ( data ) is str , '<STR_LIT>' <EOL> assert headers_set , '<STR_LIT>' <EOL> if not headers_sent : <EOL> status , responseHeaders = headers_sent [ : ] = headers_set <EOL> found = False <EOL> for header , value in responseHeaders : <EOL> if header . lower ( ) == '<STR_LIT>' : <EOL> found = True <EOL> break <EOL> if not found and result is not None : <EOL> try : <EOL> if len ( result ) == <NUM_LIT:1> : <EOL> responseHeaders . append ( ( '<STR_LIT>' , <EOL> str ( len ( data ) ) ) ) <EOL> except : <EOL> pass <EOL> s = '<STR_LIT>' % status <EOL> for header in responseHeaders : <EOL> s += '<STR_LIT>' % header <EOL> s += '<STR_LIT:\r\n>' <EOL> req . stdout . write ( s ) <EOL> req . stdout . write ( data ) <EOL> req . stdout . flush ( ) <EOL> def start_response ( status , response_headers , exc_info = None ) : <EOL> if exc_info : <EOL> try : <EOL> if headers_sent : <EOL> raise exc_info [ <NUM_LIT:0> ] , exc_info [ <NUM_LIT:1> ] , exc_info [ <NUM_LIT:2> ] <EOL> finally : <EOL> exc_info = None <EOL> else : <EOL> assert not headers_set , '<STR_LIT>' <EOL> assert type ( status ) is str , '<STR_LIT>' <EOL> assert len ( status ) >= <NUM_LIT:4> , '<STR_LIT>' <EOL> assert int ( status [ : <NUM_LIT:3> ] ) , '<STR_LIT>' <EOL> assert status [ <NUM_LIT:3> ] == '<STR_LIT:U+0020>' , '<STR_LIT>' <EOL> assert type ( response_headers ) is list , '<STR_LIT>' <EOL> if __debug__ : <EOL> for name , val in response_headers : <EOL> assert type ( name ) is str , '<STR_LIT>' <EOL> assert type ( val ) is str , '<STR_LIT>' <EOL> headers_set [ : ] = [ status , response_headers ] <EOL> return write <EOL> if not self . multithreaded : <EOL> self . _app_lock . acquire ( ) <EOL> try : <EOL> try : <EOL> result = self . application ( environ , start_response ) <EOL> try : <EOL> for data in result : <EOL> if data : <EOL> write ( data ) <EOL> if not headers_sent : <EOL> write ( '<STR_LIT>' ) <EOL> finally : <EOL> if hasattr ( result , '<STR_LIT>' ) : <EOL> result . close ( ) <EOL> except socket . error as e : <EOL> if e [ <NUM_LIT:0> ] != errno . EPIPE : <EOL> raise <EOL> finally : <EOL> if not self . multithreaded : <EOL> self . _app_lock . release ( ) <EOL> return FCGI_REQUEST_COMPLETE , <NUM_LIT:0> <EOL> def _sanitizeEnv ( self , environ ) : <EOL> """<STR_LIT>""" <EOL> if '<STR_LIT>' not in environ : <EOL> environ [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> if '<STR_LIT>' not in environ : <EOL> environ [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> for name , default in [ ( '<STR_LIT>' , '<STR_LIT:GET>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT:localhost>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , '<STR_LIT>' ) ] : <EOL> if name not in environ : <EOL> environ [ '<STR_LIT>' ] . write ( '<STR_LIT>' <EOL> '<STR_LIT>' % <EOL> ( self . __class__ . __name__ , name ) ) <EOL> environ [ name ] = default <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> def test_app ( environ , start_response ) : <EOL> """<STR_LIT>""" <EOL> import cgi <EOL> start_response ( '<STR_LIT>' , [ ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) ] ) <EOL> yield '<STR_LIT>' '<STR_LIT>' '<STR_LIT>' '<STR_LIT>' <EOL> names = environ . keys ( ) <EOL> names . sort ( ) <EOL> for name in names : <EOL> yield '<STR_LIT>' % ( <EOL> name , cgi . escape ( ` environ [ name ] ` ) ) <EOL> form = cgi . FieldStorage ( fp = environ [ '<STR_LIT>' ] , environ = environ , <EOL> keep_blank_values = <NUM_LIT:1> ) <EOL> if form . list : <EOL> yield '<STR_LIT>' <EOL> for field in form . list : <EOL> yield '<STR_LIT>' % ( <EOL> field . name , field . value ) <EOL> yield '<STR_LIT>' '<STR_LIT>' <EOL> WSGIServer ( test_app ) . run ( ) </s>
