Adaptation of the HttpServer by user yueee_yt. This version has improved handling of the HTTP headers (**NOTE**: There are limitations with this implementation and it is not fully functional. Use it only as a starting point.)

Dependents:   DMSupport DMSupport DMSupport DMSupport

Fork of DM_HttpServer by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers <title>FSHandler.cpp Source File</title>

FSHandler.cpp

00001 /*
00002 Permission is hereby granted, free of charge, to any person obtaining a copy
00003 of this software and associated documentation files (the "Software"), to deal
00004 in the Software without restriction, including without limitation the rights
00005 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00006 copies of the Software, and to permit persons to whom the Software is
00007 furnished to do so, subject to the following conditions:
00008 
00009 The above copyright notice and this permission notice shall be included in
00010 all copies or substantial portions of the Software.
00011 
00012 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00013 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00014 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00015 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00016 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00017 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00018 THE SOFTWARE.
00019 */
00020 //#define _DEBUG_FS_HANDLER
00021 
00022 #include "FSHandler.h"
00023 #include "DMBoard.h"
00024 
00025 #define CHUNK_SIZE 128
00026 
00027 #define DEFAULT_PAGE "/index.htm"
00028 
00029 //*FSHandler::FSHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) : HTTPRequestHandler(rootPath, path, pTCPSocket), m_err404(false)
00030 FSHandler::FSHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocketConnection) : HTTPRequestHandler(rootPath, path, pTCPSocketConnection), m_err404(false)
00031 {}
00032 
00033 FSHandler::~FSHandler()
00034 {
00035 #ifdef _DEBUG_FS_HANDLER
00036    DMBoard::instance().logger()-> printf("\r\n+++FSHandler destroy\r\n");
00037 #endif
00038     if(m_fp){
00039 #ifdef _DEBUG_FS_HANDLER
00040     DMBoard::instance().logger()->printf("\r\n+++FSHandler fclose start\r\n");
00041 #endif
00042         fclose(m_fp);
00043 #ifdef _DEBUG_FS_HANDLER
00044     DMBoard::instance().logger()->printf("\r\n+++FSHandler fclose end\r\n");
00045 #endif
00046        
00047         }
00048 #ifdef _DEBUG_FS_HANDLER
00049     DMBoard::instance().logger()->printf("\r\nHandler destroyed\r\n");
00050 #endif
00051 }
00052 
00053 //static init
00054 map<string,string> FSHandler::m_lFsPath = map<string,string>();
00055 
00056 void FSHandler::mount(const string& fsPath, const string& rootPath)
00057 {
00058     m_lFsPath[rootPath]=fsPath;
00059 }
00060 
00061 void FSHandler::doGet()
00062 {
00063 #ifdef _DEBUG_FS_HANDLER
00064     DMBoard::instance().logger()->printf("\r\nIn FSHandler::doGet() - rootPath=%s, path=%s\r\n", rootPath().c_str(), path().c_str());
00065 #endif
00066     //FIXME: Translate path to local/path
00067     string checkedRootPath = rootPath();
00068     if(checkedRootPath.empty())
00069         checkedRootPath="/";
00070     string filePath = m_lFsPath[checkedRootPath];
00071     if (path().size() > 1) {
00072         filePath += path();
00073     } else {
00074         filePath += DEFAULT_PAGE;
00075     }
00076 #ifdef _DEBUG_FS_HANDLER
00077     DMBoard::instance().logger()->printf("Trying to open %s\n", filePath.c_str());
00078 #endif
00079     m_fp = fopen(filePath.c_str(), "r"); //FIXME: if null, error 404
00080 
00081     if(!m_fp) {
00082         m_err404 = true;
00083         setErrCode(404);
00084         const char* msg = "File not found.";
00085         setContentLen(strlen(msg));
00086         respHeaders()["Content-Type"] = "text/html";
00087         respHeaders()["Connection"] = "close";
00088         writeData(msg,strlen(msg)); //Only send header
00089         DMBoard::instance().logger()->printf("\r\nExit FSHandler::doGet() w Error 404\r\n");
00090         return;
00091     }
00092 
00093     //Seek EOF to get length
00094     fseek(m_fp, 0, SEEK_END);
00095     setContentLen( ftell(m_fp) );
00096     fseek(m_fp, 0, SEEK_SET); //Goto SOF
00097 
00098     respHeaders()["Connection"] = "close";
00099     onWriteable();
00100 #ifdef _DEBUG_FS_HANDLER
00101     DMBoard::instance().logger()->printf("\r\nExit FSHandler::doGet()\r\n");
00102 #endif
00103 }
00104 
00105 void FSHandler::doPost()
00106 {
00107 
00108 }
00109 
00110 void FSHandler::doHead()
00111 {
00112 
00113 }
00114 
00115 void FSHandler::onReadable() //Data has been read
00116 {
00117 
00118 }
00119 
00120 void FSHandler::onWriteable() //Data has been written & buf is free
00121 {
00122 #ifdef _DEBUG_FS_HANDLER
00123     DMBoard::instance().logger()->printf("\r\nFSHandler::onWriteable() event\r\n");
00124 #endif
00125     if(m_err404) {
00126         //Error has been served, now exit
00127         close();
00128         return;
00129     }
00130 
00131     static char rBuf[CHUNK_SIZE];
00132     while(true) {
00133         int len = fread(rBuf, 1, CHUNK_SIZE, m_fp);
00134         if(len>0) {
00135             int writtenLen = writeData(rBuf, len);
00136             if(writtenLen < 0) { //Socket error
00137 #ifdef _DEBUG_FS_HANDLER
00138                 DMBoard::instance().logger()->printf("FSHandler: Socket error %d\n", writtenLen);
00139 #endif
00140                 /**  Not Work
00141                                 if(writtenLen == TCPSOCKET_MEM) {
00142                                     fseek(m_fp, -len, SEEK_CUR);
00143                                     return; //Wait for the queued TCP segments to be transmitted
00144                                 } else {
00145                                     //This is a critical error
00146                                     **/
00147                                     close();
00148                                     return;
00149                                     /**
00150                                 }
00151                 **/
00152             } else if(writtenLen < len) { //Short write, socket's buffer is full
00153                 fseek(m_fp, writtenLen - len, SEEK_CUR);
00154                 return;
00155             }
00156         } else {
00157             close(); //Data written, we can close the connection
00158             return;
00159         }
00160     }
00161 }
00162 
00163 void FSHandler::onClose() //Connection is closing
00164 {
00165     DMBoard::instance().logger()->printf("FSHandler: onClose() event\r\n");
00166     /**
00167 #ifdef _DEBUG_FS_HANDLER
00168         printf("FSHandler: onClose start \r\n");
00169 #endif
00170     if(m_fp){
00171 #ifdef _DEBUG_FS_HANDLER
00172         printf("FSHandler: fclose start \r\n");
00173 #endif
00174     fclose(m_fp);
00175 #ifdef _DEBUG_FS_HANDLER
00176     printf("FSHandler: fclose end \r\n");
00177 #endif
00178 }
00179 #ifdef _DEBUG_FS_HANDLER
00180         printf("FSHandler: onClose end \r\n");
00181 #endif
00182 **/
00183 }