Team E1

Fork of HTTPServer by Sam Kirsch

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?

UserRevisionLine numberNew 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 }