Browse Source

Changed to use std::multimap for params

yhirose 8 years ago
parent
commit
c3346a4815
2 changed files with 40 additions and 31 deletions
  1. 27 18
      httplib.h
  2. 13 13
      test/test.cc

+ 27 - 18
httplib.h

@@ -69,9 +69,8 @@ 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::smatch                             Match;
+typedef std::multimap<std::string, std::string>              MultiMap;
+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;
 
 
 struct MultipartFile {
 struct MultipartFile {
@@ -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);
-    if (it != map.end()) {
+    auto it = headers.find(key);
+    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);
-    if (it != map.end()) {
+    auto it = headers.find(key);
+    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) {

+ 13 - 13
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("val2", dic["key2"]);
-    EXPECT_EQ("val3", dic["key3"]);
+    EXPECT_EQ("val1", dic.find("key1")->second);
+    EXPECT_EQ("val2", dic.find("key2")->second);
+    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("val2", dic["key2"]);
-    EXPECT_EQ("val3", dic["key3"]);
+    EXPECT_EQ("val1", dic.find("key1")->second);
+    EXPECT_EQ("val2", dic.find("key2")->second);
+    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;
-    params["name"] = "john2";
-    params["note"] = "coder";
+    MultiMap params;
+    params.emplace("name", "john2");
+    params.emplace("note", "coder");
 
 
     res = cli_.post("/person", params);
     res = cli_.post("/person", params);
     ASSERT_TRUE(res != nullptr);
     ASSERT_TRUE(res != nullptr);