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 しないといけないというのはどうだろうか...