Merged branch 'jetty-9.3.x' into 'master'.
diff --git a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ErrorCode.java b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ErrorCode.java
index e5a69b1..7022c37 100644
--- a/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ErrorCode.java
+++ b/jetty-http2/http2-common/src/main/java/org/eclipse/jetty/http2/ErrorCode.java
@@ -21,21 +21,66 @@
 import java.util.HashMap;
 import java.util.Map;
 
+/**
+ * Standard HTTP/2 error codes.
+ */
 public enum ErrorCode
 {
+    /**
+     * Indicates no errors.
+     */
     NO_ERROR(0),
+    /**
+     * Indicates a generic HTTP/2 protocol violation.
+     */
     PROTOCOL_ERROR(1),
+    /**
+     * Indicates an internal error.
+     */
     INTERNAL_ERROR(2),
+    /**
+     * Indicates a HTTP/2 flow control violation.
+     */
     FLOW_CONTROL_ERROR(3),
+    /**
+     * Indicates that a SETTINGS frame did not receive a reply in a timely manner.
+     */
     SETTINGS_TIMEOUT_ERROR(4),
+    /**
+     * Indicates that a stream frame has been received after the stream was closed.
+     */
     STREAM_CLOSED_ERROR(5),
+    /**
+     * Indicates that a frame has an invalid length.
+     */
     FRAME_SIZE_ERROR(6),
+    /**
+     * Indicates that a stream was rejected before application processing.
+     */
     REFUSED_STREAM_ERROR(7),
+    /**
+     * Indicates that a stream is no longer needed.
+     */
     CANCEL_STREAM_ERROR(8),
+    /**
+     * Indicates inability to maintain the HPACK compression context.
+     */
     COMPRESSION_ERROR(9),
+    /**
+     * Indicates that the connection established by a HTTP CONNECT was abnormally closed.
+     */
     HTTP_CONNECT_ERROR(10),
+    /**
+     * Indicates that the other peer might be generating excessive load.
+     */
     ENHANCE_YOUR_CALM_ERROR(11),
+    /**
+     * Indicates that the transport properties do not meet minimum security requirements.
+     */
     INADEQUATE_SECURITY_ERROR(12),
+    /**
+     * Indicates that HTTP/1.1 must be used rather than HTTP/2.
+     */
     HTTP_1_1_REQUIRED_ERROR(13);
 
     public final int code;
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java
index 92e1158..df99913 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpChannelOverHTTP2.java
@@ -24,8 +24,11 @@
 import org.eclipse.jetty.client.HttpReceiver;
 import org.eclipse.jetty.client.HttpSender;
 import org.eclipse.jetty.client.api.Result;
+import org.eclipse.jetty.http2.ErrorCode;
 import org.eclipse.jetty.http2.api.Session;
 import org.eclipse.jetty.http2.api.Stream;
+import org.eclipse.jetty.http2.frames.ResetFrame;
+import org.eclipse.jetty.util.Callback;
 
 public class HttpChannelOverHTTP2 extends HttpChannel
 {
@@ -33,6 +36,7 @@
     private final Session session;
     private final HttpSenderOverHTTP2 sender;
     private final HttpReceiverOverHTTP2 receiver;
+    private Stream stream;
 
     public HttpChannelOverHTTP2(HttpDestination destination, HttpConnectionOverHTTP2 connection, Session session)
     {
@@ -65,6 +69,16 @@
         return receiver;
     }
 
+    public Stream getStream()
+    {
+        return stream;
+    }
+
+    public void setStream(Stream stream)
+    {
+        this.stream = stream;
+    }
+
     @Override
     public void send()
     {
@@ -80,6 +94,19 @@
     }
 
     @Override
+    public boolean abort(HttpExchange exchange, Throwable requestFailure, Throwable responseFailure)
+    {
+        boolean aborted = super.abort(exchange, requestFailure, responseFailure);
+        if (aborted)
+        {
+            Stream stream = getStream();
+            if (stream != null)
+                stream.reset(new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code), Callback.NOOP);
+        }
+        return aborted;
+    }
+
+    @Override
     public void exchangeTerminated(HttpExchange exchange, Result result)
     {
         super.exchangeTerminated(exchange, result);
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 827a874..51453e8 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
@@ -89,7 +89,10 @@
     {
         HttpExchange exchange = getHttpExchange();
         if (exchange == null)
+        {
+            callback.failed(new IOException("terminated"));
             return;
+        }
 
         if (responseContent(exchange, frame.getData(), callback))
         {
diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java
index db01d33..b13e68e 100644
--- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java
+++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java
@@ -33,8 +33,6 @@
 
 public class HttpSenderOverHTTP2 extends HttpSender
 {
-    private Stream stream;
-
     public HttpSenderOverHTTP2(HttpChannelOverHTTP2 channel)
     {
         super(channel);
@@ -59,7 +57,7 @@
             @Override
             public void succeeded(Stream stream)
             {
-                HttpSenderOverHTTP2.this.stream = stream;
+                getHttpChannel().setStream(stream);
                 stream.setIdleTimeout(request.getIdleTimeout());
 
                 if (content.hasContent() && !expects100Continue(request))
@@ -95,15 +93,9 @@
         }
         else
         {
+            Stream stream = getHttpChannel().getStream();
             DataFrame frame = new DataFrame(stream.getId(), content.getByteBuffer(), content.isLast());
             stream.data(frame, callback);
         }
     }
-
-    @Override
-    protected void reset()
-    {
-        super.reset();
-        stream = null;
-    }
 }
diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/AbstractTest.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/AbstractTest.java
index d4214dd..8122539 100644
--- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/AbstractTest.java
+++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/AbstractTest.java
@@ -19,8 +19,11 @@
 package org.eclipse.jetty.http2.client.http;
 
 import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.http2.api.server.ServerSessionListener;
 import org.eclipse.jetty.http2.client.HTTP2Client;
 import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
+import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
+import org.eclipse.jetty.server.ConnectionFactory;
 import org.eclipse.jetty.server.Handler;
 import org.eclipse.jetty.server.HttpConfiguration;
 import org.eclipse.jetty.server.Server;
@@ -38,25 +41,38 @@
     protected ServerConnector connector;
     protected HttpClient client;
 
-    protected void start(int maxConcurrentStreams, Handler handler) throws Exception
+    protected void start(ServerSessionListener listener) throws Exception
+    {
+        prepareServer(new RawHTTP2ServerConnectionFactory(new HttpConfiguration(), listener));
+        server.start();
+        prepareClient();
+        client.start();
+    }
+
+    protected void start(Handler handler) throws Exception
+    {
+        prepareServer(new HTTP2ServerConnectionFactory(new HttpConfiguration()));
+        server.setHandler(handler);
+        server.start();
+        prepareClient();
+        client.start();
+    }
+
+    protected void prepareServer(ConnectionFactory connectionFactory)
     {
         QueuedThreadPool serverExecutor = new QueuedThreadPool();
         serverExecutor.setName("server");
         server = new Server(serverExecutor);
-
-        HTTP2ServerConnectionFactory http2 = new HTTP2ServerConnectionFactory(new HttpConfiguration());
-        http2.setMaxConcurrentStreams(maxConcurrentStreams);
-        connector = new ServerConnector(server, 1, 1, http2);
+        connector = new ServerConnector(server, 1, 1, connectionFactory);
         server.addConnector(connector);
+    }
 
-        server.setHandler(handler);
-        server.start();
-
+    protected void prepareClient() throws Exception
+    {
         client = new HttpClient(new HttpClientTransportOverHTTP2(new HTTP2Client()), null);
         QueuedThreadPool clientExecutor = new QueuedThreadPool();
         clientExecutor.setName("client");
         client.setExecutor(clientExecutor);
-        client.start();
     }
 
     @After
diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java
index c2334ea..1dcd606 100644
--- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java
+++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/HttpClientTransportOverHTTP2Test.java
@@ -18,19 +18,32 @@
 
 package org.eclipse.jetty.http2.client.http;
 
+import java.nio.ByteBuffer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
 
 import org.eclipse.jetty.client.HttpClient;
 import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.http.HttpFields;
 import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.http.MetaData;
+import org.eclipse.jetty.http2.api.Stream;
+import org.eclipse.jetty.http2.api.server.ServerSessionListener;
 import org.eclipse.jetty.http2.client.HTTP2Client;
+import org.eclipse.jetty.http2.frames.DataFrame;
+import org.eclipse.jetty.http2.frames.HeadersFrame;
+import org.eclipse.jetty.http2.frames.ResetFrame;
+import org.eclipse.jetty.util.Callback;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
 import org.eclipse.jetty.util.thread.QueuedThreadPool;
 import org.junit.Assert;
 import org.junit.Ignore;
 import org.junit.Test;
 
-public class HttpClientTransportOverHTTP2Test
+public class HttpClientTransportOverHTTP2Test extends AbstractTest
 {
     @Test
     public void testPropertiesAreForwarded() throws Exception
@@ -56,6 +69,83 @@
         Assert.assertTrue(http2Client.isStopped());
     }
 
+    @Test
+    public void testRequestAbortSendsResetFrame() throws Exception
+    {
+        CountDownLatch resetLatch = new CountDownLatch(1);
+        start(new ServerSessionListener.Adapter()
+        {
+            @Override
+            public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
+            {
+                return new Stream.Listener.Adapter()
+                {
+                    @Override
+                    public void onReset(Stream stream, ResetFrame frame)
+                    {
+                        resetLatch.countDown();
+                    }
+                };
+            }
+        });
+
+        try
+        {
+            client.newRequest("localhost", connector.getLocalPort())
+                    .onRequestCommit(request -> request.abort(new Exception("explicitly_aborted_by_test")))
+                    .send();
+            Assert.fail();
+        }
+        catch (ExecutionException x)
+        {
+            Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
+        }
+    }
+
+    @Test
+    public void testResponseAbortSendsResetFrame() throws Exception
+    {
+        CountDownLatch resetLatch = new CountDownLatch(1);
+        start(new ServerSessionListener.Adapter()
+        {
+            @Override
+            public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
+            {
+                MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields());
+                stream.headers(new HeadersFrame(stream.getId(), metaData, null, false), new Callback()
+                {
+                    @Override
+                    public void succeeded()
+                    {
+                        ByteBuffer data = ByteBuffer.allocate(1024);
+                        stream.data(new DataFrame(stream.getId(), data, false), NOOP);
+                    }
+                });
+
+                return new Stream.Listener.Adapter()
+                {
+                    @Override
+                    public void onReset(Stream stream, ResetFrame frame)
+                    {
+                        resetLatch.countDown();
+                    }
+                };
+            }
+        });
+
+        try
+        {
+            client.newRequest("localhost", connector.getLocalPort())
+                    .onResponseContent((response, buffer) -> response.abort(new Exception("explicitly_aborted_by_test")))
+                    .send();
+            Assert.fail();
+        }
+        catch (ExecutionException x)
+        {
+            Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
+        }
+    }
+
     @Ignore
     @Test
     public void testExternalServer() throws Exception
diff --git a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java
index 78b4219..c456d02 100644
--- a/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java
+++ b/jetty-http2/http2-http-client-transport/src/test/java/org/eclipse/jetty/http2/client/http/MaxConcurrentStreamsTest.java
@@ -28,6 +28,9 @@
 
 import org.eclipse.jetty.client.api.ContentResponse;
 import org.eclipse.jetty.http.HttpStatus;
+import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.HttpConfiguration;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.handler.AbstractHandler;
 import org.junit.Assert;
@@ -35,6 +38,17 @@
 
 public class MaxConcurrentStreamsTest extends AbstractTest
 {
+    private void start(int maxConcurrentStreams, Handler handler) throws Exception
+    {
+        HTTP2ServerConnectionFactory http2 = new HTTP2ServerConnectionFactory(new HttpConfiguration());
+        http2.setMaxConcurrentStreams(maxConcurrentStreams);
+        prepareServer(http2);
+        server.setHandler(handler);
+        server.start();
+        prepareClient();
+        client.start();
+    }
+
     @Test
     public void testOneConcurrentStream() throws Exception
     {
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
index 1b6c4a8..1f8c8b4 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpInput.java
@@ -22,6 +22,7 @@
 import java.io.InterruptedIOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayDeque;
+import java.util.Deque;
 import java.util.Objects;
 import java.util.Queue;
 import java.util.concurrent.TimeoutException;
@@ -51,7 +52,7 @@
     private final static Content EARLY_EOF_CONTENT = new EofContent("EARLY_EOF");
 
     private final byte[] _oneByteBuffer = new byte[1];
-    private final Queue<Content> _inputQ = new ArrayDeque<>();
+    private final Deque<Content> _inputQ = new ArrayDeque<>();
     private final HttpChannelState _channelState;
     private ReadListener _listener;
     private State _state = STREAM;
@@ -370,6 +371,33 @@
     }
 
     /**
+     * Adds some content to the start of this input stream.
+     * <p>Typically used to push back content that has
+     * been read, perhaps mutated.  The bytes prepended are
+     * deducted for the contentConsumed total</p>
+     * @param item the content to add
+     * @return true if content channel woken for read
+     */
+    public boolean prependContent(Content item)
+    {
+        boolean woken=false;
+        synchronized (_inputQ)
+        {
+            _inputQ.push(item);
+            _contentConsumed-=item.remaining();
+            if (LOG.isDebugEnabled())
+                LOG.debug("{} prependContent {}", this, item);
+
+            if (_listener==null)
+                _inputQ.notify();
+            else
+                woken=_channelState.onReadPossible();
+        }
+
+        return woken;
+    }
+    
+    /**
      * Adds some content to this input stream.
      *
      * @param item the content to add
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
index 07c316c..c594d24 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ContextHandler.java
@@ -768,6 +768,8 @@
             old_context = __context.get();
             __context.set(_scontext);
 
+            enterScope(null, getState());
+
             // defers the calling of super.doStart()
             startContext();
 
@@ -855,7 +857,7 @@
         ClassLoader old_classloader = null;
         ClassLoader old_webapploader = null;
         Thread current_thread = null;
-
+        exitScope(null);
         Context old_context = __context.get();
         __context.set(_scontext);
         try
diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpInputTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpInputTest.java
index 5e7454c..5a404f3 100644
--- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpInputTest.java
+++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpInputTest.java
@@ -221,6 +221,67 @@
         assertThat(_history.poll(),nullValue());
     }
 
+
+    @Test
+    public void testReRead() throws Exception
+    {
+        _in.addContent(new TContent("AB"));
+        _in.addContent(new TContent("CD"));
+        _fillAndParseSimulate.offer("EF");
+        _fillAndParseSimulate.offer("GH");
+        assertThat(_in.available(),equalTo(2));
+        assertThat(_in.isFinished(),equalTo(false));
+        assertThat(_in.isReady(),equalTo(true));
+
+        assertThat(_in.getContentConsumed(),equalTo(0L));
+        assertThat(_in.read(),equalTo((int)'A'));
+        assertThat(_in.getContentConsumed(),equalTo(1L));
+        assertThat(_in.read(),equalTo((int)'B'));
+        assertThat(_in.getContentConsumed(),equalTo(2L));
+        
+        assertThat(_history.poll(),equalTo("Content succeeded AB"));
+        assertThat(_history.poll(),nullValue());
+        assertThat(_in.read(),equalTo((int)'C'));
+        assertThat(_in.read(),equalTo((int)'D'));
+        
+        assertThat(_history.poll(),equalTo("Content succeeded CD"));
+        assertThat(_history.poll(),nullValue());
+        assertThat(_in.read(),equalTo((int)'E'));
+        
+        _in.prependContent(new HttpInput.Content(BufferUtil.toBuffer("abcde")));
+
+        assertThat(_in.available(),equalTo(5));
+        assertThat(_in.isFinished(),equalTo(false));
+        assertThat(_in.isReady(),equalTo(true));
+
+        assertThat(_in.getContentConsumed(),equalTo(0L));
+        assertThat(_in.read(),equalTo((int)'a'));
+        assertThat(_in.getContentConsumed(),equalTo(1L));
+        assertThat(_in.read(),equalTo((int)'b'));
+        assertThat(_in.getContentConsumed(),equalTo(2L));
+        assertThat(_in.read(),equalTo((int)'c'));
+        assertThat(_in.read(),equalTo((int)'d'));        
+        assertThat(_in.read(),equalTo((int)'e'));
+        
+        
+        
+        assertThat(_in.read(),equalTo((int)'F'));
+
+        assertThat(_history.poll(),equalTo("produceContent 2"));
+        assertThat(_history.poll(),equalTo("Content succeeded EF"));
+        assertThat(_history.poll(),nullValue());
+        
+        assertThat(_in.read(),equalTo((int)'G'));
+        assertThat(_in.read(),equalTo((int)'H'));
+        
+        assertThat(_history.poll(),equalTo("Content succeeded GH"));
+        assertThat(_history.poll(),nullValue());
+        
+        assertThat(_in.getContentConsumed(),equalTo(8L));
+        
+        assertThat(_history.poll(),nullValue());
+    }
+    
     @Test
     public void testBlockingRead() throws Exception
     {
diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/RequestGetPartsTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/RequestGetPartsTest.java
deleted file mode 100644
index 55de8d8..0000000
--- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/RequestGetPartsTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-//
-//  ========================================================================
-//  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
-//  ------------------------------------------------------------------------
-//  All rights reserved. This program and the accompanying materials
-//  are made available under the terms of the Eclipse Public License v1.0
-//  and Apache License v2.0 which accompanies this distribution.
-//
-//      The Eclipse Public License is available at
-//      http://www.eclipse.org/legal/epl-v10.html
-//
-//      The Apache License v2.0 is available at
-//      http://www.opensource.org/licenses/apache2.0.php
-//
-//  You may elect to redistribute this code under either of these licenses.
-//  ========================================================================
-//
-
-package org.eclipse.jetty.servlet;
-
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-
-import javax.servlet.MultipartConfigElement;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.Part;
-
-import org.eclipse.jetty.http.HttpTester;
-import org.eclipse.jetty.server.LocalConnector;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.toolchain.test.FS;
-import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class RequestGetPartsTest
-{
-    @SuppressWarnings("serial")
-    public static class DumpPartInfoServlet extends HttpServlet
-    {
-        @Override
-        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
-        {
-            resp.setContentType("text/plain");
-            PrintWriter out = resp.getWriter();
-            
-            for(Part part: req.getParts())
-            {
-                out.printf("Got part: name=%s, size=%,d, filename=%s%n",part.getName(), part.getSize(), part.getSubmittedFileName());
-            }
-        }
-    }
-    
-    private static Server server;
-    private static LocalConnector connector;
-    private static File locationDir;
-    
-    @BeforeClass
-    public static void startServer() throws Exception
-    {
-        Path tmpDir = MavenTestingUtils.getTargetTestingPath("testrequest_getparts");
-        FS.ensureEmpty(tmpDir);
-        
-        locationDir = tmpDir.toFile();
-        
-        server = new Server();
-        connector = new LocalConnector(server);
-        server.addConnector(connector);
-        
-        ServletContextHandler context = new ServletContextHandler();
-        context.setContextPath("/");
-        server.setHandler(context);
-        
-        ServletHolder holder = context.addServlet(DumpPartInfoServlet.class,"/dump/*");
-        String location = locationDir.getAbsolutePath();
-        long maxFileSize = 1024*1024*5;
-        long maxRequestSize = 1024*1024*10;
-        int fileSizeThreshold = 1;
-        MultipartConfigElement multipartConfig = new MultipartConfigElement(location,maxFileSize,maxRequestSize,fileSizeThreshold);
-        ((ServletHolder.Registration) holder.getRegistration()).setMultipartConfig(multipartConfig);
-        
-        server.start();
-    }
-    
-    @AfterClass
-    public static void stopServer() throws Exception
-    {
-        server.stop();
-    }
-    
-    @Test
-    public void testMultiFileUpload_SameName() throws Exception
-    {
-        // generated and parsed test
-        HttpTester.Request request = HttpTester.newRequest();
-        HttpTester.Response response;
-
-        // test GET
-        request.setMethod("POST");
-        request.setURI("/dump/");
-        request.setVersion("HTTP/1.1");
-        request.setHeader("Host","tester");
-        request.setHeader("Connection","close");
-
-        String boundary="XyXyXy";
-        request.setHeader("Content-Type","multipart/form-data; boundary=" + boundary);
-        
-        String crocMsg = "See ya later, aligator.";
-        String aligMsg = "In a while, crocodile.";
-
-        StringBuilder content = new StringBuilder();
-        content.append("--").append(boundary).append("\r\n");
-        content.append("Content-Disposition: form-data; name=\"same\"; filename=\"crocodile.dat\"\r\n");
-        content.append("Content-Type: application/octet-stream\r\n");
-        content.append("\r\n");
-        content.append(crocMsg).append("\r\n");
-        content.append("--").append(boundary).append("\r\n");
-        content.append("Content-Disposition: form-data; name=\"same\"; filename=\"aligator.dat\"\r\n");
-        content.append("Content-Type: application/octet-stream\r\n");
-        content.append("\r\n");
-        content.append(aligMsg).append("\r\n");
-        content.append("--").append(boundary).append("--\r\n");
-        content.append("\r\n");
-        
-        request.setContent(content.toString());
-
-        response = HttpTester.parseResponse(connector.getResponses(request.generate()));
-        assertThat("Response status", response.getStatus(), is(HttpServletResponse.SC_OK));
-        assertEquals(HttpServletResponse.SC_OK,response.getStatus());
-        
-        String responseContents = response.getContent();
-        assertThat("response.contents", responseContents, containsString(String.format("Got part: name=same, size=%d, filename=crocodile.dat",crocMsg.length())));
-        assertThat("response.contents", responseContents, containsString(String.format("Got part: name=same, size=%d, filename=aligator.dat",aligMsg.length())));
-    }
-}
diff --git a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
index c2ce682..c3b43e4 100644
--- a/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
+++ b/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/MultipartFilterTest.java
@@ -18,10 +18,9 @@
 
 package org.eclipse.jetty.servlets;
 
+
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.hamcrest.Matchers.nullValue;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -31,15 +30,10 @@
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.io.Reader;
 import java.nio.charset.StandardCharsets;
-import java.nio.file.Path;
 import java.util.EnumSet;
-import java.util.Enumeration;
 import java.util.Map;
 
 import javax.servlet.DispatcherType;
@@ -51,12 +45,9 @@
 import org.eclipse.jetty.http.HttpTester;
 import org.eclipse.jetty.servlet.FilterHolder;
 import org.eclipse.jetty.servlet.ServletTester;
-import org.eclipse.jetty.toolchain.test.FS;
-import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
 import org.eclipse.jetty.util.IO;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class MultipartFilterTest
@@ -65,45 +56,16 @@
     private ServletTester tester;
     FilterHolder multipartFilter;
     
-    @SuppressWarnings("serial")
     public static class FilenameServlet extends TestServlet
     {
         @Override
         protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
         {
-            assertThat(req.getAttribute("fileup"), notNullValue());
+            assertNotNull(req.getAttribute("fileup"));
             super.doPost(req, resp);
         }
     }
-    
-    @SuppressWarnings("serial")
-    public static class ParameterListServlet extends TestServlet
-    {
-        @Override
-        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
-        {
-            resp.setContentType("text/plain");
-            PrintWriter out = resp.getWriter();
-            
-            Enumeration<String> pnames = req.getParameterNames();
-            while (pnames.hasMoreElements())
-            {
-                String pname = pnames.nextElement();
-                Object param = req.getParameter(pname);
-                out.printf("Parameter[%s] = ",pname);
-                if (param == null)
-                {
-                    out.println(" <null>");
-                }
-                else
-                {
-                    out.printf("(%s) %s%n",param.getClass().getName(),param);
-                }
-            }
-        }
-    }
 
-    @SuppressWarnings("serial")
     public static class BoundaryServlet extends TestServlet
     {
         @Override
@@ -111,11 +73,9 @@
         {
             //we have configured the multipart filter to always store to disk (file size threshold == 1)
             //but fileName has no filename param, so only the attribute should be set
-            assertThat("getParameter('fileName')", req.getParameter("fileName"), nullValue());
-            assertThat("getAttribute('fileName')", req.getAttribute("fileName"), notNullValue());
-            
+            assertNull(req.getParameter("fileName"));
+            assertNotNull(req.getAttribute("fileName"));
             File f = (File)req.getAttribute("fileName");
-            assertThat("File exists", f.exists(), is(true));
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
             IO.copy(new FileInputStream(f), baos);
             assertEquals(getServletContext().getAttribute("fileName"), baos.toString());
@@ -133,36 +93,34 @@
         }
     }
     
-    @SuppressWarnings("serial")
     public static class TestServlet extends DumpServlet
     {
 
-        @SuppressWarnings("deprecation")
         @Override
         protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
         {
-            String fileup = req.getParameter("fileup");
-            assertThat("getParameter('fileup')",fileup,notNullValue());
-            
-            System.err.println("Fileup=" + req.getParameter("fileup"));
-            
-            String fileupType = req.getParameter("fileup" + MultiPartFilter.CONTENT_TYPE_SUFFIX);
-            assertThat("req.getParameter('fileup'+CONTENT_TYPE_SUFFIX)",fileupType,is("application/octet-stream"));
+            assertNotNull(req.getParameter("fileup"));
+            System.err.println("Fileup="+req.getParameter("fileup"));
+            assertNotNull(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX));
+            assertEquals(req.getParameter("fileup"+MultiPartFilter.CONTENT_TYPE_SUFFIX), "application/octet-stream");
             super.doPost(req, resp);
         }
+
     }
 
-    @SuppressWarnings("deprecation")
+
+
     @Before
     public void setUp() throws Exception
     {
-        Path tmpDir = MavenTestingUtils.getTargetTestingPath("testmultupart");
-        FS.ensureEmpty(tmpDir);
-        
-        _dir = tmpDir.toFile();
+        _dir = File.createTempFile("testmultupart",null);
+        assertTrue(_dir.delete());
+        assertTrue(_dir.mkdir());
+        _dir.deleteOnExit();
+        assertTrue(_dir.isDirectory());
 
         tester=new ServletTester("/context");
-        tester.getContext().setResourceBase(tmpDir.toString());
+        tester.getContext().setResourceBase(_dir.getCanonicalPath());
         tester.getContext().addServlet(TestServlet.class, "/");
         tester.getContext().setAttribute("javax.servlet.context.tempdir", _dir);
         multipartFilter = tester.getContext().addFilter(MultiPartFilter.class,"/*", EnumSet.of(DispatcherType.REQUEST));
@@ -832,7 +790,6 @@
         assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, response.getStatus());
     }
 
-    @SuppressWarnings("serial")
     public static class TestServletParameterMap extends DumpServlet
     {
         @Override
@@ -843,7 +800,7 @@
             super.doPost(req, resp);
         }
     }
-    
+
     /**
      * Validate that the getParameterMap() call is correctly unencoding the parameters in the
      * map that it returns.
@@ -873,7 +830,7 @@
         "Content-Type: application/octet-stream\r\n\r\n"+
         "How now brown cow."+
         "\r\n--" + boundary + "\r\n"+
-        "Content-Disposition: form-data; name=\"strup\""+ // FIXME: this is missing a "\r\n"??
+        "Content-Disposition: form-data; name=\"strup\""+
         "Content-Type: application/octet-stream\r\n\r\n"+
         "How now brown cow."+
         "\r\n--" + boundary + "--\r\n\r\n";
@@ -884,119 +841,6 @@
         assertEquals(HttpServletResponse.SC_OK,response.getStatus());
         assertTrue(response.getContent().indexOf("brown cow")>=0);
     }
-    
-    /**
-     * Validate that the uploaded file can be accessed on the name it was given
-     * @throws Exception on test failure
-     */
-    @Test
-    @Ignore("Fails for Bug #486394")
-    public void testFileUpload_AccessViaFilename() throws Exception
-    {
-        tester.addServlet(ParameterListServlet.class,"/paramlist");
-        
-        multipartFilter.setInitParameter("fileOutputBuffer", "1");
-        multipartFilter.setInitParameter("deleteFiles", "false");
-        multipartFilter.setInitParameter("writeFilesWithFilenames", "true");
-
-        // generated and parsed test
-        HttpTester.Request request = HttpTester.newRequest();
-        HttpTester.Response response;
-
-        // test GET
-        request.setMethod("POST");
-        request.setURI("/context/paramlist");
-        request.setVersion("HTTP/1.1");
-        request.setHeader("Host","tester");
-        request.setHeader("Connection","close");
-        String boundary="XyXyXy";
-        request.setHeader("Content-Type","multipart/form-data; boundary=" + boundary);
-
-        StringBuilder content = new StringBuilder();
-        content.append("--").append(boundary).append("\r\n");
-        content.append("Content-Disposition: form-data; name=\"file\"; filename=\"tiny.dat\"\r\n");
-        content.append("Content-Type: application/octet-stream\r\n");
-        content.append("\r\n");
-        content.append("How now brown cow.\r\n");
-        content.append("--").append(boundary).append("--\r\n");
-        content.append("\r\n");
-        
-        request.setContent(content.toString());
-
-        response = HttpTester.parseResponse(tester.getResponses(request.generate()));
-        assertThat("Response status", response.getStatus(), is(HttpServletResponse.SC_OK));
-        assertEquals(HttpServletResponse.SC_OK,response.getStatus());
-        
-        String contents = assertUploadedFileExists("tiny.dat");
-        assertThat("contents", contents, containsString("How now brown cow."));
-    }
-    
-    /**
-     * Validate that the two upload files, with the same name="" on two different parts,
-     * can be accessed with the filename="" portions.
-     * @throws Exception on test failure
-     */
-    @Test
-    @Ignore("Fails for Bug #486394")
-    public void testTwoFileUploads_AccessViaFilename() throws Exception
-    {
-        tester.addServlet(ParameterListServlet.class,"/paramlist");
-        
-        multipartFilter.setInitParameter("fileOutputBuffer", "1");
-        multipartFilter.setInitParameter("deleteFiles", "false");
-        multipartFilter.setInitParameter("writeFilesWithFilenames", "true");
-
-        // generated and parsed test
-        HttpTester.Request request = HttpTester.newRequest();
-        HttpTester.Response response;
-
-        // test GET
-        request.setMethod("POST");
-        request.setURI("/context/paramlist");
-        request.setVersion("HTTP/1.1");
-        request.setHeader("Host","tester");
-        request.setHeader("Connection","close");
-
-        String boundary="XyXyXy";
-        request.setHeader("Content-Type","multipart/form-data; boundary=" + boundary);
-
-        StringBuilder content = new StringBuilder();
-        content.append("--").append(boundary).append("\r\n");
-        content.append("Content-Disposition: form-data; name=\"same\"; filename=\"crocodile.dat\"\r\n");
-        content.append("Content-Type: application/octet-stream\r\n");
-        content.append("\r\n");
-        content.append("See ya later, aligator.\r\n");
-        content.append("--").append(boundary).append("\r\n");
-        content.append("Content-Disposition: form-data; name=\"same\"; filename=\"aligator.dat\"\r\n");
-        content.append("Content-Type: application/octet-stream\r\n");
-        content.append("\r\n");
-        content.append("In a while, crocodile.\r\n");
-        content.append("--").append(boundary).append("--\r\n");
-        content.append("\r\n");
-        
-        request.setContent(content.toString());
-
-        response = HttpTester.parseResponse(tester.getResponses(request.generate()));
-        assertThat("Response status", response.getStatus(), is(HttpServletResponse.SC_OK));
-        assertEquals(HttpServletResponse.SC_OK,response.getStatus());
-        
-        String contents = assertUploadedFileExists("crocodile.dat");
-        assertThat("contents", contents, containsString("See ya later, aligator."));
-        
-        contents = assertUploadedFileExists("aligator.dat");
-        assertThat("contents", contents, containsString("In a while, crocodile."));
-    }
-    
-    private String assertUploadedFileExists(String filename) throws IOException
-    {
-        File uploadedFile = new File(_dir,filename);
-        assertThat("Uploaded File[" + uploadedFile + "].exists",uploadedFile.exists(),is(true));
-        
-        try (Reader reader = new FileReader(uploadedFile))
-        {
-            return IO.toString(reader);
-        }
-    }
 
     public static class TestServletCharSet extends HttpServlet
     {
@@ -1103,9 +947,13 @@
         assertTrue(response.getContent().indexOf("000")>=0);
     }
     
-    @SuppressWarnings("serial")
+    
+    
     public static class DumpServlet extends HttpServlet
     {
+        private static final long serialVersionUID = 201012011130L;
+
+        /* ------------------------------------------------------------ */
         /**
          * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
          */
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java
index 58e8c90..f1abf1e 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java
@@ -23,7 +23,9 @@
 import org.eclipse.jetty.io.ByteBufferPool;
 import org.eclipse.jetty.util.annotation.ManagedAttribute;
 import org.eclipse.jetty.util.annotation.ManagedObject;
+import org.eclipse.jetty.util.component.AbstractLifeCycle;
 import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.util.component.Dumpable;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
 import org.eclipse.jetty.websocket.api.BatchMode;
@@ -38,7 +40,7 @@
 import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
 
 @ManagedObject("Abstract Extension")
-public abstract class AbstractExtension extends ContainerLifeCycle implements Extension
+public abstract class AbstractExtension extends AbstractLifeCycle implements Dumpable, Extension
 {
     private final Logger log;
     private WebSocketPolicy policy;
@@ -52,11 +54,15 @@
     {
         log = Log.getLogger(this.getClass());
     }
-
+    
     @Override
+    public String dump()
+    {
+        return ContainerLifeCycle.dump(this);
+    }
+
     public void dump(Appendable out, String indent) throws IOException
     {
-        super.dump(out, indent);
         // incoming
         dumpWithHeading(out, indent, "incoming", this.nextIncoming);
         dumpWithHeading(out, indent, "outgoing", this.nextOutgoing);
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java
index 720e981..2cde3a5 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java
@@ -29,6 +29,7 @@
 import org.eclipse.jetty.util.annotation.ManagedAttribute;
 import org.eclipse.jetty.util.annotation.ManagedObject;
 import org.eclipse.jetty.util.component.ContainerLifeCycle;
+import org.eclipse.jetty.util.component.LifeCycle;
 import org.eclipse.jetty.util.log.Log;
 import org.eclipse.jetty.util.log.Logger;
 import org.eclipse.jetty.websocket.api.BatchMode;
@@ -89,6 +90,11 @@
                 Extension ext = exts.next();
                 ext.setNextOutgoingFrames(nextOutgoing);
                 nextOutgoing = ext;
+                
+                if (ext instanceof LifeCycle)
+                {
+                    addBean(ext,true);
+                }
             }
 
             // Connect incomings
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java
index ac32ad6..517f714 100644
--- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java
+++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java
@@ -74,28 +74,34 @@
 
     private final Queue<FrameEntry> entries = new ConcurrentArrayQueue<>();
     private final IteratingCallback flusher = new Flusher();
-    private final Deflater deflater;
-    private final Inflater inflater;
+    private Deflater deflaterImpl;
+    private Inflater inflaterImpl;
     protected AtomicInteger decompressCount = new AtomicInteger(0);
     private int tailDrop = TAIL_DROP_NEVER;
     private int rsvUse = RSV_USE_ALWAYS;
 
     protected CompressExtension()
     {
-        deflater = new Deflater(Deflater.DEFAULT_COMPRESSION,NOWRAP);
-        inflater = new Inflater(NOWRAP);
         tailDrop = getTailDropMode();
         rsvUse = getRsvUseMode();
     }
 
     public Deflater getDeflater()
     {
-        return deflater;
+        if (deflaterImpl == null)
+        {
+            deflaterImpl = new Deflater(Deflater.DEFAULT_COMPRESSION,NOWRAP);
+        }
+        return deflaterImpl;
     }
 
     public Inflater getInflater()
     {
-        return inflater;
+        if (inflaterImpl == null)
+        {
+            inflaterImpl = new Inflater(NOWRAP);
+        }
+        return inflaterImpl;
     }
 
     /**
@@ -155,6 +161,8 @@
         }
         byte[] output = new byte[DECOMPRESS_BUF_SIZE];
         
+        Inflater inflater = getInflater();
+        
         while(buf.hasRemaining() && inflater.needsInput())
         {
             if (!supplyInput(inflater,buf))
@@ -346,6 +354,16 @@
         }
         return true;
     }
+    
+    @Override
+    protected void doStop() throws Exception
+    {
+        if(deflaterImpl != null)
+            deflaterImpl.end();
+        if(inflaterImpl != null)
+            inflaterImpl.end();
+        super.doStop();
+    }
 
     @Override
     public String toString()
@@ -429,6 +447,8 @@
                 LOG.debug("Compressing {}: {} bytes in {} bytes chunk",entry,remaining,outputLength);
 
             boolean needsCompress = true;
+            
+            Deflater deflater = getDeflater();
 
             if (deflater.needsInput() && !supplyInput(deflater,data))
             {
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 c9d3a03..415bbe3 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
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.util.Random;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.IntStream;
 
@@ -35,6 +36,7 @@
 import org.eclipse.jetty.client.util.FutureResponseListener;
 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.handler.AbstractHandler;
 import org.junit.Assert;
@@ -239,6 +241,50 @@
         Assert.assertEquals(chunks * chunkSize, Integer.parseInt(response.getContentAsString()));
     }
 
+    @Test
+    public void testRequestAfterFailedRequest() throws Exception
+    {
+        int length = FlowControlStrategy.DEFAULT_WINDOW_SIZE;
+        start(new AbstractHandler()
+        {
+            @Override
+            public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+            {
+                baseRequest.setHandled(true);
+                response.getOutputStream().write(new byte[length]);
+            }
+        });
+
+        // Make a request with a large enough response buffer.
+        org.eclipse.jetty.client.api.Request request = client.newRequest(newURI());
+        FutureResponseListener listener = new FutureResponseListener(request, length);
+        request.send(listener);
+        ContentResponse response = listener.get(5, TimeUnit.SECONDS);
+        Assert.assertEquals(response.getStatus(), 200);
+
+        // Make a request with a small response buffer, should fail.
+        try
+        {
+            request = client.newRequest(newURI());
+            listener = new FutureResponseListener(request, length / 10);
+            request.send(listener);
+            listener.get(5, TimeUnit.SECONDS);
+            Assert.fail();
+        }
+        catch (ExecutionException x)
+        {
+            // Buffering capacity exceeded.
+            x.printStackTrace();
+        }
+
+        // Verify that we can make another request.
+        request = client.newRequest(newURI());
+        listener = new FutureResponseListener(request, length);
+        request.send(listener);
+        response = listener.get(5, TimeUnit.SECONDS);
+        Assert.assertEquals(response.getStatus(), 200);
+    }
+
     private void sleep(long time) throws IOException
     {
         try