<s> import logging <EOL> import calendar <EOL> import threading <EOL> import time <EOL> import packets <EOL> from response_router import WriteBuffer <EOL> from utility import lock <EOL> UNINITIALIZED = <NUM_LIT:0> <EOL> WRITING = <NUM_LIT:1> <EOL> READING = <NUM_LIT:2> <EOL> COMPLETED = <NUM_LIT:3> <EOL> class TFTPConversation ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , client_host , client_port , response_router ) : <EOL> """<STR_LIT>""" <EOL> self . cached_packet = None <EOL> self . client_host = client_host <EOL> self . client_port = client_port <EOL> self . lock = threading . Lock ( ) <EOL> self . response_router = response_router <EOL> self . retries_made = <NUM_LIT:0> <EOL> self . state = UNINITIALIZED <EOL> self . time_of_last_interaction = calendar . timegm ( time . gmtime ( ) ) <EOL> @ lock <EOL> def handle_packet ( self , packet ) : <EOL> """<STR_LIT>""" <EOL> if self . state == UNINITIALIZED : <EOL> output_packet = self . _handle_initial_packet ( packet ) <EOL> elif self . state == READING : <EOL> output_packet = self . _handle_read_packet ( packet ) <EOL> elif self . state == WRITING : <EOL> output_packet = self . _handle_write_packet ( packet ) <EOL> else : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> if not isinstance ( output_packet , packets . ErrorPacket ) : <EOL> self . cached_packet = output_packet <EOL> self . _reset_retry_and_time_data ( ) <EOL> return output_packet <EOL> def _handle_initial_packet ( self , packet ) : <EOL> """<STR_LIT>""" <EOL> assert self . state == UNINITIALIZED <EOL> if isinstance ( packet , packets . ReadRequestPacket ) : <EOL> return self . _handle_initial_read_packet ( packet ) <EOL> if isinstance ( packet , packets . WriteRequestPacket ) : <EOL> return self . _handle_initial_write_packet ( packet ) <EOL> else : <EOL> self . state = COMPLETED <EOL> return packets . ErrorPacket ( <NUM_LIT:5> , "<STR_LIT>" <EOL> "<STR_LIT>" % ( self . client_host , self . client_port ) ) <EOL> def _handle_initial_read_packet ( self , packet ) : <EOL> """<STR_LIT>""" <EOL> assert isinstance ( packet , packets . ReadRequestPacket ) <EOL> self . filename = packet . filename <EOL> self . mode = packet . mode <EOL> self . read_buffer = self . response_router . initialize_read ( <EOL> self . filename , self . client_host , self . client_port ) <EOL> if self . read_buffer : <EOL> self . state = READING <EOL> data = self . read_buffer . get_block ( <NUM_LIT:1> ) <EOL> self . current_block_num = <NUM_LIT:1> <EOL> return packets . DataPacket ( <NUM_LIT:1> , data ) <EOL> else : <EOL> self . log ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> self . state = COMPLETED <EOL> return packets . ErrorPacket ( <NUM_LIT:1> , "<STR_LIT>" <EOL> % ( self . client_host , self . client_port ) ) <EOL> def _handle_initial_write_packet ( self , packet ) : <EOL> """<STR_LIT>""" <EOL> assert isinstance ( packet , packets . WriteRequestPacket ) <EOL> self . filename = packet . filename <EOL> self . mode = packet . mode <EOL> self . current_block_num = <NUM_LIT:0> <EOL> self . write_action = self . response_router . initialize_write ( <EOL> self . filename , self . client_host , self . client_port ) <EOL> if self . write_action : <EOL> self . state = WRITING <EOL> self . write_buffer = WriteBuffer ( ) <EOL> return packets . AcknowledgementPacket ( <NUM_LIT:0> ) <EOL> else : <EOL> self . state = COMPLETED <EOL> self . log ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> return packets . ErrorPacket ( <NUM_LIT:2> , "<STR_LIT>" <EOL> % ( self . client_host , self . client_port ) ) <EOL> def _handle_read_packet ( self , packet ) : <EOL> """<STR_LIT>""" <EOL> assert self . state == READING <EOL> if not isinstance ( packet , packets . AcknowledgementPacket ) : <EOL> return packets . ErrorPacket ( <NUM_LIT:0> , "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> % ( self . client_host , self . client_port ) ) <EOL> if self . current_block_num != packet . block_num : <EOL> return packets . NoOpPacket ( ) <EOL> previous_block_num = packet . block_num <EOL> if previous_block_num == self . read_buffer . get_block_count ( ) : <EOL> self . state = COMPLETED <EOL> self . log ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> return packets . NoOpPacket ( ) <EOL> else : <EOL> self . current_block_num += <NUM_LIT:1> <EOL> data = self . read_buffer . get_block ( self . current_block_num ) <EOL> return packets . DataPacket ( self . current_block_num , data ) <EOL> def _handle_write_packet ( self , packet ) : <EOL> """<STR_LIT>""" <EOL> assert self . state == WRITING <EOL> if not isinstance ( packet , packets . DataPacket ) : <EOL> return packets . ErrorPacket ( <NUM_LIT:0> , "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if self . current_block_num + <NUM_LIT:1> != packet . block_num : <EOL> return packets . NoOpPacket ( ) <EOL> block_num = packet . block_num <EOL> self . write_buffer . receive_data ( packet . data ) <EOL> if len ( packet . data ) < <NUM_LIT> : <EOL> self . state = COMPLETED <EOL> self . log ( "<STR_LIT>" , "<STR_LIT>" ) <EOL> self . write_action ( self . client_host , self . client_port , <EOL> self . filename , self . write_buffer . data ) <EOL> self . current_block_num += <NUM_LIT:1> <EOL> return packets . AcknowledgementPacket ( block_num ) <EOL> def _reset_retry_and_time_data ( self , new_time_of_last_interaction = None ) : <EOL> """<STR_LIT>""" <EOL> self . _update_time_of_last_interaction ( new_time_of_last_interaction ) <EOL> self . retries_made = <NUM_LIT:0> <EOL> @ lock <EOL> def mark_retry ( self , new_time_of_last_interaction = None ) : <EOL> """<STR_LIT>""" <EOL> self . _update_time_of_last_interaction ( new_time_of_last_interaction ) <EOL> self . retries_made += <NUM_LIT:1> <EOL> return self . cached_packet <EOL> def _update_time_of_last_interaction ( self , <EOL> new_time_of_last_interaction = None ) : <EOL> """<STR_LIT>""" <EOL> if not new_time_of_last_interaction : <EOL> new_time_of_last_interaction = calendar . timegm ( time . gmtime ( ) ) <EOL> self . time_of_last_interaction = new_time_of_last_interaction <EOL> def log ( self , request_type , comment ) : <EOL> logging . info ( "<STR_LIT>" <EOL> % ( self . client_host , self . client_port , request_type , <EOL> self . filename , comment ) ) </s>
