Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: STM32F407VET6_HTTPServer
HTTPRequestHandler.cpp
00001 /* HTTPRequestHandler.cpp */ 00002 #include "mbed.h" 00003 #include "HTTPRequestHandler.h" 00004 #define DEBUG 00005 #include "hl_debug.h" 00006 #include <ctype.h> 00007 00008 00009 static char buffer[128]; 00010 00011 00012 const char hdrStandard[] = "DNT: 1\r\n" 00013 "MaxAge: 0\r\n" 00014 "Connection: Keep-Alive\r\n" 00015 "Content-Type: text/html\r\n" 00016 "Server: mbed embedded\r\n" 00017 "Accessible: 1\r\n" 00018 "\r\n"; 00019 00020 00021 static int _stricmp(const char* a, const char* b) 00022 { 00023 int la = strlen(a); 00024 int lb = strlen(b); 00025 for (int i = 0 ; i < min(la, lb) ; i++) { 00026 if (tolower((int)a[i]) != tolower((int)b[i])) 00027 return i; 00028 } 00029 return 0; 00030 } 00031 00032 00033 static const struct mapping_t { 00034 const char* key; 00035 const char* value; 00036 } fileTypeMapping[] = { 00037 {".gif", "Content-Type: image/gif\r\n" }, 00038 {".jpg", "Content-Type: image/jpeg\r\n" }, 00039 {".jpeg","Content-Type: image/jpeg\r\n" }, 00040 {".ico", "Content-Type: image/x-icon\r\n"}, 00041 {".png", "Content-Type: image/png\r\n" }, 00042 {".zip", "Content-Type: image/zip\r\n" }, 00043 {".gz", "Content-Type: image/gz\r\n" }, 00044 {".tar", "Content-Type: image/tar\r\n" }, 00045 {".txt", "Content-Type: plain/text\r\n" }, 00046 {".pdf", "Content-Type: application/pdf\r\n" }, 00047 {".htm", "Content-Type: text/html\r\n" }, 00048 {".html","Content-Type: text/html\r\n" }, 00049 {".css", "Content-Type: text/css\r\n" }, 00050 {".js", "Content-Type: text/javascript\r\n"}}; 00051 00052 HTTPRequestHandler::HTTPRequestHandler(HTTPConnection::HTTPMessage& Msg, TCPSocket* Tcp) 00053 : msg(Msg), tcp(Tcp) 00054 { 00055 msg = Msg; 00056 tcp = Tcp; 00057 } 00058 00059 HTTPRequestHandler::~HTTPRequestHandler() 00060 { 00061 } 00062 00063 void HTTPRequestHandler::getStandardHeaders(HTTPHeaders& header, const char* fext) 00064 { 00065 header.clear(); 00066 header["DNT"] = "1"; 00067 header["MaxAge"] = "0"; 00068 header["Connection"] = "Keep-Alive"; 00069 header["Server"] = "mbed Embedded"; 00070 if (fext == NULL) 00071 header["Content-Type"] = "text/html"; 00072 else { 00073 for (int i = 0 ; i < sizeof(fileTypeMapping)/sizeof(struct mapping_t) ;i++) { 00074 if (_stricmp(fileTypeMapping[i].key, fext) == 0) { 00075 header["Content-Type"] = fileTypeMapping[i].value; 00076 break; 00077 } 00078 } 00079 } 00080 } 00081 00082 void HTTPRequestHandler::handleRequest() 00083 { 00084 int err = 0; 00085 00086 switch (msg.request) { 00087 case HTTP_RT_GET: 00088 INFO("Dispatching GET Request."); 00089 err = handleGetRequest(); 00090 break; 00091 00092 case HTTP_RT_POST: 00093 INFO("Dispatching POST request."); 00094 err = handlePostRequest(); 00095 break; 00096 00097 case HTTP_RT_PUT: 00098 INFO("Dispatching PUT request."); 00099 err = handlePutRequest(); 00100 break; 00101 00102 default: 00103 INFO("Error in handleRequest, unhandled request type."); 00104 err = HTTP_NotImplemented; 00105 break; 00106 } 00107 00108 // if any of these functions returns a negative number, call the error handler 00109 if (err > 0) { 00110 handleError(err); 00111 } 00112 } 00113 00114 static const char* szErrorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error</h1><P>HTTPServer Error<P></BODY></HTML>\r\n\r\n"; 00115 00116 void HTTPRequestHandler::handleError(int errorCode, HTTPHeaders* header) 00117 { 00118 INFO("Handling error !"); 00119 tcp->set_blocking(false); 00120 sprintf(buffer,"HTTP/1.1 %d Error\r\n", errorCode); 00121 tcp->send(buffer, strlen(buffer)); 00122 sprintf(buffer, "Content-Length: %d\r\n", strlen(szErrorPage)); 00123 tcp->send(buffer, strlen(buffer)); 00124 if (header == NULL) { 00125 sprintf(buffer, "Content-Type: text/html\r\nServer: mbed embedded\r\n\n\r"); 00126 tcp->send(buffer, strlen(buffer)); 00127 } 00128 else { 00129 for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) { 00130 tcp->send((char*)cIter->first, strlen(cIter->first)); 00131 tcp->send(": ", 2); 00132 tcp->send((char*)cIter->second, strlen(cIter->second)); 00133 tcp->send("\r\n",2); 00134 } 00135 tcp->send("\r\n",2); 00136 } 00137 tcp->send((char*)szErrorPage, strlen(szErrorPage)); 00138 } 00139 00140 00141 void HTTPRequestHandler::startResponse(int returnCode, long nLen, HTTPHeaders* header) 00142 { 00143 INFO("Starting response (%ld bytes in total)!", nLen); 00144 tcp->set_blocking(false); 00145 sprintf(buffer, "HTTP/1.1 %d OK\r\n", returnCode); 00146 tcp->send(buffer, strlen(buffer)); 00147 sprintf(buffer, "Content-Length: %ld\r\n", nLen); // Add 2 chars for the terminating CR+LF 00148 tcp->send(buffer, strlen(buffer)); 00149 INFO("Sending standard headers !"); 00150 if (header == NULL) { 00151 tcp->send((char*)hdrStandard, strlen(hdrStandard)); 00152 } 00153 else { 00154 for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) { 00155 tcp->send((char*)cIter->first, strlen(cIter->first)); 00156 tcp->send(": ", 2); 00157 tcp->send((char*)cIter->second, strlen(cIter->second)); 00158 tcp->send("\r\n\r\n",2); 00159 } 00160 tcp->send("\r\n", 2); 00161 } 00162 INFO("Proceeding !"); 00163 // other content must be sent using the 'processResponse' function 00164 } 00165 00166 void HTTPRequestHandler::processResponse(int nLen, char* body) 00167 { 00168 INFO("Processing Response (%d bytes)!\n",nLen); 00169 tcp->send(body, nLen); 00170 } 00171 00172 void HTTPRequestHandler::endResponse() 00173 { 00174 INFO("Ending Response !"); 00175 }
Generated on Wed Jul 13 2022 12:04:08 by
1.7.2