Zoltan Hudak / HTTPServer

Dependents:   STM32F407VET6_HTTPServer

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPRequestHandler.cpp Source File

HTTPRequestHandler.cpp

00001 /* HTTPRequestHandler.cpp */
00002 #include "mbed.h"
00003 #include "HTTPRequestHandler.h"
00004 #define DEBUG
00005 #include "hl_debug.h"
00006 #include <ctype.h>
00007 
00008 
00009 static char buffer[128];
00010 
00011 
00012 const char hdrStandard[] = "DNT: 1\r\n"
00013                            "MaxAge: 0\r\n"
00014                            "Connection: Keep-Alive\r\n"
00015                            "Content-Type: text/html\r\n"
00016                            "Server: mbed embedded\r\n"
00017                            "Accessible: 1\r\n"
00018                            "\r\n";
00019 
00020 
00021 static int _stricmp(const char* a, const char* b)
00022 {
00023     int la = strlen(a);
00024     int lb = strlen(b);
00025     for (int i = 0 ; i < min(la, lb) ; i++) {
00026         if (tolower((int)a[i]) != tolower((int)b[i]))
00027             return i;
00028     }
00029     return 0;
00030 }
00031 
00032 
00033 static const struct mapping_t {
00034     const char* key;
00035     const char* value;
00036 } fileTypeMapping[]  = {
00037     {".gif", "Content-Type: image/gif\r\n"   },
00038     {".jpg", "Content-Type: image/jpeg\r\n"  },
00039     {".jpeg","Content-Type: image/jpeg\r\n"  },
00040     {".ico", "Content-Type: image/x-icon\r\n"},
00041     {".png", "Content-Type: image/png\r\n"   },
00042     {".zip", "Content-Type: image/zip\r\n"   },
00043     {".gz",  "Content-Type: image/gz\r\n"    },
00044     {".tar", "Content-Type: image/tar\r\n"   },
00045     {".txt", "Content-Type: plain/text\r\n"  },
00046     {".pdf", "Content-Type: application/pdf\r\n" },
00047     {".htm", "Content-Type: text/html\r\n"   },
00048     {".html","Content-Type: text/html\r\n"   },
00049     {".css", "Content-Type: text/css\r\n"    },
00050     {".js",  "Content-Type: text/javascript\r\n"}};
00051     
00052 HTTPRequestHandler::HTTPRequestHandler(HTTPConnection::HTTPMessage& Msg, TCPSocket* Tcp)
00053     : msg(Msg), tcp(Tcp)
00054 {
00055     msg = Msg;
00056     tcp = Tcp;
00057 }
00058 
00059 HTTPRequestHandler::~HTTPRequestHandler()
00060 {
00061 }
00062 
00063 void HTTPRequestHandler::getStandardHeaders(HTTPHeaders& header, const char* fext)
00064 {
00065     header.clear();
00066     header["DNT"] = "1";
00067     header["MaxAge"] = "0";
00068     header["Connection"] = "Keep-Alive";
00069     header["Server"] = "mbed Embedded";
00070     if (fext == NULL)
00071         header["Content-Type"] = "text/html";
00072     else {
00073         for (int i = 0 ; i < sizeof(fileTypeMapping)/sizeof(struct mapping_t) ;i++) {
00074             if (_stricmp(fileTypeMapping[i].key, fext) == 0) {
00075                 header["Content-Type"] = fileTypeMapping[i].value;
00076                 break;
00077             }
00078         }
00079     }
00080 }
00081 
00082 void HTTPRequestHandler::handleRequest()
00083 {
00084     int err = 0;
00085     
00086     switch (msg.request) {
00087         case HTTP_RT_GET:
00088             INFO("Dispatching GET Request.");
00089             err = handleGetRequest();
00090             break;
00091             
00092         case HTTP_RT_POST:
00093             INFO("Dispatching POST request.");
00094             err = handlePostRequest();
00095             break;
00096             
00097         case HTTP_RT_PUT:
00098             INFO("Dispatching PUT request.");
00099             err = handlePutRequest();
00100             break;
00101             
00102         default:
00103             INFO("Error in handleRequest, unhandled request type.");
00104             err = HTTP_NotImplemented;
00105             break;
00106     }
00107     
00108     //  if any of these functions returns a negative number, call the error handler
00109     if (err > 0) {
00110         handleError(err);
00111     }        
00112 }
00113 
00114 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";
00115 
00116 void HTTPRequestHandler::handleError(int errorCode, HTTPHeaders* header)
00117 {
00118     INFO("Handling error !");
00119     tcp->set_blocking(false);
00120     sprintf(buffer,"HTTP/1.1 %d Error\r\n", errorCode);
00121     tcp->send(buffer, strlen(buffer));
00122     sprintf(buffer, "Content-Length: %d\r\n", strlen(szErrorPage));
00123     tcp->send(buffer, strlen(buffer));
00124     if (header == NULL) {
00125         sprintf(buffer, "Content-Type: text/html\r\nServer: mbed embedded\r\n\n\r");
00126         tcp->send(buffer, strlen(buffer));
00127     }
00128     else {
00129         for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) {
00130             tcp->send((char*)cIter->first, strlen(cIter->first));
00131             tcp->send(": ", 2);
00132             tcp->send((char*)cIter->second, strlen(cIter->second));
00133             tcp->send("\r\n",2);
00134         }
00135         tcp->send("\r\n",2);
00136     }
00137     tcp->send((char*)szErrorPage, strlen(szErrorPage));
00138 }
00139 
00140 
00141 void HTTPRequestHandler::startResponse(int returnCode, long nLen, HTTPHeaders* header)
00142 {
00143     INFO("Starting response (%ld bytes in total)!", nLen);
00144     tcp->set_blocking(false);
00145     sprintf(buffer, "HTTP/1.1 %d OK\r\n", returnCode);
00146     tcp->send(buffer, strlen(buffer));
00147     sprintf(buffer, "Content-Length: %ld\r\n", nLen);    //  Add 2 chars for the terminating CR+LF
00148     tcp->send(buffer, strlen(buffer));
00149     INFO("Sending standard headers !");
00150     if (header == NULL) {
00151         tcp->send((char*)hdrStandard, strlen(hdrStandard));
00152     }
00153     else {
00154         for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) {
00155             tcp->send((char*)cIter->first, strlen(cIter->first));
00156             tcp->send(": ", 2);
00157             tcp->send((char*)cIter->second, strlen(cIter->second));
00158             tcp->send("\r\n\r\n",2);
00159         }
00160         tcp->send("\r\n", 2);
00161     }
00162     INFO("Proceeding !");
00163     //  other content must be sent using the 'processResponse' function
00164 }
00165 
00166 void HTTPRequestHandler::processResponse(int nLen, char* body)
00167 {
00168     INFO("Processing Response (%d bytes)!\n",nLen);
00169     tcp->send(body, nLen);
00170 }
00171 
00172 void HTTPRequestHandler::endResponse()
00173 {
00174     INFO("Ending Response !");
00175 }