From 3b4bf01a7dd9e16f1df00c70b87a533a3cd17797 Mon Sep 17 00:00:00 2001 From: Antony Woods Date: Mon, 22 Sep 2014 21:34:22 +0100 Subject: [PATCH] URL params are now present as a ci_map variable of request --- examples/example.cpp | 14 ++++++++- include/http_request.h | 5 ++-- include/parser.h | 67 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/examples/example.cpp b/examples/example.cpp index b360adb8b..9f482af08 100644 --- a/examples/example.cpp +++ b/examples/example.cpp @@ -68,8 +68,20 @@ int main() return crow::response{os.str()}; }); + CROW_ROUTE(app, "/params") + ([](const crow::request& req){ + std::ostringstream os; + os << "Params:\n"; + for (auto& i : req.url_params) { + os << "key = " << i.first << ", val = " << i.second << '\n'; + } + return crow::response{os.str()}; + }); + + + // ignore all log - crow::logger::setLogLevel(crow::LogLevel::CRITICAL); + crow::logger::setLogLevel(crow::LogLevel::DEBUG); //crow::logger::setHandler(std::make_shared()); app.port(18080) diff --git a/include/http_request.h b/include/http_request.h index 331bc80ac..24edb66fb 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 869061cfb..bda4594a9 100644 --- a/include/parser.h +++ b/include/parser.h @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include "http_request.h" @@ -11,6 +13,62 @@ namespace crow template struct HTTPParser : public http_parser { + template + struct tokenize_by_char + { + template + 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>(params)) { + std::string key, value; + auto parts = boost::tokenizer>(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(self_); @@ -21,6 +79,10 @@ namespace crow { HTTPParser* self = static_cast(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_;