HttpServer Library for "mbed-os" which added a snapshot handler.

Dependents:   GR-PEACH-webcam GR-Boards_WebCamera GR-Boards_WebCamera GR-Boards_WebCamera

Fork of HttpServer_snapshot by Renesas

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPRequestHandler.cpp Source File

HTTPRequestHandler.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 #ifdef _DEBUG_ALL
00021 #define _DEBUG_REQUEST_HANDLER
00022 #endif
00023 
00024 #include "HTTPRequestHandler.h"
00025 
00026 #include <string.h>
00027 
00028 #define HTTP_REQUEST_TIMEOUT 5000
00029 
00030 HTTPRequestHandler::HTTPRequestHandler(const char* rootPath, const char* path, TCPSocket* pTCPSocket) :
00031     m_pTCPSocket(pTCPSocket), m_reqHeaders(), m_respHeaders(),
00032     m_rootPath(rootPath), m_path(path), m_errc(200), m_closed(false), m_headersSent(false)
00033 {
00034 #ifdef _DEBUG_REQUEST_HANDLER
00035     printf("+++(HTTPRequestHandler) init \r\n");
00036 #endif
00037     //Read & parse headers
00038     readHeaders();
00039 #ifdef _DEBUG_REQUEST_HANDLER
00040     printf("+++(HTTPRequestHandler) init end \r\n");
00041 #endif
00042 }
00043 
00044 HTTPRequestHandler::~HTTPRequestHandler()
00045 {
00046     close();
00047 #ifdef _DEBUG_REQUEST_HANDLER
00048     printf("+++(HTTPRequestHandler) Destroy end\r\n");
00049 #endif
00050 }
00051 
00052 void HTTPRequestHandler::onTimeout() //Connection has timed out
00053 {
00054     close();
00055 }
00056 
00057 void HTTPRequestHandler::close() //Close socket and destroy data
00058 {
00059     if(m_closed)
00060         return;
00061     m_closed = true; //Prevent recursive calling or calling on an object being destructed by someone else
00062 }
00063 
00064 map<string, string>& HTTPRequestHandler::reqHeaders() //const
00065 {
00066     return m_reqHeaders;
00067 }
00068 
00069 string& HTTPRequestHandler::path() //const
00070 {
00071     return m_path;
00072 }
00073 
00074 int HTTPRequestHandler::dataLen() const
00075 {
00076     map<string,string>::const_iterator it;
00077     it = m_reqHeaders.find("Content-Length");
00078     if( it == m_reqHeaders.end() ) {
00079         return 0;
00080     }
00081     return atoi((*it).second.c_str()); //return 0 if parse fails, so that's fine
00082 }
00083 
00084 int HTTPRequestHandler::readData(char* buf, int len)
00085 {
00086     return m_pTCPSocket->recv(buf, len);
00087 }
00088 
00089 string& HTTPRequestHandler::rootPath() //const
00090 {
00091     return m_rootPath;
00092 }
00093 
00094 void HTTPRequestHandler::setErrCode(int errc)
00095 {
00096     m_errc = errc;
00097 }
00098 
00099 void HTTPRequestHandler::setContentLen(int len)
00100 {
00101     char len_str[6] = {0};
00102     sprintf(len_str, "%d", len);
00103     respHeaders()["Content-Length"] = len_str;
00104 }
00105 
00106 map<string, string>& HTTPRequestHandler::respHeaders()
00107 {
00108     return m_respHeaders;
00109 }
00110 
00111 int HTTPRequestHandler::writeData(const char* buf, int len)
00112 {
00113     if(!m_headersSent) {
00114         m_headersSent = true;
00115         writeHeaders();
00116     }
00117     return m_pTCPSocket->send((char *)buf, len);
00118 }
00119 
00120 void HTTPRequestHandler::readHeaders()
00121 {
00122     while( readLine(line, 128) > 0) { //if == 0, it is an empty line = end of headers
00123         int n = sscanf(line, "%[^:]: %[^\n]", key, value);
00124         if ( n == 2 ) {
00125 #ifdef _DEBUG_REQUEST_HANDLER
00126             printf("\r\n+++(HTTPRequestHandler)Read header : %s : %s\r\n", key, value);
00127 #endif
00128             m_reqHeaders[key] = value;
00129         }
00130         //TODO: Impl n==1 case (part 2 of previous header)
00131     }
00132 }
00133 
00134 void HTTPRequestHandler::writeHeaders() //Called at the first writeData call
00135 {
00136     int idx = 0;
00137 
00138     idx += sprintf(&line[idx], "HTTP/1.1 %d MbedInfo\r\n", m_errc); //Not a violation of the standard not to include the descriptive text
00139 
00140     map<string,string>::iterator it;
00141     while( !m_respHeaders.empty() ) {
00142         it = m_respHeaders.begin();
00143         idx += sprintf(&line[idx], "%s: %s\r\n", (*it).first.c_str(), (*it).second.c_str() );
00144 #ifdef _DEBUG_REQUEST_HANDLER
00145         printf("\r\n+++(HTTPRequestHandler)%s", &line[idx]);
00146 #endif
00147         m_respHeaders.erase(it);
00148     }
00149     idx += sprintf(&line[idx], "\r\n"); //End of head
00150     m_pTCPSocket->send(line, idx);
00151 }
00152 
00153 int HTTPRequestHandler::readLine(char* str, int maxLen)
00154 {
00155     int ret;
00156     int len = 0;
00157     for(int i = 0; i < maxLen - 1; i++) {
00158         ret = m_pTCPSocket->recv(str, 1);
00159         if(ret <= 0) {
00160             break;
00161         }
00162         if( (len > 1) && *(str-1)=='\r' && *str=='\n' ) {
00163             str--;
00164             len-=2;
00165             break;
00166         } else if( *str=='\n' ) {
00167             len--;
00168             break;
00169         }
00170         str++;
00171         len++;
00172     }
00173     *str = 0;
00174     return len;
00175 }
00176