src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java
branchhttp-client-branch
changeset 56345 eb72d194235c
parent 56282 10cebcd18d47
child 56417 312811f70c43
equal deleted inserted replaced
56344:2f3c34e2b691 56345:eb72d194235c
    69     final AccessControlContext acc;
    69     final AccessControlContext acc;
    70     final HttpClientImpl client;
    70     final HttpClientImpl client;
    71     final HttpResponse.BodyHandler<T> responseHandler;
    71     final HttpResponse.BodyHandler<T> responseHandler;
    72     final Executor executor;
    72     final Executor executor;
    73     final AtomicInteger attempts = new AtomicInteger();
    73     final AtomicInteger attempts = new AtomicInteger();
    74     HttpRequestImpl currentreq; // used for async only
    74     HttpRequestImpl currentreq; // used for retries & redirect
       
    75     HttpRequestImpl previousreq; // used for retries & redirect
    75     Exchange<T> exchange; // the current exchange
    76     Exchange<T> exchange; // the current exchange
    76     Exchange<T> previous;
    77     Exchange<T> previous;
    77     volatile Throwable retryCause;
    78     volatile Throwable retryCause;
    78     volatile boolean expiredOnce;
    79     volatile boolean expiredOnce;
    79     volatile HttpResponse<T> response = null;
    80     volatile HttpResponse<T> response = null;
   112                   AccessControlContext acc) {
   113                   AccessControlContext acc) {
   113         this.previous = null;
   114         this.previous = null;
   114         this.userRequest = userRequest;
   115         this.userRequest = userRequest;
   115         this.request = requestImpl;
   116         this.request = requestImpl;
   116         this.currentreq = request;
   117         this.currentreq = request;
       
   118         this.previousreq = null;
   117         this.client = client;
   119         this.client = client;
   118         this.filters = client.filterChain();
   120         this.filters = client.filterChain();
   119         this.acc = acc;
   121         this.acc = acc;
   120         this.executor = client.theExecutor();
   122         this.executor = client.theExecutor();
   121         this.responseHandler = responseHandler;
   123         this.responseHandler = responseHandler;
   183             }
   185             }
   184         }
   186         }
   185         Log.logTrace("All filters applied");
   187         Log.logTrace("All filters applied");
   186         return null;
   188         return null;
   187     }
   189     }
   188 
       
   189 //    public void cancel() {
       
   190 //        cancelled = true;
       
   191 //        getExchange().cancel();
       
   192 //    }
       
   193 
   190 
   194     public void cancel(IOException cause) {
   191     public void cancel(IOException cause) {
   195         cancelled = true;
   192         cancelled = true;
   196         getExchange().cancel(cause);
   193         getExchange().cancel(cause);
   197     }
   194     }
   226                 timedEvent = new TimedEvent(currentreq.timeout().get());
   223                 timedEvent = new TimedEvent(currentreq.timeout().get());
   227                 client.registerTimer(timedEvent);
   224                 client.registerTimer(timedEvent);
   228             }
   225             }
   229             try {
   226             try {
   230                 // 1. apply request filters
   227                 // 1. apply request filters
   231                 requestFilters(currentreq);
   228                 // if currentreq == previousreq the filters have already
       
   229                 // been applied once. Applying them a second time might
       
   230                 // cause some headers values to be added twice: for
       
   231                 // instance, the same cookie might be added again.
       
   232                 if (currentreq != previousreq) {
       
   233                     requestFilters(currentreq);
       
   234                 }
   232             } catch (IOException e) {
   235             } catch (IOException e) {
   233                 return failedFuture(e);
   236                 return failedFuture(e);
   234             }
   237             }
   235             Exchange<T> exch = getExchange();
   238             Exchange<T> exch = getExchange();
   236             // 2. get response
   239             // 2. get response
   252                         } else {
   255                         } else {
   253                             this.response =
   256                             this.response =
   254                                 new HttpResponseImpl<>(currentreq, response, this.response, null, exch);
   257                                 new HttpResponseImpl<>(currentreq, response, this.response, null, exch);
   255                             Exchange<T> oldExch = exch;
   258                             Exchange<T> oldExch = exch;
   256                             return exch.ignoreBody().handle((r,t) -> {
   259                             return exch.ignoreBody().handle((r,t) -> {
       
   260                                 previousreq = currentreq;
   257                                 currentreq = newrequest;
   261                                 currentreq = newrequest;
   258                                 expiredOnce = false;
   262                                 expiredOnce = false;
   259                                 setExchange(new Exchange<>(currentreq, this, acc));
   263                                 setExchange(new Exchange<>(currentreq, this, acc));
   260                                 return responseAsyncImpl();
   264                                 return responseAsyncImpl();
   261                             }).thenCompose(Function.identity());
   265                             }).thenCompose(Function.identity());
   298             if (!expiredOnce) {
   302             if (!expiredOnce) {
   299                 DEBUG_LOGGER.log(Level.DEBUG,
   303                 DEBUG_LOGGER.log(Level.DEBUG,
   300                     "ConnectionExpiredException (async): retrying...",
   304                     "ConnectionExpiredException (async): retrying...",
   301                     t);
   305                     t);
   302                 expiredOnce = true;
   306                 expiredOnce = true;
       
   307                 // The connection was abruptly closed.
       
   308                 // We return null to retry the same request a second time.
       
   309                 // The request filters have already been applied to the
       
   310                 // currentreq, so we set previousreq = currentreq to
       
   311                 // prevent them from being applied again.
       
   312                 previousreq = currentreq;
   303                 return null;
   313                 return null;
   304             } else {
   314             } else {
   305                 DEBUG_LOGGER.log(Level.DEBUG,
   315                 DEBUG_LOGGER.log(Level.DEBUG,
   306                     "ConnectionExpiredException (async): already retried once.",
   316                     "ConnectionExpiredException (async): already retried once.",
   307                     t);
   317                     t);