title: "S23. カスタムHTTPメソッドを扱う" order: 42
サーバーは知らないHTTPメソッドを400 Bad Requestで弾きます。RFC 4918のWebDAVメソッド(PROPFIND、PROPPATCH、MKCOLなど)やUPnPのSUBSCRIBEのような拡張メソッドを受け付けたいときは、CustomRoute()でハンドラを登録してください。登録したことがそのまま「このメソッドを受け付ける」という意味になります。
svr.CustomRoute("PROPFIND", "/dav/:id",
[](const httplib::Request &req, httplib::Response &res) {
// リクエストボディも通常どおり読める
auto id = req.path_params.at("id");
res.status = httplib::StatusCode::MultiStatus_207;
res.set_content(build_multistatus(req.body), "application/xml");
});
パターンの書き方はGet()などと同じです。正規表現もパスパラメーターもそのまま使えます。
WebDAVクライアントは接続すると、まずOPTIONSでサーバーの能力を問い合わせます。cpp-httplibはDAV:ヘッダーもAllowヘッダーも自動生成しないので、自分で返してください。ここを忘れると、PROPFINDが正しく動いてもクライアントに拒否されます。
svr.Options("/dav/.*", [](const httplib::Request &req, httplib::Response &res) {
res.set_header("DAV", "1");
res.set_header("Allow", "OPTIONS, GET, HEAD, PROPFIND, PROPPATCH, MKCOL");
});
Post()などと同じく、Content Reader版のオーバーロードがあります。大きなXMLを一度にメモリへ載せたくないときに使ってください。
svr.CustomRoute("REPORT", "/dav/.*",
[](const httplib::Request &req, httplib::Response &res,
const httplib::ContentReader &content_reader) {
content_reader([&](const char *data, size_t data_length) {
// 少しずつ処理する
return true;
});
res.status = httplib::StatusCode::MultiStatus_207;
});
listen()より前に登録してくださいGET、HEAD、POST、PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH、PRIは登録できません。これらには専用のメソッドを使ってくださいis_valid()がfalseになり、listen()が失敗します。呼ばれないハンドラを抱えたままサーバーが起動することはありませんGET/HEADのままですNote: cpp-httplibが用意するのはメソッドのルーティングまでです。WebDAVを名乗るなら、
207 Multi-StatusのXML生成、Depthヘッダーの解釈、ロックの管理は自分で実装することになります。プロトコルの本体はライブラリの外側です。ハンドラ登録の基本はS01. GET / POST / PUT / DELETEハンドラを登録するを参照してください。