Single instance HTTP Server using new Ethernet Interface with bug fix for URL arguments

Fork of HTTPServer by Henry Leinen

Committer:
leihen
Date:
Wed Jun 05 23:39:24 2013 +0000
Revision:
12:ba81cc117fb6
Parent:
11:3943841e1798
Child:
13:aa5338a5e452
Improved throughput of data.
; fixed incorrect Header handling.
; Fixed Support for other FileSystem Handler

Who changed what in which revision?

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