<s> import re <EOL> import string <EOL> import StringIO <EOL> import sys <EOL> import os <EOL> import sys <EOL> import time <EOL> import select_trigger <EOL> from supervisor . medusa import counter <EOL> from supervisor . medusa import producers <EOL> from supervisor . medusa . default_handler import unquote , get_header <EOL> import threading <EOL> class request_queue : <EOL> def __init__ ( self ) : <EOL> self . mon = threading . RLock ( ) <EOL> self . cv = threading . Condition ( self . mon ) <EOL> self . queue = [ ] <EOL> def put ( self , item ) : <EOL> self . cv . acquire ( ) <EOL> self . queue . append ( item ) <EOL> self . cv . notify ( ) <EOL> self . cv . release ( ) <EOL> def get ( self ) : <EOL> self . cv . acquire ( ) <EOL> while not self . queue : <EOL> self . cv . wait ( ) <EOL> result = self . queue . pop ( <NUM_LIT:0> ) <EOL> self . cv . release ( ) <EOL> return result <EOL> header2env = { <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:Content-Type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT>' , <EOL> } <EOL> for ( key , value ) in header2env . items ( ) : <EOL> del header2env [ key ] <EOL> key = string . lower ( key ) <EOL> header2env [ key ] = value <EOL> class thread_output_file ( select_trigger . trigger_file ) : <EOL> def close ( self ) : <EOL> self . trigger_close ( ) <EOL> class script_handler : <EOL> def __init__ ( self , queue , document_root = "<STR_LIT>" ) : <EOL> self . modules = { } <EOL> self . document_root = document_root <EOL> self . queue = queue <EOL> def add_module ( self , module , * names ) : <EOL> if not names : <EOL> names = [ "<STR_LIT>" % module . __name__ ] <EOL> for name in names : <EOL> self . modules [ '<STR_LIT:/>' + name ] = module <EOL> def match ( self , request ) : <EOL> uri = request . uri <EOL> i = string . find ( uri , "<STR_LIT:/>" , <NUM_LIT:1> ) <EOL> if i != - <NUM_LIT:1> : <EOL> uri = uri [ : i ] <EOL> i = string . find ( uri , "<STR_LIT:?>" , <NUM_LIT:1> ) <EOL> if i != - <NUM_LIT:1> : <EOL> uri = uri [ : i ] <EOL> if self . modules . has_key ( uri ) : <EOL> request . module = self . modules [ uri ] <EOL> return <NUM_LIT:1> <EOL> else : <EOL> return <NUM_LIT:0> <EOL> def handle_request ( self , request ) : <EOL> [ path , params , query , fragment ] = request . split_uri ( ) <EOL> while path and path [ <NUM_LIT:0> ] == '<STR_LIT:/>' : <EOL> path = path [ <NUM_LIT:1> : ] <EOL> if '<STR_LIT:%>' in path : <EOL> path = unquote ( path ) <EOL> env = { } <EOL> env [ '<STR_LIT>' ] = "<STR_LIT:/>" + path <EOL> env [ '<STR_LIT>' ] = string . upper ( request . command ) <EOL> env [ '<STR_LIT>' ] = str ( request . channel . server . port ) <EOL> env [ '<STR_LIT>' ] = request . channel . server . server_name <EOL> env [ '<STR_LIT>' ] = request [ '<STR_LIT>' ] <EOL> env [ '<STR_LIT>' ] = self . document_root <EOL> parts = string . split ( path , "<STR_LIT:/>" ) <EOL> env [ '<STR_LIT>' ] = "<STR_LIT:/>" + parts [ <NUM_LIT:0> ] <EOL> if query and query [ <NUM_LIT:0> ] == "<STR_LIT:?>" : <EOL> query = query [ <NUM_LIT:1> : ] <EOL> env [ '<STR_LIT>' ] = query <EOL> try : <EOL> path_info = "<STR_LIT:/>" + string . join ( parts [ <NUM_LIT:1> : ] , "<STR_LIT:/>" ) <EOL> except : <EOL> path_info = '<STR_LIT>' <EOL> env [ '<STR_LIT>' ] = path_info <EOL> env [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> env [ '<STR_LIT>' ] = request . channel . addr [ <NUM_LIT:0> ] <EOL> env [ '<STR_LIT>' ] = request . channel . addr [ <NUM_LIT:0> ] <EOL> for header in request . header : <EOL> [ key , value ] = string . split ( header , "<STR_LIT>" , <NUM_LIT:1> ) <EOL> key = string . lower ( key ) <EOL> if header2env . has_key ( key ) : <EOL> if header2env [ key ] : <EOL> env [ header2env [ key ] ] = value <EOL> else : <EOL> key = '<STR_LIT>' + string . upper ( <EOL> string . join ( <EOL> string . split ( key , "<STR_LIT:->" ) , <EOL> "<STR_LIT:_>" <EOL> ) <EOL> ) <EOL> env [ key ] = value <EOL> for key in env . keys ( ) : <EOL> if env [ key ] == "<STR_LIT>" or env [ key ] == None : <EOL> del env [ key ] <EOL> try : <EOL> httphost = env [ '<STR_LIT>' ] <EOL> parts = string . split ( httphost , "<STR_LIT::>" ) <EOL> env [ '<STR_LIT>' ] = parts [ <NUM_LIT:0> ] <EOL> except KeyError : <EOL> pass <EOL> if request . command in ( '<STR_LIT>' , '<STR_LIT>' ) : <EOL> request . collector = collector ( self , request , env ) <EOL> request . channel . set_terminator ( None ) <EOL> else : <EOL> sin = StringIO . StringIO ( '<STR_LIT>' ) <EOL> self . continue_request ( sin , request , env ) <EOL> def continue_request ( self , stdin , request , env ) : <EOL> stdout = header_scanning_file ( <EOL> request , <EOL> thread_output_file ( request . channel ) <EOL> ) <EOL> self . queue . put ( <EOL> ( request . module . main , ( env , stdin , stdout ) ) <EOL> ) <EOL> HEADER_LINE = re . compile ( '<STR_LIT>' ) <EOL> class header_scanning_file : <EOL> def __init__ ( self , request , file ) : <EOL> self . buffer = '<STR_LIT>' <EOL> self . request = request <EOL> self . file = file <EOL> self . got_header = <NUM_LIT:0> <EOL> self . bytes_out = counter . counter ( ) <EOL> def write ( self , data ) : <EOL> if self . got_header : <EOL> self . _write ( data ) <EOL> else : <EOL> self . buffer = self . buffer + data <EOL> lines = string . split ( self . buffer , '<STR_LIT:\n>' ) <EOL> lines = lines [ : - <NUM_LIT:1> ] <EOL> for i in range ( len ( lines ) ) : <EOL> li = lines [ i ] <EOL> if ( not li ) or ( HEADER_LINE . match ( li ) is None ) : <EOL> self . got_header = <NUM_LIT:1> <EOL> h = self . build_header ( lines [ : i ] ) <EOL> self . _write ( h ) <EOL> d = string . join ( lines [ i : ] , '<STR_LIT:\n>' ) <EOL> self . _write ( d ) <EOL> self . buffer = '<STR_LIT>' <EOL> break <EOL> def build_header ( self , lines ) : <EOL> status = '<STR_LIT>' <EOL> saw_content_type = <NUM_LIT:0> <EOL> hl = HEADER_LINE <EOL> for line in lines : <EOL> mo = hl . match ( line ) <EOL> if mo is not None : <EOL> h = string . lower ( mo . group ( <NUM_LIT:1> ) ) <EOL> if h == '<STR_LIT:status>' : <EOL> status = mo . group ( <NUM_LIT:2> ) <EOL> elif h == '<STR_LIT>' : <EOL> saw_content_type = <NUM_LIT:1> <EOL> lines . insert ( <NUM_LIT:0> , '<STR_LIT>' % status ) <EOL> lines . append ( '<STR_LIT>' + self . request [ '<STR_LIT>' ] ) <EOL> lines . append ( '<STR_LIT>' + self . request [ '<STR_LIT>' ] ) <EOL> if not saw_content_type : <EOL> lines . append ( '<STR_LIT>' ) <EOL> lines . append ( '<STR_LIT>' ) <EOL> return string . join ( lines , '<STR_LIT:\r\n>' ) + '<STR_LIT>' <EOL> def _write ( self , data ) : <EOL> self . bytes_out . increment ( len ( data ) ) <EOL> self . file . write ( data ) <EOL> def writelines ( self , list ) : <EOL> self . write ( string . join ( list , '<STR_LIT>' ) ) <EOL> def flush ( self ) : <EOL> pass <EOL> def close ( self ) : <EOL> if not self . got_header : <EOL> self . _write ( self . build_header ( [ '<STR_LIT>' , '<STR_LIT>' ] ) ) <EOL> self . _write ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' % ( repr ( self . buffer ) ) <EOL> ) <EOL> self . request . log ( int ( self . bytes_out . as_long ( ) ) ) <EOL> self . file . close ( ) <EOL> self . request . channel . current_request = None <EOL> class collector : <EOL> "<STR_LIT>" <EOL> def __init__ ( self , handler , request , env ) : <EOL> self . handler = handler <EOL> self . env = env <EOL> self . request = request <EOL> self . data = StringIO . StringIO ( ) <EOL> self . cl = request . get_header ( '<STR_LIT>' ) <EOL> if not self . cl : <EOL> request . error ( <NUM_LIT> ) <EOL> return <EOL> else : <EOL> self . cl = string . atoi ( self . cl ) <EOL> def collect_incoming_data ( self , data ) : <EOL> self . data . write ( data ) <EOL> if self . data . tell ( ) >= self . cl : <EOL> self . data . seek ( <NUM_LIT:0> ) <EOL> h = self . handler <EOL> r = self . request <EOL> self . request . channel . set_terminator ( '<STR_LIT>' ) <EOL> del self . handler <EOL> del self . request <EOL> h . continue_request ( self . data , r , self . env ) <EOL> class request_loop_thread ( threading . Thread ) : <EOL> def __init__ ( self , queue ) : <EOL> threading . Thread . __init__ ( self ) <EOL> self . setDaemon ( <NUM_LIT:1> ) <EOL> self . queue = queue <EOL> def run ( self ) : <EOL> while <NUM_LIT:1> : <EOL> function , ( env , stdin , stdout ) = self . queue . get ( ) <EOL> function ( env , stdin , stdout ) <EOL> stdout . close ( ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> import sys <EOL> if len ( sys . argv ) < <NUM_LIT:2> : <EOL> print '<STR_LIT>' % sys . argv [ <NUM_LIT:0> ] <EOL> else : <EOL> nthreads = string . atoi ( sys . argv [ <NUM_LIT:1> ] ) <EOL> import asyncore_25 as asyncore <EOL> from supervisor . medusa import http_server <EOL> hs = http_server . http_server ( '<STR_LIT>' , <NUM_LIT> ) <EOL> q = request_queue ( ) <EOL> sh = script_handler ( q ) <EOL> hs . install_handler ( sh ) <EOL> import test_module <EOL> import pi_module <EOL> sh . add_module ( test_module , '<STR_LIT:test>' ) <EOL> sh . add_module ( pi_module , '<STR_LIT>' ) <EOL> for i in range ( nthreads ) : <EOL> rt = request_loop_thread ( q ) <EOL> rt . start ( ) <EOL> asyncore . loop ( ) </s>
