Changed to use std::multimap for params
This commit is contained in:
parent
d2982531bd
commit
c3346a4815
41
httplib.h
41
httplib.h
@ -69,7 +69,6 @@ namespace httplib
|
|||||||
|
|
||||||
enum class HttpVersion { v1_0 = 0, v1_1 };
|
enum class HttpVersion { v1_0 = 0, v1_1 };
|
||||||
|
|
||||||
typedef std::map<std::string, std::string> Map;
|
|
||||||
typedef std::multimap<std::string, std::string> MultiMap;
|
typedef std::multimap<std::string, std::string> MultiMap;
|
||||||
typedef std::smatch Match;
|
typedef std::smatch Match;
|
||||||
typedef std::function<void (int64_t current, int64_t total)> Progress;
|
typedef std::function<void (int64_t current, int64_t total)> Progress;
|
||||||
@ -87,7 +86,7 @@ struct Request {
|
|||||||
std::string path;
|
std::string path;
|
||||||
MultiMap headers;
|
MultiMap headers;
|
||||||
std::string body;
|
std::string body;
|
||||||
Map params;
|
MultiMap params;
|
||||||
MultipartFiles files;
|
MultipartFiles files;
|
||||||
Match matches;
|
Match matches;
|
||||||
Progress progress;
|
Progress progress;
|
||||||
@ -97,6 +96,7 @@ struct Request {
|
|||||||
void set_header(const char* key, const char* val);
|
void set_header(const char* key, const char* val);
|
||||||
|
|
||||||
bool has_param(const char* key) const;
|
bool has_param(const char* key) const;
|
||||||
|
std::string get_param_value(const char* key) const;
|
||||||
|
|
||||||
bool has_file(const char* key) const;
|
bool has_file(const char* key) const;
|
||||||
MultipartFile get_file_value(const char* key) const;
|
MultipartFile get_file_value(const char* key) const;
|
||||||
@ -189,7 +189,7 @@ public:
|
|||||||
std::shared_ptr<Response> get(const char* path, Progress callback = [](int64_t,int64_t){});
|
std::shared_ptr<Response> get(const char* path, Progress callback = [](int64_t,int64_t){});
|
||||||
std::shared_ptr<Response> head(const char* path);
|
std::shared_ptr<Response> head(const char* path);
|
||||||
std::shared_ptr<Response> post(const char* path, const std::string& body, const char* content_type);
|
std::shared_ptr<Response> post(const char* path, const std::string& body, const char* content_type);
|
||||||
std::shared_ptr<Response> post(const char* path, const Map& params);
|
std::shared_ptr<Response> post(const char* path, const MultiMap& params);
|
||||||
|
|
||||||
bool send(const Request& req, Response& res);
|
bool send(const Request& req, Response& res);
|
||||||
|
|
||||||
@ -540,19 +540,19 @@ inline const char* status_message(int status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char* get_header_value(const MultiMap& map, const char* key, const char* def)
|
inline const char* get_header_value(const MultiMap& headers, const char* key, const char* def)
|
||||||
{
|
{
|
||||||
auto it = map.find(key);
|
auto it = headers.find(key);
|
||||||
if (it != map.end()) {
|
if (it != headers.end()) {
|
||||||
return it->second.c_str();
|
return it->second.c_str();
|
||||||
}
|
}
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int get_header_value_int(const MultiMap& map, const char* key, int def)
|
inline int get_header_value_int(const MultiMap& headers, const char* key, int def)
|
||||||
{
|
{
|
||||||
auto it = map.find(key);
|
auto it = headers.find(key);
|
||||||
if (it != map.end()) {
|
if (it != headers.end()) {
|
||||||
return std::stoi(it->second);
|
return std::stoi(it->second);
|
||||||
}
|
}
|
||||||
return def;
|
return def;
|
||||||
@ -576,7 +576,7 @@ inline bool read_headers(Stream& strm, MultiMap& headers)
|
|||||||
if (std::regex_match(buf, m, re)) {
|
if (std::regex_match(buf, m, re)) {
|
||||||
auto key = std::string(m[1]);
|
auto key = std::string(m[1]);
|
||||||
auto val = std::string(m[2]);
|
auto val = std::string(m[2]);
|
||||||
headers.insert(std::make_pair(key, val));
|
headers.emplace(key, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -856,7 +856,7 @@ inline void write_request(Stream& strm, const Request& req, const char* ver)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void parse_query_text(const std::string& s, Map& params)
|
inline void parse_query_text(const std::string& s, MultiMap& params)
|
||||||
{
|
{
|
||||||
split(&s[0], &s[s.size()], '&', [&](const char* b, const char* e) {
|
split(&s[0], &s[s.size()], '&', [&](const char* b, const char* e) {
|
||||||
std::string key;
|
std::string key;
|
||||||
@ -868,7 +868,7 @@ inline void parse_query_text(const std::string& s, Map& params)
|
|||||||
val.assign(b, e);
|
val.assign(b, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
params[key] = detail::decode_url(val);
|
params.emplace(key, detail::decode_url(val));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -959,7 +959,7 @@ inline bool parse_multipart_formdata(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
files.insert(std::make_pair(name, file));
|
files.emplace(name, file);
|
||||||
|
|
||||||
pos = next_pos + crlf.size();
|
pos = next_pos + crlf.size();
|
||||||
}
|
}
|
||||||
@ -998,7 +998,7 @@ inline std::string Request::get_header_value(const char* key) const
|
|||||||
|
|
||||||
inline void Request::set_header(const char* key, const char* val)
|
inline void Request::set_header(const char* key, const char* val)
|
||||||
{
|
{
|
||||||
headers.insert(std::make_pair(key, val));
|
headers.emplace(key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Request::has_param(const char* key) const
|
inline bool Request::has_param(const char* key) const
|
||||||
@ -1006,6 +1006,15 @@ inline bool Request::has_param(const char* key) const
|
|||||||
return params.find(key) != params.end();
|
return params.find(key) != params.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string Request::get_param_value(const char* key) const
|
||||||
|
{
|
||||||
|
auto it = params.find(key);
|
||||||
|
if (it != params.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
inline bool Request::has_file(const char* key) const
|
inline bool Request::has_file(const char* key) const
|
||||||
{
|
{
|
||||||
return files.find(key) != files.end();
|
return files.find(key) != files.end();
|
||||||
@ -1033,7 +1042,7 @@ inline std::string Response::get_header_value(const char* key) const
|
|||||||
|
|
||||||
inline void Response::set_header(const char* key, const char* val)
|
inline void Response::set_header(const char* key, const char* val)
|
||||||
{
|
{
|
||||||
headers.insert(std::make_pair(key, val));
|
headers.emplace(key, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Response::set_redirect(const char* url)
|
inline void Response::set_redirect(const char* url)
|
||||||
@ -1421,7 +1430,7 @@ inline std::shared_ptr<Response> Client::post(
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline std::shared_ptr<Response> Client::post(
|
inline std::shared_ptr<Response> Client::post(
|
||||||
const char* path, const Map& params)
|
const char* path, const MultiMap& params)
|
||||||
{
|
{
|
||||||
std::string query;
|
std::string query;
|
||||||
for (auto it = params.begin(); it != params.end(); ++it) {
|
for (auto it = params.begin(); it != params.end(); ++it) {
|
||||||
|
26
test/test.cc
26
test/test.cc
@ -32,7 +32,7 @@ TEST(StartupTest, WSAStartup)
|
|||||||
TEST(SplitTest, ParseQueryString)
|
TEST(SplitTest, ParseQueryString)
|
||||||
{
|
{
|
||||||
string s = "key1=val1&key2=val2&key3=val3";
|
string s = "key1=val1&key2=val2&key3=val3";
|
||||||
map<string, string> dic;
|
MultiMap dic;
|
||||||
|
|
||||||
detail::split(s.c_str(), s.c_str() + s.size(), '&', [&](const char* b, const char* e) {
|
detail::split(s.c_str(), s.c_str() + s.size(), '&', [&](const char* b, const char* e) {
|
||||||
string key, val;
|
string key, val;
|
||||||
@ -43,24 +43,24 @@ TEST(SplitTest, ParseQueryString)
|
|||||||
val.assign(b, e);
|
val.assign(b, e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dic[key] = val;
|
dic.emplace(key, val);
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_EQ("val1", dic["key1"]);
|
EXPECT_EQ("val1", dic.find("key1")->second);
|
||||||
EXPECT_EQ("val2", dic["key2"]);
|
EXPECT_EQ("val2", dic.find("key2")->second);
|
||||||
EXPECT_EQ("val3", dic["key3"]);
|
EXPECT_EQ("val3", dic.find("key3")->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ParseQueryTest, ParseQueryString)
|
TEST(ParseQueryTest, ParseQueryString)
|
||||||
{
|
{
|
||||||
string s = "key1=val1&key2=val2&key3=val3";
|
string s = "key1=val1&key2=val2&key3=val3";
|
||||||
map<string, string> dic;
|
MultiMap dic;
|
||||||
|
|
||||||
detail::parse_query_text(s, dic);
|
detail::parse_query_text(s, dic);
|
||||||
|
|
||||||
EXPECT_EQ("val1", dic["key1"]);
|
EXPECT_EQ("val1", dic.find("key1")->second);
|
||||||
EXPECT_EQ("val2", dic["key2"]);
|
EXPECT_EQ("val2", dic.find("key2")->second);
|
||||||
EXPECT_EQ("val3", dic["key3"]);
|
EXPECT_EQ("val3", dic.find("key3")->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SocketTest, OpenClose)
|
TEST(SocketTest, OpenClose)
|
||||||
@ -159,7 +159,7 @@ protected:
|
|||||||
})
|
})
|
||||||
.post("/person", [&](const Request& req, Response& res) {
|
.post("/person", [&](const Request& req, Response& res) {
|
||||||
if (req.has_param("name") && req.has_param("note")) {
|
if (req.has_param("name") && req.has_param("note")) {
|
||||||
persons_[req.params.at("name")] = req.params.at("note");
|
persons_[req.get_param_value("name")] = req.get_param_value("note");
|
||||||
} else {
|
} else {
|
||||||
res.status = 400;
|
res.status = 400;
|
||||||
}
|
}
|
||||||
@ -310,9 +310,9 @@ TEST_F(ServerTest, PostMethod2)
|
|||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
ASSERT_EQ(404, res->status);
|
ASSERT_EQ(404, res->status);
|
||||||
|
|
||||||
Map params;
|
MultiMap params;
|
||||||
params["name"] = "john2";
|
params.emplace("name", "john2");
|
||||||
params["note"] = "coder";
|
params.emplace("note", "coder");
|
||||||
|
|
||||||
res = cli_.post("/person", params);
|
res = cli_.post("/person", params);
|
||||||
ASSERT_TRUE(res != nullptr);
|
ASSERT_TRUE(res != nullptr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user