JsonContent と Request Header
JsonContent
を使う事は多いでしょう。
直接 JsonContent
を使わない場合でも、PostAsJsonAsync
等の拡張メソッドは内部的に当然 JsonContent
を用いるので、めちゃくちゃ多用されている HttpContent
です。
で、JsonContent
を用いた場合、特に何もしなければ chunked request として送信されます。
つまり request header には transfer-encoding: chunked
が付与されます。
そのため当然ながら content-length
は不要なので、付与されません。
transfer-encoding: chunked
ではなく、content-length
を付与してリクエストを飛ばしたい場合は LoadIntoBufferAsync()
を呼び出せば OK です。
var content = JsonContent.Create(...); // この一行を入れる事によって、header に `transfer-encoding: chunked` ではなく `content-length` が付与されるようになる。 await content.LoadIntoBufferAsync(cancellationToken);
Cloud Run と Request Header
さてなんでこんな記事を書いているかというと、Cloud Run 使っている時にハマったからです...。
json を DELETE で飛ばしていたのですが、なぜか Cloud Run にホストされているところに対して送ると「body がねぇぞ!」という怒られが発生してしまいました。 ローカルとか CI では特に問題なかったのに...。
で、原因を調査していたところ Cloud Run (というか Cloud Run の前段にあるであろう内部の LB) が DELETE に関しては chunked request に対応していなかったのです...! POST の場合は chunked request に対応しているのに、なぜか DELETE に関してのみ対応していないのです...!
というか Cloud Run でホストされているサーバに対して chunked request で送っても、ホストされているコンテナには transfer-encoding: chunked
が削除され、その代わりに content-length
が付与された状態で届きます。
しかしDELETE method のリクエストに関しては transfer-encoding: chunked
が削除され、content-length
も付与されません。
何故...。
ということで Cloud Run でホストされているサーバに対して DELETE で json を投げる時は chunked request ではなく、content-length
が付与された形式でリクエストは投げるようにしましょう。