yhirose 5 years ago
parent
commit
c2b6e4ac04
2 changed files with 49 additions and 9 deletions
  1. 13 3
      httplib.h
  2. 36 6
      test/test.cc

+ 13 - 3
httplib.h

@@ -312,7 +312,7 @@ struct Response {
   void set_header(const char *key, const char *val);
   void set_header(const char *key, const std::string &val);
 
-  void set_redirect(const char *url);
+  void set_redirect(const char *url, int status = 302);
   void set_content(const char *s, size_t n, const char *content_type);
   void set_content(std::string s, const char *content_type);
 
@@ -2048,6 +2048,12 @@ inline bool redirect(T &cli, const Request &req, Response &res,
   new_req.path = path;
   new_req.redirect_count -= 1;
 
+  if (res.status == 303 && (req.method != "GET" && req.method != "HEAD")) {
+    new_req.method = "GET";
+    new_req.body.clear();
+    new_req.headers.clear();
+  }
+
   Response new_res;
 
   auto ret = cli.send(new_req, new_res);
@@ -2790,10 +2796,14 @@ inline void Response::set_header(const char *key, const std::string &val) {
   }
 }
 
-inline void Response::set_redirect(const char *url) {
+inline void Response::set_redirect(const char *url, int status) {
   if (!detail::has_crlf(url)) {
     set_header("Location", url);
-    status = 302;
+    if (300 <= status && status < 400) {
+      this->status = status;
+    } else {
+      this->status = 302;
+    }
   }
 }
 

+ 36 - 6
test/test.cc

@@ -749,6 +749,13 @@ protected:
              })
         .Get("/", [&](const Request & /*req*/,
                       Response &res) { res.set_redirect("/hi"); })
+        .Post("/1", [](const Request & /*req*/,
+                       Response &res) { res.set_redirect("/2", 303); })
+        .Get("/2",
+             [](const Request & /*req*/, Response &res) {
+               res.set_content("redirected.", "text/plain");
+               res.status = 200;
+             })
         .Post("/person",
               [&](const Request &req, Response &res) {
                 if (req.has_param("name") && req.has_param("note")) {
@@ -913,10 +920,10 @@ protected:
                   res.set_content("DELETE", "text/plain");
                 })
         .Delete("/delete-body",
-               [&](const Request &req, Response &res) {
-                 EXPECT_EQ(req.body, "content");
-                 res.set_content(req.body, "text/plain");
-               })
+                [&](const Request &req, Response &res) {
+                  EXPECT_EQ(req.body, "content");
+                  res.set_content(req.body, "text/plain");
+                })
         .Options(R"(\*)",
                  [&](const Request & /*req*/, Response &res) {
                    res.set_header("Allow", "GET, POST, HEAD, OPTIONS");
@@ -1116,6 +1123,14 @@ TEST_F(ServerTest, GetMethod302) {
   EXPECT_EQ("/hi", res->get_header_value("Location"));
 }
 
+TEST_F(ServerTest, GetMethod302Redirect) {
+  cli_.set_follow_location(true);
+  auto res = cli_.Get("/");
+  ASSERT_TRUE(res != nullptr);
+  EXPECT_EQ(200, res->status);
+  EXPECT_EQ("Hello World!", res->body);
+}
+
 TEST_F(ServerTest, GetMethod404) {
   auto res = cli_.Get("/invalid");
   ASSERT_TRUE(res != nullptr);
@@ -1315,6 +1330,21 @@ TEST_F(ServerTest, GetMethodOutOfBaseDirMount2) {
   EXPECT_EQ(404, res->status);
 }
 
+TEST_F(ServerTest, PostMethod303) {
+  auto res = cli_.Post("/1", "body", "text/plain");
+  ASSERT_TRUE(res != nullptr);
+  EXPECT_EQ(303, res->status);
+  EXPECT_EQ("/2", res->get_header_value("Location"));
+}
+
+TEST_F(ServerTest, PostMethod303Redirect) {
+  cli_.set_follow_location(true);
+  auto res = cli_.Post("/1", "body", "text/plain");
+  ASSERT_TRUE(res != nullptr);
+  EXPECT_EQ(200, res->status);
+  EXPECT_EQ("redirected.", res->body);
+}
+
 TEST_F(ServerTest, UserDefinedMIMETypeMapping) {
   auto res = cli_.Get("/dir/test.abcde");
   ASSERT_TRUE(res != nullptr);
@@ -2142,8 +2172,8 @@ TEST(ServerRequestParsingTest, ReadHeadersRegexComplexity) {
   test_raw_request(
       "GET /hi HTTP/1.1\r\n"
       " :                                                                      "
-      "                                                                       "
-  );
+      "                                                                      "
+      " ");
 }
 
 TEST(ServerRequestParsingTest, ReadHeadersRegexComplexity2) {