Follow only 301, 302, 303, 307 and 308 redirects (#2646)

is_redirect treated any 3xx with a Location as a redirect, so with set_follow_location(true) a 304 or 305 that carried a Location was followed. Only 301, 302, 303, 307 and 308 are redirects a client follows (RFC 9110 section 15.4), as in Go, requests and urllib3. A Location is still required. The 304 check in process_request that is_redirect now covers is dropped.
This commit is contained in:
Wleeaf authored and GitHub committed 2026-10-25 18:55:20 -04:00
1 parent 5ceef83c54
commit 7d349cbeed
2 files changed
+54 -5

No files matched your search

+42
View File
@@ -4255,6 +4255,48 @@ TEST(RedirectToDifferentPort, TrailingCharactersInPort) {
EXPECT_FALSE(res);
}
TEST(RedirectTest, OtherStatusesWithLocationAreNotFollowed) {
Server svr;
std::atomic<bool> followed{false};
svr.Get("/304", [](const Request & /*req*/, Response &res) {
res.status = StatusCode::NotModified_304;
res.set_header("Location", "/target");
});
svr.Get("/305", [](const Request & /*req*/, Response &res) {
res.status = StatusCode::UseProxy_305;
res.set_header("Location", "/target");
});
svr.Get("/target", [&](const Request & /*req*/, Response &res) {
followed = true;
res.set_content("target", "text/plain");
});
auto th = std::thread([&]() { svr.listen("localhost", PORT); });
auto se = detail::scope_exit([&] {
svr.stop();
th.join();
ASSERT_FALSE(svr.is_running());
});
svr.wait_until_ready();
Client cli("localhost", PORT);
cli.set_follow_location(true);
auto res = cli.Get("/304");
ASSERT_TRUE(res) << "Error: " << to_string(res.error());
EXPECT_EQ(StatusCode::NotModified_304, res->status);
res = cli.Get("/305");
ASSERT_TRUE(res) << "Error: " << to_string(res.error());
EXPECT_EQ(StatusCode::UseProxy_305, res->status);
EXPECT_FALSE(followed);
}
TEST(RedirectFromPageWithContent, Redirect) {
Server svr;