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