diff --git a/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_77.mod b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_77.mod
new file mode 100644
index 00000000000..3628757cbfd
--- /dev/null
+++ b/jetty-alpn/jetty-alpn-server/src/main/config/modules/alpn-impl/alpn-1.8.0_77.mod
@@ -0,0 +1,8 @@
+[name]
+protonego-boot
+
+[files]
+http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
+
+[exec]
+-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java
index db3836639e0..484b7811065 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java
@@ -307,6 +307,7 @@ public abstract class HttpReceiver
}
default:
{
+ callback.failed(new IllegalStateException("Invalid response state " + current));
return false;
}
}
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
index c50b44a8c74..78d9548ae6c 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpReceiverOverHTTP2.java
@@ -117,6 +117,8 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen
{
byteBufferPool.release(copy);
super.succeeded();
+ if (frame.isEndStream())
+ responseSuccess(exchange);
}
@Override
@@ -127,11 +129,7 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements Stream.Listen
}
};
- if (responseContent(exchange, copy, delegate))
- {
- if (frame.isEndStream())
- responseSuccess(exchange);
- }
+ responseContent(exchange, copy, delegate);
}
@Override
diff --git a/jetty-start/src/test/resources/dist-home/modules/alpn-impl/alpn-1.8.0_77.mod b/jetty-start/src/test/resources/dist-home/modules/alpn-impl/alpn-1.8.0_77.mod
new file mode 100644
index 00000000000..3628757cbfd
--- /dev/null
+++ b/jetty-start/src/test/resources/dist-home/modules/alpn-impl/alpn-1.8.0_77.mod
@@ -0,0 +1,8 @@
+[name]
+protonego-boot
+
+[files]
+http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar
+
+[exec]
+-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.7.v20160121.jar
diff --git a/pom.xml b/pom.xml
index 009caad03e1..a16aea434c1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1041,5 +1041,17 @@
8.1.7.v20160121
+
+ 8u77
+
+
+ java.version
+ 1.8.0_77
+
+
+
+ 8.1.7.v20160121
+
+
diff --git a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java
index 2c91d53adcd..2e7bd8ffc69 100644
--- a/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java
+++ b/tests/test-http-client-transport/src/test/java/org/eclipse/jetty/http/client/HttpClientTest.java
@@ -19,9 +19,11 @@
package org.eclipse.jetty.http.client;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InterruptedIOException;
import java.util.EnumSet;
import java.util.Random;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
@@ -33,15 +35,16 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.client.util.BytesContentProvider;
import org.eclipse.jetty.client.util.FutureResponseListener;
+import org.eclipse.jetty.client.util.InputStreamResponseListener;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http2.FlowControlStrategy;
import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
-import org.eclipse.jetty.util.log.StacklessLogging;
+import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.hamcrest.Matchers;
@@ -377,6 +380,36 @@ public class HttpClientTest extends AbstractTest
Assert.assertEquals(HttpStatus.OK_200, response.getStatus());
}
+ @Test
+ public void testDownloadWithInputStreamResponseListener() throws Exception
+ {
+ String content = "hello world";
+ start(new AbstractHandler()
+ {
+ @Override
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ {
+ baseRequest.setHandled(true);
+ response.getOutputStream().print(content);
+ }
+ });
+
+ CountDownLatch latch = new CountDownLatch(1);
+ InputStreamResponseListener listener = new InputStreamResponseListener();
+ client.newRequest("localhost", connector.getLocalPort())
+ .scheme(getScheme())
+ .onResponseSuccess(response -> latch.countDown())
+ .send(listener);
+ Response response = listener.get(5, TimeUnit.SECONDS);
+ Assert.assertEquals(200, response.getStatus());
+
+ // Response cannot succeed until we read the content.
+ Assert.assertFalse(latch.await(500, TimeUnit.MILLISECONDS));
+
+ InputStream input = listener.getInputStream();
+ Assert.assertEquals(content, IO.toString(input));
+ }
+
private void sleep(long time) throws IOException
{
try