[httpcore 4.1.4、httpclient 4.2.5、Oracle JDK 1.7.0_25 を使用]
webapp の javascript (AJAX) コードに代わってサードパーティの web サービスへの接続を「プロキシ」しようとしていますが、大きなchunked
応答で失敗したようで、複数の RST を送信してorg.apache.http.TruncatedChunkException
.
だから私は疑問に思っています:
- http クライアントが接続を切断しようとするのはなぜですか?
- それは賢明なことをしていますか?(つまり、サーバーに問題がある可能性があります)、またはここで何かバグがありますか?
私の基本的なアプローチは、サーブレットのリクエスト オブジェクトから apache コンポーネントの httpclient リクエストにすべてをコピーして実行することです。より具体的には、私は:
- Apache Commons httpclient DefaultHttpClient オブジェクトを作成し、
- すべてのリクエスト ヘッダーを新しいリクエスト オブジェクトにコピーし、
host
プロキシ先のホスト/ポートを使用して、新しいリクエストのヘッダーを設定 (/オーバーライド) します。- すべての HTTP パラメータを新しいリクエストにコピーします。
- エンティティ本体を新しいリクエストにコピーし、
- リクエストを実行し、
- 応答ヘッダーをサーブレットの応答ヘッダーにコピーし、
- エンティティ本体をストリームとしてサーブレットの出力ストリームにコピーします。
問題を引き起こしているビットは最後のビットです。チャンクの途中で失敗したようで、次のスタック トレースが表示されます。
org.apache.http.TruncatedChunkException: Truncated chunk ( expected size: 7752; actual size: 4077)
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:186)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:138)
at <mypackage>.<MyServlet>.service(<MyServlet>.java:XXX)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.resteasy.plugins.server.servlet.FilterDispatcher.doFilter(FilterDispatcher.java:63)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:724)
私はWiresharkでそれをスヌープし、次のようなプロセスを取得しました:
source dest info
client server [SYN] seq=0
server client [SYN, ACK] seq=0 ack=1
client server [ACK] seq=1 ack=1
client server GET /url?param=value... HTTP/1.1
server client [ACK] seq=1 ack=221
server client [TCP segment of a reassembled PDU]
client server [ACK] seq=221 ack=4345
client server [FIN, ACK] seq=221 ack=4345
server client [TCP segment of a reassembled PDU]
client server [RST] seq=221
server client Continuation or non-HTTP traffic
client server [RST] seq=221
私の限られた理解では、FIN は「送信が完了しました」を意味します。これは、クライアント ヘッダーが既に送信されているため、IMO で十分です。ただし、RST/リセットは接続を切断しようとしているようです。
クライアントの HTTP ヘッダーは次のとおりです。
GET /some/path?params=values HTTP/1.1
connection: Keep-Alive
host: target.host.com
accept: */*
user-agent: Wget/1.14 (linux-gnu)
サーバーの場合:
HTTP/1.1 200 OK
Date: Mon, 16 Sep 2013 03:59:37 GMT
Server: Apache-Coyote/1.1
Content-Disposition: inline; filename=geoserver-GetFeature.text
Content-Type: text/xml; subtype=gml/2.1.2
Vary: Accept-Encoding
Connection: close
Transfer-Encoding: chunked
ところで、この質問: [restlet ]TruncatedChunkException:は似ていますが、役立つ情報はないようです。
更新:チャンクされていないサイト (/. :-) ) で試してみましたが、次のように同様に失敗します:
org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body