60 lines
3.3 KiB
Markdown
60 lines
3.3 KiB
Markdown
---
|
||
title: "S23. カスタムHTTPメソッドを扱う"
|
||
order: 42
|
||
status: "draft"
|
||
---
|
||
|
||
サーバーは知らないHTTPメソッドを`400 Bad Request`で弾きます。RFC 4918のWebDAVメソッド(`PROPFIND`、`PROPPATCH`、`MKCOL`など)やUPnPの`SUBSCRIBE`のような拡張メソッドを受け付けたいときは、`CustomRoute()`でハンドラを登録してください。登録したことがそのまま「このメソッドを受け付ける」という意味になります。
|
||
|
||
## 基本の使い方
|
||
|
||
```cpp
|
||
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()`などと同じです。正規表現もパスパラメーターもそのまま使えます。
|
||
|
||
## OPTIONSで対応メソッドを知らせる
|
||
|
||
WebDAVクライアントは接続すると、まず`OPTIONS`でサーバーの能力を問い合わせます。cpp-httplibは`DAV:`ヘッダーも`Allow`ヘッダーも自動生成しないので、自分で返してください。ここを忘れると、`PROPFIND`が正しく動いてもクライアントに拒否されます。
|
||
|
||
```cpp
|
||
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を一度にメモリへ載せたくないときに使ってください。
|
||
|
||
```cpp
|
||
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;
|
||
});
|
||
```
|
||
|
||
## 覚えておくこと
|
||
|
||
- メソッド名はHTTPのトークン(RFC 9110)である必要があります。`listen()`より前に登録してください
|
||
- `GET`、`HEAD`、`POST`、`PUT`、`DELETE`、`CONNECT`、`OPTIONS`、`TRACE`、`PATCH`、`PRI`は登録できません。これらには専用のメソッドを使ってください
|
||
- 登録が拒否されると`is_valid()`が`false`になり、`listen()`が失敗します。呼ばれないハンドラを抱えたままサーバーが起動することはありません
|
||
- 静的ファイルの配信とWebSocketのアップグレードは`GET`/`HEAD`のままです
|
||
|
||
> **Note:** cpp-httplibが用意するのはメソッドのルーティングまでです。WebDAVを名乗るなら、`207 Multi-Status`のXML生成、`Depth`ヘッダーの解釈、ロックの管理は自分で実装することになります。プロトコルの本体はライブラリの外側です。
|
||
|
||
> ハンドラ登録の基本は[S01. GET / POST / PUT / DELETEハンドラを登録する](../s01-handlers)を参照してください。
|