Help us understand the problem. What is going on with this article?

[apache2.4]Expect :100-continueヘッダーに対応していないHTTPサーバをOrigin/バックエンドで使う時は「Proxy100Continue Off」

解決に1日要しました。涙

お役にたてば幸いです。

背景

  • あるAPIを実装
  • APIは簡易HTTPサーバ上で動作(HTTPメソッド=POSTで待受)
  • Apacheをリバースプロキシとして利用
  • 動作試験(curlや簡易クライアント)は良好
  • 本番クライアント(.NETアプリ)からのリクエストでエラー(100%)

エラー内容

  • Apacheが返しているHTTPステータスコードは503
    • IP制限の場合は403エラーになるのでIP制限は無関係
  • APIクライアントではタイムアウトエラー
  • Apacheのエラーログの内容は以下
[proxy_http:error] [pid xxx] (104)Connection reset by peer: [client IPアドレス:ポート] \
   AH01102: error reading status line from remote server バックエンドのIPアドレス:ポート

よくわからなかったので、Apacheのdumpioモジュールを有効にして、リクエストヘッダー等を記録。
試験と本番のリクエストの違いを調査してみたところ以下がわかりました。

本番(=エラー)リクエストにはHTTPヘッダーにExpect: 100-continueが含まれている。(そしてbodyは空)

このHTTPヘッダを動作試験用のスクリプト(curl)に追加してみてたら同じ事象が再現しました。
これが原因のようです。

curl -H 'Expect: 100-continue' 以下省略

原因

Expect: 100-continueヘッダーは、「これからPOSTします(コンテンツ長はこれです)けどいいですか?」というサーバへの問い合わせです。
サーバはリクエストを受け取れる場合は「いいですよ。」とHTTPステータスコード100を返す必要があります。

ところが、バックエンドの簡易HTTPサーバはこのヘッダーに対応していないようです。
本来は、「100を返す」「次のリクエストボディを待つ」という動作が必要なのですが、
「100を返さずに」「リクエストボディを待つ」という挙動をしてしまっているようです。

今後、IoT機器などで簡易なHTTPサーバ使われることがあり、こういった事象に出くわすこともあるかもしれませんね。

対策

1日要しました。

Expect: 100-continueでググって出てくる対策は以下でした。

  • APIクライアント側でExpect: 100-continueを送らないようにする
  • HTTPヘッダーから除去

前者はAPIクライアント側が変更不可でした。
後者はリクエストにBODYが含まれていれば有効(=curlで確認)ですが、クライアント側がRFP仕様どおりにボディは空で、100応答を待っている場合は、機能しません。

これはHTTPサーバ(とAPI一式)を変えるしかないのか…。そんな時間ないよ…。と絶望。

原点に戻って、Proxyの設定で何かいいのないかなぁとApacheのドキュメントを眺めていたら、、、
何やら期待できそうなディレクティブがありました。

Proxy100Continue - Apache2.4(公式)

このディレクティブは、プロキシが Expect 100-continue をOriginサーバに転送すべきかどうかを決定します。
これにより、HTTP リクエストボディを読み込むべきかどうか、あるいは、 リクエストボディを転送する前に
プロキシが 100-CONTINUE 中間応答を生成するべきかどうかを決定することができます。

説明がちょっとわかりづらいのですが、この設定のデフォルトはOnです。
現在の挙動からして、おそらく「Originに転送する」になっています。
するとOffにすればApacheが変わって100を返してくれて、万事OKになるのでは?

で、試してみたところ、、、ビンゴでした!!

関係者(全員リモートですが)から歓声と安堵のため息が上がりました(たぶん)。
良かった・・。

s-katsumata
東京在住の二児の父。絶賛育児中。業界歴21年、フリーランス歴13年。在宅でシステム開発(受託、自社パッケージ)に従事。生涯コード書いていたいアラフィフプログラマ。悩みは老眼。ミッションはスクラッチ開発した宿泊・アクティビティ予約システム「みなたび」で地域で頑張る人を支援
https://nyango.com/services/travel
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away