Single instance HTTP Server using WiFly Interface.

Dependents:   WiFlyHTTPServerSample MultiThreadingHTTPServer

This is my implementation for a HTTP Server using the WiFly Interface. Please note that this is still under development.

It may still contain several bugs. I have tested it using a 1768 on an application board plus RN-XV board.

Currently there is only a FileSystem implemented. Also it is limited to GET request.

I try to extend it further so it will be more useful.

Btw, it does NOT work with RTOS, which seems not to be the Problem of my library.

Do not Forget to Import the WiFly Interface into your Project when using this library.

Change History:

REV5: - added support for basic RPC GET request functionality.

REV4: - added argument parsing from the request uri. - documentation extended and updated.

Committer:
leihen
Date:
Wed Jun 26 22:41:05 2013 +0000
Revision:
14:7f9fbfc18623
Parent:
13:93ff322420b0
Moved the HttpServer module inside this library.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
leihen 5:dc88012caef1 1 /* FsHandler.cpp */
leihen 5:dc88012caef1 2 #include "mbed.h"
leihen 5:dc88012caef1 3 #include "FsHandler.h"
leihen 5:dc88012caef1 4
leihen 13:93ff322420b0 5 //#define DEBUG
leihen 13:93ff322420b0 6 #include "debug.h"
leihen 5:dc88012caef1 7
leihen 5:dc88012caef1 8
leihen 5:dc88012caef1 9
leihen 12:ba81cc117fb6 10 static int matchstrings(const char* one, const char* two)
leihen 12:ba81cc117fb6 11 {
leihen 12:ba81cc117fb6 12 int m = 0;
leihen 12:ba81cc117fb6 13
leihen 12:ba81cc117fb6 14 for (m = 0; m < min(strlen(one), strlen(two)) ; m++) {
leihen 12:ba81cc117fb6 15 if (one[m] != two[m])
leihen 12:ba81cc117fb6 16 return m;
leihen 12:ba81cc117fb6 17 }
leihen 12:ba81cc117fb6 18 return m;
leihen 12:ba81cc117fb6 19 }
leihen 5:dc88012caef1 20
leihen 5:dc88012caef1 21 std::map<const char*, const char*> HTTPFsRequestHandler::m_fsMap;
leihen 5:dc88012caef1 22
leihen 13:93ff322420b0 23 HTTPFsRequestHandler::HTTPFsRequestHandler(const char* rootPath, const char* localPath, HTTPConnection::HTTPMessage& Msg)
leihen 13:93ff322420b0 24 : HTTPRequestHandler(Msg)
leihen 5:dc88012caef1 25 {
leihen 5:dc88012caef1 26 m_rootPath = rootPath;
leihen 5:dc88012caef1 27 m_localPath = localPath;
leihen 5:dc88012caef1 28
leihen 12:ba81cc117fb6 29 string myPath = m_rootPath + m_localPath;
leihen 12:ba81cc117fb6 30
leihen 5:dc88012caef1 31 // Now replace the virtual root path with a mounted device path
leihen 5:dc88012caef1 32 std::map<const char*, const char*>::iterator it;
leihen 12:ba81cc117fb6 33 const char *bestMatch = NULL;
leihen 12:ba81cc117fb6 34 const char *bestMatchExchange = NULL;
leihen 12:ba81cc117fb6 35 int match_ind = -1;
leihen 5:dc88012caef1 36 for (it = m_fsMap.begin() ; it != m_fsMap.end() ; it++) {
leihen 5:dc88012caef1 37 // find best match (if the given logical path is containted in the root
leihen 12:ba81cc117fb6 38 int s = matchstrings(myPath.c_str(), it->second);
leihen 12:ba81cc117fb6 39 INFO("Matching Root %s with handler %s results in %d identical characters\n", myPath.c_str(), it->second, s);
leihen 12:ba81cc117fb6 40 if ((s == strlen(it->second)) && (s > match_ind)) {
leihen 12:ba81cc117fb6 41 match_ind = s;
leihen 12:ba81cc117fb6 42 bestMatch = it->first;
leihen 12:ba81cc117fb6 43 bestMatchExchange = it->second;
leihen 5:dc88012caef1 44 }
leihen 5:dc88012caef1 45 }
leihen 12:ba81cc117fb6 46
leihen 12:ba81cc117fb6 47 if (bestMatch != NULL) {
leihen 12:ba81cc117fb6 48 m_rootPath = bestMatch;
leihen 12:ba81cc117fb6 49 m_localPath = string(myPath).substr(strlen(bestMatchExchange));
leihen 12:ba81cc117fb6 50 }
leihen 12:ba81cc117fb6 51
leihen 5:dc88012caef1 52 handleRequest();
leihen 5:dc88012caef1 53 }
leihen 5:dc88012caef1 54
leihen 5:dc88012caef1 55 HTTPFsRequestHandler::~HTTPFsRequestHandler()
leihen 5:dc88012caef1 56 {
leihen 5:dc88012caef1 57 }
leihen 5:dc88012caef1 58
leihen 5:dc88012caef1 59 int HTTPFsRequestHandler::handleGetRequest()
leihen 5:dc88012caef1 60 {
leihen 12:ba81cc117fb6 61 HTTPHeaders headers;
leihen 12:ba81cc117fb6 62
leihen 12:ba81cc117fb6 63 if (m_localPath.length() > 4)
leihen 12:ba81cc117fb6 64 getStandardHeaders(headers, m_localPath.substr(m_localPath.length()-4).c_str());
leihen 12:ba81cc117fb6 65 else
leihen 12:ba81cc117fb6 66 getStandardHeaders(headers);
leihen 12:ba81cc117fb6 67
leihen 12:ba81cc117fb6 68 INFO("Handling Get Request (root = %s, local = %s).", m_rootPath.c_str(), m_localPath.c_str());
leihen 5:dc88012caef1 69 int retval = 0; //success
leihen 5:dc88012caef1 70 std::string reqPath;
leihen 5:dc88012caef1 71
leihen 5:dc88012caef1 72 // Check if we received a directory with the local bath
leihen 5:dc88012caef1 73 if ((m_localPath.length() == 0) || (m_localPath.substr( m_localPath.length()-1, 1) == "/")) {
leihen 5:dc88012caef1 74 // yes, we shall append the default page name
leihen 5:dc88012caef1 75 m_localPath += "index.html";
leihen 5:dc88012caef1 76 }
leihen 5:dc88012caef1 77
leihen 5:dc88012caef1 78 reqPath = m_rootPath + m_localPath;
leihen 5:dc88012caef1 79
leihen 5:dc88012caef1 80 INFO("Mapping \"%s\" to \"%s\"", msg.uri.c_str(), reqPath.c_str());
leihen 5:dc88012caef1 81
leihen 5:dc88012caef1 82 FILE *fp = fopen(reqPath.c_str(), "r");
leihen 5:dc88012caef1 83 if (fp != NULL) {
leihen 12:ba81cc117fb6 84 char * pBuffer = NULL;
leihen 12:ba81cc117fb6 85 int sz = 8192;
leihen 12:ba81cc117fb6 86 while( pBuffer == NULL) {
leihen 12:ba81cc117fb6 87 sz /= 2;
leihen 12:ba81cc117fb6 88 pBuffer = (char*)malloc(sz);
leihen 12:ba81cc117fb6 89 if (sz < 128)
leihen 12:ba81cc117fb6 90 error ("OutOfMemory");
leihen 12:ba81cc117fb6 91 }
leihen 12:ba81cc117fb6 92
leihen 5:dc88012caef1 93 // File was found and can be returned
leihen 5:dc88012caef1 94
leihen 5:dc88012caef1 95 // first determine the size
leihen 5:dc88012caef1 96 fseek(fp, 0, SEEK_END);
leihen 5:dc88012caef1 97 long size = ftell(fp);
leihen 5:dc88012caef1 98 fseek(fp, 0, SEEK_SET);
leihen 5:dc88012caef1 99
leihen 5:dc88012caef1 100 startResponse(200, size);
leihen 5:dc88012caef1 101 while(!feof(fp) && !ferror(fp)) {
leihen 12:ba81cc117fb6 102 int cnt = fread(pBuffer, 1, sz , fp);
leihen 7:cb7fec1265b5 103 if (cnt < 0)
leihen 7:cb7fec1265b5 104 cnt = 0;
leihen 12:ba81cc117fb6 105 processResponse(cnt, pBuffer);
leihen 5:dc88012caef1 106 }
leihen 12:ba81cc117fb6 107 delete pBuffer;
leihen 5:dc88012caef1 108 endResponse();
leihen 5:dc88012caef1 109 fclose(fp);
leihen 5:dc88012caef1 110 }
leihen 5:dc88012caef1 111 else {
leihen 5:dc88012caef1 112 retval = 404;
leihen 5:dc88012caef1 113 ERR("Requested file was not found !");
leihen 5:dc88012caef1 114 }
leihen 5:dc88012caef1 115
leihen 5:dc88012caef1 116 return retval;
leihen 5:dc88012caef1 117 }
leihen 5:dc88012caef1 118
leihen 5:dc88012caef1 119 int HTTPFsRequestHandler::handlePostRequest()
leihen 5:dc88012caef1 120 {
leihen 5:dc88012caef1 121 return 404;
leihen 5:dc88012caef1 122 }
leihen 5:dc88012caef1 123
leihen 5:dc88012caef1 124 int HTTPFsRequestHandler::handlePutRequest()
leihen 5:dc88012caef1 125 {
leihen 5:dc88012caef1 126 return 404;
leihen 5:dc88012caef1 127 }