<s> import logging <EOL> import os <EOL> import pyuv <EOL> import signal <EOL> import sys <EOL> import time <EOL> import traceback <EOL> try : <EOL> from io import BytesIO <EOL> except ImportError : <EOL> from cStringIO import StringIO as BytesIO <EOL> from http_parser . parser import HttpParser <EOL> __all__ = [ '<STR_LIT>' ] <EOL> __version__ = '<STR_LIT>' <EOL> logger = logging . getLogger ( '<STR_LIT>' ) <EOL> logger . setLevel ( logging . DEBUG ) <EOL> logging . basicConfig ( ) <EOL> DEBUG = os . getenv ( '<STR_LIT>' , None ) is not None <EOL> PY2 = sys . version_info [ <NUM_LIT:0> ] == <NUM_LIT:2> <EOL> if PY2 : <EOL> bytes_type = str <EOL> unicode_type = unicode <EOL> exec ( """<STR_LIT>""" ) <EOL> else : <EOL> bytes_type = bytes <EOL> unicode_type = str <EOL> def reraise ( tp , value , tb = None ) : <EOL> if value . __traceback__ is not tb : <EOL> raise value . with_traceback ( tb ) <EOL> raise value <EOL> def wsgi_to_bytes ( s ) : <EOL> if isinstance ( s , bytes_type ) : <EOL> return s <EOL> assert isinstance ( s , unicode_type ) <EOL> return s . encode ( '<STR_LIT>' ) <EOL> _WEEKDAYNAME = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] <EOL> _MONTHNAME = [ None , <EOL> "<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> def date_time_string ( timestamp = None ) : <EOL> if timestamp is None : <EOL> timestamp = time . time ( ) <EOL> year , month , day , hh , mm , ss , wd , _y , _z = time . gmtime ( timestamp ) <EOL> return "<STR_LIT>" % ( <EOL> _WEEKDAYNAME [ wd ] , day , _MONTHNAME [ month ] , year , hh , mm , ss ) <EOL> class ErrorStream ( object ) : <EOL> def __init__ ( self , logger ) : <EOL> self . _logger = logger <EOL> def write ( self , data ) : <EOL> self . _logger . error ( data ) <EOL> def writelines ( self , seq ) : <EOL> for item in seq : <EOL> self . write ( item ) <EOL> def flush ( self ) : <EOL> pass <EOL> class HTTPRequest ( object ) : <EOL> def __init__ ( self , connection ) : <EOL> self . connection = connection <EOL> self . headers = None <EOL> self . body = None <EOL> self . method = None <EOL> self . url = None <EOL> self . protocol_version = None <EOL> self . close_connection = False <EOL> def process_data ( self , data ) : <EOL> parser = self . connection . parser <EOL> ndata = len ( data ) <EOL> parsed = parser . execute ( data , ndata ) <EOL> if ndata != parsed : <EOL> logger . error ( '<STR_LIT>' ) <EOL> self . connection . close ( ) <EOL> return <EOL> if parser . is_headers_complete ( ) and not self . headers : <EOL> self . headers = parser . get_headers ( ) <EOL> self . method = parser . get_method ( ) <EOL> self . url = parser . get_url ( ) <EOL> self . protocol_version = '<STR_LIT>' % '<STR_LIT:.>' . join ( map ( str , parser . get_version ( ) ) ) <EOL> self . close_connection = not parser . should_keep_alive ( ) <EOL> if parser . is_message_complete ( ) : <EOL> self . body = BytesIO ( parser . recv_body ( ) ) <EOL> self . run_wsgi ( ) <EOL> def run_wsgi ( self ) : <EOL> headers_set = [ ] <EOL> headers_sent = [ ] <EOL> def write ( data ) : <EOL> if not headers_set : <EOL> raise AssertionError ( "<STR_LIT>" ) <EOL> elif not headers_sent : <EOL> buf = [ ] <EOL> status , response_headers = headers_sent [ : ] = headers_set <EOL> code , _ , msg = status . partition ( '<STR_LIT:U+0020>' ) <EOL> buf . append ( wsgi_to_bytes ( '<STR_LIT>' % ( self . protocol_version , int ( code ) , msg ) ) ) <EOL> header_keys = set ( ) <EOL> for key , value in response_headers : <EOL> buf . append ( wsgi_to_bytes ( '<STR_LIT>' % ( key , value ) ) ) <EOL> header_keys . add ( key . lower ( ) ) <EOL> if '<STR_LIT>' not in header_keys : <EOL> self . close_connection = True <EOL> if '<STR_LIT>' not in header_keys : <EOL> buf . append ( wsgi_to_bytes ( '<STR_LIT>' % __version__ ) ) <EOL> if '<STR_LIT:date>' not in header_keys : <EOL> buf . append ( wsgi_to_bytes ( '<STR_LIT>' % date_time_string ( ) ) ) <EOL> buf . append ( b'<STR_LIT:\r\n>' ) <EOL> self . connection . write ( b'<STR_LIT>' . join ( buf ) ) <EOL> assert type ( data ) is bytes , '<STR_LIT>' <EOL> self . connection . write ( data ) <EOL> def start_response ( status , response_headers , exc_info = None ) : <EOL> if exc_info : <EOL> try : <EOL> if headers_sent : <EOL> reraise ( * exc_info ) <EOL> finally : <EOL> exc_info = None <EOL> elif headers_set : <EOL> raise AssertionError ( "<STR_LIT>" ) <EOL> headers_set [ : ] = [ status , response_headers ] <EOL> return write <EOL> env = self . connection . parser . get_wsgi_environ ( ) <EOL> env [ '<STR_LIT>' ] = ( <NUM_LIT:1> , <NUM_LIT:0> ) <EOL> env [ '<STR_LIT>' ] = '<STR_LIT:http>' <EOL> env [ '<STR_LIT>' ] = self . body <EOL> env [ '<STR_LIT>' ] = ErrorStream ( logger ) <EOL> env [ '<STR_LIT>' ] = False <EOL> env [ '<STR_LIT>' ] = False <EOL> env [ '<STR_LIT>' ] = False <EOL> app = self . connection . server . app <EOL> try : <EOL> app_response = app ( env , start_response ) <EOL> except Exception : <EOL> logger . exception ( '<STR_LIT>' ) <EOL> if DEBUG : <EOL> response_body = traceback . format_exc ( ) <EOL> response_headers = [ ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) , <EOL> ( '<STR_LIT>' , str ( len ( response_body ) ) ) ] <EOL> start_response ( '<STR_LIT>' , response_headers , exc_info = sys . exc_info ( ) ) <EOL> app_response = [ response_body ] <EOL> else : <EOL> self . connection . finish ( ) <EOL> return <EOL> try : <EOL> for data in app_response : <EOL> write ( data ) <EOL> if not headers_sent : <EOL> write ( b'<STR_LIT>' ) <EOL> except Exception : <EOL> logger . exception ( '<STR_LIT>' ) <EOL> finally : <EOL> if hasattr ( app_response , '<STR_LIT>' ) : <EOL> app_response . close ( ) <EOL> self . end ( ) <EOL> if DEBUG : <EOL> status = headers_set [ <NUM_LIT:0> ] <EOL> self . _log ( int ( status . split ( ) [ <NUM_LIT:0> ] ) ) <EOL> def end ( self ) : <EOL> if self . close_connection : <EOL> self . connection . finish ( ) <EOL> else : <EOL> self . connection . request = None <EOL> def _log ( self , code ) : <EOL> if code < <NUM_LIT> : <EOL> log_method = logger . info <EOL> elif code < <NUM_LIT> : <EOL> log_method = logger . warning <EOL> else : <EOL> log_method = logger . error <EOL> log_method ( '<STR_LIT>' , code , self . method , self . url , self . connection . remote_address ) <EOL> class HTTPConnection ( object ) : <EOL> def __init__ ( self , handle , server ) : <EOL> self . server = server <EOL> self . request = None <EOL> self . parser = HttpParser ( kind = <NUM_LIT:0> ) <EOL> self . _handle = handle <EOL> self . _handle . start_read ( self . _on_read ) <EOL> self . _closed = False <EOL> self . _must_close = False <EOL> self . _pending_writes = <NUM_LIT:0> <EOL> self . _remote_address = self . _handle . getpeername ( ) <EOL> @ property <EOL> def remote_address ( self ) : <EOL> return self . _remote_address <EOL> def write ( self , data ) : <EOL> self . _handle . write ( data , self . _on_write ) <EOL> self . _pending_writes += <NUM_LIT:1> <EOL> def finish ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _closed or self . _must_close : <EOL> return <EOL> if self . _pending_writes == <NUM_LIT:0> : <EOL> self . close ( ) <EOL> else : <EOL> self . _must_close = True <EOL> def close ( self ) : <EOL> if self . _closed : <EOL> return <EOL> if DEBUG : <EOL> logger . debug ( '<STR_LIT>' , self . remote_address ) <EOL> self . _handle . close ( self . _on_close ) <EOL> self . _closed = True <EOL> def _on_read ( self , handle , data , error ) : <EOL> if error is not None : <EOL> if DEBUG : <EOL> if error == pyuv . errno . UV_EOF : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> else : <EOL> logger . debug ( '<STR_LIT>' , error , pyuv . errno . strerror ( error ) ) <EOL> self . close ( ) <EOL> return <EOL> if self . request is None : <EOL> self . request = HTTPRequest ( self ) <EOL> self . request . process_data ( data ) <EOL> def _on_close ( self , handle ) : <EOL> self . server . connections . remove ( self ) <EOL> self . _handle = self . server = self . request = self . parser = None <EOL> def _on_write ( self , handle , error ) : <EOL> if DEBUG and error is not None : <EOL> logger . error ( '<STR_LIT>' , error , pyuv . errno . strerror ( error ) ) <EOL> self . _pending_writes -= <NUM_LIT:1> <EOL> if self . _pending_writes == <NUM_LIT:0> and self . _must_close : <EOL> self . close ( ) <EOL> class WSGIServer ( object ) : <EOL> def __init__ ( self , loop , application , address , fd ) : <EOL> self . app = application <EOL> self . connections = set ( ) <EOL> self . _loop = loop <EOL> self . _handle = pyuv . TCP ( loop ) <EOL> if fd is None : <EOL> self . _handle . bind ( address ) <EOL> else : <EOL> self . _handle . open ( os . dup ( fd ) ) <EOL> self . _stopped = False <EOL> logger . info ( '<STR_LIT>' , self . __class__ . __name__ , self . _handle . getsockname ( ) ) <EOL> def start ( self ) : <EOL> self . _handle . listen ( self . _on_connection ) <EOL> def stop ( self ) : <EOL> if self . _stopped : <EOL> return <EOL> self . _handle . close ( ) <EOL> for c in self . connections : <EOL> c . close ( ) <EOL> self . _loop . stop ( ) <EOL> self . _stopped = True <EOL> def _on_connection ( self , handle , error ) : <EOL> if error is not None : <EOL> logger . error ( '<STR_LIT>' , error , pyuv . errno . strerror ( error ) ) <EOL> return <EOL> conn = pyuv . TCP ( self . _handle . loop ) <EOL> self . _handle . accept ( conn ) <EOL> http_connection = HTTPConnection ( conn , self ) <EOL> self . connections . add ( http_connection ) <EOL> if DEBUG : <EOL> logger . debug ( '<STR_LIT>' , conn . getpeername ( ) ) <EOL> def run ( application , address = None , fd = None ) : <EOL> loop = pyuv . Loop . default_loop ( ) <EOL> server = WSGIServer ( loop , application , address , fd ) <EOL> sigint_h = pyuv . Signal ( loop ) <EOL> sigint_h . start ( lambda * x : server . stop ( ) , signal . SIGINT ) <EOL> sigterm_h = pyuv . Signal ( loop ) <EOL> sigterm_h . start ( lambda * x : server . stop ( ) , signal . SIGTERM ) <EOL> server . start ( ) <EOL> loop . run ( ) <EOL> for handle in loop . handles : <EOL> if not handle . closed : <EOL> handle . close ( ) <EOL> def main ( ) : <EOL> from optparse import OptionParser <EOL> def import_app ( s ) : <EOL> sys . path . insert ( <NUM_LIT:0> , os . path . abspath ( os . curdir ) ) <EOL> mod , attr = s . rsplit ( '<STR_LIT::>' , <NUM_LIT:1> ) <EOL> module = __import__ ( mod ) <EOL> return getattr ( module , attr ) <EOL> parser = OptionParser ( ) <EOL> parser . add_option ( '<STR_LIT>' , '<STR_LIT>' , default = '<STR_LIT>' , help = '<STR_LIT>' ) <EOL> parser . add_option ( '<STR_LIT>' , '<STR_LIT>' , default = '<STR_LIT>' , help = '<STR_LIT>' ) <EOL> parser . add_option ( '<STR_LIT>' , '<STR_LIT>' , default = None , help = '<STR_LIT>' ) <EOL> options , args = parser . parse_args ( ) <EOL> if len ( args ) != <NUM_LIT:1> : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> app = import_app ( args [ <NUM_LIT:0> ] ) <EOL> if options . fd is None : <EOL> interface = options . interface <EOL> port = int ( options . port ) <EOL> address = ( interface , port ) <EOL> fd = None <EOL> else : <EOL> address = None <EOL> fd = int ( options . fd ) <EOL> run ( app , address = address , fd = fd ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> main ( ) </s>
