当使用带有available()方法的流返回相对较小的值时,Jetty HttpClient在POST时崩溃

时间:2011-03-15 19:47:06

标签: java jetty httpclient

我使用Jetty HttpClient发送POST请求,身体大约几MB。我希望Jetty尽快开始流式传输请求,因此我使用setRequestContentSource方法。

问题是,当我使用带有available()方法的任何输入流返回相对较小的值(如4096)时,Jetty有时会因以下错误而崩溃:


org.eclipse.jetty.io.EofException
    at org.eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.java:911)
    at org.eclipse.jetty.client.HttpConnection.handle(HttpConnection.java:241)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:520)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:528)
    at java.lang.Thread.run(Thread.java:680)
Caused by: 
java.io.IOException: Broken pipe
    at sun.nio.ch.FileDispatcher.write0(Native Method)
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:29)
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:100)
    at sun.nio.ch.IOUtil.write(IOUtil.java:71)
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:334)
    at org.eclipse.jetty.io.nio.ChannelEndPoint.flush(ChannelEndPoint.java:195)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.flush(SelectChannelEndPoint.java:285)
    at org.eclipse.jetty.io.nio.ChannelEndPoint.flush(ChannelEndPoint.java:316)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.flush(SelectChannelEndPoint.java:267)
    at org.eclipse.jetty.http.HttpGenerator.flushBuffer(HttpGenerator.java:846)
    at org.eclipse.jetty.client.HttpConnection.handle(HttpConnection.java:241)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:520)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:40)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:528)
    at java.lang.Thread.run(Thread.java:680)

这是非确定性的,似乎将Thread.sleep(10)放在流的read()方法中可以解决问题。使用管道流时,也可以修复此错误。这3件事让我觉得这是某种竞争条件。

我想这是Jetty中的错误,但我想确定在这种情况下我是不是做了一些奇怪的事情。

1 个答案:

答案 0 :(得分:0)

特别是在通过代理和做多部分时,我得到了很多。

Buffer okBuffer = new ByteArrayBuffer(IOUtils.toByteArray(streamToTranslate));
exchange.setRequestContent(okBuffer);

我知道这不会传播它,这是你想要做的,但对我来说,我发布的文件有一个上限,所以它的工作原理。