for pet feeder system & add timer function
Fork of httpServer by
HTTPRequestHandler.cpp@5:3c24e937da61, 2016-05-04 (annotated)
- Committer:
- justinkim
- Date:
- Wed May 04 00:43:24 2016 +0000
- Revision:
- 5:3c24e937da61
- Parent:
- 2:dd293a10a772
pet feeder system ver 0.1
Who changed what in which revision?
User | Revision | Line number | New 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 | } |
justinkim | 2:dd293a10a772 | 177 | |
justinkim | 2:dd293a10a772 | 178 |