MXS-1220: Add option parsing
The options of a request are now parsed and exposed by the HttpRequest class. Added tests for the request options. Also added missing error handling of invalid requests.
This commit is contained in:
committed by
Markus Mäkelä
parent
9d0d394361
commit
34ee4a1997
@ -14,6 +14,7 @@
|
||||
#include "maxscale/httprequest.hh"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
/** TODO: Move this to a C++ string utility header */
|
||||
namespace maxscale
|
||||
@ -52,17 +53,68 @@ static inline string& trim(string& str)
|
||||
HttpRequest* HttpRequest::parse(string data)
|
||||
{
|
||||
size_t pos = data.find("\r\n");
|
||||
|
||||
if (pos == string::npos)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string request_line = data.substr(0, pos);
|
||||
data.erase(0, pos + 2);
|
||||
|
||||
pos = request_line.find(" ");
|
||||
/** Request method */
|
||||
if ((pos = request_line.find(" ")) == string::npos)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string verb = request_line.substr(0, pos);
|
||||
request_line.erase(0, pos + 1);
|
||||
|
||||
pos = request_line.find(" ");
|
||||
/** Get the combined URL/option string */
|
||||
if ((pos = request_line.find(" ")) == string::npos)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
string uri = request_line.substr(0, pos);
|
||||
request_line.erase(0, pos + 1);
|
||||
|
||||
/** Process request options */
|
||||
pos = uri.find("?");
|
||||
map<string, string> options;
|
||||
|
||||
if (pos != string::npos)
|
||||
{
|
||||
string optionstr = uri.substr(pos + 1);
|
||||
uri.erase(pos);
|
||||
|
||||
char buf[optionstr.size() + 1];
|
||||
strcpy(buf, optionstr.c_str());
|
||||
char* saved;
|
||||
char* tok = strtok_r(buf, ",", &saved);
|
||||
|
||||
while (tok && *tok)
|
||||
{
|
||||
string opt(tok);
|
||||
pos = opt.find("=");
|
||||
|
||||
if (pos != string::npos)
|
||||
{
|
||||
string key = opt.substr(0, pos - 1);
|
||||
string value = opt.substr(pos + 1);
|
||||
options[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Invalid option */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tok = strtok_r(NULL, ",", &saved);
|
||||
}
|
||||
}
|
||||
|
||||
pos = request_line.find("\r\n");
|
||||
string http_version = request_line.substr(0, pos);
|
||||
request_line.erase(0, pos + 2);
|
||||
@ -86,10 +138,18 @@ HttpRequest* HttpRequest::parse(string data)
|
||||
header_line.erase(0, pos + 1);
|
||||
headers[key] = mxs::trim(header_line);
|
||||
}
|
||||
else
|
||||
{
|
||||
/** Invalid header */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/** The headers are now processed and consumed. The message body is
|
||||
* the only thing left in the request string. */
|
||||
/**
|
||||
* The headers are now processed and consumed. The message body is
|
||||
* the only thing left in the request string and it should be a JSON object.
|
||||
* Attempt to parse it and return an error if it fails.
|
||||
*/
|
||||
|
||||
bool ok = false;
|
||||
HttpRequest* request = NULL;
|
||||
@ -120,11 +180,12 @@ HttpRequest* HttpRequest::parse(string data)
|
||||
if (ok)
|
||||
{
|
||||
request = new HttpRequest();
|
||||
request->m_verb = verb_value;
|
||||
request->m_resource = uri;
|
||||
request->m_headers = headers;
|
||||
request->m_options = options;
|
||||
request->m_json.reset(body);
|
||||
request->m_json_string = data;
|
||||
request->m_resource = uri;
|
||||
request->m_verb = verb_value;
|
||||
}
|
||||
|
||||
return request;
|
||||
|
||||
Reference in New Issue
Block a user