<s> import errno <EOL> import logging <EOL> import os <EOL> import signal <EOL> import sys <EOL> import time <EOL> import gevent <EOL> from gevent . server import StreamServer <EOL> from gevent import socket <EOL> from gevent import monkey <EOL> monkey . noisy = False <EOL> monkey . patch_all ( ) <EOL> from . client import ClientConnection <EOL> from . route import Route <EOL> from . import util <EOL> log = logging . getLogger ( __name__ ) <EOL> class ProxyServer ( StreamServer ) : <EOL> def __init__ ( self , listener , script , backlog = None , <EOL> spawn = '<STR_LIT:default>' , ** sslargs ) : <EOL> StreamServer . __init__ ( self , listener , backlog = backlog , <EOL> spawn = spawn , ** sslargs ) <EOL> self . script = script <EOL> self . nb_connections = <NUM_LIT:0> <EOL> self . route = None <EOL> self . rewrite_request = None <EOL> self . rewrite_response = None <EOL> def handle_quit ( self , * args ) : <EOL> """<STR_LIT>""" <EOL> gevent . spawn ( self . stop ) <EOL> def handle_exit ( self , * args ) : <EOL> """<STR_LIT>""" <EOL> gevent . spawn ( self . stop , <NUM_LIT> ) <EOL> def handle_winch ( self , * args ) : <EOL> return <EOL> def pre_start ( self ) : <EOL> """<STR_LIT>""" <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> self . socket = tcp_listener ( self . address , self . backlog ) <EOL> self . address = self . socket . getsockname ( ) <EOL> self . _stopped_event . clear ( ) <EOL> if self . ssl_enabled : <EOL> self . _handle = self . wrap_socket_and_handle <EOL> else : <EOL> self . _handle = self . handle <EOL> signal . signal ( signal . SIGQUIT , self . handle_quit ) <EOL> signal . signal ( signal . SIGTERM , self . handle_exit ) <EOL> signal . signal ( signal . SIGINT , self . handle_exit ) <EOL> signal . signal ( signal . SIGWINCH , self . handle_winch ) <EOL> def init_route ( self ) : <EOL> if self . route is not None : <EOL> return <EOL> self . route = Route ( self . script ) <EOL> def start_accepting ( self ) : <EOL> self . init_route ( ) <EOL> super ( ProxyServer , self ) . start_accepting ( ) <EOL> def handle ( self , socket , address ) : <EOL> """<STR_LIT>""" <EOL> conn = ClientConnection ( socket , address , self ) <EOL> conn . handle ( ) <EOL> def wrap_socket_and_handle ( self , client_socket , address ) : <EOL> ssl_socket = self . wrap_socket ( client_socket , ** self . ssl_args ) <EOL> return self . handle ( ssl_socket , address ) <EOL> def tcp_listener ( address , backlog = None ) : <EOL> backlog = backlog or <NUM_LIT> <EOL> if util . is_ipv6 ( address [ <NUM_LIT:0> ] ) : <EOL> family = socket . AF_INET6 <EOL> else : <EOL> family = socket . AF_INET <EOL> bound = False <EOL> if '<STR_LIT>' in os . environ : <EOL> fd = int ( os . environ . pop ( '<STR_LIT>' ) ) <EOL> try : <EOL> sock = socket . fromfd ( fd , family , socket . SOCK_STREAM ) <EOL> except socket . error , e : <EOL> if e [ <NUM_LIT:0> ] == errno . ENOTCONN : <EOL> log . error ( "<STR_LIT>" ) <EOL> else : <EOL> raise <EOL> bound = True <EOL> else : <EOL> sock = socket . socket ( family , socket . SOCK_STREAM ) <EOL> sock . setsockopt ( socket . SOL_SOCKET , socket . SO_REUSEADDR , <NUM_LIT:1> ) <EOL> for i in range ( <NUM_LIT:5> ) : <EOL> try : <EOL> if not bound : <EOL> sock . bind ( address ) <EOL> sock . setblocking ( <NUM_LIT:0> ) <EOL> sock . listen ( backlog ) <EOL> return sock <EOL> except socket . error , e : <EOL> if e [ <NUM_LIT:0> ] == errno . EADDRINUSE : <EOL> log . error ( "<STR_LIT>" % str ( address ) ) <EOL> if e [ <NUM_LIT:0> ] == errno . EADDRNOTAVAIL : <EOL> log . error ( "<STR_LIT>" % str ( address ) ) <EOL> sys . exit ( <NUM_LIT:1> ) <EOL> if i < <NUM_LIT:5> : <EOL> log . error ( "<STR_LIT>" % str ( e ) ) <EOL> time . sleep ( <NUM_LIT:1> ) </s>
