HTTP Server library for Mbed OS-5. A fork of Henry Leinen's [[https://os.mbed.com/users/leihen/code/HTTPServer/]] library.
Dependents: STM32F407VET6_HTTPServer
HTTPRequestHandler.cpp@17:8bcc62289a07, 2019-10-06 (annotated)
- Committer:
- hudakz
- Date:
- Sun Oct 06 18:10:41 2019 +0000
- Revision:
- 17:8bcc62289a07
- Parent:
- 16:cc3f5c53d0d5
HTTP Server library for Mbed OS-5. A fork of Henry Leine's [[https://os.mbed.com/users/leihen/code/HTTPServer | HTTPServer]] library.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
leihen | 1:6b7472d5e9ee | 1 | /* HTTPRequestHandler.cpp */ |
leihen | 1:6b7472d5e9ee | 2 | #include "mbed.h" |
leihen | 1:6b7472d5e9ee | 3 | #include "HTTPRequestHandler.h" |
leihen | 13:aa5338a5e452 | 4 | #define DEBUG |
leihen | 16:cc3f5c53d0d5 | 5 | #include "hl_debug.h" |
leihen | 12:ba81cc117fb6 | 6 | #include <ctype.h> |
leihen | 1:6b7472d5e9ee | 7 | |
leihen | 1:6b7472d5e9ee | 8 | |
leihen | 3:d6224049b3bf | 9 | static char buffer[128]; |
leihen | 3:d6224049b3bf | 10 | |
leihen | 11:3943841e1798 | 11 | |
leihen | 13:aa5338a5e452 | 12 | const char hdrStandard[] = "DNT: 1\r\n" |
hudakz | 17:8bcc62289a07 | 13 | "MaxAge: 0\r\n" |
hudakz | 17:8bcc62289a07 | 14 | "Connection: Keep-Alive\r\n" |
hudakz | 17:8bcc62289a07 | 15 | "Content-Type: text/html\r\n" |
hudakz | 17:8bcc62289a07 | 16 | "Server: mbed embedded\r\n" |
hudakz | 17:8bcc62289a07 | 17 | "Accessible: 1\r\n" |
hudakz | 17:8bcc62289a07 | 18 | "\r\n"; |
leihen | 11:3943841e1798 | 19 | |
leihen | 12:ba81cc117fb6 | 20 | |
leihen | 12:ba81cc117fb6 | 21 | static int _stricmp(const char* a, const char* b) |
leihen | 12:ba81cc117fb6 | 22 | { |
leihen | 12:ba81cc117fb6 | 23 | int la = strlen(a); |
leihen | 12:ba81cc117fb6 | 24 | int lb = strlen(b); |
leihen | 12:ba81cc117fb6 | 25 | for (int i = 0 ; i < min(la, lb) ; i++) { |
leihen | 12:ba81cc117fb6 | 26 | if (tolower((int)a[i]) != tolower((int)b[i])) |
leihen | 12:ba81cc117fb6 | 27 | return i; |
leihen | 12:ba81cc117fb6 | 28 | } |
leihen | 12:ba81cc117fb6 | 29 | return 0; |
leihen | 12:ba81cc117fb6 | 30 | } |
leihen | 12:ba81cc117fb6 | 31 | |
leihen | 12:ba81cc117fb6 | 32 | |
leihen | 12:ba81cc117fb6 | 33 | static const struct mapping_t { |
leihen | 12:ba81cc117fb6 | 34 | const char* key; |
leihen | 12:ba81cc117fb6 | 35 | const char* value; |
leihen | 12:ba81cc117fb6 | 36 | } fileTypeMapping[] = { |
hudakz | 17:8bcc62289a07 | 37 | {".gif", "Content-Type: image/gif\r\n" }, |
leihen | 12:ba81cc117fb6 | 38 | {".jpg", "Content-Type: image/jpeg\r\n" }, |
leihen | 12:ba81cc117fb6 | 39 | {".jpeg","Content-Type: image/jpeg\r\n" }, |
leihen | 12:ba81cc117fb6 | 40 | {".ico", "Content-Type: image/x-icon\r\n"}, |
leihen | 12:ba81cc117fb6 | 41 | {".png", "Content-Type: image/png\r\n" }, |
leihen | 12:ba81cc117fb6 | 42 | {".zip", "Content-Type: image/zip\r\n" }, |
leihen | 12:ba81cc117fb6 | 43 | {".gz", "Content-Type: image/gz\r\n" }, |
leihen | 12:ba81cc117fb6 | 44 | {".tar", "Content-Type: image/tar\r\n" }, |
leihen | 12:ba81cc117fb6 | 45 | {".txt", "Content-Type: plain/text\r\n" }, |
leihen | 12:ba81cc117fb6 | 46 | {".pdf", "Content-Type: application/pdf\r\n" }, |
leihen | 12:ba81cc117fb6 | 47 | {".htm", "Content-Type: text/html\r\n" }, |
leihen | 13:aa5338a5e452 | 48 | {".html","Content-Type: text/html\r\n" }, |
leihen | 13:aa5338a5e452 | 49 | {".css", "Content-Type: text/css\r\n" }, |
leihen | 13:aa5338a5e452 | 50 | {".js", "Content-Type: text/javascript\r\n"}}; |
leihen | 12:ba81cc117fb6 | 51 | |
hudakz | 17:8bcc62289a07 | 52 | HTTPRequestHandler::HTTPRequestHandler(HTTPConnection::HTTPMessage& Msg, TCPSocket* Tcp) |
leihen | 3:d6224049b3bf | 53 | : msg(Msg), tcp(Tcp) |
leihen | 1:6b7472d5e9ee | 54 | { |
leihen | 3:d6224049b3bf | 55 | msg = Msg; |
leihen | 3:d6224049b3bf | 56 | tcp = Tcp; |
leihen | 1:6b7472d5e9ee | 57 | } |
leihen | 1:6b7472d5e9ee | 58 | |
leihen | 1:6b7472d5e9ee | 59 | HTTPRequestHandler::~HTTPRequestHandler() |
leihen | 1:6b7472d5e9ee | 60 | { |
leihen | 3:d6224049b3bf | 61 | } |
leihen | 3:d6224049b3bf | 62 | |
leihen | 12:ba81cc117fb6 | 63 | void HTTPRequestHandler::getStandardHeaders(HTTPHeaders& header, const char* fext) |
leihen | 12:ba81cc117fb6 | 64 | { |
leihen | 12:ba81cc117fb6 | 65 | header.clear(); |
leihen | 12:ba81cc117fb6 | 66 | header["DNT"] = "1"; |
leihen | 12:ba81cc117fb6 | 67 | header["MaxAge"] = "0"; |
leihen | 12:ba81cc117fb6 | 68 | header["Connection"] = "Keep-Alive"; |
leihen | 12:ba81cc117fb6 | 69 | header["Server"] = "mbed Embedded"; |
leihen | 12:ba81cc117fb6 | 70 | if (fext == NULL) |
leihen | 12:ba81cc117fb6 | 71 | header["Content-Type"] = "text/html"; |
leihen | 12:ba81cc117fb6 | 72 | else { |
leihen | 12:ba81cc117fb6 | 73 | for (int i = 0 ; i < sizeof(fileTypeMapping)/sizeof(struct mapping_t) ;i++) { |
leihen | 12:ba81cc117fb6 | 74 | if (_stricmp(fileTypeMapping[i].key, fext) == 0) { |
leihen | 12:ba81cc117fb6 | 75 | header["Content-Type"] = fileTypeMapping[i].value; |
leihen | 12:ba81cc117fb6 | 76 | break; |
leihen | 12:ba81cc117fb6 | 77 | } |
leihen | 12:ba81cc117fb6 | 78 | } |
leihen | 12:ba81cc117fb6 | 79 | } |
leihen | 12:ba81cc117fb6 | 80 | } |
leihen | 12:ba81cc117fb6 | 81 | |
leihen | 3:d6224049b3bf | 82 | void HTTPRequestHandler::handleRequest() |
leihen | 3:d6224049b3bf | 83 | { |
leihen | 3:d6224049b3bf | 84 | int err = 0; |
leihen | 3:d6224049b3bf | 85 | |
leihen | 3:d6224049b3bf | 86 | switch (msg.request) { |
leihen | 3:d6224049b3bf | 87 | case HTTP_RT_GET: |
leihen | 3:d6224049b3bf | 88 | INFO("Dispatching GET Request."); |
leihen | 3:d6224049b3bf | 89 | err = handleGetRequest(); |
leihen | 3:d6224049b3bf | 90 | break; |
leihen | 3:d6224049b3bf | 91 | |
leihen | 4:d065642c32cc | 92 | case HTTP_RT_POST: |
leihen | 4:d065642c32cc | 93 | INFO("Dispatching POST request."); |
leihen | 4:d065642c32cc | 94 | err = handlePostRequest(); |
leihen | 4:d065642c32cc | 95 | break; |
leihen | 3:d6224049b3bf | 96 | |
leihen | 4:d065642c32cc | 97 | case HTTP_RT_PUT: |
leihen | 4:d065642c32cc | 98 | INFO("Dispatching PUT request."); |
leihen | 4:d065642c32cc | 99 | err = handlePutRequest(); |
leihen | 4:d065642c32cc | 100 | break; |
leihen | 3:d6224049b3bf | 101 | |
leihen | 3:d6224049b3bf | 102 | default: |
leihen | 3:d6224049b3bf | 103 | INFO("Error in handleRequest, unhandled request type."); |
leihen | 9:c2a1462b9b71 | 104 | err = HTTP_NotImplemented; |
leihen | 3:d6224049b3bf | 105 | break; |
leihen | 3:d6224049b3bf | 106 | } |
leihen | 3:d6224049b3bf | 107 | |
leihen | 3:d6224049b3bf | 108 | // if any of these functions returns a negative number, call the error handler |
leihen | 3:d6224049b3bf | 109 | if (err > 0) { |
leihen | 3:d6224049b3bf | 110 | handleError(err); |
leihen | 3:d6224049b3bf | 111 | } |
leihen | 3:d6224049b3bf | 112 | } |
leihen | 3:d6224049b3bf | 113 | |
leihen | 13:aa5338a5e452 | 114 | 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"; |
leihen | 3:d6224049b3bf | 115 | |
leihen | 3:d6224049b3bf | 116 | void HTTPRequestHandler::handleError(int errorCode, HTTPHeaders* header) |
leihen | 3:d6224049b3bf | 117 | { |
leihen | 3:d6224049b3bf | 118 | INFO("Handling error !"); |
hudakz | 17:8bcc62289a07 | 119 | tcp->set_blocking(false); |
leihen | 11:3943841e1798 | 120 | sprintf(buffer,"HTTP/1.1 %d Error\r\n", errorCode); |
hudakz | 17:8bcc62289a07 | 121 | tcp->send(buffer, strlen(buffer)); |
leihen | 3:d6224049b3bf | 122 | sprintf(buffer, "Content-Length: %d\r\n", strlen(szErrorPage)); |
hudakz | 17:8bcc62289a07 | 123 | tcp->send(buffer, strlen(buffer)); |
leihen | 3:d6224049b3bf | 124 | if (header == NULL) { |
leihen | 3:d6224049b3bf | 125 | sprintf(buffer, "Content-Type: text/html\r\nServer: mbed embedded\r\n\n\r"); |
hudakz | 17:8bcc62289a07 | 126 | tcp->send(buffer, strlen(buffer)); |
leihen | 3:d6224049b3bf | 127 | } |
leihen | 3:d6224049b3bf | 128 | else { |
leihen | 3:d6224049b3bf | 129 | for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) { |
hudakz | 17:8bcc62289a07 | 130 | tcp->send((char*)cIter->first, strlen(cIter->first)); |
hudakz | 17:8bcc62289a07 | 131 | tcp->send(": ", 2); |
hudakz | 17:8bcc62289a07 | 132 | tcp->send((char*)cIter->second, strlen(cIter->second)); |
hudakz | 17:8bcc62289a07 | 133 | tcp->send("\r\n",2); |
leihen | 3:d6224049b3bf | 134 | } |
hudakz | 17:8bcc62289a07 | 135 | tcp->send("\r\n",2); |
leihen | 3:d6224049b3bf | 136 | } |
hudakz | 17:8bcc62289a07 | 137 | tcp->send((char*)szErrorPage, strlen(szErrorPage)); |
leihen | 3:d6224049b3bf | 138 | } |
leihen | 3:d6224049b3bf | 139 | |
leihen | 3:d6224049b3bf | 140 | |
leihen | 7:cb7fec1265b5 | 141 | void HTTPRequestHandler::startResponse(int returnCode, long nLen, HTTPHeaders* header) |
leihen | 3:d6224049b3bf | 142 | { |
leihen | 7:cb7fec1265b5 | 143 | INFO("Starting response (%ld bytes in total)!", nLen); |
hudakz | 17:8bcc62289a07 | 144 | tcp->set_blocking(false); |
leihen | 11:3943841e1798 | 145 | sprintf(buffer, "HTTP/1.1 %d OK\r\n", returnCode); |
hudakz | 17:8bcc62289a07 | 146 | tcp->send(buffer, strlen(buffer)); |
leihen | 7:cb7fec1265b5 | 147 | sprintf(buffer, "Content-Length: %ld\r\n", nLen); // Add 2 chars for the terminating CR+LF |
hudakz | 17:8bcc62289a07 | 148 | tcp->send(buffer, strlen(buffer)); |
leihen | 13:aa5338a5e452 | 149 | INFO("Sending standard headers !"); |
leihen | 3:d6224049b3bf | 150 | if (header == NULL) { |
hudakz | 17:8bcc62289a07 | 151 | tcp->send((char*)hdrStandard, strlen(hdrStandard)); |
leihen | 3:d6224049b3bf | 152 | } |
leihen | 3:d6224049b3bf | 153 | else { |
leihen | 3:d6224049b3bf | 154 | for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) { |
hudakz | 17:8bcc62289a07 | 155 | tcp->send((char*)cIter->first, strlen(cIter->first)); |
hudakz | 17:8bcc62289a07 | 156 | tcp->send(": ", 2); |
hudakz | 17:8bcc62289a07 | 157 | tcp->send((char*)cIter->second, strlen(cIter->second)); |
hudakz | 17:8bcc62289a07 | 158 | tcp->send("\r\n\r\n",2); |
leihen | 3:d6224049b3bf | 159 | } |
hudakz | 17:8bcc62289a07 | 160 | tcp->send("\r\n", 2); |
leihen | 3:d6224049b3bf | 161 | } |
leihen | 13:aa5338a5e452 | 162 | INFO("Proceeding !"); |
leihen | 3:d6224049b3bf | 163 | // other content must be sent using the 'processResponse' function |
leihen | 3:d6224049b3bf | 164 | } |
leihen | 3:d6224049b3bf | 165 | |
leihen | 3:d6224049b3bf | 166 | void HTTPRequestHandler::processResponse(int nLen, char* body) |
leihen | 3:d6224049b3bf | 167 | { |
leihen | 7:cb7fec1265b5 | 168 | INFO("Processing Response (%d bytes)!\n",nLen); |
hudakz | 17:8bcc62289a07 | 169 | tcp->send(body, nLen); |
leihen | 3:d6224049b3bf | 170 | } |
leihen | 3:d6224049b3bf | 171 | |
leihen | 3:d6224049b3bf | 172 | void HTTPRequestHandler::endResponse() |
leihen | 3:d6224049b3bf | 173 | { |
leihen | 3:d6224049b3bf | 174 | INFO("Ending Response !"); |
leihen | 3:d6224049b3bf | 175 | } |