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

Committer:
embeddedartists
Date:
Tue Dec 02 15:04:43 2014 +0000
Revision:
6:7b3320c34654
Parent:
5:b8f6a11c70db
Child:
7:ee7af5de4b95
Fixed stack sizes so that FSHandler works. Changed printfs to RtosLog. Changed sprintf to snprintf to prevent overwrite.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yueee_yt 0:fdf9c2c5200f 1 /*
yueee_yt 0:fdf9c2c5200f 2 Permission is hereby granted, free of charge, to any person obtaining a copy
yueee_yt 0:fdf9c2c5200f 3 of this software and associated documentation files (the "Software"), to deal
yueee_yt 0:fdf9c2c5200f 4 in the Software without restriction, including without limitation the rights
yueee_yt 0:fdf9c2c5200f 5 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
yueee_yt 0:fdf9c2c5200f 6 copies of the Software, and to permit persons to whom the Software is
yueee_yt 0:fdf9c2c5200f 7 furnished to do so, subject to the following conditions:
yueee_yt 4:1b6b021ee21d 8
yueee_yt 0:fdf9c2c5200f 9 The above copyright notice and this permission notice shall be included in
yueee_yt 0:fdf9c2c5200f 10 all copies or substantial portions of the Software.
yueee_yt 4:1b6b021ee21d 11
yueee_yt 0:fdf9c2c5200f 12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
yueee_yt 0:fdf9c2c5200f 13 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
yueee_yt 0:fdf9c2c5200f 14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
yueee_yt 0:fdf9c2c5200f 15 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
yueee_yt 0:fdf9c2c5200f 16 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
yueee_yt 0:fdf9c2c5200f 17 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
yueee_yt 0:fdf9c2c5200f 18 THE SOFTWARE.
yueee_yt 0:fdf9c2c5200f 19 */
yueee_yt 5:b8f6a11c70db 20 //#define _DEBUG_FS_HANDLER
yueee_yt 0:fdf9c2c5200f 21
yueee_yt 0:fdf9c2c5200f 22 #include "FSHandler.h"
embeddedartists 6:7b3320c34654 23 #include "DMBoard.h"
yueee_yt 0:fdf9c2c5200f 24
yueee_yt 0:fdf9c2c5200f 25 #define CHUNK_SIZE 128
yueee_yt 0:fdf9c2c5200f 26
yueee_yt 0:fdf9c2c5200f 27 #define DEFAULT_PAGE "/index.htm"
yueee_yt 0:fdf9c2c5200f 28
yueee_yt 0:fdf9c2c5200f 29 //*FSHandler::FSHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) : HTTPRequestHandler(rootPath, path, pTCPSocket), m_err404(false)
yueee_yt 0:fdf9c2c5200f 30 FSHandler::FSHandler(const char* rootPath, const char* path, TCPSocketConnection* pTCPSocketConnection) : HTTPRequestHandler(rootPath, path, pTCPSocketConnection), m_err404(false)
yueee_yt 0:fdf9c2c5200f 31 {}
yueee_yt 0:fdf9c2c5200f 32
yueee_yt 0:fdf9c2c5200f 33 FSHandler::~FSHandler()
yueee_yt 0:fdf9c2c5200f 34 {
yueee_yt 5:b8f6a11c70db 35 #ifdef _DEBUG_FS_HANDLER
embeddedartists 6:7b3320c34654 36 DMBoard::instance().logger()-> printf("\r\n+++FSHandler destroy\r\n");
yueee_yt 5:b8f6a11c70db 37 #endif
yueee_yt 5:b8f6a11c70db 38 if(m_fp){
yueee_yt 5:b8f6a11c70db 39 #ifdef _DEBUG_FS_HANDLER
embeddedartists 6:7b3320c34654 40 DMBoard::instance().logger()->printf("\r\n+++FSHandler fclose start\r\n");
yueee_yt 5:b8f6a11c70db 41 #endif
yueee_yt 4:1b6b021ee21d 42 fclose(m_fp);
yueee_yt 4:1b6b021ee21d 43 #ifdef _DEBUG_FS_HANDLER
embeddedartists 6:7b3320c34654 44 DMBoard::instance().logger()->printf("\r\n+++FSHandler fclose end\r\n");
yueee_yt 5:b8f6a11c70db 45 #endif
yueee_yt 5:b8f6a11c70db 46
yueee_yt 5:b8f6a11c70db 47 }
yueee_yt 5:b8f6a11c70db 48 #ifdef _DEBUG_FS_HANDLER
embeddedartists 6:7b3320c34654 49 DMBoard::instance().logger()->printf("\r\nHandler destroyed\r\n");
yueee_yt 4:1b6b021ee21d 50 #endif
yueee_yt 0:fdf9c2c5200f 51 }
yueee_yt 0:fdf9c2c5200f 52
yueee_yt 0:fdf9c2c5200f 53 //static init
yueee_yt 0:fdf9c2c5200f 54 map<string,string> FSHandler::m_lFsPath = map<string,string>();
yueee_yt 0:fdf9c2c5200f 55
yueee_yt 0:fdf9c2c5200f 56 void FSHandler::mount(const string& fsPath, const string& rootPath)
yueee_yt 0:fdf9c2c5200f 57 {
yueee_yt 4:1b6b021ee21d 58 m_lFsPath[rootPath]=fsPath;
yueee_yt 0:fdf9c2c5200f 59 }
yueee_yt 0:fdf9c2c5200f 60
yueee_yt 0:fdf9c2c5200f 61 void FSHandler::doGet()
yueee_yt 0:fdf9c2c5200f 62 {
yueee_yt 4:1b6b021ee21d 63 #ifdef _DEBUG_FS_HANDLER
embeddedartists 6:7b3320c34654 64 DMBoard::instance().logger()->printf("\r\nIn FSHandler::doGet() - rootPath=%s, path=%s\r\n", rootPath().c_str(), path().c_str());
yueee_yt 4:1b6b021ee21d 65 #endif
yueee_yt 4:1b6b021ee21d 66 //FIXME: Translate path to local/path
yueee_yt 4:1b6b021ee21d 67 string checkedRootPath = rootPath();
yueee_yt 4:1b6b021ee21d 68 if(checkedRootPath.empty())
yueee_yt 4:1b6b021ee21d 69 checkedRootPath="/";
yueee_yt 4:1b6b021ee21d 70 string filePath = m_lFsPath[checkedRootPath];
yueee_yt 4:1b6b021ee21d 71 if (path().size() > 1) {
yueee_yt 4:1b6b021ee21d 72 filePath += path();
yueee_yt 4:1b6b021ee21d 73 } else {
yueee_yt 4:1b6b021ee21d 74 filePath += DEFAULT_PAGE;
yueee_yt 4:1b6b021ee21d 75 }
yueee_yt 4:1b6b021ee21d 76 #ifdef _DEBUG_FS_HANDLER
embeddedartists 6:7b3320c34654 77 DMBoard::instance().logger()->printf("Trying to open %s\n", filePath.c_str());
yueee_yt 4:1b6b021ee21d 78 #endif
yueee_yt 4:1b6b021ee21d 79 m_fp = fopen(filePath.c_str(), "r"); //FIXME: if null, error 404
yueee_yt 0:fdf9c2c5200f 80
yueee_yt 4:1b6b021ee21d 81 if(!m_fp) {
yueee_yt 4:1b6b021ee21d 82 m_err404 = true;
yueee_yt 4:1b6b021ee21d 83 setErrCode(404);
yueee_yt 4:1b6b021ee21d 84 const char* msg = "File not found.";
yueee_yt 4:1b6b021ee21d 85 setContentLen(strlen(msg));
yueee_yt 4:1b6b021ee21d 86 respHeaders()["Content-Type"] = "text/html";
yueee_yt 4:1b6b021ee21d 87 respHeaders()["Connection"] = "close";
yueee_yt 4:1b6b021ee21d 88 writeData(msg,strlen(msg)); //Only send header
embeddedartists 6:7b3320c34654 89 DMBoard::instance().logger()->printf("\r\nExit FSHandler::doGet() w Error 404\r\n");
yueee_yt 4:1b6b021ee21d 90 return;
yueee_yt 4:1b6b021ee21d 91 }
yueee_yt 4:1b6b021ee21d 92
yueee_yt 4:1b6b021ee21d 93 //Seek EOF to get length
yueee_yt 4:1b6b021ee21d 94 fseek(m_fp, 0, SEEK_END);
yueee_yt 4:1b6b021ee21d 95 setContentLen( ftell(m_fp) );
yueee_yt 4:1b6b021ee21d 96 fseek(m_fp, 0, SEEK_SET); //Goto SOF
yueee_yt 4:1b6b021ee21d 97
yueee_yt 0:fdf9c2c5200f 98 respHeaders()["Connection"] = "close";
yueee_yt 4:1b6b021ee21d 99 onWriteable();
yueee_yt 4:1b6b021ee21d 100 #ifdef _DEBUG_FS_HANDLER
embeddedartists 6:7b3320c34654 101 DMBoard::instance().logger()->printf("\r\nExit SimpleHandler::doGet()\r\n");
yueee_yt 4:1b6b021ee21d 102 #endif
yueee_yt 0:fdf9c2c5200f 103 }
yueee_yt 0:fdf9c2c5200f 104
yueee_yt 0:fdf9c2c5200f 105 void FSHandler::doPost()
yueee_yt 0:fdf9c2c5200f 106 {
yueee_yt 0:fdf9c2c5200f 107
yueee_yt 0:fdf9c2c5200f 108 }
yueee_yt 0:fdf9c2c5200f 109
yueee_yt 0:fdf9c2c5200f 110 void FSHandler::doHead()
yueee_yt 0:fdf9c2c5200f 111 {
yueee_yt 0:fdf9c2c5200f 112
yueee_yt 0:fdf9c2c5200f 113 }
yueee_yt 0:fdf9c2c5200f 114
yueee_yt 0:fdf9c2c5200f 115 void FSHandler::onReadable() //Data has been read
yueee_yt 0:fdf9c2c5200f 116 {
yueee_yt 0:fdf9c2c5200f 117
yueee_yt 0:fdf9c2c5200f 118 }
yueee_yt 0:fdf9c2c5200f 119
yueee_yt 0:fdf9c2c5200f 120 void FSHandler::onWriteable() //Data has been written & buf is free
yueee_yt 0:fdf9c2c5200f 121 {
yueee_yt 4:1b6b021ee21d 122 #ifdef _DEBUG_FS_HANDLER
embeddedartists 6:7b3320c34654 123 DMBoard::instance().logger()->printf("\r\nFSHandler::onWriteable() event\r\n");
yueee_yt 4:1b6b021ee21d 124 #endif
yueee_yt 4:1b6b021ee21d 125 if(m_err404) {
yueee_yt 4:1b6b021ee21d 126 //Error has been served, now exit
yueee_yt 4:1b6b021ee21d 127 close();
yueee_yt 4:1b6b021ee21d 128 return;
yueee_yt 4:1b6b021ee21d 129 }
yueee_yt 4:1b6b021ee21d 130
yueee_yt 4:1b6b021ee21d 131 static char rBuf[CHUNK_SIZE];
yueee_yt 4:1b6b021ee21d 132 while(true) {
yueee_yt 4:1b6b021ee21d 133 int len = fread(rBuf, 1, CHUNK_SIZE, m_fp);
yueee_yt 4:1b6b021ee21d 134 if(len>0) {
yueee_yt 4:1b6b021ee21d 135 int writtenLen = writeData(rBuf, len);
yueee_yt 4:1b6b021ee21d 136 if(writtenLen < 0) { //Socket error
yueee_yt 4:1b6b021ee21d 137 #ifdef _DEBUG_FS_HANDLER
embeddedartists 6:7b3320c34654 138 DMBoard::instance().logger()->printf("FSHandler: Socket error %d\n", writtenLen);
yueee_yt 4:1b6b021ee21d 139 #endif
yueee_yt 5:b8f6a11c70db 140 /** Not Work
yueee_yt 5:b8f6a11c70db 141 if(writtenLen == TCPSOCKET_MEM) {
yueee_yt 5:b8f6a11c70db 142 fseek(m_fp, -len, SEEK_CUR);
yueee_yt 5:b8f6a11c70db 143 return; //Wait for the queued TCP segments to be transmitted
yueee_yt 5:b8f6a11c70db 144 } else {
yueee_yt 5:b8f6a11c70db 145 //This is a critical error
yueee_yt 5:b8f6a11c70db 146 **/
yueee_yt 5:b8f6a11c70db 147 close();
yueee_yt 5:b8f6a11c70db 148 return;
yueee_yt 5:b8f6a11c70db 149 /**
yueee_yt 5:b8f6a11c70db 150 }
yueee_yt 5:b8f6a11c70db 151 **/
yueee_yt 4:1b6b021ee21d 152 } else if(writtenLen < len) { //Short write, socket's buffer is full
yueee_yt 4:1b6b021ee21d 153 fseek(m_fp, writtenLen - len, SEEK_CUR);
yueee_yt 4:1b6b021ee21d 154 return;
yueee_yt 4:1b6b021ee21d 155 }
yueee_yt 4:1b6b021ee21d 156 } else {
yueee_yt 4:1b6b021ee21d 157 close(); //Data written, we can close the connection
yueee_yt 4:1b6b021ee21d 158 return;
yueee_yt 0:fdf9c2c5200f 159 }
yueee_yt 0:fdf9c2c5200f 160 }
yueee_yt 0:fdf9c2c5200f 161 }
yueee_yt 0:fdf9c2c5200f 162
yueee_yt 0:fdf9c2c5200f 163 void FSHandler::onClose() //Connection is closing
yueee_yt 0:fdf9c2c5200f 164 {
embeddedartists 6:7b3320c34654 165 DMBoard::instance().logger()->printf("FSHandler: onClose() event\r\n");
yueee_yt 5:b8f6a11c70db 166 /**
yueee_yt 5:b8f6a11c70db 167 #ifdef _DEBUG_FS_HANDLER
yueee_yt 5:b8f6a11c70db 168 printf("FSHandler: onClose start \r\n");
yueee_yt 5:b8f6a11c70db 169 #endif
yueee_yt 5:b8f6a11c70db 170 if(m_fp){
yueee_yt 5:b8f6a11c70db 171 #ifdef _DEBUG_FS_HANDLER
yueee_yt 5:b8f6a11c70db 172 printf("FSHandler: fclose start \r\n");
yueee_yt 5:b8f6a11c70db 173 #endif
yueee_yt 5:b8f6a11c70db 174 fclose(m_fp);
yueee_yt 5:b8f6a11c70db 175 #ifdef _DEBUG_FS_HANDLER
yueee_yt 5:b8f6a11c70db 176 printf("FSHandler: fclose end \r\n");
yueee_yt 5:b8f6a11c70db 177 #endif
yueee_yt 0:fdf9c2c5200f 178 }
yueee_yt 5:b8f6a11c70db 179 #ifdef _DEBUG_FS_HANDLER
yueee_yt 5:b8f6a11c70db 180 printf("FSHandler: onClose end \r\n");
yueee_yt 5:b8f6a11c70db 181 #endif
yueee_yt 5:b8f6a11c70db 182 **/
yueee_yt 5:b8f6a11c70db 183 }