<s> from __future__ import unicode_literals <EOL> from . green import socket , socks , listen , serve , wrap_ssl , GreenPool <EOL> from . utils import parse_proxy_uri , printable_uri , get_logger <EOL> __all__ = [ '<STR_LIT>' ] <EOL> class Server ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , concurrency = <NUM_LIT:1000> ) : <EOL> self . logger = get_logger ( ) . getChild ( '<STR_LIT>' ) <EOL> self . server = None <EOL> self . concurrency = concurrency <EOL> def listen ( self , address ) : <EOL> """<STR_LIT>""" <EOL> self . server = listen ( address ) <EOL> self . logger . info ( '<STR_LIT>' % address ) <EOL> def loop ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . server is None : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> self . logger . info ( '<STR_LIT>' ) <EOL> try : <EOL> serve ( self . server , self . handle_incoming , self . concurrency ) <EOL> except ( SystemExit , KeyboardInterrupt ) : <EOL> self . logger . info ( '<STR_LIT>' ) <EOL> def handle_incoming ( self , client_sock , client_addr ) : <EOL> raise NotImplementedError <EOL> class ReverseProxyServer ( Server ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , upstream , use_ssl = False , chunk_size = <NUM_LIT> ) : <EOL> super ( ReverseProxyServer , self ) . __init__ ( ) <EOL> self . upstream = upstream <EOL> self . use_ssl = use_ssl <EOL> self . chunk_size = chunk_size <EOL> self . proxy_server = None <EOL> self . proxy_timeout = <NUM_LIT> <EOL> def set_proxy ( self , uri , timeout = None ) : <EOL> if timeout : <EOL> self . proxy_timeout = timeout <EOL> self . proxy_server = parse_proxy_uri ( uri ) <EOL> self . logger . info ( '<STR_LIT>' % printable_uri ( uri ) ) <EOL> def handle_incoming ( self , client_sock , client_addr ) : <EOL> self . logger . info ( '<STR_LIT>' % client_addr ) <EOL> try : <EOL> upstream_sock = self . _connect_to_upstream ( ) <EOL> except ( socket . error , socks . ProxyError ) as e : <EOL> self . logger . exception ( e ) <EOL> return <EOL> pool = GreenPool ( ) <EOL> pool . spawn_n ( self . _forward , client_sock , upstream_sock , '<STR_LIT:w>' ) <EOL> pool . spawn_n ( self . _forward , upstream_sock , client_sock , '<STR_LIT:r>' ) <EOL> pool . waitall ( ) <EOL> drop_socket ( upstream_sock ) <EOL> drop_socket ( client_sock ) <EOL> def _connect_to_upstream ( self ) : <EOL> if self . proxy_server : <EOL> upstream_sock = socks . socksocket ( ) <EOL> upstream_sock . set_proxy ( ** self . proxy_server ) <EOL> else : <EOL> upstream_sock = socket . socket ( ) <EOL> try : <EOL> upstream_sock . settimeout ( self . proxy_timeout ) <EOL> upstream_sock . connect ( self . upstream ) <EOL> if self . use_ssl : <EOL> upstream_sock = wrap_ssl ( upstream_sock ) <EOL> except : <EOL> drop_socket ( upstream_sock ) <EOL> raise <EOL> self . logger . info ( <EOL> '<STR_LIT>' % self . upstream ) <EOL> return upstream_sock <EOL> def _forward ( self , src , dst , direction ) : <EOL> assert direction in ( '<STR_LIT:w>' , '<STR_LIT:r>' ) <EOL> while True : <EOL> try : <EOL> data = src . recv ( self . chunk_size ) <EOL> except socket . error as e : <EOL> if e . args and e . args [ <NUM_LIT:0> ] == '<STR_LIT>' : <EOL> self . logger . debug ( '<STR_LIT>' % direction ) <EOL> return <EOL> if not data : <EOL> self . logger . debug ( '<STR_LIT>' % direction ) <EOL> return <EOL> self . logger . debug ( '<STR_LIT>' % ( direction , len ( data ) ) ) <EOL> dst . sendall ( data ) <EOL> def drop_socket ( sock ) : <EOL> try : <EOL> sock . shutdown ( socket . SHUT_RDWR ) <EOL> except socket . error : <EOL> pass <EOL> sock . close ( ) </s>
