Skip to content

Instantly share code, notes, and snippets.

@KowalskiThomas
Created August 9, 2018 08:23
Show Gist options
  • Save KowalskiThomas/4e15d05af82d0a52c9a1054837d446b6 to your computer and use it in GitHub Desktop.
Save KowalskiThomas/4e15d05af82d0a52c9a1054837d446b6 to your computer and use it in GitHub Desktop.
RequestParser
#ifndef REQUESTPARSER_H
#define REQUESTPARSER_H
#include "Strings.hpp"
#ifdef DEBUG
#warning Debug
#include <iostream>
#include <ostream>
#else
#warning Arduino
#endif
#define _MAX_ARGUMENTNAME_LENGTH 32
#define _MAX_ARGUMENTVALUE_LENGTH 32
#define _MAX_HOST_LENGTH 64
#define _MAX_PORT_LENGTH 10
#define _MAX_PARAMETERS_GET 10
#define _MAX_REQUEST_LENGTH 1024
#define _MAX_PATH_LENGTH 128
typedef struct
{
char name[_MAX_ARGUMENTNAME_LENGTH];
char value[_MAX_ARGUMENTVALUE_LENGTH];
} argument;
class RequestParser
{
private:
char request[_MAX_REQUEST_LENGTH];
char path[_MAX_PATH_LENGTH];
char host[_MAX_HOST_LENGTH];
char port[_MAX_PORT_LENGTH];
char method[10];
char urlMethod[10];
argument arguments[_MAX_PARAMETERS_GET];
unsigned int argCount;
unsigned int requestLength;
void parseUrl(const char * url)
{
if (url == NULL)
return;
enum
{
Method,
Host,
Port,
Path
} state = Method;
StringBuffer buffer;
int urlLength = strlen(url);
for (int i = 0; i < urlLength; i++)
{
if (state == Method
&& (i >= 2 && url[i - 2] == ':')
&& (i >= 1 && url[i - 1] == '/')
&& url[i] == '/')
{
strcpy(urlMethod, buffer.str());
trim(urlMethod, '/');
trim(urlMethod, ':');
buffer.reset();
state = Host;
}
else if (state == Method)
buffer << url[i];
else if (state == Host && url[i] == ':')
{
strcpy(host, buffer.str());
buffer.reset();
state = Port;
}
else if (state == Host && url[i] == '/')
{
strcpy(host, buffer.str());
strcpy(port, "80");
buffer.reset();
state = Path;
}
else if (state == Host)
buffer << url[i];
else if (state == Port && url[i] == '/')
{
strcpy(port, buffer.str());
buffer.reset();
buffer << '/';
state = Path;
}
else if (state == Port)
buffer << url[i];
else if (state == Path)
buffer << url[i];
else
std::cout << "Unexpected state." << std::endl;
}
strcpy(path, buffer.str());
}
void parse()
{
if (request == NULL)
return;
StringBuffer methodBuffer;
int i;
for (i = 0; i < requestLength; i++)
{
if (request[i] == ' ')
{
strcpy(method, methodBuffer.str());
i++;
break;
}
else
methodBuffer << request[i];
}
shiftLeft(request, requestLength, -1 * i);
StringSplitter splitter(request, '?');
// Find the path
parseUrl(splitter.getStringAt(0));
if (splitter.getCount() > 1)
{
std::cout << "Parsing args: " << splitter.getStringAt(1) << std::endl;
StringSplitter splitterArgs(splitter.getStringAt(1), '&');
for (int i = 0; i < splitterArgs.getCount(); i++)
{
StringSplitter splitterNameValue(splitterArgs.getStringAt(i), '=');
std::cout << splitterArgs.getStringAt(i) << " / " << splitterArgs.getCount() << std::endl;
argCount++;
strcpy(arguments[argCount].name, splitterNameValue.getStringAt(0));
strcpy(arguments[argCount].value, splitterNameValue.getStringAt(1));
}
}
std::cout << "Over!" << std::endl;
}
public:
RequestParser(const char * request)
: argCount(0)
, requestLength(strlen(request))
{
if (request == NULL)
return;
strcpy(this->request, request);
parse();
std::cout << "Parsing complete: " << std::endl
<< "HTTP Method:" << method << std::endl
<< "Method: " << urlMethod << std::endl
<< "Host: " << host << std::endl
<< "Port: " << port << std::endl
<< "Path: " << path << std::endl;
}
~RequestParser()
{
argCount = -1;
}
const char * getPath() const
{
return path;
}
const unsigned int getParameterCount() const
{
return argCount;
}
const argument * getArguments() const
{
return arguments;
}
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment