String ka = response.getHeader(HttpHeaders.Names.CONNECTION);
future.setKeepAlive(ka == null || ka.toLowerCase().equals("keep-alive"));
List<String> wwwAuth = getAuthorizationToken(response.getHeaders(), HttpHeaders.Names.WWW_AUTHENTICATE);
Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();
HttpResponseStatus status = new ResponseStatus(future.getURI(), response, this);
FilterContext<?> fc = new FilterContext.FilterContextBuilder().asyncHandler(handler).request(request).responseStatus(status).build();
for (ResponseFilter asyncFilter : config.getResponseFilters()) {
try {
fc = asyncFilter.filter(fc);
if (fc == null) {
throw new NullPointerException("FilterContext is null");
}
} catch (FilterException efe) {
abort(future, efe);
}
}
// The request has changed
if (fc.replayRequest()) {
replayRequest(future, fc, response, ctx);
return;
}
Realm newRealm = null;
ProxyServer proxyServer = request.getProxyServer() != null ? request.getProxyServer() : config.getProxyServer();
final FluentCaseInsensitiveStringsMap headers = request.getHeaders();
final RequestBuilder builder = new RequestBuilder(future.getRequest());
if (realm != null && !future.getURI().getPath().equalsIgnoreCase(realm.getUri())) {
builder.setUrl(future.getURI().toString());
}
if (statusCode == 401
&& wwwAuth.size() > 0
&& !future.getAndSetAuth(true)) {
future.setState(NettyResponseFuture.STATE.NEW);
// NTLM
if ( !wwwAuth.contains("Kerberos") && (wwwAuth.contains("NTLM") || (wwwAuth.contains("Negotiate"))) ) {
newRealm = ntlmChallenge(wwwAuth, request, proxyServer, headers, realm, future);
// SPNEGO KERBEROS
} else if (wwwAuth.contains("Negotiate")) {
newRealm = kerberosChallenge(wwwAuth, request, proxyServer, headers, realm, future );
if (newRealm == null) return;
} else {
Realm.RealmBuilder realmBuilder;
if (realm != null) {
realmBuilder = new Realm.RealmBuilder().clone(realm).setScheme(realm.getAuthScheme())
;
} else {
realmBuilder = new Realm.RealmBuilder();
}
newRealm = realmBuilder
.setUri(URI.create(request.getUrl()).getPath())
.setMethodName(request.getMethod())
.setUsePreemptiveAuth(true)
.parseWWWAuthenticateHeader(wwwAuth.get(0))
.build();
}
final Realm nr = newRealm;
log.debug("Sending authentication to {}", request.getUrl());
AsyncCallable ac = new AsyncCallable(future) {
public Object call() throws Exception {
drainChannel(ctx, future, future.getKeepAlive(), future.getURI());