Single instance HTTP Server using WiFly Interface.

Dependents:   WiFlyHTTPServerSample MultiThreadingHTTPServer

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPConnection.cpp Source File

HTTPConnection.cpp

00001 /* HTTPConnection.cpp */
00002 
00003 #include "mbed.h"
00004 #include "HTTPConnection.h"
00005 
00006 #define DEBUG
00007 
00008 #include "debug.h"
00009 
00010 #include <vector>
00011 using std::vector;
00012 
00013 using std::string;
00014 
00015 
00016 const struct HTTPRequestConfig {
00017     const char* request_string;
00018     HTTPRequestType request_type;
00019 } g_requestConfig[] = {
00020     { "GET",    HTTP_RT_GET },
00021     { "POST",   HTTP_RT_POST},
00022     { "PUT",    HTTP_RT_PUT},
00023     { "OPTIONS",HTTP_RT_OPTIONS},
00024     { "HEAD",   HTTP_RT_HEAD},
00025     { "DELETE", HTTP_RT_DELETE},
00026     { "TRACE",  HTTP_RT_TRACE},
00027     { "CONNECT",HTTP_RT_CONNECT}
00028 };
00029 
00030 
00031 HTTPConnection::HTTPConnection()
00032 {
00033 }
00034 
00035 
00036 HTTPConnection::~HTTPConnection()
00037 {
00038     close();
00039 }
00040 
00041 void HTTPConnection::close()
00042 {
00043     m_Msg.headers.clear();
00044 }
00045 
00046 int HTTPConnection::parse(char* buffer)
00047 {
00048     //  Check if buffer is invalid or its content not long enough.
00049     if ((buffer == NULL) || (strlen(buffer) < 4)) {
00050         ERR("Buffer content is invalid or too short.");
00051         return -1;
00052     }
00053     
00054     std::vector<std::string> args;
00055     args.clear();
00056     
00057     int argno = 0;
00058     //  decompose string into a list of arguments
00059     char s = 0; // current starting char
00060     int nLen = strlen(buffer)+1;
00061     for (int i = 0 ; i < nLen ; i++) {
00062         if ((buffer[i] == ' ') || (buffer[i] == '\n') || (buffer[i] == 0)) {
00063             // new arg found
00064             buffer[i] = 0;
00065             if (argno++ == 1) {
00066                 //  its the uri
00067                 // parse the uri args
00068                 parseUriArgs(&buffer[s], m_Msg.args);
00069             }
00070             INFO("Found argument \"%s\"", &buffer[s]);
00071             args.push_back(&buffer[s]);
00072             s = i+1;
00073         }
00074     }
00075     
00076     // store the uri and the HTTP version
00077     m_Msg.uri = args[1];
00078     m_Msg.version = args[2];    
00079     
00080     //  Find matching request type
00081     for (int i = 0 ; i < sizeof(g_requestConfig)/sizeof(struct HTTPRequestConfig) ; i++) {
00082         if (args.at(0) == g_requestConfig[i].request_string) {
00083             m_Msg.request = g_requestConfig[i].request_type;
00084         }
00085     }
00086     args.clear();
00087     
00088     return 1;
00089 }
00090 
00091 int HTTPConnection::parseUriArgs(char *buffer, map<string,string>&args)
00092 {
00093     // Check if the buffer is invalid or if the content is too short to be meaningful
00094     if ((strlen(buffer) <3) || (buffer == NULL))
00095         return -1;
00096         
00097     int args_start = -1;
00098     int value_start = -1;
00099     int buflen = strlen(buffer) +1;
00100     const char* argname = NULL;
00101     const char* valuename = NULL;
00102     for (int i = 0; i < buflen ; i++) {
00103         if (args_start == -1) {  // args section not yet found
00104             if (buffer[i] == '?') {  // starts with a question mark, so got it
00105                 buffer[i] = 0;
00106                 args_start = i; //  set the start of the args section
00107                 INFO("Argument section found !");
00108             }
00109         }
00110         else {                  // search arg-value touples
00111             if (argname == NULL) {    //  arg-name found ?
00112                 if (buffer[i] == '=') {
00113                     //  yes, separate the arg-name
00114                     buffer[i] = 0;
00115                     argname = &buffer[args_start];
00116                     value_start = i+1;
00117                     INFO("Argument name %s", argname);
00118                 }
00119             }
00120             else { // search for end of value
00121                 if ((buffer[i] == '&') || (buffer[i] == 0) || (buffer[i] == '\r') || (buffer[i] == '\n')) {
00122                     buffer[i] = 0;
00123                     valuename = &buffer[value_start];
00124                     INFO("Argument value %s", valuename);
00125                     args[argname] = valuename;
00126                     //  reset all indicators
00127                     argname = NULL;
00128                     valuename = NULL;
00129                 }
00130             }
00131         }
00132     }
00133     
00134     return 0;
00135 }