Single instance HTTP Server using new Ethernet Interface. Blocking mode only; this improved stability, but the HTTP server must be started from a separate thread.
Fork of HTTPServer by
Revision 2:8653bbcf7e58, committed 2013-05-26
- Comitter:
- leihen
- Date:
- Sun May 26 23:22:36 2013 +0000
- Parent:
- 1:6b7472d5e9ee
- Child:
- 3:d6224049b3bf
- Commit message:
- Optimized for RAM.
Changed in this revision
--- a/HTTPConnection.cpp Sun May 26 22:49:42 2013 +0000 +++ b/HTTPConnection.cpp Sun May 26 23:22:36 2013 +0000 @@ -8,7 +8,7 @@ using std::string; -#if (0 && !defined(TARGET_LPC11U24)) +#if (1 && !defined(TARGET_LPC11U24)) #define INFO(x, ...) std::printf("[HttpConnection : INFO]"x"\r\n", ##__VA_ARGS__); #define WARN(x, ...) std::printf("[HttpConnection : WARN]"x"\r\n", ##__VA_ARGS__); #define ERR(x, ...) std::printf("[HttpConnection : ERR]"x"\r\n", ##__VA_ARGS__); @@ -39,7 +39,6 @@ int HTTPConnection::poll() { static char buffer[256] = {}; - static char echoHeader[256] = {}; int rcvd= 0; @@ -58,9 +57,8 @@ if (rcvd == -1) { // Invalid content received, so close the connection INFO("Invalid message received, so sending negative response and closing connection !"); - sprintf(echoHeader,"HTTP/1.1 400 NOK\n\rContent-Length: %d\n\rContent-Type: text\n\rConnection: Close\n\r\n\r",strlen(buffer)); + sprintf(buffer,"HTTP/1.1 400 NOK\n\rContent-Length: %d\n\rContent-Type: text\n\rConnection: Close\n\r\n\r",0); m_Tcp.set_blocking(true, 1500); - m_Tcp.send(echoHeader,strlen(echoHeader)); m_Tcp.send(buffer,strlen(buffer)); close(); rcvd = -1; @@ -85,17 +83,6 @@ } } } - if (rcvd == 0) { -// sprintf(echoHeader,"HTTP/1.1 200 OK\n\rContent-Length: %d\n\rContent-Type: text\n\rConnection: Close\n\r\n\r",strlen(buffer)); -// m_Tcp.set_blocking(true); -// m_Tcp.send_all(echoHeader,strlen(echoHeader)); -// m_Tcp.send_all(buffer,strlen(buffer)); - - /// INSERT PRCESSING OF REQUESST HERE - /// END OF PROCESSING REQUEST - - // Do not close the connection, it may be reused - } INFO("Leaving poll function!"); return rcvd; } @@ -147,7 +134,7 @@ return i; } -int HTTPConnection::parse(const char* buffer) +int HTTPConnection::parse(char* buffer) { if ((buffer == NULL) || (strlen(buffer) < 4)) { ERR("Buffer content is invalid or too short."); @@ -159,14 +146,13 @@ // decompose string into a list of arguments char s = 0; // current starting char - static char buff[255] = {}; - for (int i = 0 ; i < strlen(buffer)+1 ; i++) { + int nLen = strlen(buffer)+1; + for (int i = 0 ; i < nLen ; i++) { if ((buffer[i] == ' ') || (buffer[i] == '\n') || (buffer[i] == 0)) { // new arg found - strncpy(buff, &buffer[s], i-s); - buff[i-s] = 0; - INFO("Found argument \"%s\"", buff); - args.push_back(std::string(buff)); + buffer[i] = 0; + INFO("Found argument \"%s\"", &buffer[s]); + args.push_back(&buffer[s]); s = i+1; } }
--- a/HTTPConnection.h Sun May 26 22:49:42 2013 +0000 +++ b/HTTPConnection.h Sun May 26 23:22:36 2013 +0000 @@ -62,7 +62,7 @@ TCPSocketConnection m_Tcp; HTTPMessage m_Msg; - int parse(const char *buffer); + int parse(char *buffer); int parseHeader(const char *buffer); int receiveHeaders(const char* buffer, int nBuffSize); int receiveLine(char* szLine, int nMaxLen, int nTimeout = -1, char szLineTerm = '\n');
--- a/HTTPServer.cpp Sun May 26 22:49:42 2013 +0000 +++ b/HTTPServer.cpp Sun May 26 23:22:36 2013 +0000 @@ -16,13 +16,12 @@ #define ERR(x, ...) #endif -static const char* szMsgs = "No such file or folder."; - HTTPServer::HTTPServer(Serial* pDbg) { m_pDbg = pDbg; m_pSvr = NULL; m_bServerListening = false; + m_pErrorHandler = StdErrorHandler; } HTTPServer::~HTTPServer() @@ -34,6 +33,20 @@ } } + +const char* szStdErrorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error 404</h1><P>This resource is not available<P></BODY></HTML>\r\n\r\n"; + +void HTTPServer::StdErrorHandler(HTTPMessage& msg, TCPSocketConnection& tcp) +{ + char echoHeader[512]; + + tcp.set_blocking(true, 1500); + sprintf(echoHeader,"HTTP/1.1 404 Fail\r\nContent-Length: %d\r\nContent-Type: text/html\r\nServer: mbed embedded\r\n\n\r",strlen(szStdErrorPage)); + tcp.send(echoHeader, strlen(echoHeader)); + tcp.send((char*)szStdErrorPage, strlen(szStdErrorPage)); +} + + int HTTPServer::start(int port) { // check if the start member was called already once @@ -121,29 +134,14 @@ void HTTPServer::HandleRequest(HTTPMessage& msg, TCPSocketConnection& tcp) { - static char echoHeader[256] = {}; - static const char* szPage = { - "<HTML>\r\n" - "<HEAD>\r\n" - "<META content=\"text/html\" http-equiv=Content-Type>\r\n" - "</HEAD>\r\n" - "<BODY>\r\n" - "<h1>ERROR 404</h1>\r\n" - "<P>File not found<P>\r\n" - "</BODY>\r\n" - "</HTML>\r\n\r\n"}; - map<string, HTTPRequestHandlerFunction>::iterator it; it = m_pHandlers.find(msg.uri); if (it == m_pHandlers.end()) { // There is no such handler, so return invalid - - tcp.set_blocking(true, 1500); - sprintf(echoHeader,"HTTP/1.1 404 Fail\r\nContent-Length: %d\r\nContent-Type: text/html\r\nServer: mbed embedded\r\nConnection: Close\r\n\r\n",strlen(szPage)); - tcp.send(echoHeader,strlen(echoHeader)); - tcp.send((char*)szPage,strlen(szMsgs)); + + m_pErrorHandler(msg, tcp); INFO("Webrequest left unhandled."); } else {
--- a/HTTPServer.h Sun May 26 22:49:42 2013 +0000 +++ b/HTTPServer.h Sun May 26 23:22:36 2013 +0000 @@ -52,7 +52,9 @@ void addHandler(const char* path, HTTPRequestHandlerFunction hdlFunc) { m_pHandlers[path] = hdlFunc; } - + + void addErrorHandler(HTTPRequestHandlerFunction hdlFunc) + { m_pErrorHandler = hdlFunc!=NULL ?hdlFunc : StdErrorHandler; } ///Starts listening /** Binds server to a specific port and starts listening. This member prepares the internal variables and the server socket @@ -70,6 +72,8 @@ private: + static void StdErrorHandler(HTTPMessage&, TCPSocketConnection&); + TCPSocketServer* m_pSvr; bool m_bServerListening; @@ -77,6 +81,8 @@ void HandleRequest(HTTPMessage& con, TCPSocketConnection&); map<string, HTTPRequestHandlerFunction> m_pHandlers; + HTTPRequestHandlerFunction m_pErrorHandler; + }; #endif //__HTTPSERVER_H__ \ No newline at end of file