diff --git a/include/pistache/http.h b/include/pistache/http.h index 8e4313a0c..26433e7ef 100644 --- a/include/pistache/http.h +++ b/include/pistache/http.h @@ -131,6 +131,7 @@ namespace Pistache std::initializer_list> params); void add(std::string name, std::string value); + void update(std::string& name, std::string value); std::optional get(const std::string& name) const; bool has(const std::string& name) const; // Return empty string or "?key1=value1&key2=value2" if query exist @@ -191,6 +192,7 @@ namespace Pistache const std::string& resource() const; const Uri::Query& query() const; + const std::vector>& rawParams() const; /* @Investigate: this is disabled because of a lock in the shared_ptr / weak_ptr implementation of libstdc++. Under contention, we experience a @@ -224,6 +226,7 @@ namespace Pistache Method method_; std::string resource_; Uri::Query query_; + std::vector> raw_params_; #ifdef LIBSTDCPP_SMARTPTR_LOCK_FIXME std::weak_ptr peer_; diff --git a/src/common/http.cc b/src/common/http.cc index d691e4789..b93afeaa1 100644 --- a/src/common/http.cc +++ b/src/common/http.cc @@ -194,10 +194,12 @@ namespace Pistache::Http auto c = cursor.current(); if (c == ' ') { + request->raw_params_.emplace_back(std::make_pair(std::string(key), std::string())); request->query_.add(std::move(key), ""); } else if (c == '&') { + request->raw_params_.emplace_back(std::make_pair(std::string(key), std::string())); request->query_.add(std::move(key), ""); if (!cursor.advance(1)) return State::Again; @@ -212,7 +214,16 @@ namespace Pistache::Http return State::Again; std::string value = valueToken.text(); - request->query_.add(std::move(key), std::move(value)); + request->raw_params_.emplace_back(std::make_pair(std::string(key), std::string(value))); + if (!request->query_.has(key)) { + request->query_.add(std::move(key), std::move(value)); + } else { + // If an existing param, append it to the current value seperated by ',' + // so that down stream the values will be converted to std::vector of multiple values. + std::string newValue = request->query_.get(key).value(); + newValue += "," + value; + request->query_.update(key, std::move(newValue)); + } if (cursor.current() == '&') { if (!cursor.advance(1)) @@ -588,6 +599,11 @@ namespace Pistache::Http { params.insert(std::make_pair(std::move(name), std::move(value))); } + + void + Query::update(std::string& name, std::string value) { + params[name] = std::move(value); + } std::optional Query::get(const std::string& name) const { @@ -644,6 +660,11 @@ namespace Pistache::Http const std::string& Request::resource() const { return resource_; } const Uri::Query& Request::query() const { return query_; } + + const std::vector>& + Request::rawParams() const { + return raw_params_; + } const Address& Request::address() const { return address_; }