int statusCode = urlConnection.getResponseCode();
logger.debug("\n\nRequest {}\n\nResponse {}\n", request, statusCode);
ResponseStatus status = new ResponseStatus(uri, urlConnection, JDKAsyncHttpProvider.this);
FilterContext fc = new FilterContext.FilterContextBuilder().asyncHandler(asyncHandler).request(request).responseStatus(status).build();
for (ResponseFilter asyncFilter : config.getResponseFilters()) {
fc = asyncFilter.filter(fc);
if (fc == null) {
throw new NullPointerException("FilterContext is null");
}
}
// The request has changed
if (fc.replayRequest()) {
request = fc.getRequest();
urlConnection = createUrlConnection(request);
terminate = false;
return call();
}
boolean redirectEnabled = (request.isRedirectEnabled() || config.isRedirectEnabled());
if (redirectEnabled && (statusCode == 302 || statusCode == 301)) {
if (currentRedirectCount++ < config.getMaxRedirects()) {
String location = urlConnection.getHeaderField("Location");
URI redirUri = AsyncHttpProviderUtils.getRedirectUri(uri, location);
String newUrl = redirUri.toString();
if (!newUrl.equals(uri.toString())) {
RequestBuilder builder = new RequestBuilder(request);
logger.debug("Redirecting to {}", newUrl);
request = builder.setUrl(newUrl).build();
urlConnection = createUrlConnection(request);
terminate = false;
return call();
}
} else {
throw new MaxRedirectException("Maximum redirect reached: " + config.getMaxRedirects());
}
}
Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();
if (statusCode == 401 && !isAuth.getAndSet(true) && realm != null ) {
String wwwAuth = urlConnection.getHeaderField("WWW-Authenticate");
logger.debug("Sending authentication to {}", request.getUrl());
Realm nr = new Realm.RealmBuilder().clone(realm)
.parseWWWAuthenticateHeader(wwwAuth)
.setUri(URI.create(request.getUrl()).getPath())
.setMethodName(request.getMethod())
.setUsePreemptiveAuth(true)
.build();
RequestBuilder builder = new RequestBuilder(request);
request = builder.setRealm(nr).build();
urlConnection = createUrlConnection(request);
terminate = false;
return call();
}
state = asyncHandler.onStatusReceived(status);
if (state == AsyncHandler.STATE.CONTINUE) {
state = asyncHandler.onHeadersReceived(new ResponseHeaders(uri, urlConnection, JDKAsyncHttpProvider.this));
}
if (state == AsyncHandler.STATE.CONTINUE) {
InputStream is = getInputStream(urlConnection);
String contentEncoding = urlConnection.getHeaderField("Content-Encoding");
boolean isGZipped = contentEncoding == null ? false : "gzip".equalsIgnoreCase(contentEncoding);
if (isGZipped) {
is = new GZIPInputStream(is);
}
int byteToRead = urlConnection.getContentLength();
InputStream stream = is;
if (bufferResponseInMemory || byteToRead <= 0) {
int[] lengthWrapper = new int[1];
byte[] bytes = AsyncHttpProviderUtils.readFully(is, lengthWrapper);
stream = new ByteArrayInputStream(bytes, 0, lengthWrapper[0]);
byteToRead = lengthWrapper[0];
}
if (byteToRead > 0) {
int minBytes = Math.min(8192, byteToRead);
byte[] bytes = new byte[minBytes];
int leftBytes = minBytes < 8192 ? minBytes : byteToRead;
int read = 0;
while (leftBytes > -1) {
read = stream.read(bytes);
if (read == -1) {
break;
}
future.touch();
byte[] b = new byte[read];
System.arraycopy(bytes, 0, b, 0, read);
asyncHandler.onBodyPartReceived(new ResponseBodyPart(uri, b, JDKAsyncHttpProvider.this));
leftBytes -= read;
}
}
if (request.getMethod().equalsIgnoreCase("HEAD")) {
asyncHandler.onBodyPartReceived(new ResponseBodyPart(uri, "".getBytes(), JDKAsyncHttpProvider.this));
}
}
if (ProgressAsyncHandler.class.isAssignableFrom(asyncHandler.getClass())) {
ProgressAsyncHandler.class.cast(asyncHandler).onHeaderWriteCompleted();
ProgressAsyncHandler.class.cast(asyncHandler).onContentWriteCompleted();
}
try {
T t = asyncHandler.onCompleted();
future.content(t);
future.done(null);
return t;
} catch (Throwable t) {
RuntimeException ex = new RuntimeException();
ex.initCause(t);
throw ex;
}
} catch (Throwable t) {
logger.debug(t.getMessage(), t);
if (IOException.class.isAssignableFrom(t.getClass()) && config.getIOExceptionFilters().size() > 0) {
FilterContext fc = new FilterContext.FilterContextBuilder().asyncHandler(asyncHandler)
.request(request).ioException(IOException.class.cast(t)).build();
try {
fc = handleIoException(fc);
} catch (FilterException e) {
if (config.getMaxTotalConnections() != -1) {
maxConnections.decrementAndGet();
}
future.done(null);
}
if (fc.replayRequest()) {
request = fc.getRequest();
urlConnection = createUrlConnection(request);
return call();
}
}