Changes made for RPC
Embed:
(wiki syntax)
Show/hide line numbers
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 Mon Jul 18 2022 11:51:41 by
