HTTP Server library for Mbed OS-5. A fork of Henry Leinen's [[https://os.mbed.com/users/leihen/code/HTTPServer/]] library.

Dependents:   STM32F407VET6_HTTPServer

Committer:
hudakz
Date:
Sun Oct 06 18:10:41 2019 +0000
Revision:
17:8bcc62289a07
Parent:
16:cc3f5c53d0d5
HTTP Server library for Mbed OS-5. A fork of Henry Leine's [[https://os.mbed.com/users/leihen/code/HTTPServer | HTTPServer]] library.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
leihen 0:7a2421e63e74 1 #include "mbed.h"
leihen 0:7a2421e63e74 2 #include "HTTPServer.h"
leihen 13:aa5338a5e452 3 #define DEBUG
leihen 16:cc3f5c53d0d5 4 #include "hl_debug.h"
leihen 4:d065642c32cc 5
leihen 0:7a2421e63e74 6
leihen 4:d065642c32cc 7
leihen 4:d065642c32cc 8 /* Constructor */
leihen 4:d065642c32cc 9 /* initialize all members and set the standard error handler. */
leihen 13:aa5338a5e452 10 HTTPServer::HTTPServer()
leihen 14:011edcd33e86 11 : m_pEthernet(NULL)
leihen 0:7a2421e63e74 12 {
leihen 9:c2a1462b9b71 13 m_pErrorHandler = StdErrorHandler;
leihen 0:7a2421e63e74 14 }
leihen 0:7a2421e63e74 15
leihen 0:7a2421e63e74 16 HTTPServer::~HTTPServer()
leihen 0:7a2421e63e74 17 {
leihen 14:011edcd33e86 18 if (m_pEthernet == NULL) {
leihen 14:011edcd33e86 19 INFO("Deleting EthernetInterface Object.\n");
leihen 14:011edcd33e86 20 delete m_pEthernet;
leihen 14:011edcd33e86 21 }
leihen 0:7a2421e63e74 22 }
leihen 0:7a2421e63e74 23
leihen 4:d065642c32cc 24 static 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";
leihen 2:8653bbcf7e58 25
hudakz 17:8bcc62289a07 26 void HTTPServer::StdErrorHandler(HTTPConnection::HTTPMessage& msg, TCPSocket* tcp)
leihen 2:8653bbcf7e58 27 {
leihen 4:d065642c32cc 28 char echoHeader[256];
hudakz 17:8bcc62289a07 29 tcp->set_blocking(false);
leihen 11:3943841e1798 30 sprintf(echoHeader,"HTTP/1.0 404 Fail\r\nConnection: close\r\nContent-Length: %d\r\nContent-Type: text/html\r\nServer: mbed embedded\r\n\n\r",strlen(szStdErrorPage));
hudakz 17:8bcc62289a07 31 tcp->send(echoHeader, strlen(echoHeader));
hudakz 17:8bcc62289a07 32 tcp->send((char*)szStdErrorPage, strlen(szStdErrorPage));
leihen 2:8653bbcf7e58 33 }
leihen 2:8653bbcf7e58 34
leihen 2:8653bbcf7e58 35
leihen 14:011edcd33e86 36 bool HTTPServer::start(int port, EthernetInterface* pEthernet)
leihen 0:7a2421e63e74 37 {
leihen 14:011edcd33e86 38 // If no ethernet interface is provided, instantiate own on the heap. This has to be deleted later in the destructor.
leihen 14:011edcd33e86 39 // If a valid pointer to an thernet interface is proveded, we can simply use it.
leihen 14:011edcd33e86 40 if (pEthernet == NULL) {
hudakz 17:8bcc62289a07 41 ERR("Socket is not opened!!\r\n");
leihen 14:011edcd33e86 42
leihen 14:011edcd33e86 43 } else {
leihen 14:011edcd33e86 44 // In the case that the ethernet interface is provided, it is assumed that a connection has already been created.
hudakz 17:8bcc62289a07 45 INFO("Using connection IP %s", pEthernet->get_ip_address());
leihen 14:011edcd33e86 46 }
leihen 14:011edcd33e86 47
hudakz 17:8bcc62289a07 48 nsapi_error_t r;
hudakz 17:8bcc62289a07 49 const char* ip = pEthernet->get_ip_address();
hudakz 17:8bcc62289a07 50
hudakz 17:8bcc62289a07 51 /* Open the server on ethernet stack */
hudakz 17:8bcc62289a07 52 INFO("Opening server on the Ethernet stack ...");
hudakz 17:8bcc62289a07 53 r = m_Svr.open(pEthernet);
hudakz 17:8bcc62289a07 54 if (r != 0) {
hudakz 17:8bcc62289a07 55 INFO("Error! Opening server returned: %d\n", r);
hudakz 17:8bcc62289a07 56 error("Opening server");
hudakz 17:8bcc62289a07 57 return false;
hudakz 17:8bcc62289a07 58 }
hudakz 17:8bcc62289a07 59
leihen 13:aa5338a5e452 60 INFO("Binding to port %d...", port);
hudakz 17:8bcc62289a07 61 if (m_Svr.bind(ip, port) < 0) {
leihen 13:aa5338a5e452 62 ERR("Failed to bind to port !\n");
leihen 13:aa5338a5e452 63 error("Binding");
leihen 13:aa5338a5e452 64 return false;
leihen 0:7a2421e63e74 65 }
leihen 0:7a2421e63e74 66
leihen 13:aa5338a5e452 67 if (m_Svr.listen(1) < 0) {
leihen 13:aa5338a5e452 68 ERR("Failed to listen !\n");
leihen 13:aa5338a5e452 69 error("Listening");
leihen 13:aa5338a5e452 70 return false;
leihen 0:7a2421e63e74 71 }
leihen 0:7a2421e63e74 72
hudakz 17:8bcc62289a07 73 INFO("Listening ...");
hudakz 17:8bcc62289a07 74 // set into non blocking operation after timeout
hudakz 17:8bcc62289a07 75 m_Svr.set_timeout(1500);
hudakz 17:8bcc62289a07 76
leihen 13:aa5338a5e452 77 return true;
leihen 0:7a2421e63e74 78 }
leihen 0:7a2421e63e74 79
leihen 0:7a2421e63e74 80
leihen 6:fe661fa9d18a 81 int HTTPServer::poll(bool blocking)
leihen 13:aa5338a5e452 82 {
leihen 0:7a2421e63e74 83 // This thread basically checks if there is a new incoming connection.
leihen 0:7a2421e63e74 84 // If so , a new HTTPConnection is created and the connection thread is started.
hudakz 17:8bcc62289a07 85 nsapi_error_t error;
hudakz 17:8bcc62289a07 86 SocketAddress clntAddress;
hudakz 17:8bcc62289a07 87 TCPSocket* clnt = m_Svr.accept(&error);
hudakz 17:8bcc62289a07 88
hudakz 17:8bcc62289a07 89 if (clnt == NULL) {
leihen 0:7a2421e63e74 90 return -1;
leihen 0:7a2421e63e74 91 }
hudakz 17:8bcc62289a07 92
hudakz 17:8bcc62289a07 93 if (error != 0) {
hudakz 17:8bcc62289a07 94 clnt->close();
hudakz 17:8bcc62289a07 95 return error;
hudakz 17:8bcc62289a07 96 }
leihen 13:aa5338a5e452 97
leihen 13:aa5338a5e452 98 // a new connection was received
hudakz 17:8bcc62289a07 99 clnt->getpeername(&clntAddress);
hudakz 17:8bcc62289a07 100 INFO("Client (IP=%s) is connected !\n", clntAddress.get_ip_address());
hudakz 17:8bcc62289a07 101 HTTPConnection con(clnt);
leihen 13:aa5338a5e452 102 int c = con.poll();
leihen 13:aa5338a5e452 103 if (c == 0) {
leihen 13:aa5338a5e452 104 // Handle the request
leihen 13:aa5338a5e452 105 INFO("Handling request !");
hudakz 17:8bcc62289a07 106 HandleRequest(con.m_Msg, clnt);
leihen 0:7a2421e63e74 107 }
leihen 13:aa5338a5e452 108 if (c == -1) {
leihen 13:aa5338a5e452 109 // break;
leihen 13:aa5338a5e452 110 }
leihen 13:aa5338a5e452 111
leihen 0:7a2421e63e74 112 INFO("Leaving polling thread");
leihen 0:7a2421e63e74 113 return 0;
leihen 1:6b7472d5e9ee 114 }
leihen 1:6b7472d5e9ee 115
hudakz 17:8bcc62289a07 116 void HTTPServer::HandleRequest(HTTPConnection::HTTPMessage& msg, TCPSocket* tcp)
leihen 3:d6224049b3bf 117 {
leihen 3:d6224049b3bf 118 std::string localPath;
hudakz 17:8bcc62289a07 119 std::map<std::string, HTTPRequestHandler*(*)(const char*, const char*, HTTPConnection::HTTPMessage&, TCPSocket*), handlersComp>::const_iterator it;
leihen 3:d6224049b3bf 120
leihen 4:d065642c32cc 121 // Iterate through registered handlers and check if the handler's path is a subset of the requested uri.
leihen 3:d6224049b3bf 122 for (it = m_lpHandlers.begin() ; it != m_lpHandlers.end() ; it++) {
leihen 3:d6224049b3bf 123 // check if this entries' path is fully contained at the beginning of the requested path
leihen 3:d6224049b3bf 124 std::string curpth = it->first;
leihen 3:d6224049b3bf 125
leihen 3:d6224049b3bf 126 if (msg.uri.find(curpth) == 0) {
leihen 4:d065642c32cc 127 // firts matching handler found, we just take it and we'll be happy
leihen 3:d6224049b3bf 128 localPath = msg.uri.substr(curpth.length());
leihen 3:d6224049b3bf 129 break;
leihen 3:d6224049b3bf 130 }
leihen 3:d6224049b3bf 131 }
leihen 13:aa5338a5e452 132
leihen 3:d6224049b3bf 133 if (it == m_lpHandlers.end()) {
leihen 3:d6224049b3bf 134 // There is no such handler, so return invalid
leihen 3:d6224049b3bf 135
leihen 13:aa5338a5e452 136 m_pErrorHandler(msg, tcp);
leihen 3:d6224049b3bf 137 INFO("Webrequest left unhandled.");
leihen 13:aa5338a5e452 138 } else {
leihen 4:d065642c32cc 139 // Valid handler was found
leihen 3:d6224049b3bf 140 INFO("Routing webrequest !");
leihen 4:d065642c32cc 141 // Instantiate the handler object (handling will be done from withing the object's constructor
leihen 3:d6224049b3bf 142 HTTPRequestHandler *phdl = (*it->second)(it->first.c_str(), localPath.c_str(), msg, tcp);
leihen 4:d065642c32cc 143 // now we can delete the object, because handling is completed.
leihen 3:d6224049b3bf 144 if (phdl != NULL)
leihen 3:d6224049b3bf 145 delete phdl;
leihen 3:d6224049b3bf 146 }
leihen 3:d6224049b3bf 147 }