int TransmitFileToSocket( int clientsock, char * verified_filename, unsigned long start_at_byte, // Optionally start with an offset ( resume download functionality ) unsigned long end_at_byte // Optionally end at an offset ( resume download functionality ) ) { FILE * pFile = fopen (verified_filename, "rb" ); if (pFile==0) { fprintf(stderr,"Could not open file %s , files open %u \n",verified_filename,files_open); return 0;} ++files_open; // obtain file size: if ( fseek (pFile , 0 , SEEK_END)!=0 ) { warning("Could not find file size..!\nUnable to serve client\n"); fclose(pFile); --files_open; return 0; } unsigned long lSize = ftell (pFile); if ( (end_at_byte!=0) && (lSize<end_at_byte) ) { fprintf(stderr,"TODO: Handle incorrect range request ( from %u to %u file 0 to %u ..!\n",(unsigned int) start_at_byte,(unsigned int) end_at_byte,(unsigned int) lSize); } fprintf(stderr,"Sending file %s , size %0.2f Kbytes , Open files %u \n",verified_filename,(double) lSize/1024,files_open); char reply_header[MAX_HTTP_REQUEST_SHORT_HEADER_REPLY]={0}; //THIS ALSO EXISTS IN THE Cached resource response CODE around line 395 if ( (start_at_byte!=0) || (end_at_byte!=0) ) { //error(" TransmitFileToSocket Content-Range response"); //Content-Range: bytes 1000-3979/3980 int endAtBytePrinted = end_at_byte; if (endAtBytePrinted == 0 ) { endAtBytePrinted = lSize; } snprintf(reply_header,MAX_HTTP_REQUEST_SHORT_HEADER_REPLY,"Content-Range: bytes %lu-%u/%lu\nContent-length: %lu\n\n",start_at_byte,endAtBytePrinted,lSize,lSize-start_at_byte); } else { //error("TransmitFileToSocket Plain Content-Length "); //This is the last header part , so we are appending an extra \n to mark the end of the header snprintf(reply_header,MAX_HTTP_REQUEST_SHORT_HEADER_REPLY,"Content-length: %u\n\n",(unsigned int) lSize); } if (!SendPart(clientsock,reply_header,strlen(reply_header))) { fprintf(stderr,"Failed sending Content-length @ SendFile ..!\n"); } rewind (pFile); if (start_at_byte!=0) { fseek (pFile , start_at_byte , SEEK_SET); } if (end_at_byte==0) { end_at_byte=lSize-start_at_byte; } int res = TransmitFileToSocketInternal(pFile,clientsock,end_at_byte); --files_open; fclose (pFile); return res; }
int TransmitFileToSocket( struct AmmServer_Instance * instance, int clientsock, const char * verified_filename, unsigned long start_at_byte, // Optionally start with an offset ( resume download functionality ) unsigned long end_at_byte // Optionally end at an offset ( resume download functionality ) ) { int res = 0; FILE * pFile = fopen (verified_filename, "rb" ); //If we can't open the file we fail to transmit the file if (pFile==0) { fprintf(stderr,"Could not open file %s , files open %lu \n",verified_filename,instance->statistics.filesCurrentlyOpen); return 0; } else { //Count the open file ++instance->statistics.filesCurrentlyOpen; //Try to obtain file size if not fail to transmit the fail if ( fseek (pFile , 0 , SEEK_END)!=0 ) { warning("Could not find file size..!\nUnable to serve client\n"); fclose(pFile); if (instance->statistics.filesCurrentlyOpen>0) { --instance->statistics.filesCurrentlyOpen; } //Count the closed file return 0; } unsigned long lSize = ftell (pFile); //------------------------------------------------------- if ( (end_at_byte!=0) && (lSize<end_at_byte) ) { fprintf(stderr,"Incorrect range request , the file changed? ( from %u to %u file 0 to %u ..! ) ,forcing known size\n",(unsigned int) start_at_byte,(unsigned int) end_at_byte,(unsigned int) lSize); end_at_byte=lSize; } fprintf(stderr,"Sending => Size %0.2f KB / Open files %lu / Filename %s \n",(double) lSize/1024,instance->statistics.filesCurrentlyOpen,verified_filename); if ( TransmitFileHeaderToSocket( instance, clientsock, start_at_byte, // Optionally start with an offset ( resume download functionality ) end_at_byte, // Optionally end at an offset ( resume download functionality ) lSize ) ) { rewind (pFile); if (start_at_byte!=0) { fseek (pFile , start_at_byte , SEEK_SET); } if (end_at_byte==0) { end_at_byte=lSize-start_at_byte; } res = TransmitFileToSocketInternal(instance,pFile,clientsock,end_at_byte); } fclose (pFile); if (instance->statistics.filesCurrentlyOpen>0) { --instance->statistics.filesCurrentlyOpen; } //Count the closed file } return res; }