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.
Dependents: RPC_HTTP RPC_HTTP_WIZnetInterface RPC_HTTP rpc_over_http_TL_interrupter_gatePJ
Fork of HTTPServer by
Revision 13:aa5338a5e452, committed 2013-06-22
- Comitter:
- leihen
- Date:
- Sat Jun 22 15:41:34 2013 +0000
- Parent:
- 12:ba81cc117fb6
- Child:
- 14:011edcd33e86
- Commit message:
- First Version of a working Ethernet HTTP Server.
Changed in this revision
--- a/HTTPConnection.cpp Wed Jun 05 23:39:24 2013 +0000
+++ b/HTTPConnection.cpp Sat Jun 22 15:41:34 2013 +0000
@@ -2,24 +2,14 @@
#include "mbed.h"
#include "HTTPConnection.h"
-
-#define _DEBUG 0
+#define DEBUG
+#include "debug.h"
#include <vector>
using std::vector;
using std::string;
-#if (_DEBUG && !defined(TARGET_LPC11U24))
-#define INFO(x, ...) std::printf("[HttpConnection : INFO]"x"\r\n", ##__VA_ARGS__);
-#define WARN(x, ...) std::printf("[HttpConnection : WARN]"x"\r\n", ##__VA_ARGS__);
-#define ERR(x, ...) std::printf("[HttpConnection : ERR]"x"\r\n", ##__VA_ARGS__);
-#else
-#define INFO(x, ...)
-#define WARN(x, ...)
-#define ERR(x, ...)
-#endif
-
const struct HTTPRequestConfig {
@@ -37,7 +27,7 @@
};
-HTTPConnection::HTTPConnection()
+HTTPConnection::HTTPConnection(TCPSocketConnection& clnt) : m_Tcp(clnt)
{
}
@@ -108,8 +98,13 @@
if ((szLine == NULL) || (nMaxLen == 0))
return -1;
+ szLine[0] = 0;
m_Tcp.set_blocking(false);
+ if (!m_Tcp.is_connected()) {
+ error("NOT COnnected anymore");
+ return -1;
+ }
Timer tm;
int i;
@@ -129,7 +124,9 @@
// Check if line terminating character was received
if (szLine[i] == cLineTerm)
+ {
break;
+ }
}
// Terminate with \0
szLine[i] = 0;
@@ -139,7 +136,6 @@
i--;
szLine[i] = 0;
}
- INFO("receiveLine : \"%s\".", szLine);
// return number of characters received in the line or return -2 if an empty line was received
if ((i == 0) || ((i==1) &&(szLine[0] == '\r')))
--- a/HTTPConnection.h Wed Jun 05 23:39:24 2013 +0000
+++ b/HTTPConnection.h Sat Jun 22 15:41:34 2013 +0000
@@ -75,7 +75,7 @@
/** Public constructor for HTTPConnection objects.
*
*/
- HTTPConnection ();
+ HTTPConnection (TCPSocketConnection& clnt);
/** Destructor for HTTPConnection objects.
*
--- a/HTTPRequestHandler.cpp Wed Jun 05 23:39:24 2013 +0000
+++ b/HTTPRequestHandler.cpp Sat Jun 22 15:41:34 2013 +0000
@@ -1,30 +1,21 @@
/* HTTPRequestHandler.cpp */
#include "mbed.h"
#include "HTTPRequestHandler.h"
+#define DEBUG
+#include "debug.h"
#include <ctype.h>
-#define _DEBUG 0
-
-#if (_DEBUG && !defined(TARGET_LPC11U24))
-#define INFO(x, ...) std::printf("[HTTPRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
-#define WARN(x, ...) std::printf("[HTTPRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
-#define ERR(x, ...) std::printf("[HTTPRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
-#else
-#define INFO(x, ...)
-#define WARN(x, ...)
-#define ERR(x, ...)
-#endif
static char buffer[128];
-const char hdrDNT[] = "DNT: 1\r\n";
-const char hdrMaxAge[] = "MaxAge: 0\r\n";
-const char hdrConClose[] = "Connection: Keep-Alive\r\n";
-//const char hdrTrsfrEnc[] = "Transfer-Encoding: Chunked\r\n";
-const char hdrContent[] = "Content-Type: text/html\r\n";
-const char hdrServer[] = "Server: mbed embedded\r\n";
-const char hdrEndl[] = "\r\n";
+const char hdrStandard[] = "DNT: 1\r\n"
+ "MaxAge: 0\r\n"
+ "Connection: Keep-Alive\r\n"
+ "Content-Type: text/html\r\n"
+ "Server: mbed embedded\r\n"
+ "Accessible: 1\r\n"
+ "\r\n";
static int _stricmp(const char* a, const char* b)
@@ -54,7 +45,9 @@
{".txt", "Content-Type: plain/text\r\n" },
{".pdf", "Content-Type: application/pdf\r\n" },
{".htm", "Content-Type: text/html\r\n" },
- {".html","Content-Type: text/html\r\n" }};
+ {".html","Content-Type: text/html\r\n" },
+ {".css", "Content-Type: text/css\r\n" },
+ {".js", "Content-Type: text/javascript\r\n"}};
HTTPRequestHandler::HTTPRequestHandler(HTTPConnection::HTTPMessage& Msg, TCPSocketConnection& Tcp)
: msg(Msg), tcp(Tcp)
@@ -119,12 +112,12 @@
}
}
-static const char* szErrorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error %d</h1><P>HTTPServer Error<P></BODY></HTML>\r\n\r\n";
+static const char* szErrorPage = "<HTML><HEAD><META content=\"text/html\" http-equiv=Content-Type></HEAD><BODY><h1>Error</h1><P>HTTPServer Error<P></BODY></HTML>\r\n\r\n";
void HTTPRequestHandler::handleError(int errorCode, HTTPHeaders* header)
{
INFO("Handling error !");
- tcp.set_blocking(true, 1500);
+ tcp.set_blocking(false, 1500);
sprintf(buffer,"HTTP/1.1 %d Error\r\n", errorCode);
tcp.send(buffer, strlen(buffer));
sprintf(buffer, "Content-Length: %d\r\n", strlen(szErrorPage));
@@ -149,29 +142,25 @@
void HTTPRequestHandler::startResponse(int returnCode, long nLen, HTTPHeaders* header)
{
INFO("Starting response (%ld bytes in total)!", nLen);
- tcp.set_blocking(true, 1500);
+ tcp.set_blocking(false, 1500);
sprintf(buffer, "HTTP/1.1 %d OK\r\n", returnCode);
- tcp.send_all(buffer, strlen(buffer));
- tcp.send_all((char*)hdrConClose, strlen(hdrConClose));
+ tcp.send(buffer, strlen(buffer));
sprintf(buffer, "Content-Length: %ld\r\n", nLen); // Add 2 chars for the terminating CR+LF
- tcp.send_all(buffer, strlen(buffer));
+ tcp.send(buffer, strlen(buffer));
+ INFO("Sending standard headers !");
if (header == NULL) {
- tcp.send_all((char*)hdrDNT, strlen(hdrDNT));
- tcp.send_all((char*)hdrMaxAge, strlen(hdrMaxAge));
- tcp.send_all((char*)hdrContent, strlen(hdrContent));
-// tcp.send_all((char*)hdrTrsfrEnc, strlen(hdrTrsfrEnc));
- tcp.send_all((char*)hdrServer, strlen(hdrServer));
- tcp.send_all((char*)hdrEndl, strlen(hdrEndl));
+ tcp.send_all((char*)hdrStandard, strlen(hdrStandard));
}
else {
for ( map<const char*, const char*>::iterator cIter = header->begin() ; cIter != header->end() ; cIter ++) {
- tcp.send((char*)cIter->first, strlen(cIter->first));
- tcp.send(": ", 2);
- tcp.send((char*)cIter->second, strlen(cIter->second));
- tcp.send("\r\n\r\n",2);
+ tcp.send_all((char*)cIter->first, strlen(cIter->first));
+ tcp.send_all(": ", 2);
+ tcp.send_all((char*)cIter->second, strlen(cIter->second));
+ tcp.send_all("\r\n\r\n",2);
}
tcp.send_all("\r\n", 2);
}
+ INFO("Proceeding !");
// other content must be sent using the 'processResponse' function
}
@@ -184,5 +173,4 @@
void HTTPRequestHandler::endResponse()
{
INFO("Ending Response !");
-// tcp.send("\r\n\r\n", 4);
}
--- a/HTTPServer.cpp Wed Jun 05 23:39:24 2013 +0000
+++ b/HTTPServer.cpp Sat Jun 22 15:41:34 2013 +0000
@@ -1,7 +1,9 @@
#include "mbed.h"
#include "HTTPServer.h"
+#define DEBUG
+#include "debug.h"
-#define _DEBUG 0
+#define _DEBUG 1
#ifdef _DEBUG
DigitalOut led1(LED1);
@@ -10,32 +12,17 @@
DigitalOut led4(LED4);
#endif
-#if (_DEBUG && !defined(TARGET_LPC11U24))
-#define INFO(x, ...) std::printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__);
-#define WARN(x, ...) std::printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__);
-#define ERR(x, ...) std::printf("[HttpServer : DBG]"x"\r\n", ##__VA_ARGS__);
-#else
-#define INFO(x, ...)
-#define WARN(x, ...)
-#define ERR(x, ...)
-#endif
-
+static EthernetInterface eth;
/* Constructor */
/* initialize all members and set the standard error handler. */
-HTTPServer::HTTPServer(PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec)
- : m_wifly(tx, rx, reset, tcp_status, ssid, phrase, sec)
+HTTPServer::HTTPServer()
{
m_pErrorHandler = StdErrorHandler;
- m_pSvr = NULL;
}
HTTPServer::~HTTPServer()
{
- if (m_pSvr) {
- delete m_pSvr;
- m_pSvr = NULL;
- }
}
@@ -51,93 +38,47 @@
}
-int HTTPServer::start(int port)
+bool HTTPServer::start(int port)
{
- // check if the start member was called already once
- if (m_pSvr != NULL) {
- ERR("start function was already called, server is already in listening state.");
- return -1;
- }
- INFO("Initializing wifly\n");
- // Initialize the wifly wlan device
- m_wifly.init();
+ INFO("Initializing network\n");
+ eth.init();
INFO("Connecting to network...");
- // Try join the network
- while(!m_wifly.connect()) {
- INFO("Failed to connect. Trying again\n");
- m_wifly.reset();
- }
- INFO("connected\n");
+ eth.connect();
- // check if the start member was called already once
- if (m_pSvr != NULL) {
- ERR("start function was already called, server is already in listening state.");
- return -1;
- }
-
- // Create a new server object
- m_pSvr = new TCPSocketServer();
-
- // Bind the local server to the given port
- if (m_pSvr->bind(port) < 0) {
- ERR("Failed to bind to port %d\n", port);
- return -1;
- }
- else {
- INFO("Binding succeeded !\n");
+ INFO("Binding to port %d...", port);
+ if (m_Svr.bind(port) < 0) {
+ ERR("Failed to bind to port !\n");
+ error("Binding");
+ return false;
}
- // Listen to a maximum of 10 concurrent connections
- if (m_pSvr->listen(1) < 0) {
- ERR("Faild to listen !\n");
- delete m_pSvr;
- m_pSvr = NULL;
- return -1;
- }
- else {
- INFO("Listening\n");
+ INFO("Listening ...");
+ if (m_Svr.listen(1) < 0) {
+ ERR("Failed to listen !\n");
+ error("Listening");
+ return false;
}
+ ERR("Connected !");
// set into non blocking operation
- m_pSvr->set_blocking(false, 100);
-
- return 0;
+ m_Svr.set_blocking(false, 100);
+
+ return true;
}
int HTTPServer::poll(bool blocking)
-{
+{
int retval = -1;
- INFO("Listening for new connection requests.");
+#ifdef _DEBUG
+ led4 = 1; // Indicate we are waiting for a new connection
+#endif
// This thread basically checks if there is a new incoming connection.
// If so , a new HTTPConnection is created and the connection thread is started.
TCPSocketConnection Clnt;
-
-#ifdef _DEBUG
- led4 = 1; // Indicate we are waiting for a new connection
-#endif
- m_pSvr->set_blocking(blocking);
- retval = m_pSvr->accept(Clnt);
- if (retval > 0) {
- // no connection availale yet, so just return
-#ifdef _DEBUG
-led4 = 0;
-led3 = 0;
-led2 = 0;
-#endif
- return retval;
- }
- if ( retval < 0) {
- // an error occured
- ERR("There was an error, Accept returned with an error. Probably the connection to the router was lost. Shutting down server");
-#ifdef _DEBUG
- led2 = 0;
-#endif
- m_pSvr->close();
- delete m_pSvr;
- m_pSvr = NULL;
+ if (m_Svr.accept(Clnt) < 0) {
#ifdef _DEBUG
led4 = 0;
led3 = 1; // ERROR
@@ -146,40 +87,35 @@
#endif
return -1;
}
- else {
+
+ // a new connection was received
+ INFO("Client (IP=%s) is connected !\n", Clnt.get_address());
+#ifdef _DEBUG
+ led4 = 0;
+ led3 = 0;
+ led2 = 0;
+#endif
+
#ifdef _DEBUG
- led4 = 0;
-#endif
- // a new connection was received
- INFO("Client (IP=%s) is connected !\n", Clnt.get_address());
- // Start the main connection thread
-// while(1) {
-
- #ifdef _DEBUG
- led3 = 1;
- led2 = 1;
- #endif
- HTTPConnection con;
- int c = con.poll();
- if (c == 0) {
- // Handle the request
- HandleRequest(con.m_Msg, Clnt);
-// INFO("Closing connection.\n");
-// if (!m_wifly.close()) {
-// ERR("Failed to close connection !\n");
-// }
- }
- if (c == -1) {
- // No more data available or error
- // break;
- }
- #ifdef _DEBUG
- led2 = 0;
- led3 = 0;
- #endif
-// }
+ led3 = 1;
+ led2 = 1;
+#endif
+ HTTPConnection con(Clnt);
+ int c = con.poll();
+ if (c == 0) {
+ // Handle the request
+ INFO("Handling request !");
+ HandleRequest(con.m_Msg, Clnt);
}
-
+ if (c == -1) {
+// break;
+ }
+#ifdef _DEBUG
+ led2 = 0;
+ led3 = 0;
+#endif
+
+
INFO("Leaving polling thread");
return 0;
}
@@ -200,14 +136,13 @@
break;
}
}
-
+
if (it == m_lpHandlers.end()) {
// There is no such handler, so return invalid
- m_pErrorHandler(msg, tcp);
+ m_pErrorHandler(msg, tcp);
INFO("Webrequest left unhandled.");
- }
- else {
+ } else {
// Valid handler was found
INFO("Routing webrequest !");
// Instantiate the handler object (handling will be done from withing the object's constructor
--- a/HTTPServer.h Wed Jun 05 23:39:24 2013 +0000
+++ b/HTTPServer.h Sat Jun 22 15:41:34 2013 +0000
@@ -23,7 +23,7 @@
#ifndef __HTTPSERVER_H__
#define __HTTPSERVER_H__
#include "mbed.h"
-#include "WiflyInterface.h"
+#include "EthernetInterface.h"
#include "HTTPConnection.h"
#include "HTTPRequestHandler.h"
@@ -76,14 +76,13 @@
class HTTPServer
{
- TCPSocketServer* m_pSvr;
+ TCPSocketServer m_Svr;
bool m_bServerListening;
- WiflyInterface m_wifly;
public:
/** Constructor for HTTPServer objects.
*/
- HTTPServer(PinName tx, PinName rx, PinName reset, PinName tcp_status, const char * ssid, const char * phrase, Security sec);
+ HTTPServer();
/** Destructor for HTTPServer objects.
*/
@@ -130,7 +129,7 @@
* @param port : port on which to listen for incoming connections
* @returns : -1 if an unrecoverable error occured, or 0 if everything was ok.
*/
- int start(int port = 80);
+ bool start(int port = 80);
/** Performs the regular polling of the server component. Needs to be called cyclically.
* The function will internally check whether new connections are requested by a client and will also poll all existing client connections.
@@ -139,10 +138,7 @@
* ready for processing the next request. Simply call \c poll as long as you want to serve new incoming requests.
*/
int poll(bool blocking = true);
-
- string getTime()
- { return m_wifly.getTime(false); }
-
+
private:
/** The standard error handler function.
* @param msg : Request message data.
--- a/Handler/FsHandler.cpp Wed Jun 05 23:39:24 2013 +0000
+++ b/Handler/FsHandler.cpp Sat Jun 22 15:41:34 2013 +0000
@@ -1,19 +1,8 @@
/* FsHandler.cpp */
#include "mbed.h"
#include "FsHandler.h"
-
-
-#define _DEBUG 0
-
-#if (_DEBUG && !defined(TARGET_LPC11U24))
-#define INFO(x, ...) std::printf("[HTTPFsRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
-#define WARN(x, ...) std::printf("[HTTPFsRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
-#define ERR(x, ...) std::printf("[HTTPFsRequestHandler : DBG]"x"\r\n", ##__VA_ARGS__);
-#else
-#define INFO(x, ...)
-#define WARN(x, ...)
-#define ERR(x, ...)
-#endif
+#define DEBUG
+#include "debug.h"
