HTTP Server upon new mbed Ethernet Interface. Based on original code by Henry Leinen.
Dependencies: EthernetInterface mbed-rtos mbed
Fork of HTTP_server by
Diff: HTTPServer.cpp
- Revision:
- 2:dc9184e97328
- Parent:
- 0:fcceff3299be
- Child:
- 3:27b3a889b327
--- a/HTTPServer.cpp Fri Jul 26 22:33:47 2013 +0000 +++ b/HTTPServer.cpp Sun Jul 28 07:53:35 2013 +0000 @@ -1,16 +1,6 @@ #include "mbed.h" #include "HTTPServer.h" -#define DEBUG -#include "debug.h" - -#define TIMEOUT 500 -#define OK 0 -#define ERROR -1 -#define EMPTY -2 -#define MIN_LONG 3 - - RequestConfig rq_conf[] = { { "GET", HTTP_RT_GET }, { "POST", HTTP_RT_POST} @@ -32,7 +22,7 @@ INFO("Connected !"); // set into blocking operation - socketServer.set_blocking (true, TIMEOUT); + socketServer.set_blocking (true); path = _path; @@ -50,24 +40,24 @@ return ERROR; } - // a new connection was received - INFO("Client (IP=%s) is connected !\n", cliente->get_address()); + // a new connection was received + INFO("Client (IP=%s) is connected !", cliente->get_address()); msg = new HTTPMsg; // estructura para decodificar y alojar el mensaje - int c = pollConnection (); // esto parsea y llena las cosas contenidas en msg + int c = pollConnection (); // esto parsea y llena las cosas contenidas en msg if (c == OK) { - // Handle the request + // Handle the request + // cliente->set_blocking (true); INFO("Handling request !"); - //cliente->set_blocking (true, TIMEOUT); handleRequest (); } delete msg; delete cliente; - INFO("Leaving polling thread"); + INFO("Leaving polling thread\n"); return c; } @@ -90,14 +80,11 @@ if (received == ERROR) { // Invalid content received, so close the connection INFO("Invalid message received, so sending negative response and closing connection !"); - sprintf (buffer,"HTTP/1.1 400 BadRequest\n\rContent-Length: %d\n\rContent-Type: text\n\r\n\r\n\r",0); - - cliente->send (buffer, strlen (buffer)); - + tcpsend ("HTTP/1.1 400 BadRequest\n\rContent-Length: %d\n\rContent-Type: text\n\r\n\r\n\r", 0); return ERROR; } - /* The request has been received, try receive the body + // The request has been received, try receive the body do { received = receiveLine (); if (received == ERROR) {return ERROR;} @@ -108,12 +95,12 @@ received = 0; break; } else { - // add message body + /* add message body if (parseHeader () != 0) { WARN("Invalid message header received !"); - } + }*/ } - } while (received > 0); */ + } while (received > 0); // INFO("Leaving poll function!"); return received; @@ -137,7 +124,7 @@ // Check that - if no character was currently received - the timeout period is reached. if (c == 0 || c == -1) { // no character was read, so check if operation timed out - if (tm.read_ms() > TIMEOUT) { + if (tm.read_ms() > 2*TIMEOUT) { // Operation timed out INFO("Timeout occured in function 'receiveLine'."); return ERROR; @@ -306,9 +293,9 @@ int HTTPServer::handleGetRequest() { - INFO("Handling Get Request."); + int retval = OK; //success - int retval = OK; //success + INFO("Handling Get Request."); // maping to root path std::string reqPath = path + msg->uri.substr(1); @@ -321,37 +308,38 @@ INFO("Mapping \"%s\" to \"%s\"", msg->uri.c_str(), reqPath.c_str()); - FILE *fp = fopen(reqPath.c_str(), "r"); - if (fp != NULL) { + FILE *file = fopen(reqPath.c_str(), "r"); + if (file != NULL) { - char * pBuffer = NULL; - int sz = 8192; // fixme harcode - while( pBuffer == NULL) { - sz /= 2; - pBuffer = (char*)malloc(sz); - if (sz < 128) // fixme harcode + // asigna toda la memoria dinámica disponible para 'chunk' + char * chunk = NULL; + int chunk_sz = MAX_CHUNK_SIZE; + while(chunk == NULL) { + chunk_sz /= 2; + chunk = (char*) malloc (chunk_sz); + if (chunk_sz < MIN_CHUNK_SIZE) { error ("OutOfMemory"); + } } - // File was found and can be returned - - // first determine the size - fseek(fp, 0, SEEK_END); - long size = ftell(fp); - fseek(fp, 0, SEEK_SET); + // File was found and can be returned; first determine the size + fseek (file, 0, SEEK_END); + int size = ftell (file); + fseek (file, 0, SEEK_SET); - startResponse (200, size); // response: 200 - while (!feof(fp) && !ferror(fp)) { - int cnt = fread (pBuffer, 1, sz , fp); - if (cnt < 0) - cnt = 0; - processResponse (cnt, pBuffer); + startResponse (200, size); // response: 200 = HTTP_Ok + while (!feof(file) && !ferror(file)) { + int count = fread (chunk, 1, chunk_sz , file); + INFO("Processing Response (%d bytes)!", count); + if (cliente->send_all (chunk, count) != count) { + WARN ("Unsent bytes left !"); // TODO: handle filesystem errors + } } INFO("Ending Response !"); - free (pBuffer); - fclose (fp); + free (chunk); + fclose (file); } else { retval = 404; @@ -370,30 +358,21 @@ static const char hdrStandard[] = "DNT: 1\r\n" "MaxAge: 0\r\n" "Connection: Keep-Alive\r\n" - "Content-Type: text/html\r\n" + "Content-Type: text/html\r\n" // TODO: handle file types "Server: mbed embedded\r\n" "Accessible: 1\r\n" "\r\n"; -void HTTPServer::startResponse (int returnCode, long nLen) { - - INFO("Starting response (%ld bytes in total)!", nLen); +void HTTPServer::startResponse (int returnCode, int nLen) { - sprintf (buffer, "HTTP/1.1 %d OK\r\n", returnCode); - cliente->send(buffer, strlen(buffer)); - sprintf (buffer, "Content-Length: %ld\r\n", nLen); // Add 2 chars for the terminating CR+LF - cliente->send(buffer, strlen(buffer)); + INFO("Starting response (%d bytes in total)!", nLen); + + tcpsend ("HTTP/1.1 %d OK\r\n", returnCode); + tcpsend ("Content-Length: %d\r\n", nLen); // Add 2 chars for the terminating CR+LF INFO("Sending standard headers !"); - cliente->send_all((char*)hdrStandard, strlen(hdrStandard)); + tcpsend (hdrStandard); - INFO("Proceeding !"); - // other content must be sent using the 'processResponse' function -} - -void HTTPServer::processResponse (int nLen, char* body) { - - INFO("Processing Response (%d bytes)!\n", nLen); - cliente->send_all (body, nLen); + INFO("Done !"); } @@ -403,14 +382,10 @@ INFO("Handling error !"); - sprintf (buffer,"HTTP/1.1 %d Error\r\n", errorCode); - cliente->send (buffer, strlen(buffer)); - sprintf (buffer, "Content-Length: %ld\r\n", strlen(errorPage)); - cliente->send (buffer, strlen(buffer)); - sprintf(buffer, "Content-Type: text/html\r\nServer: mbed embedded\r\n\r\n"); - cliente->send(buffer, strlen(buffer)); - cliente->send_all((char*)errorPage, strlen(errorPage)); - cliente->send("\r\n", 3); + tcpsend ("HTTP/1.1 %d Error\r\n", errorCode); + tcpsend ("Content-Length: %d\r\n", strlen(errorPage)); + tcpsend ("Content-Type: text/html\r\nServer: mbed embedded\r\n\r\n"); + tcpsend (errorPage); // TODO: better error page (handle error type) INFO("Done !");