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 0:7a2421e63e74 1 /* HTTPConnection.cpp */
leihen 0:7a2421e63e74 2
leihen 0:7a2421e63e74 3 #include "mbed.h"
leihen 0:7a2421e63e74 4 #include "HTTPConnection.h"
leihen 0:7a2421e63e74 5
leihen 13:93ff322420b0 6 #define DEBUG
leihen 13:93ff322420b0 7
leihen 13:93ff322420b0 8 #include "debug.h"
leihen 6:fe661fa9d18a 9
leihen 0:7a2421e63e74 10 #include <vector>
leihen 0:7a2421e63e74 11 using std::vector;
leihen 0:7a2421e63e74 12
leihen 0:7a2421e63e74 13 using std::string;
leihen 0:7a2421e63e74 14
leihen 0:7a2421e63e74 15
leihen 4:d065642c32cc 16 const struct HTTPRequestConfig {
leihen 4:d065642c32cc 17 const char* request_string;
leihen 4:d065642c32cc 18 HTTPRequestType request_type;
leihen 4:d065642c32cc 19 } g_requestConfig[] = {
leihen 4:d065642c32cc 20 { "GET", HTTP_RT_GET },
leihen 4:d065642c32cc 21 { "POST", HTTP_RT_POST},
leihen 4:d065642c32cc 22 { "PUT", HTTP_RT_PUT},
leihen 4:d065642c32cc 23 { "OPTIONS",HTTP_RT_OPTIONS},
leihen 4:d065642c32cc 24 { "HEAD", HTTP_RT_HEAD},
leihen 4:d065642c32cc 25 { "DELETE", HTTP_RT_DELETE},
leihen 4:d065642c32cc 26 { "TRACE", HTTP_RT_TRACE},
leihen 4:d065642c32cc 27 { "CONNECT",HTTP_RT_CONNECT}
leihen 4:d065642c32cc 28 };
leihen 4:d065642c32cc 29
leihen 0:7a2421e63e74 30
leihen 0:7a2421e63e74 31 HTTPConnection::HTTPConnection()
leihen 0:7a2421e63e74 32 {
leihen 0:7a2421e63e74 33 }
leihen 0:7a2421e63e74 34
leihen 0:7a2421e63e74 35
leihen 0:7a2421e63e74 36 HTTPConnection::~HTTPConnection()
leihen 0:7a2421e63e74 37 {
leihen 0:7a2421e63e74 38 close();
leihen 0:7a2421e63e74 39 }
leihen 0:7a2421e63e74 40
leihen 0:7a2421e63e74 41 void HTTPConnection::close()
leihen 0:7a2421e63e74 42 {
leihen 0:7a2421e63e74 43 m_Msg.headers.clear();
leihen 0:7a2421e63e74 44 }
leihen 0:7a2421e63e74 45
leihen 2:8653bbcf7e58 46 int HTTPConnection::parse(char* buffer)
leihen 0:7a2421e63e74 47 {
leihen 4:d065642c32cc 48 // Check if buffer is invalid or its content not long enough.
leihen 0:7a2421e63e74 49 if ((buffer == NULL) || (strlen(buffer) < 4)) {
leihen 0:7a2421e63e74 50 ERR("Buffer content is invalid or too short.");
leihen 0:7a2421e63e74 51 return -1;
leihen 0:7a2421e63e74 52 }
leihen 0:7a2421e63e74 53
leihen 4:d065642c32cc 54 std::vector<std::string> args;
leihen 0:7a2421e63e74 55 args.clear();
leihen 0:7a2421e63e74 56
leihen 4:d065642c32cc 57 int argno = 0;
leihen 0:7a2421e63e74 58 // decompose string into a list of arguments
leihen 0:7a2421e63e74 59 char s = 0; // current starting char
leihen 2:8653bbcf7e58 60 int nLen = strlen(buffer)+1;
leihen 2:8653bbcf7e58 61 for (int i = 0 ; i < nLen ; i++) {
leihen 0:7a2421e63e74 62 if ((buffer[i] == ' ') || (buffer[i] == '\n') || (buffer[i] == 0)) {
leihen 0:7a2421e63e74 63 // new arg found
leihen 2:8653bbcf7e58 64 buffer[i] = 0;
leihen 4:d065642c32cc 65 if (argno++ == 1) {
leihen 4:d065642c32cc 66 // its the uri
leihen 4:d065642c32cc 67 // parse the uri args
leihen 4:d065642c32cc 68 parseUriArgs(&buffer[s], m_Msg.args);
leihen 4:d065642c32cc 69 }
leihen 2:8653bbcf7e58 70 INFO("Found argument \"%s\"", &buffer[s]);
leihen 2:8653bbcf7e58 71 args.push_back(&buffer[s]);
leihen 0:7a2421e63e74 72 s = i+1;
leihen 0:7a2421e63e74 73 }
leihen 0:7a2421e63e74 74 }
leihen 4:d065642c32cc 75
leihen 4:d065642c32cc 76 // store the uri and the HTTP version
leihen 4:d065642c32cc 77 m_Msg.uri = args[1];
leihen 4:d065642c32cc 78 m_Msg.version = args[2];
leihen 4:d065642c32cc 79
leihen 4:d065642c32cc 80 // Find matching request type
leihen 4:d065642c32cc 81 for (int i = 0 ; i < sizeof(g_requestConfig)/sizeof(struct HTTPRequestConfig) ; i++) {
leihen 4:d065642c32cc 82 if (args.at(0) == g_requestConfig[i].request_string) {
leihen 4:d065642c32cc 83 m_Msg.request = g_requestConfig[i].request_type;
leihen 0:7a2421e63e74 84 }
leihen 0:7a2421e63e74 85 }
leihen 0:7a2421e63e74 86 args.clear();
leihen 0:7a2421e63e74 87
leihen 0:7a2421e63e74 88 return 1;
leihen 0:7a2421e63e74 89 }
leihen 0:7a2421e63e74 90
leihen 4:d065642c32cc 91 int HTTPConnection::parseUriArgs(char *buffer, map<string,string>&args)
leihen 4:d065642c32cc 92 {
leihen 4:d065642c32cc 93 // Check if the buffer is invalid or if the content is too short to be meaningful
leihen 4:d065642c32cc 94 if ((strlen(buffer) <3) || (buffer == NULL))
leihen 4:d065642c32cc 95 return -1;
leihen 4:d065642c32cc 96
leihen 4:d065642c32cc 97 int args_start = -1;
leihen 4:d065642c32cc 98 int value_start = -1;
leihen 4:d065642c32cc 99 int buflen = strlen(buffer) +1;
leihen 4:d065642c32cc 100 const char* argname = NULL;
leihen 4:d065642c32cc 101 const char* valuename = NULL;
leihen 4:d065642c32cc 102 for (int i = 0; i < buflen ; i++) {
leihen 4:d065642c32cc 103 if (args_start == -1) { // args section not yet found
leihen 4:d065642c32cc 104 if (buffer[i] == '?') { // starts with a question mark, so got it
leihen 4:d065642c32cc 105 buffer[i] = 0;
leihen 4:d065642c32cc 106 args_start = i; // set the start of the args section
leihen 4:d065642c32cc 107 INFO("Argument section found !");
leihen 4:d065642c32cc 108 }
leihen 4:d065642c32cc 109 }
leihen 4:d065642c32cc 110 else { // search arg-value touples
leihen 4:d065642c32cc 111 if (argname == NULL) { // arg-name found ?
leihen 4:d065642c32cc 112 if (buffer[i] == '=') {
leihen 4:d065642c32cc 113 // yes, separate the arg-name
leihen 4:d065642c32cc 114 buffer[i] = 0;
leihen 4:d065642c32cc 115 argname = &buffer[args_start];
leihen 4:d065642c32cc 116 value_start = i+1;
leihen 4:d065642c32cc 117 INFO("Argument name %s", argname);
leihen 4:d065642c32cc 118 }
leihen 4:d065642c32cc 119 }
leihen 4:d065642c32cc 120 else { // search for end of value
leihen 4:d065642c32cc 121 if ((buffer[i] == '&') || (buffer[i] == 0) || (buffer[i] == '\r') || (buffer[i] == '\n')) {
leihen 4:d065642c32cc 122 buffer[i] = 0;
leihen 4:d065642c32cc 123 valuename = &buffer[value_start];
leihen 4:d065642c32cc 124 INFO("Argument value %s", valuename);
leihen 4:d065642c32cc 125 args[argname] = valuename;
leihen 4:d065642c32cc 126 // reset all indicators
leihen 4:d065642c32cc 127 argname = NULL;
leihen 4:d065642c32cc 128 valuename = NULL;
leihen 4:d065642c32cc 129 }
leihen 4:d065642c32cc 130 }
leihen 4:d065642c32cc 131 }
leihen 4:d065642c32cc 132 }
leihen 4:d065642c32cc 133
leihen 4:d065642c32cc 134 return 0;
leihen 4:d065642c32cc 135 }