Skip to content

Commit

Permalink
http: add to_reply() in httpd::redirect_exception
Browse files Browse the repository at this point in the history
This function allows for the creation of an `http::reply`
from a thrown `redirect_exception`, with a url for the `Location`
header and an optional `Retry-After` timeout value.
  • Loading branch information
WillemKauf committed Apr 25, 2024
1 parent a965080 commit ac23cf0
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
16 changes: 14 additions & 2 deletions include/seastar/http/exception.hh
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,22 @@ private:
*/
class redirect_exception : public base_exception {
public:
redirect_exception(const std::string& url, http::reply::status_type status = http::reply::status_type::moved_permanently)
: base_exception("", status), url(url) {
redirect_exception(const std::string& url, http::reply::status_type status = http::reply::status_type::moved_permanently, const std::optional<int>& retry_after = std::nullopt)
: base_exception("", status), url(url), retry_after(retry_after) {
}

http::reply to_reply() const {
http::reply reply{};
reply.add_header("Location", url);
if (retry_after.has_value()) {
reply.add_header("Retry-After", std::to_string(retry_after.value()));
}
reply.set_status(status()).done("json");
return reply;
}

std::string url;
std::optional<int> retry_after;
};

/**
Expand Down
13 changes: 10 additions & 3 deletions src/http/routes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ namespace httpd {
using namespace std;

routes::routes() : _general_handler([this](std::exception_ptr eptr) mutable {
try {
std::rethrow_exception(eptr);
} catch (const redirect_exception& _e) {
return std::make_unique<http::reply>(_e.to_reply());
} catch (...) {
// Fall through to return exception reply
}

return exception_reply(eptr);
}) {}

Expand Down Expand Up @@ -72,9 +80,6 @@ std::unique_ptr<http::reply> routes::exception_reply(std::exception_ptr eptr) {
}
}
std::rethrow_exception(eptr);
} catch (const redirect_exception& _e) {
rep.reset(new http::reply());
rep->add_header("Location", _e.url).set_status(_e.status());
} catch (const base_exception& e) {
rep->set_status(e.status(), json_exception(e).to_json());
} catch (...) {
Expand All @@ -94,6 +99,8 @@ future<std::unique_ptr<http::reply> > routes::handle(const sstring& path, std::u
handler->verify_mandatory_params(*req);
auto r = handler->handle(path, std::move(req), std::move(rep));
return r.handle_exception(_general_handler);
} catch (const redirect_exception& _e) {
*rep = _e.to_reply();
} catch (...) {
rep = exception_reply(std::current_exception());
}
Expand Down

0 comments on commit ac23cf0

Please sign in to comment.