HttpRequest が完了しない
また HttpRequest ではまった...
今度はなんと...
HttpRequest がいつまで経っても完了しない...
まず HttpRequest#start() を実行して システムに認証後、HttpHeader から set-cookie を読み取り、それを HttpHeader にセットして 再度 HttpRequest#start() で別のページにアクセスしたかった。
ただそれだけなのに...
どうしても 一度目の HttpRequest の onDone が実行されない。
サーバはちゃんとレスポンスを返しているし...
ステータスコードも 200、ヘッダもちゃんと返って来ているのに...
コードは こんな感じ...
var request: HttpRequest; request = HttpRequest { location: "http://localhost:8080/foo/bar/hoge" headers: HttpHeader.basicAuth("guest", "guest"); // BASIC 認証 // ステータスコード 出力 onResponseCode: function(code) { println(code); } // レスポンス ヘッダ 出力 onResponseHeaders: function(names) { for (name in names) { println("{name}: {request.getResponseHeaderValue(name)}"); } } onDone: function() { // レスポンスが返ってきたら 再度 HttpRequest#start() } } request.start();
まさか!! スレッドがロックしてる?
と言うことで スレッドダンプを取ってみた...
java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x0000000106b449d0> (a com.sun.javafx.io.http.impl.WaitingInputStream) at java.lang.Object.wait(Object.java:485) at com.sun.javafx.io.http.impl.WaitingInputStream.waitUntilClosed(WaitingInputStream.java:88) - locked <0x0000000106b449d0> (a com.sun.javafx.io.http.impl.WaitingInputStream) at com.sun.javafx.io.http.impl.HttpTask.tryRun(HttpTask.java:227) at com.sun.javafx.io.http.impl.HttpTask.run(HttpTask.java:31) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:637)
スレッドダンプを見てみると...
5行目に
WaitingInputStream.waitUntilClosed ?
しかも6行目には locked !!
えっ、InputStream を close するまで wait する?
と言うことで...
その通りに onInput を追加して InputStream を close してみることに...
var request: HttpRequest; request = HttpRequest { location: "http://localhost:8080/foo/bar/hoge" headers: HttpHeader.basicAuth("guest", "guest"); // BASIC 認証 // ステータスコード 出力 onResponseCode: function(code) { println(code); } // レスポンス ヘッダ 出力 onResponseHeaders: function(names) { for (name in names) { println("{name}: {request.getResponseHeaderValue(name)}"); } } // InputStream を close onInput: funrction(in) { in.close(); } onDone: function() { // レスポンスが返ってきたら 再度 HttpRequest#start() } } request.start();
おっ、今度は ちゃんと onDone が実行された!!
どうやら HttpRequest では InputStream の close が必須ということらしい...
API ドキュメントにも微妙ではあるが 必ず close しなさいと書いてあった。
しかし、ヘッダの情報だけが必要な場合でも IntputStream を close しないといけないというのはどうだろうか...