// Check if file exists in Save Dir. If not, copies it from Data dir. bool CopyFileIfMissing(const std::string& filename, const std::string& srcDir, const std::string& destDir) { bool doCopy = true; std::string dest = destDir + "/" + filename; if (FileExists(dest)) { //std::cout << "File already exists: " << dest << "\n"; Time destTime = GetFileModifiedTime(dest); std::string src = srcDir + "/" + filename; Time srcTime = GetFileModifiedTime(src); if (!(destTime < srcTime)) { doCopy = false; } } if (doCopy) { #ifdef FILECOPY_DEBUG std::cout << "Copying file " << filename << " as dest is older than src, or doesn't exist.\n"; #endif if (FileCopy(srcDir, destDir, filename)) { #ifdef FILECOPY_DEBUG std::cout << "..FileCopy was OK!\n"; #endif } else { // Always show for diagnosing crashes etc std::cout << "FileCopy FAILED: srcDir: " << srcDir << " destDir: " << destDir << " file: " << filename << "\n"; } } else { #ifdef FILECOPY_DEBUG2 std::cout << "No need to copy file " << filename << ", it's up to date.\n"; #endif } /* if (FileExists(dest)) { std::cout << "File already exists: " << s << "\n"; } else { std::cout << "Copying file " << filename << "\n"; if (FileCopy(srcDir, destDir, filename)) { std::cout << "..FileCopy was OK!\n"; } else { std::cout << "..FileCopy FAILED!\n"; } } */ return true; }
/*************************************************** OnConnect This member is called when a connection is made and accepted. Do all processing here, since the connection is automatically terminated when this function returns. Plus the thread that this function runs in is terminated as well. This function is the main engine that process all clients commands. PARAM NONE RETURN VOID ****************************************************/ void CUT_HTTPThread::OnConnect(){ char command[30]; int success = TRUE; // Clear the data variables m_szFileName[0] = 0; m_szBuf[0] = 0; m_szData[0] = 0; // Get the current tick count long tickCount = GetTickCount(); // Get the first line int len = ReceiveLine(m_szData, WSS_BUFFER_SIZE*2); // Break on error or disconnect if(len <= 0) return; // Remove the CRLF pair from the string CUT_StrMethods::RemoveCRLF(m_szData); // Parse the line if(CUT_StrMethods::ParseString(m_szData," ",0,command,30) != UTE_SUCCESS) { // Command not reconized Send("Command Not Reconized\r\n"); return; } // Get the command ID int commandID = GetCommandID(command); if(commandID == CUT_NA) { Send("Command Not Reconized\r\n"); return; } //********************************** // Check for GET //********************************** if(commandID == CUT_GET || commandID == CUT_HEAD ){ // Get the filename if(CUT_StrMethods::ParseString(m_szData," ?",1,m_szBuf, WSS_BUFFER_SIZE) != UTE_SUCCESS) { // Command not reconized Send("Command Not Reconized\r\n"); return; } // Get the absolute path if(MakePath(m_szFileName,m_szBuf) != UTE_SUCCESS) { Send("HTTP/1.0 404 Requested file not found\r\n"); return; } // Send a start notification if(OnNotify(CUT_START,commandID,m_szFileName,sizeof(m_szFileName),success) == FALSE) { // If FALSE is returned then do not continue ClearReceiveBuffer(); return; } // Open the file // v4.2 using CreateFileA here HANDLE hFile = CreateFileA(m_szFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); if(hFile == INVALID_HANDLE_VALUE) { Send("HTTP/1.0 404 Requested file not found\r\n"); success = FALSE; } else { // Send the MIME header Send("HTTP/1.0 200 OK\r\n"); _snprintf(m_szBuf,sizeof(m_szBuf)-1,"Date:%s\r\n",GetGMTStamp()); Send(m_szBuf); Send("Server: The Ultimate Toolbox WWW Server\r\n"); Send("MIME-verion: 1.0\r\n"); _snprintf(m_szBuf,sizeof(m_szBuf)-1,"Content-type: %s\r\n",GetContentType(m_szFileName)); Send(m_szBuf); _snprintf(m_szBuf,sizeof(m_szBuf)-1,"Last-modified: %s\r\n",GetFileModifiedTime(hFile)); Send(m_szBuf); DWORD hiVal; long OrigFileSize = GetFileSize(hFile,&hiVal); _snprintf(m_szBuf,sizeof(m_szBuf)-1,"Content-length: %ld\r\n",OrigFileSize); Send(m_szBuf); Send("\r\n"); // Send the file only for a GET if(commandID == CUT_GET) { // Get the max send size to send at once len = GetMaxSend(); if(len > WSS_BUFFER_SIZE*2) len = WSS_BUFFER_SIZE*2; // Send the file DWORD readLen; int rt; long totalLen = 0; // v4.2 change - was while(1) - gave conditional expression is constant warning for (;;) { rt = ReadFile(hFile,m_szData,len,&readLen,NULL); if(rt == FALSE || readLen ==0) break; if(Send(m_szData,readLen) == SOCKET_ERROR) break; totalLen+= readLen; } if(totalLen != OrigFileSize) success = FALSE; } CloseHandle(hFile); ClearReceiveBuffer(); } // Send a finish notification OnNotify(CUT_FINISH,commandID,m_szFileName,sizeof(m_szFileName),success); } //********************************** // Check for POST //********************************** else if(commandID == CUT_POST) { while(IsDataWaiting()) { len = ReceiveLine(m_szData, WSS_BUFFER_SIZE*2); CUT_StrMethods::RemoveCRLF(m_szData); ((CUT_HTTPServer *)m_winsockclass_this)->OnStatus(m_szData); } } //********************************** // Check for PUT //********************************** else if(commandID == CUT_PUT){ Send("HTTP/1.0 501 Not Implemented\r\n\r\n"); Send("Server: The Ultimate Toolbox WWW Server\r\n"); Send("MIME-verion: 1.0\r\n"); return; } //********************************** // Check for PLACE //********************************** else if(commandID == CUT_PLACE) { Send("HTTP/1.0 501 Not Implemented\r\n\r\n"); return; } //********************************** // Check for DELETE //********************************** else if(commandID == CUT_DELETE) { // Get the filename if(CUT_StrMethods::ParseString(m_szData," ",1,m_szBuf, WSS_BUFFER_SIZE) != UTE_SUCCESS) { // Command not reconized Send("HTTP/1.0 400 Bad Request\r\n\r\n"); return; } // Get the absolute path if(MakePath(m_szFileName,m_szBuf) != UTE_SUCCESS) { Send("HTTP/1.0 404 Requested file not found\r\n\r\n"); return; } // Send a start notification if(OnNotify(CUT_START,commandID,m_szFileName,sizeof(m_szFileName),success) == FALSE) { // If FALSE is returned then do not continue Send("HTTP/1.0 405 Method Not Allowed\r\n"); Send("Content-Type: text/html\r\n\r\n"); Send("<html><body>DELETE Method Not Allowed</body></html>"); ClearReceiveBuffer(); return; } // Send the finish notify // v4.2 using DeleteFileA here if(DeleteFileA(m_szFileName) == FALSE) { Send("HTTP/1.0 500 Internal Server Error\r\n"); success = FALSE; return ; } // Send a start notification OnNotify(CUT_FINISH,commandID,m_szFileName,sizeof(m_szFileName),success); } //********************************** // Allow handling for custom commands //********************************** else { // Get the rest of the data after the command char* pData = strstr(m_szData, " "); if (pData) strncpy(m_szBuf, pData+1, sizeof(m_szBuf)); if(OnNotify(CUT_START,commandID,m_szBuf,sizeof(m_szBuf),success) == FALSE) { // If FALSE is returned then do not continue ClearReceiveBuffer(); return; } OnCustomCommand(commandID,m_szBuf,WSS_BUFFER_SIZE); // Send a finish notification OnNotify(CUT_FINISH,commandID,m_szBuf,sizeof(m_szBuf),success); //Returns so the default OnSendStatus() implementation is not called. // If needed OnStatus() can be called in the OnNotify(CUT_FINISH)! return; } // Send a status line to the server history window OnSendStatus(commandID,m_szFileName,success,tickCount); }