diff options
author | Antony Woods <acron1@gmail.com> | 2014-09-22 21:34:22 +0100 |
---|---|---|
committer | Antony Woods <acron1@gmail.com> | 2014-09-22 21:34:22 +0100 |
commit | 3b4bf01a7dd9e16f1df00c70b87a533a3cd17797 (patch) | |
tree | 5b23e56fac9ccbc16436e64cd694de1e111a5cd4 /include | |
parent | c9e8bf3c6496c5027153735e446ae19cd4bcb4f4 (diff) | |
download | crow-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.h | 5 | ||||
-rw-r--r-- | include/parser.h | 67 |
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_; |