HTTPServer

Committer:
jphuc96
Date:
Sat Sep 16 02:39:55 2017 +0000
Revision:
0:caf5feddac47
v1

Who changed what in which revision?

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