mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-09 21:03:18 +00:00
Drop the spaces between Japanese text and inline code or alphanumerics in the tour and the few other pages that still had them, and reword sentences that read awkwardly. The client compression page now lists Zstd alongside zlib and Brotli.
2.4 KiB
2.4 KiB
title, order, status
| title | order | status |
|---|---|---|
| S12. res.user_dataでハンドラ間データを渡す | 31 | draft |
Pre-requestハンドラで認証トークンをデコードして、その結果をルートハンドラで使いたい。こういう「ハンドラ間のデータ受け渡し」は、res.user_dataに任意の型を入れて解決します。
基本の使い方
struct AuthUser {
std::string id;
std::string name;
bool is_admin;
};
svr.set_pre_request_handler(
[](const httplib::Request &req, httplib::Response &res) {
auto token = req.get_header_value("Authorization");
auto user = decode_token(token); // 認証トークンをデコード
res.user_data.set("user", user);
return httplib::Server::HandlerResponse::Unhandled;
});
svr.Get("/me", [](const httplib::Request &req, httplib::Response &res) {
auto *user = res.user_data.get<AuthUser>("user");
if (!user) {
res.status = 401;
return;
}
res.set_content("Hello, " + user->name, "text/plain");
});
user_data.set()で任意の型の値を保存し、user_data.get<T>()で取り出します。型を正しく指定しないとnullptrが返るので注意してください。
よくある型
std::string、数値、構造体、std::shared_ptrなど、コピーできる値なら何でも入れられます。
res.user_data.set("user_id", std::string{"42"});
res.user_data.set("is_admin", true);
res.user_data.set("started_at", std::chrono::steady_clock::now());
どこで設定し、どこで読むか
設定する側はset_pre_routing_handler()かset_pre_request_handler()、読む側は通常のルートハンドラ、という流れが一般的です。Pre-requestのほうがルーティング後に呼ばれるので、req.matched_routeと組み合わせて「このルートにマッチしたときだけセット」という書き方ができます。
注意点
user_dataはResponseに乗っています(req.user_dataではありません)。これは、ハンドラにはResponse&として可変参照が渡されるためです。一見不思議ですが、「ハンドラ間で共有する可変コンテキスト」だと考えると納得がいきます。
Warning:
user_data.get<T>()は型が一致しないとnullptrを返します。保存時と取得時で同じ型を指定してください。AuthUserで入れてconst AuthUserで取ろうとすると失敗します。