HttpHeaders responseHeaders = response.headers();
String location = responseHeaders.get(HttpHeaders.Names.LOCATION);
Uri uri = Uri.create(future.getUri(), location);
if (!uri.equals(future.getUri())) {
final RequestBuilder requestBuilder = new RequestBuilder(future.getRequest());
if (!config.isRemoveQueryParamOnRedirect())
requestBuilder.addQueryParams(future.getRequest().getQueryParams());
// if we are to strictly handle 302, we should keep the original method (which browsers don't)
// 303 must force GET
if ((statusCode == FOUND.code() && !config.isStrict302Handling()) || statusCode == SEE_OTHER.code())
requestBuilder.setMethod("GET");
// in case of a redirect from HTTP to HTTPS, future attributes might change
final boolean initialConnectionKeepAlive = future.isKeepAlive();
final String initialPoolKey = channelManager.getPartitionId(future);
future.setUri(uri);
String newUrl = uri.toUrl();
if (request.getUri().getScheme().startsWith(WEBSOCKET)) {
newUrl = newUrl.replaceFirst(HTTP, WEBSOCKET);
}
logger.debug("Redirecting to {}", newUrl);
for (String cookieStr : responseHeaders.getAll(HttpHeaders.Names.SET_COOKIE)) {
Cookie c = CookieDecoder.decode(cookieStr, timeConverter);
if (c != null)
requestBuilder.addOrReplaceCookie(c);
}
requestBuilder.setHeaders(propagatedHeaders(future.getRequest()));
Callback callback = channelManager.newDrainCallback(future, channel, initialConnectionKeepAlive, initialPoolKey);
if (HttpHeaders.isTransferEncodingChunked(response)) {
// We must make sure there is no bytes left before
// executing the next request.
// FIXME investigate this
Channels.setAttribute(channel, callback);
} else {
// FIXME don't understand: this offers the connection to the pool, or even closes it, while the
// request has not been sent, right?
callback.call();
}
Request redirectRequest = requestBuilder.setUrl(newUrl).build();
// FIXME why not reuse the channel is same host?
requestSender.sendNextRequest(redirectRequest, future);
return true;
}
}