src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java
branchhttp-client-branch
changeset 56345 eb72d194235c
parent 56282 10cebcd18d47
child 56417 312811f70c43
--- a/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java	Thu Mar 22 16:13:36 2018 +0000
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java	Fri Mar 23 18:01:52 2018 +0000
@@ -71,7 +71,8 @@
     final HttpResponse.BodyHandler<T> responseHandler;
     final Executor executor;
     final AtomicInteger attempts = new AtomicInteger();
-    HttpRequestImpl currentreq; // used for async only
+    HttpRequestImpl currentreq; // used for retries & redirect
+    HttpRequestImpl previousreq; // used for retries & redirect
     Exchange<T> exchange; // the current exchange
     Exchange<T> previous;
     volatile Throwable retryCause;
@@ -114,6 +115,7 @@
         this.userRequest = userRequest;
         this.request = requestImpl;
         this.currentreq = request;
+        this.previousreq = null;
         this.client = client;
         this.filters = client.filterChain();
         this.acc = acc;
@@ -186,11 +188,6 @@
         return null;
     }
 
-//    public void cancel() {
-//        cancelled = true;
-//        getExchange().cancel();
-//    }
-
     public void cancel(IOException cause) {
         cancelled = true;
         getExchange().cancel(cause);
@@ -228,7 +225,13 @@
             }
             try {
                 // 1. apply request filters
-                requestFilters(currentreq);
+                // if currentreq == previousreq the filters have already
+                // been applied once. Applying them a second time might
+                // cause some headers values to be added twice: for
+                // instance, the same cookie might be added again.
+                if (currentreq != previousreq) {
+                    requestFilters(currentreq);
+                }
             } catch (IOException e) {
                 return failedFuture(e);
             }
@@ -254,6 +257,7 @@
                                 new HttpResponseImpl<>(currentreq, response, this.response, null, exch);
                             Exchange<T> oldExch = exch;
                             return exch.ignoreBody().handle((r,t) -> {
+                                previousreq = currentreq;
                                 currentreq = newrequest;
                                 expiredOnce = false;
                                 setExchange(new Exchange<>(currentreq, this, acc));
@@ -300,6 +304,12 @@
                     "ConnectionExpiredException (async): retrying...",
                     t);
                 expiredOnce = true;
+                // The connection was abruptly closed.
+                // We return null to retry the same request a second time.
+                // The request filters have already been applied to the
+                // currentreq, so we set previousreq = currentreq to
+                // prevent them from being applied again.
+                previousreq = currentreq;
                 return null;
             } else {
                 DEBUG_LOGGER.log(Level.DEBUG,