Main Server - Listen to different ports and write information to SD card, synchronize RTC with NTP over the internet, and stream events over serial

Fork of HoneyPot by Shlomi Ruder

Honeypot Server - WIZnet W7500

/media/uploads/proxytype/honeypot.png

Main server library responsible for detecting and report unwanted activities.

Features:

  • listen up to 7 different ports.
  • synchronize RTC with NTP service.
  • support http chunks responses.
  • write connection details to log file on SD card.
  • inject data to pattern html file (like real server).
  • administrator control panel.
  • visitors display message over http.

Http Server Upgrade

the based code of wiznet http server example load file from the sd card and return it to the user, using content-length to define the size of the package, because reading from file the size is fixed so it's very easy to handle but if you want to use the file as pattern and then inject dynamic data directly like a real server it's become more difficult because memory limitation of the device, to solved this we must to remove the content length header and replace it with transfer-encoding, this way we can stream the data to the client without knowing the content length only the chunks size.

 header["Transfer-Encoding"] = "chunked";
Committer:
hjjeon
Date:
Mon Jun 29 09:03:40 2015 +0000
Revision:
0:e59cc54df17c
Child:
2:f52734664057
httpServer

Who changed what in which revision?

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