HttpServer Library for "mbed classic" which added a snapshot handler.

Dependents:   GR-PEACH_WebCamera_OV5642_fixedIP GR-PEACH_WebCamera_AP

Fork of HttpServer by Yasushi TAUCHI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FSHandler.cpp Source File

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 
00024 #define CHUNK_SIZE 128
00025 
00026 #define DEFAULT_PAGE "/index.htm"
00027 
00028 Semaphore FSHandler::req_sem(1);
00029 
00030 
00031 //*FSHandler::FSHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) : HTTPRequestHandler(rootPath, path, pTCPSocket), m_err404(false)
00032 FSHandler::FSHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) : HTTPRequestHandler(rootPath, path, pTCPSocketConnection), m_err404(false)
00033 {}
00034 
00035 FSHandler::~FSHandler()
00036 {
00037 #ifdef _DEBUG_FS_HANDLER
00038     printf("\r\n+++FSHandler destroy\r\n");
00039 #endif
00040     if(m_fp){
00041 #ifdef _DEBUG_FS_HANDLER
00042     printf("\r\n+++FSHandler fclose start\r\n");
00043 #endif
00044         fclose(m_fp);
00045 #ifdef _DEBUG_FS_HANDLER
00046     printf("\r\n+++FSHandler fclose end\r\n");
00047 #endif
00048        
00049         }
00050 #ifdef _DEBUG_FS_HANDLER
00051     printf("\r\nHandler destroyed\r\n");
00052 #endif
00053 }
00054 
00055 //static init
00056 map<string,string> FSHandler::m_lFsPath = map<string,string>();
00057 
00058 void FSHandler::mount(const string& fsPath, const string& rootPath)
00059 {
00060     m_lFsPath[rootPath]=fsPath;
00061 }
00062 
00063 void FSHandler::doGet()
00064 {
00065     req_sem.wait();
00066 #ifdef _DEBUG_FS_HANDLER
00067     printf("\r\nIn FSHandler::doGet() - rootPath=%s, path=%s\r\n", rootPath().c_str(), path().c_str());
00068 #endif
00069     //FIXME: Translate path to local/path
00070     string checkedRootPath = rootPath();
00071     if(checkedRootPath.empty())
00072         checkedRootPath="/";
00073     string filePath = m_lFsPath[checkedRootPath];
00074     if (path().size() > 1) {
00075         filePath += path();
00076     } else {
00077         filePath += DEFAULT_PAGE;
00078     }
00079 #ifdef _DEBUG_FS_HANDLER
00080     printf("Trying to open %s\n", filePath.c_str());
00081 #endif
00082     m_fp = fopen(filePath.c_str(), "r"); //FIXME: if null, error 404
00083 
00084     if(!m_fp) {
00085         m_err404 = true;
00086         setErrCode(404);
00087         const char* msg = "File not found.";
00088         setContentLen(strlen(msg));
00089         respHeaders()["Content-Type"] = "text/html";
00090         respHeaders()["Connection"] = "close";
00091         writeData(msg,strlen(msg)); //Only send header
00092         printf("\r\nExit FSHandler::doGet() w Error 404\r\n");
00093         req_sem.release();
00094         return;
00095     }
00096 
00097     //Seek EOF to get length
00098     fseek(m_fp, 0, SEEK_END);
00099     setContentLen( ftell(m_fp) );
00100     fseek(m_fp, 0, SEEK_SET); //Goto SOF
00101 
00102     respHeaders()["Connection"] = "close";
00103     onWriteable();
00104 #ifdef _DEBUG_FS_HANDLER
00105     printf("\r\nExit SimpleHandler::doGet()\r\n");
00106 #endif
00107     req_sem.release();
00108 }
00109 
00110 void FSHandler::doPost()
00111 {
00112 
00113 }
00114 
00115 void FSHandler::doHead()
00116 {
00117 
00118 }
00119 
00120 void FSHandler::onReadable() //Data has been read
00121 {
00122 
00123 }
00124 
00125 void FSHandler::onWriteable() //Data has been written & buf is free
00126 {
00127 #ifdef _DEBUG_FS_HANDLER
00128     printf("\r\nFSHandler::onWriteable() event\r\n");
00129 #endif
00130     if(m_err404) {
00131         //Error has been served, now exit
00132         close();
00133         return;
00134     }
00135 
00136     static char rBuf[CHUNK_SIZE];
00137     while(true) {
00138         int len = fread(rBuf, 1, CHUNK_SIZE, m_fp);
00139         if(len>0) {
00140             int writtenLen = writeData(rBuf, len);
00141             if(writtenLen < 0) { //Socket error
00142 #ifdef _DEBUG_FS_HANDLER
00143                 printf("FSHandler: Socket error %d\n", writtenLen);
00144 #endif
00145                 /**  Not Work
00146                                 if(writtenLen == TCPSOCKET_MEM) {
00147                                     fseek(m_fp, -len, SEEK_CUR);
00148                                     return; //Wait for the queued TCP segments to be transmitted
00149                                 } else {
00150                                     //This is a critical error
00151                                     **/
00152                                     close();
00153                                     return;
00154                                     /**
00155                                 }
00156                 **/
00157             } else if(writtenLen < len) { //Short write, socket's buffer is full
00158                 fseek(m_fp, writtenLen - len, SEEK_CUR);
00159                 return;
00160             }
00161         } else {
00162             close(); //Data written, we can close the connection
00163             return;
00164         }
00165     }
00166 }
00167 
00168 void FSHandler::onClose() //Connection is closing
00169 {
00170     /**
00171 #ifdef _DEBUG_FS_HANDLER
00172         printf("FSHandler: onClose start \r\n");
00173 #endif
00174     if(m_fp){
00175 #ifdef _DEBUG_FS_HANDLER
00176         printf("FSHandler: fclose start \r\n");
00177 #endif
00178     fclose(m_fp);
00179 #ifdef _DEBUG_FS_HANDLER
00180     printf("FSHandler: fclose end \r\n");
00181 #endif
00182 }
00183 #ifdef _DEBUG_FS_HANDLER
00184         printf("FSHandler: onClose end \r\n");
00185 #endif
00186 **/
00187 }