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.
Fork of HTTPServer by
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 wait(10.0); 00068 INFO("Connected IP %s", m_pEthernet->getIPAddress()); 00069 00070 } else { 00071 // In the case that the ethernet interface is provided, it is assumed that a connection has already been created. 00072 INFO("Using connection IP %s", pEthernet->getIPAddress()); 00073 } 00074 00075 INFO("Binding to port %d...", port); 00076 if (m_Svr.bind(port) < 0) { 00077 ERR("Failed to bind to port !\n"); 00078 error("Binding"); 00079 return false; 00080 } 00081 00082 INFO("Listening ..."); 00083 if (m_Svr.listen(1) < 0) { 00084 ERR("Failed to listen !\n"); 00085 error("Listening"); 00086 return false; 00087 } 00088 00089 INFO("Connected !"); 00090 // set into non blocking operation 00091 m_Svr.set_blocking(false, 100); 00092 00093 return true; 00094 } 00095 00096 00097 int HTTPServer::poll(bool blocking) 00098 { 00099 // This thread basically checks if there is a new incoming connection. 00100 // If so , a new HTTPConnection is created and the connection thread is started. 00101 TCPSocketConnection Clnt; 00102 if (m_Svr.accept(Clnt) < 0) { 00103 return -1; 00104 } 00105 00106 // a new connection was received 00107 INFO("Client (IP=%s) is connected !\n", Clnt.get_address()); 00108 HTTPConnection con(Clnt); 00109 int c = con.poll(); 00110 if (c == 0) { 00111 // Handle the request 00112 INFO("Handling request !"); 00113 HandleRequest(con.m_Msg, Clnt); 00114 } 00115 if (c == -1) { 00116 // break; 00117 } 00118 00119 INFO("Leaving polling thread"); 00120 return 0; 00121 } 00122 00123 void HTTPServer::HandleRequest(HTTPConnection::HTTPMessage& msg, TCPSocketConnection& tcp) 00124 { 00125 std::string localPath; 00126 std::map<std::string, HTTPRequestHandler*(*)(const char*, const char*, HTTPConnection::HTTPMessage&, TCPSocketConnection&), handlersComp>::const_iterator it; 00127 00128 // Iterate through registered handlers and check if the handler's path is a subset of the requested uri. 00129 for (it = m_lpHandlers.begin() ; it != m_lpHandlers.end() ; it++) { 00130 // check if this entries' path is fully contained at the beginning of the requested path 00131 std::string curpth = it->first; 00132 00133 if (msg.uri.find(curpth) == 0) { 00134 // firts matching handler found, we just take it and we'll be happy 00135 localPath = msg.uri.substr(curpth.length()); 00136 break; 00137 } 00138 } 00139 00140 if (it == m_lpHandlers.end()) { 00141 // There is no such handler, so return invalid 00142 00143 m_pErrorHandler(msg, tcp); 00144 INFO("Webrequest left unhandled."); 00145 } else { 00146 // Valid handler was found 00147 INFO("Routing webrequest !"); 00148 // Instantiate the handler object (handling will be done from withing the object's constructor 00149 HTTPRequestHandler *phdl = (*it->second)(it->first.c_str(), localPath.c_str(), msg, tcp); 00150 // now we can delete the object, because handling is completed. 00151 if (phdl != NULL) 00152 delete phdl; 00153 } 00154 }
Generated on Tue Jul 12 2022 19:23:50 by
1.7.2
