equal
deleted
inserted
replaced
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); |