質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Tomcat

TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

Q&A

1回答

1930閲覧

(ch=input.read()) != -1とcontent-lengthが必要な理由

退会済みユーザー

退会済みユーザー

総合スコア0

Tomcat

TomcatはApache Software Foundation (ASF)で開発されたオープンソースのWebコンテナです。

0グッド

0クリップ

投稿2017/02/07 11:40

ただいま、tomcatがブラウザからのpostを受けとる時に通るコードで、分からないところがありました。

僕は、input.read()=-1でブラウザからのリクエストの終了を検知すると思っていたのですが、これだけでは、postの時に、while文が終わりませんでした。つまり、終わりのはずなのに、-1が返ってきません。
しかし、ヘッダのcontent-lengthも合わせることで、リクエストの終わりを検知するようです。
どうして、input-read()=-1だけでは、リクエストの終了を検知できないのですか?

どなたかご教授お願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2017/02/08 02:29

問題がおきているプログラムのコードを示して下さい。コードが無いので「postの時に、while文が終わりませんでした」が何を意味するか理解不可能です。
guest

回答1

0

クライアントはリクエストを送った後、接続を切断せずにサーバからのレスポンスを待ちます。接続が閉じられていませんから、サーバ側でいくらread()してもEOFは返ってきません。

POSTリクエストの場合、リクエストボディの長さがわからなければ、サーバはいつまでもリクエストボディの読み込みを続けてしまいます。そのため、Content-Lengthリクエストフィールドの値を見て、必要な長さだけ読み込んだらリクエストの読み込みが終わったと判断しているのだと考えられます。

一方で、クライアントがリクエストを送っている最中に接続が切れてしまうことはありえますから、EOFを返すかどうかも検査する必要があります。

補足

具体的なコードが示されないので、想像で補足しておきます。

たとえば、IOUtilsクラスにこんなコードがあります (Tomcat 8.5.11で確認しましたが、以前のバージョンでも同様でしょう)。

java

1public static int read(final InputStream input, final byte[] buffer, final int offset, final int length) throws IOException { 2... 3 int remaining = length; 4 while (remaining > 0) { 5 final int location = length - remaining; 6 final int count = input.read(buffer, offset + location, remaining); 7 if (EOF == count) { // EOF 8 break; 9 } 10 remaining -= count; 11 } 12 return length - remaining; 13} 14

このメソッドを使ってリクエストボディを読み込むには、length引数に正の値を指定しなければなりません。

リクエストの読み込みが終わればinput.read()EOFを返す (上述の通り実際は違います) ので、lengthを使わずに次のように書けばいいではないか、というのがご質問の趣旨だと思います。

java

1... 2 int location = 0; 3 while (1) { 4 final int count = input.read(buffer, offset + location, READSIZE); 5 if (EOF == count) { // EOF 6 break; 7 } 8 location += count; 9 } 10 return location; 11...

投稿2017/02/10 11:43

ikedas

総合スコア4315

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問