<s> """<STR_LIT>""" <EOL> import os <EOL> import sys <EOL> import subprocess <EOL> from six . moves . urllib . parse import quote <EOL> try : <EOL> import select <EOL> except ImportError : <EOL> select = None <EOL> import six <EOL> from paste . util import converters <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> class CGIError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class CGIApplication ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , <EOL> global_conf , <EOL> script , <EOL> path = None , <EOL> include_os_environ = True , <EOL> query_string = None ) : <EOL> if global_conf : <EOL> raise NotImplemented ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> self . script_filename = script <EOL> if path is None : <EOL> path = os . environ . get ( '<STR_LIT>' , '<STR_LIT>' ) . split ( '<STR_LIT::>' ) <EOL> self . path = path <EOL> if '<STR_LIT:?>' in script : <EOL> assert query_string is None , ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % ( script , query_string ) ) <EOL> script , query_string = script . split ( '<STR_LIT:?>' , <NUM_LIT:1> ) <EOL> if os . path . abspath ( script ) != script : <EOL> for path_dir in self . path : <EOL> if os . path . exists ( os . path . join ( path_dir , script ) ) : <EOL> self . script = os . path . join ( path_dir , script ) <EOL> break <EOL> else : <EOL> raise CGIError ( <EOL> "<STR_LIT>" <EOL> % ( script , self . path ) ) <EOL> else : <EOL> self . script = script <EOL> self . include_os_environ = include_os_environ <EOL> self . query_string = query_string <EOL> def __call__ ( self , environ , start_response ) : <EOL> if '<STR_LIT>' not in environ : <EOL> environ [ '<STR_LIT>' ] = ( <EOL> quote ( environ . get ( '<STR_LIT>' , '<STR_LIT>' ) ) <EOL> + quote ( environ . get ( '<STR_LIT>' , '<STR_LIT>' ) ) ) <EOL> if self . include_os_environ : <EOL> cgi_environ = os . environ . copy ( ) <EOL> else : <EOL> cgi_environ = { } <EOL> for name in environ : <EOL> if ( name . upper ( ) == name <EOL> and isinstance ( environ [ name ] , str ) ) : <EOL> cgi_environ [ name ] = environ [ name ] <EOL> if self . query_string is not None : <EOL> old = cgi_environ . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> if old : <EOL> old += '<STR_LIT:&>' <EOL> cgi_environ [ '<STR_LIT>' ] = old + self . query_string <EOL> cgi_environ [ '<STR_LIT>' ] = self . script <EOL> proc = subprocess . Popen ( <EOL> [ self . script ] , <EOL> stdin = subprocess . PIPE , <EOL> stdout = subprocess . PIPE , <EOL> stderr = subprocess . PIPE , <EOL> env = cgi_environ , <EOL> cwd = os . path . dirname ( self . script ) , <EOL> ) <EOL> writer = CGIWriter ( environ , start_response ) <EOL> if select and sys . platform != '<STR_LIT:win32>' : <EOL> proc_communicate ( <EOL> proc , <EOL> stdin = StdinReader . from_environ ( environ ) , <EOL> stdout = writer , <EOL> stderr = environ [ '<STR_LIT>' ] ) <EOL> else : <EOL> stdout , stderr = proc . communicate ( StdinReader . from_environ ( environ ) . read ( ) ) <EOL> if stderr : <EOL> environ [ '<STR_LIT>' ] . write ( stderr ) <EOL> writer . write ( stdout ) <EOL> if not writer . headers_finished : <EOL> start_response ( writer . status , writer . headers ) <EOL> return [ ] <EOL> class CGIWriter ( object ) : <EOL> def __init__ ( self , environ , start_response ) : <EOL> self . environ = environ <EOL> self . start_response = start_response <EOL> self . status = '<STR_LIT>' <EOL> self . headers = [ ] <EOL> self . headers_finished = False <EOL> self . writer = None <EOL> self . buffer = b'<STR_LIT>' <EOL> def write ( self , data ) : <EOL> if self . headers_finished : <EOL> self . writer ( data ) <EOL> return <EOL> self . buffer += data <EOL> while b'<STR_LIT:\n>' in self . buffer : <EOL> if b'<STR_LIT:\r\n>' in self . buffer and self . buffer . find ( b'<STR_LIT:\r\n>' ) < self . buffer . find ( b'<STR_LIT:\n>' ) : <EOL> line1 , self . buffer = self . buffer . split ( b'<STR_LIT:\r\n>' , <NUM_LIT:1> ) <EOL> else : <EOL> line1 , self . buffer = self . buffer . split ( b'<STR_LIT:\n>' , <NUM_LIT:1> ) <EOL> if not line1 : <EOL> self . headers_finished = True <EOL> self . writer = self . start_response ( <EOL> self . status , self . headers ) <EOL> self . writer ( self . buffer ) <EOL> del self . buffer <EOL> del self . headers <EOL> del self . status <EOL> break <EOL> elif b'<STR_LIT::>' not in line1 : <EOL> raise CGIError ( <EOL> "<STR_LIT>" % line1 ) <EOL> else : <EOL> name , value = line1 . split ( b'<STR_LIT::>' , <NUM_LIT:1> ) <EOL> value = value . lstrip ( ) <EOL> name = name . strip ( ) <EOL> if six . PY3 : <EOL> name = name . decode ( '<STR_LIT:utf8>' ) <EOL> value = value . decode ( '<STR_LIT:utf8>' ) <EOL> if name . lower ( ) == '<STR_LIT:status>' : <EOL> if '<STR_LIT:U+0020>' not in value : <EOL> value = '<STR_LIT>' % value <EOL> self . status = value <EOL> else : <EOL> self . headers . append ( ( name , value ) ) <EOL> class StdinReader ( object ) : <EOL> def __init__ ( self , stdin , content_length ) : <EOL> self . stdin = stdin <EOL> self . content_length = content_length <EOL> @ classmethod <EOL> def from_environ ( cls , environ ) : <EOL> length = environ . get ( '<STR_LIT>' ) <EOL> if length : <EOL> length = int ( length ) <EOL> else : <EOL> length = <NUM_LIT:0> <EOL> return cls ( environ [ '<STR_LIT>' ] , length ) <EOL> def read ( self , size = None ) : <EOL> if not self . content_length : <EOL> return b'<STR_LIT>' <EOL> if size is None : <EOL> text = self . stdin . read ( self . content_length ) <EOL> else : <EOL> text = self . stdin . read ( min ( self . content_length , size ) ) <EOL> self . content_length -= len ( text ) <EOL> return text <EOL> def proc_communicate ( proc , stdin = None , stdout = None , stderr = None ) : <EOL> """<STR_LIT>""" <EOL> read_set = [ ] <EOL> write_set = [ ] <EOL> input_buffer = b'<STR_LIT>' <EOL> trans_nl = proc . universal_newlines and hasattr ( open , '<STR_LIT>' ) <EOL> if proc . stdin : <EOL> proc . stdin . flush ( ) <EOL> if input : <EOL> write_set . append ( proc . stdin ) <EOL> else : <EOL> proc . stdin . close ( ) <EOL> else : <EOL> assert stdin is None <EOL> if proc . stdout : <EOL> read_set . append ( proc . stdout ) <EOL> else : <EOL> assert stdout is None <EOL> if proc . stderr : <EOL> read_set . append ( proc . stderr ) <EOL> else : <EOL> assert stderr is None <EOL> while read_set or write_set : <EOL> rlist , wlist , xlist = select . select ( read_set , write_set , [ ] ) <EOL> if proc . stdin in wlist : <EOL> next , input_buffer = input_buffer , b'<STR_LIT>' <EOL> next_len = <NUM_LIT> - len ( next ) <EOL> if next_len : <EOL> next += stdin . read ( next_len ) <EOL> if not next : <EOL> proc . stdin . close ( ) <EOL> write_set . remove ( proc . stdin ) <EOL> else : <EOL> bytes_written = os . write ( proc . stdin . fileno ( ) , next ) <EOL> if bytes_written < len ( next ) : <EOL> input_buffer = next [ bytes_written : ] <EOL> if proc . stdout in rlist : <EOL> data = os . read ( proc . stdout . fileno ( ) , <NUM_LIT> ) <EOL> if data == b"<STR_LIT>" : <EOL> proc . stdout . close ( ) <EOL> read_set . remove ( proc . stdout ) <EOL> if trans_nl : <EOL> data = proc . _translate_newlines ( data ) <EOL> stdout . write ( data ) <EOL> if proc . stderr in rlist : <EOL> data = os . read ( proc . stderr . fileno ( ) , <NUM_LIT> ) <EOL> if data == b"<STR_LIT>" : <EOL> proc . stderr . close ( ) <EOL> read_set . remove ( proc . stderr ) <EOL> if trans_nl : <EOL> data = proc . _translate_newlines ( data ) <EOL> stderr . write ( data ) <EOL> try : <EOL> proc . wait ( ) <EOL> except OSError as e : <EOL> if e . errno != <NUM_LIT:10> : <EOL> raise <EOL> def make_cgi_application ( global_conf , script , path = None , include_os_environ = None , <EOL> query_string = None ) : <EOL> """<STR_LIT>""" <EOL> if path is None : <EOL> path = global_conf . get ( '<STR_LIT:path>' ) or global_conf . get ( '<STR_LIT>' ) <EOL> include_os_environ = converters . asbool ( include_os_environ ) <EOL> return CGIApplication ( <EOL> None , <EOL> script , path = path , include_os_environ = include_os_environ , <EOL> query_string = query_string ) </s>
