Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
HTTPServer.cpp
00001 #include "mbed.h" 00002 #include "HTTPServer.h" 00003 #define DEBUG 00004 #include "hl_debug.h" 00005 00006 00007 00008 /* Constructor */ 00009 /* initialize all members and set the standard error handler. */ 00010 HTTPServer::HTTPServer() 00011 : m_pEthernet(NULL) 00012 { 00013 m_pErrorHandler = StdErrorHandler; 00014 } 00015 00016 HTTPServer::~HTTPServer() 00017 { 00018 if (m_pEthernet == NULL) { 00019 INFO("Deleting EthernetInterface Object.\n"); 00020 delete m_pEthernet; 00021 } 00022 } 00023 00024 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"; 00025 00026 void HTTPServer::StdErrorHandler(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp) 00027 { 00028 char echoHeader[256]; 00029 tcp.set_blocking(true, 1500); 00030 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)); 00031 tcp.send(echoHeader, strlen(echoHeader)); 00032 tcp.send((char*)szStdErrorPage, strlen(szStdErrorPage)); 00033 } 00034 00035 00036 bool HTTPServer::start(int port, EthernetInterface* pEthernet) 00037 { 00038 // If no ethernet interface is provided, instantiate own on the heap. This has to be deleted later in the destructor. 00039 // If a valid pointer to an thernet interface is proveded, we can simply use it. 00040 if (pEthernet == NULL) { 00041 INFO("Creating EthernetInterface object\n"); 00042 m_pEthernet = new EthernetInterface(); 00043 00044 if (m_pEthernet == NULL) { 00045 ERR("Out of memory, unable to instantiate an EthernetInterface object."); 00046 return false; 00047 } 00048 00049 // Initiaize the network 00050 INFO("Initializing network\n"); 00051 if (m_pEthernet->init() != 0) { 00052 ERR("Failed to initialize the ethernet interface !"); 00053 delete m_pEthernet; 00054 m_pEthernet = NULL; 00055 return false; 00056 } 00057 00058 // Connect to the network using DHCP 00059 INFO("Connecting to the network using DHCP..."); 00060 if (m_pEthernet->connect() != 0) { 00061 ERR("Failed to connect to the ethernet !"); 00062 delete m_pEthernet; 00063 m_pEthernet = NULL; 00064 return false; 00065 } 00066 00067 INFO("Connected IP %s", m_pEthernet->getIPAddress()); 00068 00069 } else { 00070 // In the case that the ethernet interface is provided, it is assumed that a connection has already been created. 00071 INFO("Using connection IP %s", pEthernet->getIPAddress()); 00072 } 00073 00074 INFO("Binding to port %d...", port); 00075 if (m_Svr.bind(port) < 0) { 00076 ERR("Failed to bind to port !\n"); 00077 error("Binding"); 00078 return false; 00079 } 00080 00081 INFO("Listening ..."); 00082 if (m_Svr.listen(1) < 0) { 00083 ERR("Failed to listen !\n"); 00084 error("Listening"); 00085 return false; 00086 } 00087 00088 INFO("Connected !"); 00089 // set into non blocking operation 00090 m_Svr.set_blocking(false, 100); 00091 00092 return true; 00093 } 00094 00095 00096 int HTTPServer::poll(bool blocking) 00097 { 00098 // This thread basically checks if there is a new incoming connection. 00099 // If so , a new HTTPConnection is created and the connection thread is started. 00100 TCPSocketConnection Clnt; 00101 if (m_Svr.accept(Clnt) < 0) { 00102 return -1; 00103 } 00104 00105 // a new connection was received 00106 INFO("Client (IP=%s) is connected !\n", Clnt.get_address()); 00107 HTTPConnection con(Clnt); 00108 int c = con.poll(); 00109 if (c == 0) { 00110 // Handle the request 00111 INFO("Handling request !"); 00112 HandleRequest(con.m_Msg, Clnt); 00113 } 00114 if (c == -1) { 00115 // break; 00116 } 00117 00118 INFO("Leaving polling thread"); 00119 return 0; 00120 } 00121 00122 void HTTPServer::HandleRequest(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp) 00123 { 00124 std::string localPath; 00125 std::map<std::string, HTTPRequestHandler*(*)(const char*, const char*, HTTPConnection::HTTPMessage&, TCPSocketConnection&), handlersComp>::const_iterator it; 00126 00127 // Iterate through registered handlers and check if the handler's path is a subset of the requested uri. 00128 for (it = m_lpHandlers.begin() ; it != m_lpHandlers.end() ; it++) { 00129 // check if this entries' path is fully contained at the beginning of the requested path 00130 std::string curpth = it->first; 00131 00132 if (msg.uri.find(curpth) == 0) { 00133 // firts matching handler found, we just take it and we'll be happy 00134 localPath = msg.uri.substr(curpth.length()); 00135 break; 00136 } 00137 } 00138 00139 if (it == m_lpHandlers.end()) { 00140 // There is no such handler, so return invalid 00141 00142 m_pErrorHandler(msg, tcp); 00143 INFO("Webrequest left unhandled."); 00144 } else { 00145 // Valid handler was found 00146 INFO("Routing webrequest !"); 00147 // Instantiate the handler object (handling will be done from withing the object's constructor 00148 HTTPRequestHandler *phdl = (*it->second)(it->first.c_str(), localPath.c_str(), msg, tcp); 00149 // now we can delete the object, because handling is completed. 00150 if (phdl != NULL) 00151 delete phdl; 00152 } 00153 }
Generated on Wed Jul 13 2022 04:37:34 by
1.7.2