<s> from cStringIO import StringIO <EOL> from sys import stdout <EOL> import time <EOL> from clock import clock <EOL> from gzip import GzipFile <EOL> try : <EOL> True <EOL> except : <EOL> True = <NUM_LIT:1> <EOL> False = <NUM_LIT:0> <EOL> DEBUG = False <EOL> weekdays = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> months = [ None , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> class HTTPConnection : <EOL> def __init__ ( self , handler , connection ) : <EOL> self . handler = handler <EOL> self . connection = connection <EOL> self . buf = '<STR_LIT>' <EOL> self . closed = False <EOL> self . done = False <EOL> self . donereading = False <EOL> self . next_func = self . read_type <EOL> def get_ip ( self ) : <EOL> return self . connection . get_ip ( ) <EOL> def data_came_in ( self , data ) : <EOL> if self . donereading or self . next_func is None : <EOL> return True <EOL> self . buf += data <EOL> while True : <EOL> try : <EOL> i = self . buf . index ( '<STR_LIT:\n>' ) <EOL> except ValueError : <EOL> return True <EOL> val = self . buf [ : i ] <EOL> self . buf = self . buf [ i + <NUM_LIT:1> : ] <EOL> self . next_func = self . next_func ( val ) <EOL> if self . donereading : <EOL> return True <EOL> if self . next_func is None or self . closed : <EOL> return False <EOL> def read_type ( self , data ) : <EOL> self . header = data . strip ( ) <EOL> words = data . split ( ) <EOL> if len ( words ) == <NUM_LIT:3> : <EOL> self . command , self . path , garbage = words <EOL> self . pre1 = False <EOL> elif len ( words ) == <NUM_LIT:2> : <EOL> self . command , self . path = words <EOL> self . pre1 = True <EOL> if self . command != '<STR_LIT:GET>' : <EOL> return None <EOL> else : <EOL> return None <EOL> if self . command not in ( '<STR_LIT>' , '<STR_LIT:GET>' ) : <EOL> return None <EOL> self . headers = { } <EOL> return self . read_header <EOL> def read_header ( self , data ) : <EOL> data = data . strip ( ) <EOL> if data == '<STR_LIT>' : <EOL> self . donereading = True <EOL> if self . headers . get ( '<STR_LIT>' , '<STR_LIT>' ) . find ( '<STR_LIT>' ) > - <NUM_LIT:1> : <EOL> self . encoding = '<STR_LIT>' <EOL> else : <EOL> self . encoding = '<STR_LIT>' <EOL> r = self . handler . getfunc ( self , self . path , self . headers ) <EOL> if r is not None : <EOL> self . answer ( r ) <EOL> return None <EOL> try : <EOL> i = data . index ( '<STR_LIT::>' ) <EOL> except ValueError : <EOL> return None <EOL> self . headers [ data [ : i ] . strip ( ) . lower ( ) ] = data [ i + <NUM_LIT:1> : ] . strip ( ) <EOL> if DEBUG : <EOL> print data [ : i ] . strip ( ) + "<STR_LIT>" + data [ i + <NUM_LIT:1> : ] . strip ( ) <EOL> return self . read_header <EOL> def answer ( self , ( responsecode , responsestring , headers , data ) ) : <EOL> if self . closed : <EOL> return <EOL> if self . encoding == '<STR_LIT>' : <EOL> compressed = StringIO ( ) <EOL> gz = GzipFile ( fileobj = compressed , mode = '<STR_LIT:wb>' , compresslevel = <NUM_LIT:9> ) <EOL> gz . write ( data ) <EOL> gz . close ( ) <EOL> cdata = compressed . getvalue ( ) <EOL> if len ( cdata ) >= len ( data ) : <EOL> self . encoding = '<STR_LIT>' <EOL> else : <EOL> if DEBUG : <EOL> print "<STR_LIT>" % ( len ( cdata ) , len ( data ) ) <EOL> data = cdata <EOL> headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> if self . encoding == '<STR_LIT>' : <EOL> ident = '<STR_LIT:->' <EOL> else : <EOL> ident = self . encoding <EOL> self . handler . log ( self . connection . get_ip ( ) , ident , '<STR_LIT:->' , <EOL> self . header , responsecode , len ( data ) , <EOL> self . headers . get ( '<STR_LIT>' , '<STR_LIT:->' ) , <EOL> self . headers . get ( '<STR_LIT>' , '<STR_LIT:->' ) ) <EOL> self . done = True <EOL> r = StringIO ( ) <EOL> r . write ( '<STR_LIT>' + str ( responsecode ) + '<STR_LIT:U+0020>' + <EOL> responsestring + '<STR_LIT:\r\n>' ) <EOL> if not self . pre1 : <EOL> headers [ '<STR_LIT>' ] = len ( data ) <EOL> for key , value in headers . items ( ) : <EOL> r . write ( key + '<STR_LIT>' + str ( value ) + '<STR_LIT:\r\n>' ) <EOL> r . write ( '<STR_LIT:\r\n>' ) <EOL> if self . command != '<STR_LIT>' : <EOL> r . write ( data ) <EOL> self . connection . write ( r . getvalue ( ) ) <EOL> if self . connection . is_flushed ( ) : <EOL> self . connection . shutdown ( <NUM_LIT:1> ) <EOL> class HTTPHandler : <EOL> def __init__ ( self , getfunc , minflush ) : <EOL> self . connections = { } <EOL> self . getfunc = getfunc <EOL> self . minflush = minflush <EOL> self . lastflush = clock ( ) <EOL> def external_connection_made ( self , connection ) : <EOL> self . connections [ connection ] = HTTPConnection ( self , connection ) <EOL> def connection_flushed ( self , connection ) : <EOL> if self . connections [ connection ] . done : <EOL> connection . shutdown ( <NUM_LIT:1> ) <EOL> def connection_lost ( self , connection ) : <EOL> ec = self . connections [ connection ] <EOL> ec . closed = True <EOL> del ec . connection <EOL> del ec . next_func <EOL> del self . connections [ connection ] <EOL> def data_came_in ( self , connection , data ) : <EOL> c = self . connections [ connection ] <EOL> if not c . data_came_in ( data ) and not c . closed : <EOL> c . connection . shutdown ( <NUM_LIT:1> ) <EOL> def log ( self , ip , ident , username , header , <EOL> responsecode , length , referrer , useragent ) : <EOL> year , month , day , hour , minute , second , a , b , c = time . localtime ( time . time ( ) ) <EOL> print '<STR_LIT>' % ( <EOL> ip , ident , username , day , months [ month ] , year , hour , <EOL> minute , second , header , responsecode , length , referrer , useragent ) <EOL> t = clock ( ) <EOL> if t - self . lastflush > self . minflush : <EOL> self . lastflush = t <EOL> stdout . flush ( ) </s>
