/* * Modification History * * 2003-September-5 Jason Rohrer * Created. * * 2003-September-7 Jason Rohrer * Fixed bugs in path parsing and directory list generation. * Fixed memory leaks. * * 2003-September-25 Jason Rohrer * Changed to handle unknown contacts properly. * Added default page with contact list. */ #include "FileTransferPageGenerator.h" #include "MUTE/layers/fileTransfer/fileTransmitter.h" #include "MUTE/layers/pointToPoint/pointToPointCommunicator.h" #include "minorGems/util/log/AppLog.h" #include "minorGems/util/stringUtils.h" #include "minorGems/util/StringBufferOutputStream.h" #include "minorGems/network/web/URLUtils.h" #include "minorGems/formats/html/HTMLUtils.h" #include #include #include FileTransferPageGenerator::FileTransferPageGenerator() { } FileTransferPageGenerator::~FileTransferPageGenerator() { } char FileTransferPageGenerator::extractContactAndFilePath( char *inGetRequestPath, char **outContactName, char **outFilePath ) { char returnValue = false; int numParts; char **pathParts = split( inGetRequestPath, "/", &numParts ); if( numParts >= 2 ) { *outContactName = stringDuplicate( pathParts[1] ); if( numParts >= 3 ) { // join remaining parts char **partsToJoin = &( pathParts[2] ); char *filePath = join( partsToJoin, numParts - 2, "/" ); if( strlen( filePath ) == 0 ) { // empty path is root delete [] filePath; filePath = stringDuplicate( "/" ); } *outFilePath = filePath; } else { // no path, just user name, so use root path *outFilePath = stringDuplicate( "/" ); } returnValue = true; } for( int i=0; iwrite( inChunk, inChunkLengthInBytes ); } void FileTransferPageGenerator::generatePage( char *inGetRequestPath, OutputStream *inOutputStream ) { if( strcmp( inGetRequestPath, "/" ) == 0 ) { // a request for the root path // display the default page (contact list) int numContacts; char **contacts = muteGetContactList( &numContacts ); inOutputStream->writeString( "" "MUTE Web Interface" "" "

Known Contacts:

" ); for( int i=0; i%s
\n", contacts[i], contacts[i] ); inOutputStream->writeString( contactLink ); delete [] contactLink; delete [] contacts[i]; } delete [] contacts; inOutputStream->writeString( "" ); return; } char *contactName; char *filePath; char partsFound = extractContactAndFilePath( inGetRequestPath, &contactName, &filePath ); if( !partsFound ) { inOutputStream->writeString( "Badly formatted URL: " ); inOutputStream->writeString( inGetRequestPath ); return; } char isDirectory; int length; int chunkCount; char *mimeType; int status = muteGetFileInfo( contactName, filePath, &isDirectory, &length, &chunkCount, &mimeType ); if( status == MUTE_FILE_CONTACT_NOT_REACHABLE ) { inOutputStream->writeString( "Could not reach contact: " ); inOutputStream->writeString( contactName ); delete [] mimeType; delete [] filePath; delete [] contactName; return; } else if( status == MUTE_FILE_NOT_FOUND ) { inOutputStream->writeString( "File not found: " ); inOutputStream->writeString( filePath ); delete [] mimeType; delete [] filePath; delete [] contactName; return; } else if( status == MUTE_FILE_CONTACT_UNKNOWN ) { inOutputStream->writeString( "Contact name unknown: " ); inOutputStream->writeString( contactName ); delete [] mimeType; delete [] filePath; delete [] contactName; return; } // else file found // ignore mime type delete [] mimeType; if( isDirectory ) { char *absoluteDirPath; if( inGetRequestPath[ strlen( inGetRequestPath ) - 1 ] != '/' ) { // path does not end with / // fix it absoluteDirPath = autoSprintf( "%s/", inGetRequestPath ); } else { absoluteDirPath = stringDuplicate( inGetRequestPath ); } int numEntries; char **dirList = muteGetDirectoryListing( contactName, filePath, &numEntries ); if( dirList == NULL ) { inOutputStream->writeString( "Failed to fetch file list from contact." ); } else { // generate HTML for the directory list char *pageHeadHTML = autoSprintf( "" "File List For %s : %s" "" "

Contact: %s
Folder: %s

", contactName, filePath, contactName, filePath ); inOutputStream->writeString( pageHeadHTML ); delete [] pageHeadHTML; for( int i=0; i%s
", absoluteDirPath, dirList[i], dirList[i] ); inOutputStream->writeString( entryHTML ); delete [] entryHTML; delete [] dirList[i]; } inOutputStream->writeString( "" ); delete [] dirList; } delete [] absoluteDirPath; } else { // fetch and send data file char fetched = muteGetFile( contactName, filePath, fileTransferPageGenerator_internalFileHandler, (void *)inOutputStream ); if( !fetched ) { inOutputStream->writeString( "Failed to fetch file from contact." ); } } delete [] contactName; delete [] filePath; } char *FileTransferPageGenerator::getMimeType( char *inGetRequestPath ) { char *contactName; char *filePath; char partsFound = extractContactAndFilePath( inGetRequestPath, &contactName, &filePath ); if( !partsFound ) { return stringDuplicate( "text/html" ); } char isDirectory; int length; int chunkCount; char *mimeType; int status = muteGetFileInfo( contactName, filePath, &isDirectory, &length, &chunkCount, &mimeType ); delete [] filePath; delete [] contactName; if( status == MUTE_FILE_CONTACT_NOT_REACHABLE ) { delete [] mimeType; return stringDuplicate( "text/html" ); } else if( status == MUTE_FILE_NOT_FOUND ) { delete [] mimeType; return stringDuplicate( "text/html" ); } else if( status == MUTE_FILE_CONTACT_UNKNOWN ) { delete [] mimeType; return stringDuplicate( "text/html" ); } // else found return mimeType; }