@@ -540,18 +540,11 @@ def execute_api_request(self, command_id, url, method='GET', body=None, shareify
540540 except json .JSONDecodeError :
541541 response_data = response .text
542542
543- if self .sio .connected :
544- try :
545- self .sio .emit ('command_response' , {
546- 'command_id' : command_id ,
547- 'response' : response_data
548- })
549- print (f"Successfully emitted response for command { command_id } " )
550- time .sleep (0.1 )
551- except Exception as emit_error :
552- print (f"Failed to emit response: { emit_error } " )
543+ is_file_endpoint = url .endswith ('/get_file' ) or 'get_file' in url
544+ if is_file_endpoint and isinstance (response_data , dict ) and 'content' in response_data :
545+ self .handle_large_file_response (command_id , response_data )
553546 else :
554- print ( "Socket not connected, cannot emit response" )
547+ self . send_standard_response ( command_id , response_data )
555548
556549 except requests .exceptions .Timeout :
557550 print (f"API request timeout for command { command_id } " )
@@ -585,6 +578,128 @@ def execute_api_request(self, command_id, url, method='GET', body=None, shareify
585578 })
586579 except Exception as emit_error :
587580 print (f"Failed to emit general error: { emit_error } " )
581+
582+ def send_standard_response (self , command_id , response_data ):
583+ if self .sio .connected :
584+ try :
585+ self .sio .emit ('command_response' , {
586+ 'command_id' : command_id ,
587+ 'response' : response_data
588+ })
589+ print (f"Successfully emitted response for command { command_id } " )
590+ time .sleep (0.1 )
591+ except Exception as emit_error :
592+ print (f"Failed to emit response: { emit_error } " )
593+ else :
594+ print ("Socket not connected, cannot emit response" )
595+
596+ def handle_large_file_response (self , command_id , response_data ):
597+ import base64
598+
599+ if 'content' not in response_data :
600+ self .send_standard_response (command_id , response_data )
601+ return
602+
603+ content = response_data ['content' ]
604+
605+ if response_data .get ('type' ) == 'binary' :
606+ content_size = len (content ) * 3 // 4
607+ else :
608+ content_size = len (content .encode ('utf-8' ))
609+
610+ chunk_threshold = 4 * 1024 * 1024
611+
612+ if content_size > chunk_threshold :
613+ print (f"File content size ({ content_size } bytes) exceeds threshold, chunking..." )
614+ self .send_chunked_file_response (command_id , response_data )
615+ else :
616+ print (f"File content size ({ content_size } bytes) within limit, sending normally" )
617+ self .send_standard_response (command_id , response_data )
618+
619+ def send_chunked_file_response (self , command_id , response_data ):
620+ import base64
621+
622+ content = response_data ['content' ]
623+ file_type = response_data .get ('type' , 'text' )
624+ status = response_data .get ('status' , 'File content retrieved' )
625+
626+ chunk_size = 3 * 1024 * 1024
627+
628+ if file_type == 'binary' :
629+ try :
630+ original_bytes = base64 .b64decode (content )
631+ total_size = len (original_bytes )
632+ chunks_needed = (total_size + chunk_size - 1 ) // chunk_size
633+
634+ print (f"Sending binary file in { chunks_needed } chunks..." )
635+
636+ self .sio .emit ('command_response' , {
637+ 'command_id' : command_id ,
638+ 'response' : {
639+ 'status' : status ,
640+ 'type' : file_type ,
641+ 'chunked' : True ,
642+ 'total_chunks' : chunks_needed ,
643+ 'total_size' : total_size ,
644+ 'chunk_index' : 0
645+ }
646+ })
647+ time .sleep (0.1 )
648+
649+ for i in range (chunks_needed ):
650+ start_pos = i * chunk_size
651+ end_pos = min (start_pos + chunk_size , total_size )
652+ chunk_bytes = original_bytes [start_pos :end_pos ]
653+ chunk_b64 = base64 .b64encode (chunk_bytes ).decode ('utf-8' )
654+
655+ self .sio .emit ('command_response_chunk' , {
656+ 'command_id' : command_id ,
657+ 'chunk_index' : i ,
658+ 'total_chunks' : chunks_needed ,
659+ 'content' : chunk_b64 ,
660+ 'is_final' : (i == chunks_needed - 1 )
661+ })
662+ print (f"Sent chunk { i + 1 } /{ chunks_needed } " )
663+ time .sleep (0.05 )
664+
665+ except Exception as e :
666+ print (f"Error chunking binary content: { e } " )
667+ self .send_standard_response (command_id , {'error' : 'Failed to chunk binary content' })
668+ else :
669+ content_bytes = content .encode ('utf-8' )
670+ total_size = len (content_bytes )
671+ chunks_needed = (total_size + chunk_size - 1 ) // chunk_size
672+
673+ print (f"Sending text file in { chunks_needed } chunks..." )
674+
675+ self .sio .emit ('command_response' , {
676+ 'command_id' : command_id ,
677+ 'response' : {
678+ 'status' : status ,
679+ 'type' : file_type ,
680+ 'chunked' : True ,
681+ 'total_chunks' : chunks_needed ,
682+ 'total_size' : total_size ,
683+ 'chunk_index' : 0
684+ }
685+ })
686+ time .sleep (0.1 )
687+
688+ for i in range (chunks_needed ):
689+ start_pos = i * chunk_size
690+ end_pos = min (start_pos + chunk_size , total_size )
691+ chunk_bytes = content_bytes [start_pos :end_pos ]
692+ chunk_text = chunk_bytes .decode ('utf-8' , errors = 'ignore' )
693+
694+ self .sio .emit ('command_response_chunk' , {
695+ 'command_id' : command_id ,
696+ 'chunk_index' : i ,
697+ 'total_chunks' : chunks_needed ,
698+ 'content' : chunk_text ,
699+ 'is_final' : (i == chunks_needed - 1 )
700+ })
701+ print (f"Sent chunk { i + 1 } /{ chunks_needed } " )
702+ time .sleep (0.05 )
588703
589704def main ():
590705 try :
0 commit comments