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:
proxytype
Date:
Fri Sep 01 23:37:29 2017 +0000
Revision:
3:1d6096332358
Parent:
2:f52734664057

        

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
proxytype 2:f52734664057 52 HTTPRequestHandler::HTTPRequestHandler(HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp, int isMaster, int * ports, int portsCount, int * hits)
hjjeon 0:e59cc54df17c 53 : msg(Msg), tcp(Tcp)
hjjeon 0:e59cc54df17c 54 {
hjjeon 0:e59cc54df17c 55 msg = Msg;
hjjeon 0:e59cc54df17c 56 tcp = Tcp;
proxytype 2:f52734664057 57 m_isMaster = isMaster;
proxytype 2:f52734664057 58 m_ports = ports;
proxytype 2:f52734664057 59 m_portsCount = portsCount;
proxytype 2:f52734664057 60 m_hits = hits;
hjjeon 0:e59cc54df17c 61
hjjeon 0:e59cc54df17c 62 }
hjjeon 0:e59cc54df17c 63
hjjeon 0:e59cc54df17c 64 HTTPRequestHandler::~HTTPRequestHandler()
hjjeon 0:e59cc54df17c 65 {
hjjeon 0:e59cc54df17c 66 }
hjjeon 0:e59cc54df17c 67
hjjeon 0:e59cc54df17c 68 void HTTPRequestHandler::getStandardHeaders(HTTPHeaders& header, const char* fext)
hjjeon 0:e59cc54df17c 69 {
hjjeon 0:e59cc54df17c 70 header.clear();
hjjeon 0:e59cc54df17c 71 header["DNT"] = "1";
hjjeon 0:e59cc54df17c 72 header["MaxAge"] = "0";
hjjeon 0:e59cc54df17c 73 header["Connection"] = "Keep-Alive";
hjjeon 0:e59cc54df17c 74 header["Server"] = "mbed Embedded";
hjjeon 0:e59cc54df17c 75 if (fext == NULL)
hjjeon 0:e59cc54df17c 76 header["Content-Type"] = "text/html";
hjjeon 0:e59cc54df17c 77 else {
hjjeon 0:e59cc54df17c 78 for (int i = 0 ; i < sizeof(fileTypeMapping)/sizeof(struct mapping_t) ;i++) {
hjjeon 0:e59cc54df17c 79 if (_stricmp(fileTypeMapping[i].key, fext) == 0) {
hjjeon 0:e59cc54df17c 80 header["Content-Type"] = fileTypeMapping[i].value;
proxytype 2:f52734664057 81 header["Transfer-Encoding"] = "chunked";
hjjeon 0:e59cc54df17c 82 break;
hjjeon 0:e59cc54df17c 83 }
hjjeon 0:e59cc54df17c 84 }
hjjeon 0:e59cc54df17c 85 }
hjjeon 0:e59cc54df17c 86 }
hjjeon 0:e59cc54df17c 87
hjjeon 0:e59cc54df17c 88 void HTTPRequestHandler::handleRequest()
hjjeon 0:e59cc54df17c 89 {
hjjeon 0:e59cc54df17c 90 int err = 0;
hjjeon 0:e59cc54df17c 91
hjjeon 0:e59cc54df17c 92 switch (msg.request) {
hjjeon 0:e59cc54df17c 93 case HTTP_RT_GET:
hjjeon 0:e59cc54df17c 94 INFO("Dispatching GET Request.");
hjjeon 0:e59cc54df17c 95 err = handleGetRequest();
hjjeon 0:e59cc54df17c 96 break;
hjjeon 0:e59cc54df17c 97
hjjeon 0:e59cc54df17c 98 case HTTP_RT_POST:
hjjeon 0:e59cc54df17c 99 INFO("Dispatching POST request.");
hjjeon 0:e59cc54df17c 100 err = handlePostRequest();
hjjeon 0:e59cc54df17c 101 break;
hjjeon 0:e59cc54df17c 102
hjjeon 0:e59cc54df17c 103 case HTTP_RT_PUT:
hjjeon 0:e59cc54df17c 104 INFO("Dispatching PUT request.");
hjjeon 0:e59cc54df17c 105 err = handlePutRequest();
hjjeon 0:e59cc54df17c 106 break;
hjjeon 0:e59cc54df17c 107
hjjeon 0:e59cc54df17c 108 default:
hjjeon 0:e59cc54df17c 109 INFO("Error in handleRequest, unhandled request type.");
hjjeon 0:e59cc54df17c 110 err = HTTP_NotImplemented;
hjjeon 0:e59cc54df17c 111 break;
hjjeon 0:e59cc54df17c 112 }
hjjeon 0:e59cc54df17c 113
hjjeon 0:e59cc54df17c 114 // if any of these functions returns a negative number, call the error handler
hjjeon 0:e59cc54df17c 115 if (err > 0) {
hjjeon 0:e59cc54df17c 116 handleError(err);
hjjeon 0:e59cc54df17c 117 }
hjjeon 0:e59cc54df17c 118 }
hjjeon 0:e59cc54df17c 119
hjjeon 0:e59cc54df17c 120 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 121
hjjeon 0:e59cc54df17c 122 void HTTPRequestHandler::handleError(int errorCode, HTTPHeaders* header)
hjjeon 0:e59cc54df17c 123 {
hjjeon 0:e59cc54df17c 124 INFO("Handling error !");
hjjeon 0:e59cc54df17c 125 tcp.set_blocking(false, 1500);
hjjeon 0:e59cc54df17c 126 sprintf(buffer,"HTTP/1.1 %d Error\r\n", errorCode);
hjjeon 0:e59cc54df17c 127 tcp.send(buffer, strlen(buffer));
hjjeon 0:e59cc54df17c 128 sprintf(buffer, "Content-Length: %d\r\n", strlen(szErrorPage));
hjjeon 0:e59cc54df17c 129 tcp.send(buffer, strlen(buffer));
hjjeon 0:e59cc54df17c 130 if (header == NULL) {
hjjeon 0:e59cc54df17c 131 sprintf(buffer, "Content-Type: text/html\r\nServer: mbed embedded\r\n\n\r");
hjjeon 0:e59cc54df17c 132 tcp.send(buffer, strlen(buffer));
hjjeon 0:e59cc54df17c 133 }
hjjeon 0:e59cc54df17c 134 else {
hjjeon 0:e59cc54df17c 135 for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) {
hjjeon 0:e59cc54df17c 136 tcp.send((char*)cIter->first, strlen(cIter->first));
hjjeon 0:e59cc54df17c 137 tcp.send(": ", 2);
hjjeon 0:e59cc54df17c 138 tcp.send((char*)cIter->second, strlen(cIter->second));
hjjeon 0:e59cc54df17c 139 tcp.send("\r\n",2);
hjjeon 0:e59cc54df17c 140 }
hjjeon 0:e59cc54df17c 141 tcp.send("\r\n",2);
hjjeon 0:e59cc54df17c 142 }
hjjeon 0:e59cc54df17c 143 tcp.send((char*)szErrorPage, strlen(szErrorPage));
hjjeon 0:e59cc54df17c 144 }
hjjeon 0:e59cc54df17c 145
proxytype 2:f52734664057 146 //this is chunked package content length remove
proxytype 2:f52734664057 147 //stream stay open until zero size chunked.
proxytype 2:f52734664057 148 void HTTPRequestHandler::startResponse(int returnCode, HTTPHeaders* header)
hjjeon 0:e59cc54df17c 149 {
hjjeon 0:e59cc54df17c 150 tcp.set_blocking(false, 1500);
hjjeon 0:e59cc54df17c 151 sprintf(buffer, "HTTP/1.1 %d OK\r\n", returnCode);
hjjeon 0:e59cc54df17c 152 tcp.send(buffer, strlen(buffer));
hjjeon 0:e59cc54df17c 153 INFO("Sending standard headers !");
hjjeon 0:e59cc54df17c 154 if (header == NULL) {
hjjeon 0:e59cc54df17c 155 tcp.send_all((char*)hdrStandard, strlen(hdrStandard));
hjjeon 0:e59cc54df17c 156 }
hjjeon 0:e59cc54df17c 157 else {
hjjeon 0:e59cc54df17c 158 for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) {
hjjeon 0:e59cc54df17c 159 tcp.send_all((char*)cIter->first, strlen(cIter->first));
hjjeon 0:e59cc54df17c 160 tcp.send_all(": ", 2);
hjjeon 0:e59cc54df17c 161 tcp.send_all((char*)cIter->second, strlen(cIter->second));
hjjeon 0:e59cc54df17c 162 tcp.send_all("\r\n\r\n",2);
hjjeon 0:e59cc54df17c 163 }
hjjeon 0:e59cc54df17c 164 tcp.send_all("\r\n", 2);
hjjeon 0:e59cc54df17c 165 }
hjjeon 0:e59cc54df17c 166 INFO("Proceeding !");
hjjeon 0:e59cc54df17c 167 // other content must be sent using the 'processResponse' function
hjjeon 0:e59cc54df17c 168 }
hjjeon 0:e59cc54df17c 169
hjjeon 0:e59cc54df17c 170 void HTTPRequestHandler::processResponse(int nLen, char* body)
hjjeon 0:e59cc54df17c 171 {
hjjeon 0:e59cc54df17c 172 INFO("Processing Response (%d bytes)!\n",nLen);
hjjeon 0:e59cc54df17c 173 tcp.send_all(body, nLen);
hjjeon 0:e59cc54df17c 174 }
hjjeon 0:e59cc54df17c 175
hjjeon 0:e59cc54df17c 176 void HTTPRequestHandler::endResponse()
hjjeon 0:e59cc54df17c 177 {
proxytype 2:f52734664057 178 tcp.send_all("\0",1);
hjjeon 0:e59cc54df17c 179 INFO("Ending Response !");
hjjeon 0:e59cc54df17c 180 }