<s> """<STR_LIT>""" <EOL> import logging <EOL> from . import sessioncontainer , periodic , proto <EOL> from . util import bytes_to_str <EOL> class ConnectionInfo ( object ) : <EOL> """<STR_LIT>""" <EOL> _exposed_headers = set ( [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> def __init__ ( self , ip , cookies , arguments , headers , path ) : <EOL> self . ip = ip <EOL> self . cookies = cookies <EOL> self . arguments = arguments <EOL> self . headers = { } <EOL> self . path = path <EOL> for header in headers : <EOL> if header . lower ( ) in ConnectionInfo . _exposed_headers : <EOL> self . headers [ header ] = headers [ header ] <EOL> def get_argument ( self , name ) : <EOL> """<STR_LIT>""" <EOL> val = self . arguments . get ( name ) <EOL> if val : <EOL> return val [ <NUM_LIT:0> ] <EOL> return None <EOL> def get_cookie ( self , name ) : <EOL> """<STR_LIT>""" <EOL> return self . cookies . get ( name ) <EOL> def get_header ( self , name ) : <EOL> """<STR_LIT>""" <EOL> return self . headers . get ( name ) <EOL> CONNECTING = <NUM_LIT:0> <EOL> OPEN = <NUM_LIT:1> <EOL> CLOSING = <NUM_LIT:2> <EOL> CLOSED = <NUM_LIT:3> <EOL> class BaseSession ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , conn , server ) : <EOL> """<STR_LIT>""" <EOL> self . server = server <EOL> self . stats = server . stats <EOL> self . send_expects_json = False <EOL> self . handler = None <EOL> self . state = CONNECTING <EOL> self . conn_info = None <EOL> self . conn = conn ( self ) <EOL> self . close_reason = None <EOL> def set_handler ( self , handler ) : <EOL> """<STR_LIT>""" <EOL> if self . handler is not None : <EOL> raise Exception ( '<STR_LIT>' ) <EOL> self . handler = handler <EOL> self . transport_name = self . handler . name <EOL> if self . conn_info is None : <EOL> self . conn_info = handler . get_conn_info ( ) <EOL> self . stats . on_sess_opened ( self . transport_name ) <EOL> return True <EOL> def verify_state ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . state == CONNECTING : <EOL> self . state = OPEN <EOL> self . conn . on_open ( self . conn_info ) <EOL> def remove_handler ( self , handler ) : <EOL> """<STR_LIT>""" <EOL> if self . handler != handler : <EOL> raise Exception ( '<STR_LIT>' ) <EOL> self . handler = None <EOL> def close ( self , code = <NUM_LIT> , message = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> if self . state != CLOSED : <EOL> try : <EOL> self . conn . on_close ( ) <EOL> except : <EOL> logging . debug ( "<STR_LIT>" , exc_info = True ) <EOL> finally : <EOL> self . state = CLOSED <EOL> self . close_reason = ( code , message ) <EOL> self . stats . on_sess_closed ( self . transport_name ) <EOL> if self . handler is not None : <EOL> self . handler . session_closed ( ) <EOL> def delayed_close ( self ) : <EOL> """<STR_LIT>""" <EOL> self . state = CLOSING <EOL> self . server . io_loop . add_callback ( self . close ) <EOL> def get_close_reason ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . close_reason : <EOL> return self . close_reason <EOL> return ( <NUM_LIT> , '<STR_LIT>' ) <EOL> @ property <EOL> def is_closed ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . state == CLOSED or self . state == CLOSING <EOL> def send_message ( self , msg , stats = True , binary = False ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplemented ( ) <EOL> def send_jsonified ( self , msg , stats = True ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplemented ( ) <EOL> def broadcast ( self , clients , msg ) : <EOL> """<STR_LIT>""" <EOL> self . server . broadcast ( clients , msg ) <EOL> class Session ( BaseSession , sessioncontainer . SessionMixin ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , conn , server , session_id , expiry = None ) : <EOL> """<STR_LIT>""" <EOL> sessioncontainer . SessionMixin . __init__ ( self , session_id , expiry ) <EOL> BaseSession . __init__ ( self , conn , server ) <EOL> self . send_queue = '<STR_LIT>' <EOL> self . send_expects_json = True <EOL> self . _heartbeat_timer = None <EOL> self . _heartbeat_interval = self . server . settings [ '<STR_LIT>' ] * <NUM_LIT:1000> <EOL> self . _immediate_flush = self . server . settings [ '<STR_LIT>' ] <EOL> self . _pending_flush = False <EOL> self . _verify_ip = self . server . settings [ '<STR_LIT>' ] <EOL> def on_delete ( self , forced ) : <EOL> """<STR_LIT>""" <EOL> if not forced and self . handler is not None and not self . is_closed : <EOL> self . promote ( ) <EOL> else : <EOL> self . close ( ) <EOL> def set_handler ( self , handler , start_heartbeat = True ) : <EOL> """<STR_LIT>""" <EOL> if self . handler is not None : <EOL> handler . send_pack ( proto . disconnect ( <NUM_LIT> , "<STR_LIT>" ) ) <EOL> return False <EOL> if self . _verify_ip and self . conn_info is not None : <EOL> if handler . request . remote_ip != self . conn_info . ip : <EOL> logging . error ( '<STR_LIT>' % ( <EOL> self . session_id , <EOL> self . conn_info . ip , <EOL> handler . request . remote_ip <EOL> ) ) <EOL> handler . send_pack ( proto . disconnect ( <NUM_LIT> , "<STR_LIT>" ) ) <EOL> return False <EOL> if self . state == CLOSING or self . state == CLOSED : <EOL> handler . send_pack ( proto . disconnect ( * self . get_close_reason ( ) ) ) <EOL> return False <EOL> super ( Session , self ) . set_handler ( handler ) <EOL> self . promote ( ) <EOL> if start_heartbeat : <EOL> self . start_heartbeat ( ) <EOL> return True <EOL> def verify_state ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . state == CONNECTING : <EOL> self . handler . send_pack ( proto . CONNECT ) <EOL> super ( Session , self ) . verify_state ( ) <EOL> def remove_handler ( self , handler ) : <EOL> """<STR_LIT>""" <EOL> super ( Session , self ) . remove_handler ( handler ) <EOL> self . promote ( ) <EOL> self . stop_heartbeat ( ) <EOL> def send_message ( self , msg , stats = True , binary = False ) : <EOL> """<STR_LIT>""" <EOL> self . send_jsonified ( proto . json_encode ( bytes_to_str ( msg ) ) , stats ) <EOL> def send_jsonified ( self , msg , stats = True ) : <EOL> """<STR_LIT>""" <EOL> msg = bytes_to_str ( msg ) <EOL> if self . _immediate_flush : <EOL> if self . handler and self . handler . active and not self . send_queue : <EOL> self . handler . send_pack ( '<STR_LIT>' % msg ) <EOL> else : <EOL> if self . send_queue : <EOL> self . send_queue += '<STR_LIT:U+002C>' <EOL> self . send_queue += msg <EOL> self . flush ( ) <EOL> else : <EOL> if self . send_queue : <EOL> self . send_queue += '<STR_LIT:U+002C>' <EOL> self . send_queue += msg <EOL> if not self . _pending_flush : <EOL> self . server . io_loop . add_callback ( self . flush ) <EOL> self . _pending_flush = True <EOL> if stats : <EOL> self . stats . on_pack_sent ( <NUM_LIT:1> ) <EOL> def flush ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _pending_flush = False <EOL> if self . handler is None or not self . handler . active or not self . send_queue : <EOL> return <EOL> self . handler . send_pack ( '<STR_LIT>' % self . send_queue ) <EOL> self . send_queue = '<STR_LIT>' <EOL> def close ( self , code = <NUM_LIT> , message = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> if self . state != CLOSED : <EOL> if self . handler is not None : <EOL> self . handler . send_pack ( proto . disconnect ( code , message ) ) <EOL> super ( Session , self ) . close ( code , message ) <EOL> def start_heartbeat ( self ) : <EOL> """<STR_LIT>""" <EOL> self . stop_heartbeat ( ) <EOL> self . _heartbeat_timer = periodic . Callback ( self . _heartbeat , <EOL> self . _heartbeat_interval , <EOL> self . server . io_loop ) <EOL> self . _heartbeat_timer . start ( ) <EOL> def stop_heartbeat ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _heartbeat_timer is not None : <EOL> self . _heartbeat_timer . stop ( ) <EOL> self . _heartbeat_timer = None <EOL> def delay_heartbeat ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _heartbeat_timer is not None : <EOL> self . _heartbeat_timer . delay ( ) <EOL> def _heartbeat ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . handler is not None : <EOL> self . handler . send_pack ( proto . HEARTBEAT ) <EOL> else : <EOL> self . stop_heartbeat ( ) <EOL> def on_messages ( self , msg_list ) : <EOL> """<STR_LIT>""" <EOL> self . stats . on_pack_recv ( len ( msg_list ) ) <EOL> for msg in msg_list : <EOL> self . conn . on_message ( msg ) </s>
