Java HttpClient在访问大块资源时引发TruncatedChunkException

Java HttpClient在访问大块资源时引发TruncatedChunkException,java,apache,http,httpclient,chunked,Java,Apache,Http,Httpclient,Chunked,[使用httpcore 4.1.4、httpclient 4.2.5、Oracle JDK 1.7.0_25] 我试图代表webapp的javascript(AJAX)代码“代理”到第三方web服务的连接,但在大型分块的响应上似乎失败了,通过发送多个RST并抛出org.apache.http.TruncatedChunkException在一个分块中出错 所以我想知道: 为什么http客户端试图断开连接 它在做一些明智的事情吗?(即,服务器是否可能有故障)或者这里是否有问题 我的基本方法是将se

[使用httpcore 4.1.4、httpclient 4.2.5、Oracle JDK 1.7.0_25]

我试图代表webapp的javascript(AJAX)代码“代理”到第三方web服务的连接,但在大型
分块的
响应上似乎失败了,通过发送多个RST并抛出
org.apache.http.TruncatedChunkException
在一个分块中出错

所以我想知道:

  • 为什么http客户端试图断开连接
  • 它在做一些明智的事情吗?(即,服务器是否可能有故障)或者这里是否有问题
  • 我的基本方法是将servlet的请求对象复制到apache组件httpclient请求并执行。更具体地说,我:

  • 创建apache commons httpclient DefaultHttpClient对象
  • 将所有请求头复制到新的请求对象
  • 使用我要代理的主机/端口在新请求上设置(/override)主机的
    host
  • 将所有HTTP参数复制到新请求
  • 将任何实体实体复制到新请求
  • 执行请求
  • 将响应头复制到我的servlet的响应头,然后
  • 将任何实体体作为流复制到servlet的输出流
  • 给我带来麻烦的是最后一点。它似乎在一个块中失败了一半,我得到了以下堆栈跟踪:

    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)
    
    在我有限的理解中,哪个IMO是足够公平的,因为客户端头已经发送了。然而,RST/reset似乎只是试图断开连接

    客户端的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
    
    顺便说一句,这个问题:看起来很相似,但似乎没有任何有用的信息

    更新:我尝试了一个非分块站点(/。:-),但同样失败的是:

    org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body
    

    好吧,我知道我做了什么。我清理我的连接太早了——基本上我的连接方法中的样板文件有一个错误

    finally
    {
        client.getConnectionManager().shutdown();
    }
    

    但是该方法返回了stream对象,因此在关机时读取未完成。

    那么您是如何释放连接的?抱歉,这是很久以前的事了,我不记得了!我怀疑在等待结果之后,我会添加一个明确的结束。
    finally
    {
        client.getConnectionManager().shutdown();
    }