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@1:6b7472d5e9ee, 2013-05-26 (annotated)
- Committer:
- leihen
- Date:
- Sun May 26 22:49:42 2013 +0000
- Revision:
- 1:6b7472d5e9ee
- Parent:
- 0:7a2421e63e74
- Child:
- 2:8653bbcf7e58
Basic functionality demonstrated. One issue exists with error pages, which does not work 100%
;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
leihen | 0:7a2421e63e74 | 1 | #include "mbed.h" |
leihen | 0:7a2421e63e74 | 2 | #include "HTTPServer.h" |
leihen | 0:7a2421e63e74 | 3 | |
leihen | 0:7a2421e63e74 | 4 | DigitalOut led1(LED1); |
leihen | 0:7a2421e63e74 | 5 | DigitalOut led2(LED2); |
leihen | 0:7a2421e63e74 | 6 | DigitalOut led3(LED3); |
leihen | 0:7a2421e63e74 | 7 | DigitalOut led4(LED4); |
leihen | 0:7a2421e63e74 | 8 | |
leihen | 1:6b7472d5e9ee | 9 | #if (0 && !defined(TARGET_LPC11U24)) |
leihen | 0:7a2421e63e74 | 10 | #define INFO(x, ...) if (m_pDbg) m_pDbg->printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__); else printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__); |
leihen | 0:7a2421e63e74 | 11 | #define WARN(x, ...) if (m_pDbg) m_pDbg->printf("[HttpServer : WARN]"x"\r\n", ##__VA_ARGS__); else printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__); |
leihen | 0:7a2421e63e74 | 12 | #define ERR(x, ...) if (m_pDbg) m_pDbg->printf("[HttpServer : ERR]"x"\r\n", ##__VA_ARGS__); else printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__); |
leihen | 0:7a2421e63e74 | 13 | #else |
leihen | 0:7a2421e63e74 | 14 | #define INFO(x, ...) |
leihen | 0:7a2421e63e74 | 15 | #define WARN(x, ...) |
leihen | 0:7a2421e63e74 | 16 | #define ERR(x, ...) |
leihen | 0:7a2421e63e74 | 17 | #endif |
leihen | 0:7a2421e63e74 | 18 | |
leihen | 1:6b7472d5e9ee | 19 | static const char* szMsgs = "No such file or folder."; |
leihen | 0:7a2421e63e74 | 20 | |
leihen | 0:7a2421e63e74 | 21 | HTTPServer::HTTPServer(Serial* pDbg) |
leihen | 0:7a2421e63e74 | 22 | { |
leihen | 0:7a2421e63e74 | 23 | m_pDbg = pDbg; |
leihen | 0:7a2421e63e74 | 24 | m_pSvr = NULL; |
leihen | 0:7a2421e63e74 | 25 | m_bServerListening = false; |
leihen | 0:7a2421e63e74 | 26 | } |
leihen | 0:7a2421e63e74 | 27 | |
leihen | 0:7a2421e63e74 | 28 | HTTPServer::~HTTPServer() |
leihen | 0:7a2421e63e74 | 29 | { |
leihen | 0:7a2421e63e74 | 30 | if (m_pSvr) { |
leihen | 0:7a2421e63e74 | 31 | delete m_pSvr; |
leihen | 0:7a2421e63e74 | 32 | m_pSvr = NULL; |
leihen | 0:7a2421e63e74 | 33 | m_bServerListening = false; |
leihen | 0:7a2421e63e74 | 34 | } |
leihen | 0:7a2421e63e74 | 35 | } |
leihen | 0:7a2421e63e74 | 36 | |
leihen | 0:7a2421e63e74 | 37 | int HTTPServer::start(int port) |
leihen | 0:7a2421e63e74 | 38 | { |
leihen | 0:7a2421e63e74 | 39 | // check if the start member was called already once |
leihen | 0:7a2421e63e74 | 40 | if (m_pSvr != NULL) { |
leihen | 0:7a2421e63e74 | 41 | ERR("start function was already called, server is already in listening state."); |
leihen | 0:7a2421e63e74 | 42 | return -1; |
leihen | 0:7a2421e63e74 | 43 | } |
leihen | 0:7a2421e63e74 | 44 | |
leihen | 0:7a2421e63e74 | 45 | m_bServerListening = false; |
leihen | 0:7a2421e63e74 | 46 | |
leihen | 0:7a2421e63e74 | 47 | // Create a new server object |
leihen | 0:7a2421e63e74 | 48 | m_pSvr = new TCPSocketServer(); |
leihen | 0:7a2421e63e74 | 49 | |
leihen | 0:7a2421e63e74 | 50 | // Bind the local server to the given port |
leihen | 0:7a2421e63e74 | 51 | if (m_pSvr->bind(port) < 0) { |
leihen | 0:7a2421e63e74 | 52 | ERR("Failed to bind to port %d\n", port); |
leihen | 0:7a2421e63e74 | 53 | return -1; |
leihen | 0:7a2421e63e74 | 54 | } |
leihen | 0:7a2421e63e74 | 55 | else { |
leihen | 0:7a2421e63e74 | 56 | INFO("Binding succeeded !\n"); |
leihen | 0:7a2421e63e74 | 57 | } |
leihen | 0:7a2421e63e74 | 58 | |
leihen | 0:7a2421e63e74 | 59 | // Listen to a maximum of 10 concurrent connections |
leihen | 0:7a2421e63e74 | 60 | if (m_pSvr->listen(1) < 0) { |
leihen | 0:7a2421e63e74 | 61 | ERR("Faild to listen !\n"); |
leihen | 0:7a2421e63e74 | 62 | delete m_pSvr; |
leihen | 0:7a2421e63e74 | 63 | m_pSvr = NULL; |
leihen | 0:7a2421e63e74 | 64 | return -1; |
leihen | 0:7a2421e63e74 | 65 | } |
leihen | 0:7a2421e63e74 | 66 | else { |
leihen | 0:7a2421e63e74 | 67 | INFO("Listening\n"); |
leihen | 0:7a2421e63e74 | 68 | m_bServerListening = true; |
leihen | 0:7a2421e63e74 | 69 | } |
leihen | 0:7a2421e63e74 | 70 | |
leihen | 0:7a2421e63e74 | 71 | // set into non blocking operation |
leihen | 0:7a2421e63e74 | 72 | m_pSvr->set_blocking(false, 100); |
leihen | 0:7a2421e63e74 | 73 | |
leihen | 0:7a2421e63e74 | 74 | return 0; |
leihen | 0:7a2421e63e74 | 75 | } |
leihen | 0:7a2421e63e74 | 76 | |
leihen | 0:7a2421e63e74 | 77 | |
leihen | 0:7a2421e63e74 | 78 | int HTTPServer::poll() |
leihen | 0:7a2421e63e74 | 79 | { |
leihen | 0:7a2421e63e74 | 80 | INFO("Listening for new connection requests."); |
leihen | 0:7a2421e63e74 | 81 | |
leihen | 0:7a2421e63e74 | 82 | // This thread basically checks if there is a new incoming connection. |
leihen | 0:7a2421e63e74 | 83 | // If so , a new HTTPConnection is created and the connection thread is started. |
leihen | 0:7a2421e63e74 | 84 | TCPSocketConnection Clnt; |
leihen | 0:7a2421e63e74 | 85 | |
leihen | 0:7a2421e63e74 | 86 | led4 = 1; // Indicate we are waiting for a new connection |
leihen | 0:7a2421e63e74 | 87 | if (m_pSvr->accept(Clnt) < 0) { |
leihen | 0:7a2421e63e74 | 88 | // an error occured |
leihen | 0:7a2421e63e74 | 89 | ERR("There was an error, Accept returned with an error. Probably the connection to the router was lost. Shutting down server"); |
leihen | 0:7a2421e63e74 | 90 | led2 = 0; |
leihen | 0:7a2421e63e74 | 91 | m_bServerListening = false; |
leihen | 0:7a2421e63e74 | 92 | m_pSvr->close(); |
leihen | 0:7a2421e63e74 | 93 | delete m_pSvr; |
leihen | 0:7a2421e63e74 | 94 | m_pSvr = NULL; |
leihen | 0:7a2421e63e74 | 95 | led4 = 0; |
leihen | 0:7a2421e63e74 | 96 | led3 = 1; // ERROR |
leihen | 0:7a2421e63e74 | 97 | led2 = 0; |
leihen | 0:7a2421e63e74 | 98 | led1 = 0; |
leihen | 0:7a2421e63e74 | 99 | return -1; |
leihen | 0:7a2421e63e74 | 100 | } |
leihen | 0:7a2421e63e74 | 101 | else { |
leihen | 0:7a2421e63e74 | 102 | led4 = 0; |
leihen | 0:7a2421e63e74 | 103 | // a new connection was received |
leihen | 0:7a2421e63e74 | 104 | INFO("Client (IP=%s) is connected !\n", Clnt.get_address()); |
leihen | 0:7a2421e63e74 | 105 | // Start the main connection thread |
leihen | 0:7a2421e63e74 | 106 | led3 = 1; |
leihen | 0:7a2421e63e74 | 107 | led2 = 1; |
leihen | 0:7a2421e63e74 | 108 | HTTPConnection con; |
leihen | 0:7a2421e63e74 | 109 | int c = con.poll(); |
leihen | 0:7a2421e63e74 | 110 | if (c == 0) { |
leihen | 1:6b7472d5e9ee | 111 | // Handle the request |
leihen | 1:6b7472d5e9ee | 112 | HandleRequest(con.m_Msg, Clnt); |
leihen | 0:7a2421e63e74 | 113 | } |
leihen | 0:7a2421e63e74 | 114 | led2 = 0; |
leihen | 0:7a2421e63e74 | 115 | led3 = 0; |
leihen | 0:7a2421e63e74 | 116 | } |
leihen | 0:7a2421e63e74 | 117 | |
leihen | 0:7a2421e63e74 | 118 | INFO("Leaving polling thread"); |
leihen | 0:7a2421e63e74 | 119 | return 0; |
leihen | 1:6b7472d5e9ee | 120 | } |
leihen | 1:6b7472d5e9ee | 121 | |
leihen | 1:6b7472d5e9ee | 122 | void HTTPServer::HandleRequest(HTTPMessage& msg, TCPSocketConnection& tcp) |
leihen | 1:6b7472d5e9ee | 123 | { |
leihen | 1:6b7472d5e9ee | 124 | static char echoHeader[256] = {}; |
leihen | 1:6b7472d5e9ee | 125 | static const char* szPage = { |
leihen | 1:6b7472d5e9ee | 126 | "<HTML>\r\n" |
leihen | 1:6b7472d5e9ee | 127 | "<HEAD>\r\n" |
leihen | 1:6b7472d5e9ee | 128 | "<META content=\"text/html\" http-equiv=Content-Type>\r\n" |
leihen | 1:6b7472d5e9ee | 129 | "</HEAD>\r\n" |
leihen | 1:6b7472d5e9ee | 130 | "<BODY>\r\n" |
leihen | 1:6b7472d5e9ee | 131 | "<h1>ERROR 404</h1>\r\n" |
leihen | 1:6b7472d5e9ee | 132 | "<P>File not found<P>\r\n" |
leihen | 1:6b7472d5e9ee | 133 | "</BODY>\r\n" |
leihen | 1:6b7472d5e9ee | 134 | "</HTML>\r\n\r\n"}; |
leihen | 1:6b7472d5e9ee | 135 | |
leihen | 1:6b7472d5e9ee | 136 | map<string, HTTPRequestHandlerFunction>::iterator it; |
leihen | 1:6b7472d5e9ee | 137 | |
leihen | 1:6b7472d5e9ee | 138 | it = m_pHandlers.find(msg.uri); |
leihen | 1:6b7472d5e9ee | 139 | |
leihen | 1:6b7472d5e9ee | 140 | if (it == m_pHandlers.end()) { |
leihen | 1:6b7472d5e9ee | 141 | // There is no such handler, so return invalid |
leihen | 1:6b7472d5e9ee | 142 | |
leihen | 1:6b7472d5e9ee | 143 | tcp.set_blocking(true, 1500); |
leihen | 1:6b7472d5e9ee | 144 | 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)); |
leihen | 1:6b7472d5e9ee | 145 | tcp.send(echoHeader,strlen(echoHeader)); |
leihen | 1:6b7472d5e9ee | 146 | tcp.send((char*)szPage,strlen(szMsgs)); |
leihen | 1:6b7472d5e9ee | 147 | INFO("Webrequest left unhandled."); |
leihen | 1:6b7472d5e9ee | 148 | } |
leihen | 1:6b7472d5e9ee | 149 | else { |
leihen | 1:6b7472d5e9ee | 150 | // Handler was found so pass action to handler |
leihen | 1:6b7472d5e9ee | 151 | INFO("Routing webrequest !"); |
leihen | 1:6b7472d5e9ee | 152 | (it->second)(msg, tcp); |
leihen | 1:6b7472d5e9ee | 153 | } |
leihen | 0:7a2421e63e74 | 154 | } |