SOAP::Liteに苦戦
文献(http://www.studyinghttp.net/header#Expect)によると…
- 多くの古い HTTP/1.0 や HTTP/1.1 各アプリケーションは、Expect ヘッダを理解できない。
SOAPも 0.65_5 までは対応してなかったよ。
- クライアントは、希望する拡張を Expect によって与える事ができます。 HTTP/1.1 では、100 というステータスコードを扱いたいという状況が想定されています。 (逆に言うと、それ以外の Expect 値が定義されていません。)
一気に確信へ!「クライアント」が「希望する」拡張を「Expect によって」与えることができるんですって。
ぢゃ、クライアントに設定すればよいのかなー。
- Expect はホップバイホップ扱いなので、その希望を受け付けられない (あるいはその上流のサーバが受け付けられないと確実に知っている) サーバやプロクシは、直ちに 417 ステータスコードを返さなければなりません。
SOAPはその辺意識していないように思われ。
それって HTTP に準拠してないんじゃない?#とか思ってみるテスツ。
- 8.2.3 100 (Continue) ステータスの使用
- もしクライアントがリクエストボディを送る前に 100 (Continue) レスポンスのために待とうとするならば、"100-continue" という expectation を持った Expect リクエストヘッダフィールド(section 14.20) を送らなければならない。
漏れのシステムは待たねぇよ# 待たないから送ってねぇよ##
-
- もしリクエストボディを送るつもりが無いならば、"100-continue" という expectation を持った Expect リクエストヘッダフィールド(section 14.20) を送ってはならない。
(゚д゚)ハァ?
…サーバが判断できてない=送られてないってことだと推測しているんですがぁ###
- 未だに古い実装が存在するため、プロトコルではクライアントが 417 (Expectation Failed) ステータスや 100 (Continue) ステータスを受け取る前に、"Expect: 100-continue" を送ってしまうかもしれないようなあいまいな場面を認めている。
コラ!送っちゃったらレスポンスあるまで待っちゃうんでしょ?送ったか送ってないかわからないだなんて、僕どうなっても知らないぞ!
- それ故に、クライアントが 100 (Continue) ステータスを見た事が無いようなオリジンサーバ (あるいは経由するプロクシ) にこれを送るような時でも、リクエストボディを送る前に無期限で待つような事はすべきではない。
送っていないことを伝えるモノを送れってぇことですかぃねぇ…本末転倒っちゃぁこのことだぁな。
以下は「100-continue」を受け取ってしまったサーバの数奇な運命を調査してます。
- それ故に、クライアントが 100 (Continue) ステータスを見た事が無いようなオリジンサーバ (あるいは経由するプロクシ) にこれを送るような時でも、リクエストボディを送る前に無期限で待つような事はすべきではない。
うん。「終了」ステータスを送った時点で、クライアントがどんなリクエスト出してようが処理は終了。
- オリジンサーバは、リクエストメッセージが "100-continue" という expectation を持つ Expect リクエストヘッダを含んでいなければ 100 (Continue) レスポンスを送るべきではなく、リクエストが HTTP/1.0 (あるいはそれ以前) のクライアントからのものであったら、100 (Continue) レスポンスを送ってはならない。
ははぁ、リクエストを HTTP/1.0で送れば良かったって訳ですな。。
…いや違う、ソレはプロトコルの話で、SOAP::Lite はどっちで送ろうと解析する…ハズ。
- オリジンサーバは、すでにそのリクエストに関する一部、あるいは全部のリクエストボディを既に受け取っている場合、100 (Continue) レスポンスを省略する事ができる。
リクエスト全文受け取ってるのに、再取得するわけない ですよね 〜。まぁ今自分が抱えてる問題に何の関係もないわけですが
- 100 (Continue) レスポンスを送るオリジンサーバは、先に転送接続が切られているので無ければ、一度リクエストボディが受け取られ、処理され、最終的には最終ステータスコードを送らなければならない。
通常の リクエスト-レスポンス な関係と一緒っちゃ一緒。切断されちゃったら最終ステータスが遅れませんが、そうでないなら必ず最終ステータスを送れと。
- オリジンサーバが "100-continue" という expectation を持つ Expect リクエストヘッダフィールドを含まないリクエストを受け取ったならば、リクエストはリクエストボディを含んでいるので、サーバはその転送接続からのリクエストボディ全体を読みきる前に最終ステータスコードを返すが、リクエスト全体を読みきるまで、あるいはクライアントがその接続を切断するまでは、サーバは、その転送接続を切断すべきではない。
なんだか灰色いプロトコルですね。リクエストは全文受け取ってからレスポンスカエセヨって感じに脳内変換。
う〜ん… 100-continue を使用する目的(メリット) としては、リクエストを数回に分けて送ることができるってことなのかな?
一回繋いじゃえば毎回切断/通信を繰り返すことなく動的な結果を引き出せるってことなんでしょう、きっと。
HTTP/1.1 プロクシの必要条件とかもあるらしい。
- プロクシが "100-continue" という expectation を持つ Expect リクエストヘッダフィールドを含むリクエストを受け取った時に、プロクシが次に接続する{next-hop} サーバが HTTP/1.1 以上に従っている事を知っている、あるいは次に接続するサーバの HTTP バージョンを知らない場合には、Expect ヘッダフィールドを含めて、リクエストを転送しなければならない。
「まぁそうですねぇ」
- プロクシが、次に接続するサーバが HTTP/1.0 以下のバージョンである事を知っていたら、そのリクエストは転送せずに、417 (Expectation Failed) ステータスを返さなければならない。
プロキシだろうとなかろうと同じじゃい。
- プロクシは、最近参照したネクストホップサーバから受け取った HTTP バージョン番号をキャッシュに記録し保管すべきである。
「すべきである」。灰色な日本語は素敵です。こういうのって Apache(web鯖) 任せでいいのかな?
- プロクシは、HTTP/1.0 (あるいはそれ以前) のクライアントから受け取り、そこに "100-continue" という expectation を持つ Expect リクエストヘッダフィールドを含んでいないリクエストメッセージは、100 (Continue) レスポンスを転送してはならない。
- この必要条件は、1xx レスポンス (section 10.1 参照) を転送するという一般規則を上書きする。
長すぎて読めんorz
プロキシが HTTP/1.0 で受け取っても、HTTP/1.1 で送りなおすことが可能だろ?って言いたいんですか?
まぁプロトコルについては異常以上かな?
よし、判定しようじゃないか。
〜〜〜ザ・ジャッジ〜〜〜
A. クライアントがリクエスト時に設定する
B. サーバがレスポンス時に送信する
☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
A. クライアントがリクエスト時に設定する
★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★
Expect フィールドを明示的に空っぽにしてあげれば
▼
×:全然NG。今と同じ状態・状況
Expect フィールドに "100-continue" 以外の適当な値
▼
△:いいのかなぁって感じ。まぁ問題ないんでしょうけど、修正案としては気分が悪い
サーバ側で $ENV{Expect} にテキトーな値を突っ込んでみる
▼
△:うまく行くならそれでいいんですが…見込み薄。環境変数でなく、Apacheヘッダしか見てないような希ガス
SOAPモジュールにメスを入れる
▼
×:一番やりたくない。バグ報告でもする?バグなのか判断しかねてますが、バグだろコレ。
大分頭使いました。つか使い切りました。上記を試して仕舞いじゃぼけー