def test_confirm_and_receive(self): self.action = ftplib.ACTIONS.RECEIVE with open(os.path.join(ftplib.CONTENT_DIR, self.filename), 'rb') as f: f.seek(0) # beginning of file file_data = f.read(ftplib.BUFFER_SIZE - ftplib.PROTO_HEADER_LENGTH) file_offset = f.tell() ftp_receive = ftplib.create_packet(file_data, self.action) self.packet_testing(ftp_receive) self.packet.checksum = ftplib.packet_md5sum(file_data) self.assertEqual(file_offset, ftplib.BUFFER_SIZE - ftplib.PROTO_HEADER_LENGTH) self.assertEqual(file_data, self.packet.content) packet_md5sum = ftplib.packet_md5sum(self.packet.content) data_md5sum = ftplib.packet_md5sum(file_data) self.assertEqual(packet_md5sum, data_md5sum) self.assertEqual(packet_md5sum, self.packet.checksum) self.setUp() self.action = ftplib.ACTIONS.CONFIRM ftp_confirm = ftplib.create_packet(packet_md5sum, self.action) self.packet_testing(ftp_confirm) self.assertEqual(data_md5sum, ftplib.decode(self.packet.content)) self.assertEqual(packet_md5sum, ftplib.decode(self.packet.content))
def startup(self, host_address=ftplib.HOST, port=ftplib.PORT): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as self._socket: self._socket.connect( (host_address, port)) # Connect to server and send file request ftp_request = ftplib.create_packet( self.file_request, action=ftplib.ACTIONS.START_REQUEST) self._socket.send(ftp_request) while True: try: # Receive data from the server and send packet checksum once entire packet is received data = self._socket.recv(ftplib.BUFFER_SIZE) except BlockingIOError: pass else: if data: # Non-zero number of bytes were received self.packet.buffer += data ftplib.process_packet(self.packet) if self.packet.content is not None: action = self.packet.header[ftplib.HEADERS.ACTION] if action == ftplib.ACTIONS.RECEIVE: # Process received file data self.do_RECEIVE() elif action == ftplib.ACTIONS.END_REQUEST: # Verify file checksum and exit self.do_END_REQUEST() break else: raise ValueError( f"invalid action '{action}' specified for client" )
def test_end_packet(self): self.action = ftplib.ACTIONS.END_REQUEST file_md5sum = ftplib.file_md5sum(self.filename) ftp_end_request = ftplib.create_packet(file_md5sum, self.action) self.packet_testing(ftp_end_request) self.assertEqual(file_md5sum, ftplib.decode(self.packet.content))
def test_start_packet(self): self.action = ftplib.ACTIONS.START_REQUEST ftp_start_request = ftplib.create_packet(self.filename, self.action) self.packet_testing(ftp_start_request) # Test Decoding self.assertEqual(self.filename, ftplib.decode(self.packet.content)) self.assertEqual('test.png', ftplib.decode(self.packet.content))
def do_RECEIVE(self): with open(os.path.join(DIR, 'copy_of_' + self.file_request), 'ab') as f: # Append received data to file f.write(self.packet.content) checksum = ftplib.packet_md5sum(self.packet.content) confirmation_packet = ftplib.create_packet( checksum, action=ftplib.ACTIONS.CONFIRM) self._socket.send(confirmation_packet) self.packet.reset()
def do_END_REQUEST(self): file_checksum = ftplib.file_md5sum(self._requested_file) ftp_end_packet = ftplib.create_packet( file_checksum, action=ftplib.ACTIONS.END_REQUEST) print( f"All '{self._requested_file}' data sent to client; shutting down . . ." ) self._file_offset = 0 self._requested_file = None self.request.send(ftp_end_packet) self._awaiting_confirmation = False
def do_RECEIVE(self, file_chunk: bytes): self.packet.checksum = ftplib.packet_md5sum(file_chunk) ftp_data_packet = ftplib.create_packet(file_chunk, action=ftplib.ACTIONS.RECEIVE) self._awaiting_confirmation = True self.request.send(ftp_data_packet)