aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAntony Woods <acron1@gmail.com>2014-09-22 21:34:22 +0100
committerAntony Woods <acron1@gmail.com>2014-09-22 21:34:22 +0100
commit3b4bf01a7dd9e16f1df00c70b87a533a3cd17797 (patch)
tree5b23e56fac9ccbc16436e64cd694de1e111a5cd4 /include
parentc9e8bf3c6496c5027153735e446ae19cd4bcb4f4 (diff)
downloadcrow-3b4bf01a7dd9e16f1df00c70b87a533a3cd17797.tar.gz
crow-3b4bf01a7dd9e16f1df00c70b87a533a3cd17797.zip
URL params are now present as a ci_map variable of request
Diffstat (limited to 'include')
-rw-r--r--include/http_request.h5
-rw-r--r--include/parser.h67
2 files changed, 69 insertions, 3 deletions
diff --git a/include/http_request.h b/include/http_request.h
index 331bc80..24edb66 100644
--- a/include/http_request.h
+++ b/include/http_request.h
@@ -20,6 +20,7 @@ namespace crow
{
HTTPMethod method;
std::string url;
+ ci_map url_params;
ci_map headers;
std::string body;
@@ -30,8 +31,8 @@ namespace crow
{
}
- request(HTTPMethod method, std::string url, ci_map headers, std::string body)
- : method(method), url(std::move(url)), headers(std::move(headers)), body(std::move(body))
+ request(HTTPMethod method, std::string url, ci_map url_params, ci_map headers, std::string body)
+ : method(method), url(std::move(url)), url_params(std::move(url_params)), headers(std::move(headers)), body(std::move(body))
{
}
diff --git a/include/parser.h b/include/parser.h
index 869061c..bda4594 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -3,6 +3,8 @@
#include <string>
#include <unordered_map>
#include <boost/algorithm/string.hpp>
+#include <boost/tokenizer.hpp>
+#include <algorithm>
#include "http_request.h"
@@ -11,6 +13,62 @@ namespace crow
template <typename Handler>
struct HTTPParser : public http_parser
{
+ template<const char delimiter>
+ struct tokenize_by_char
+ {
+ template<typename It>
+ bool operator()(It& next, It end, std::string & tok)
+ {
+ if (next == end)
+ return false;
+ const char dels = delimiter;
+ const char* del = &dels;
+ auto pos = std::search(next, end, del, del + 1);
+ tok.assign(next, pos);
+ next = pos;
+ if (next != end)
+ std::advance(next, 1);
+ return true;
+ }
+
+ void reset() {}
+ };
+
+ static ci_map get_url_params(std::string url)
+ {
+ const char url_delimiter = '&';
+ const char param_delimiter = '=';
+ ci_map ret;
+
+ int qMarkPos = url.find("?");
+ if(!(qMarkPos >=0 && qMarkPos != (url.length()-1))) {
+ return ret;
+ }
+
+ auto params = url.substr(qMarkPos+1);
+
+ // substitute ';' for '&' for recommended process of delimintation
+ // (http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2.2)
+ std::replace(params.begin(), params.end(), ';', url_delimiter);
+
+ // url tokenizer
+ for (auto i : boost::tokenizer<tokenize_by_char<url_delimiter>>(params)) {
+ std::string key, value;
+ auto parts = boost::tokenizer<tokenize_by_char<param_delimiter>>(i);
+ int count = 0;
+ for(auto p = parts.begin(); p != parts.end(); ++p, ++count) {
+ if(count == 0){
+ key = *p;
+ } else {
+ value = *p;
+ }
+ }
+ ret.insert(std::make_pair(key, value));
+ }
+
+ return ret;
+ }
+
static int on_message_begin(http_parser* self_)
{
HTTPParser* self = static_cast<HTTPParser*>(self_);
@@ -21,6 +79,10 @@ namespace crow
{
HTTPParser* self = static_cast<HTTPParser*>(self_);
self->url.insert(self->url.end(), at, at+length);
+
+ // url params
+ self->url_params = get_url_params(self->url);
+
return 0;
}
static int on_header_field(http_parser* self_, const char* at, size_t length)
@@ -115,6 +177,7 @@ namespace crow
header_field.clear();
header_value.clear();
headers.clear();
+ url_params.clear();
body.clear();
}
@@ -130,7 +193,7 @@ namespace crow
request to_request() const
{
- return request{(HTTPMethod)method, std::move(url), std::move(headers), std::move(body)};
+ return request{(HTTPMethod)method, std::move(url), std::move(url_params), std::move(headers), std::move(body)};
}
bool check_version(int major, int minor) const
@@ -139,10 +202,12 @@ namespace crow
}
std::string url;
+
int header_building_state = 0;
std::string header_field;
std::string header_value;
ci_map headers;
+ ci_map url_params;
std::string body;
Handler* handler_;