Single instance HTTP Server using new Ethernet Interface.

Dependents:   EthHTTPServer if201410_section5 _PE2E_12-04_EthernetInterfaceServer MGAS_GR_Peach ... more

Fork of WiFlyHTTPServer by Henry Leinen

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, TCPSocketConnection& Tcp)
00053     : msg(Msg), tcp(Tcp)
00054 {
00055     msg = Msg;
00056     tcp = Tcp;
00057 
00058 }
00059 
00060 HTTPRequestHandler::~HTTPRequestHandler()
00061 {
00062 }
00063 
00064 void HTTPRequestHandler::getStandardHeaders(HTTPHeaders& header, const char* fext)
00065 {
00066     header.clear();
00067     header["DNT"] = "1";
00068     header["MaxAge"] = "0";
00069     header["Connection"] = "Keep-Alive";
00070     header["Server"] = "mbed Embedded";
00071     if (fext == NULL)
00072         header["Content-Type"] = "text/html";
00073     else {
00074         for (int i = 0 ; i < sizeof(fileTypeMapping)/sizeof(struct mapping_t) ;i++) {
00075             if (_stricmp(fileTypeMapping[i].key, fext) == 0) {
00076                 header["Content-Type"] = fileTypeMapping[i].value;
00077                 break;
00078             }
00079         }
00080     }
00081 }
00082 
00083 void HTTPRequestHandler::handleRequest()
00084 {
00085     int err = 0;
00086     
00087     switch (msg.request) {
00088         case HTTP_RT_GET:
00089             INFO("Dispatching GET Request.");
00090             err = handleGetRequest();
00091             break;
00092             
00093         case HTTP_RT_POST:
00094             INFO("Dispatching POST request.");
00095             err = handlePostRequest();
00096             break;
00097             
00098         case HTTP_RT_PUT:
00099             INFO("Dispatching PUT request.");
00100             err = handlePutRequest();
00101             break;
00102             
00103         default:
00104             INFO("Error in handleRequest, unhandled request type.");
00105             err = HTTP_NotImplemented;
00106             break;
00107     }
00108     
00109     //  if any of these functions returns a negative number, call the error handler
00110     if (err > 0) {
00111         handleError(err);
00112     }        
00113 }
00114 
00115 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";
00116 
00117 void HTTPRequestHandler::handleError(int errorCode, HTTPHeaders* header)
00118 {
00119     INFO("Handling error !");
00120     tcp.set_blocking(false, 1500);
00121     sprintf(buffer,"HTTP/1.1 %d Error\r\n", errorCode);
00122     tcp.send(buffer, strlen(buffer));
00123     sprintf(buffer, "Content-Length: %d\r\n", strlen(szErrorPage));
00124     tcp.send(buffer, strlen(buffer));
00125     if (header == NULL) {
00126         sprintf(buffer, "Content-Type: text/html\r\nServer: mbed embedded\r\n\n\r");
00127         tcp.send(buffer, strlen(buffer));
00128     }
00129     else {
00130         for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) {
00131             tcp.send((char*)cIter->first, strlen(cIter->first));
00132             tcp.send(": ", 2);
00133             tcp.send((char*)cIter->second, strlen(cIter->second));
00134             tcp.send("\r\n",2);
00135         }
00136         tcp.send("\r\n",2);
00137     }
00138     tcp.send((char*)szErrorPage, strlen(szErrorPage));
00139 }
00140 
00141 
00142 void HTTPRequestHandler::startResponse(int returnCode, long nLen, HTTPHeaders* header)
00143 {
00144     INFO("Starting response (%ld bytes in total)!", nLen);
00145     tcp.set_blocking(false, 1500);
00146     sprintf(buffer, "HTTP/1.1 %d OK\r\n", returnCode);
00147     tcp.send(buffer, strlen(buffer));
00148     sprintf(buffer, "Content-Length: %ld\r\n", nLen);    //  Add 2 chars for the terminating CR+LF
00149     tcp.send(buffer, strlen(buffer));
00150     INFO("Sending standard headers !");
00151     if (header == NULL) {
00152         tcp.send_all((char*)hdrStandard, strlen(hdrStandard));
00153     }
00154     else {
00155         for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) {
00156             tcp.send_all((char*)cIter->first, strlen(cIter->first));
00157             tcp.send_all(": ", 2);
00158             tcp.send_all((char*)cIter->second, strlen(cIter->second));
00159             tcp.send_all("\r\n\r\n",2);
00160         }
00161         tcp.send_all("\r\n", 2);
00162     }
00163     INFO("Proceeding !");
00164     //  other content must be sent using the 'processResponse' function
00165 }
00166 
00167 void HTTPRequestHandler::processResponse(int nLen, char* body)
00168 {
00169     INFO("Processing Response (%d bytes)!\n",nLen);
00170     tcp.send_all(body, nLen);
00171 }
00172 
00173 void HTTPRequestHandler::endResponse()
00174 {
00175     INFO("Ending Response !");
00176 }