use of org.asynchttpclient.Realm in project async-http-client by AsyncHttpClient.
the class NettyRequestSender method sendRequestWithNewChannel.
private <//
T> //
ListenableFuture<T> sendRequestWithNewChannel(//
Request request, //
ProxyServer proxy, //
NettyResponseFuture<T> future, //
AsyncHandler<T> asyncHandler, boolean performingNextRequest) {
// some headers are only set when performing the first request
HttpHeaders headers = future.getNettyRequest().getHttpRequest().headers();
Realm realm = future.getRealm();
Realm proxyRealm = future.getProxyRealm();
requestFactory.addAuthorizationHeader(headers, perConnectionAuthorizationHeader(request, proxy, realm));
requestFactory.setProxyAuthorizationHeader(headers, perConnectionProxyAuthorizationHeader(request, proxyRealm));
future.setInAuth(realm != null && realm.isUsePreemptiveAuth() && realm.getScheme() != AuthScheme.NTLM);
future.setInProxyAuth(proxyRealm != null && proxyRealm.isUsePreemptiveAuth() && proxyRealm.getScheme() != AuthScheme.NTLM);
// Do not throw an exception when we need an extra connection for a redirect
// FIXME why? This violate the max connection per host handling, right?
Bootstrap bootstrap = channelManager.getBootstrap(request.getUri(), proxy);
Object partitionKey = future.getPartitionKey();
// we disable channelPreemption when performing next requests
final boolean acquireChannelLock = !performingNextRequest;
try {
// redirect.
if (acquireChannelLock) {
// if there's an exception here, channel wasn't preempted and resolve won't happen
channelManager.acquireChannelLock(partitionKey);
}
} catch (Throwable t) {
abort(null, future, getCause(t));
// exit and don't try to resolve address
return future;
}
scheduleRequestTimeout(future);
//
RequestHostnameResolver.INSTANCE.resolve(request, proxy, asyncHandler).addListener(new SimpleFutureListener<List<InetSocketAddress>>() {
@Override
protected void onSuccess(List<InetSocketAddress> addresses) {
NettyConnectListener<T> connectListener = new NettyConnectListener<>(future, NettyRequestSender.this, channelManager, acquireChannelLock, partitionKey);
NettyChannelConnector connector = new NettyChannelConnector(request.getLocalAddress(), addresses, asyncHandler, clientState, config);
if (!future.isDone()) {
connector.connect(bootstrap, connectListener);
} else if (acquireChannelLock) {
channelManager.releaseChannelLock(partitionKey);
}
}
@Override
protected void onFailure(Throwable cause) {
if (acquireChannelLock) {
channelManager.releaseChannelLock(partitionKey);
}
abort(null, future, getCause(cause));
}
});
return future;
}
use of org.asynchttpclient.Realm in project async-http-client by AsyncHttpClient.
the class Interceptors method exitAfterIntercept.
public //
boolean exitAfterIntercept(//
Channel channel, //
NettyResponseFuture<?> future, //
AsyncHandler<?> handler, //
HttpResponse response, //
HttpResponseStatus status, HttpResponseHeaders responseHeaders) throws Exception {
HttpRequest httpRequest = future.getNettyRequest().getHttpRequest();
ProxyServer proxyServer = future.getProxyServer();
int statusCode = response.status().code();
Request request = future.getCurrentRequest();
Realm realm = request.getRealm() != null ? request.getRealm() : config.getRealm();
if (hasResponseFilters && responseFiltersInterceptor.exitAfterProcessingFilters(channel, future, handler, status, responseHeaders)) {
return true;
}
if (statusCode == UNAUTHORIZED_401) {
return unauthorized401Interceptor.exitAfterHandling401(channel, future, response, request, statusCode, realm, proxyServer, httpRequest);
} else if (statusCode == PROXY_AUTHENTICATION_REQUIRED_407) {
return proxyUnauthorized407Interceptor.exitAfterHandling407(channel, future, response, request, statusCode, proxyServer, httpRequest);
} else if (statusCode == CONTINUE_100) {
return continue100Interceptor.exitAfterHandling100(channel, future, statusCode);
} else if (Redirect30xInterceptor.REDIRECT_STATUSES.contains(statusCode)) {
return redirect30xInterceptor.exitAfterHandlingRedirect(channel, future, response, request, statusCode, realm);
} else if (httpRequest.method() == HttpMethod.CONNECT && statusCode == OK_200) {
return connectSuccessInterceptor.exitAfterHandlingConnect(channel, future, request, proxyServer, statusCode, httpRequest);
}
return false;
}
use of org.asynchttpclient.Realm in project async-http-client by AsyncHttpClient.
the class ProxyUnauthorized407Interceptor method exitAfterHandling407.
public //
boolean exitAfterHandling407(//
Channel channel, //
NettyResponseFuture<?> future, //
HttpResponse response, //
Request request, //
int statusCode, //
ProxyServer proxyServer, HttpRequest httpRequest) {
if (future.isAndSetInProxyAuth(true)) {
LOGGER.info("Can't handle 407 as auth was already performed");
return false;
}
Realm proxyRealm = future.getProxyRealm();
if (proxyRealm == null) {
LOGGER.debug("Can't handle 407 as there's no proxyRealm");
return false;
}
List<String> proxyAuthHeaders = response.headers().getAll(PROXY_AUTHENTICATE);
if (proxyAuthHeaders.isEmpty()) {
LOGGER.info("Can't handle 407 as response doesn't contain Proxy-Authenticate headers");
return false;
}
// FIXME what's this???
future.setChannelState(ChannelState.NEW);
HttpHeaders requestHeaders = new DefaultHttpHeaders(false).add(request.getHeaders());
switch(proxyRealm.getScheme()) {
case BASIC:
if (getHeaderWithPrefix(proxyAuthHeaders, "Basic") == null) {
LOGGER.info("Can't handle 407 with Basic realm as Proxy-Authenticate headers don't match");
return false;
}
if (proxyRealm.isUsePreemptiveAuth()) {
// FIXME do we need this, as future.getAndSetAuth
// was tested above?
// auth was already performed, most likely auth
// failed
LOGGER.info("Can't handle 407 with Basic realm as auth was preemptive and already performed");
return false;
}
// FIXME do we want to update the realm, or directly
// set the header?
Realm newBasicRealm = //
realm(proxyRealm).setUsePreemptiveAuth(//
true).build();
future.setProxyRealm(newBasicRealm);
break;
case DIGEST:
String digestHeader = getHeaderWithPrefix(proxyAuthHeaders, "Digest");
if (digestHeader == null) {
LOGGER.info("Can't handle 407 with Digest realm as Proxy-Authenticate headers don't match");
return false;
}
Realm newDigestRealm = //
realm(proxyRealm).setUri(//
request.getUri()).setMethodName(//
request.getMethod()).setUsePreemptiveAuth(//
true).parseProxyAuthenticateHeader(//
digestHeader).build();
future.setProxyRealm(newDigestRealm);
break;
case NTLM:
String ntlmHeader = getHeaderWithPrefix(proxyAuthHeaders, "NTLM");
if (ntlmHeader == null) {
LOGGER.info("Can't handle 407 with NTLM realm as Proxy-Authenticate headers don't match");
return false;
}
ntlmProxyChallenge(ntlmHeader, request, requestHeaders, proxyRealm, future);
Realm newNtlmRealm = //
realm(proxyRealm).setUsePreemptiveAuth(//
true).build();
future.setProxyRealm(newNtlmRealm);
break;
case KERBEROS:
case SPNEGO:
if (getHeaderWithPrefix(proxyAuthHeaders, NEGOTIATE) == null) {
LOGGER.info("Can't handle 407 with Kerberos or Spnego realm as Proxy-Authenticate headers don't match");
return false;
}
try {
kerberosProxyChallenge(channel, proxyAuthHeaders, request, proxyServer, proxyRealm, requestHeaders, future);
} catch (SpnegoEngineException e) {
// FIXME
String ntlmHeader2 = getHeaderWithPrefix(proxyAuthHeaders, "NTLM");
if (ntlmHeader2 != null) {
LOGGER.warn("Kerberos/Spnego proxy auth failed, proceeding with NTLM");
ntlmProxyChallenge(ntlmHeader2, request, requestHeaders, proxyRealm, future);
Realm newNtlmRealm2 = //
realm(proxyRealm).setScheme(//
AuthScheme.NTLM).setUsePreemptiveAuth(//
true).build();
future.setProxyRealm(newNtlmRealm2);
} else {
requestSender.abort(channel, future, e);
return false;
}
}
break;
default:
throw new IllegalStateException("Invalid Authentication scheme " + proxyRealm.getScheme());
}
RequestBuilder nextRequestBuilder = new RequestBuilder(future.getCurrentRequest()).setHeaders(requestHeaders);
if (future.getCurrentRequest().getUri().isSecured()) {
nextRequestBuilder.setMethod(CONNECT);
}
final Request nextRequest = nextRequestBuilder.build();
LOGGER.debug("Sending proxy authentication to {}", request.getUri());
if (//
future.isKeepAlive() && //
!HttpUtil.isTransferEncodingChunked(httpRequest) && !HttpUtil.isTransferEncodingChunked(response)) {
future.setConnectAllowed(true);
future.setReuseChannel(true);
requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
} else {
channelManager.closeChannel(channel);
requestSender.sendNextRequest(nextRequest, future);
}
return true;
}
use of org.asynchttpclient.Realm in project async-http-client by AsyncHttpClient.
the class Unauthorized401Interceptor method exitAfterHandling401.
public //
boolean exitAfterHandling401(//
final Channel channel, //
final NettyResponseFuture<?> future, //
HttpResponse response, //
final Request request, //
int statusCode, //
Realm realm, //
ProxyServer proxyServer, HttpRequest httpRequest) {
if (realm == null) {
LOGGER.debug("Can't handle 401 as there's no realm");
return false;
}
if (future.isAndSetInAuth(true)) {
LOGGER.info("Can't handle 401 as auth was already performed");
return false;
}
List<String> wwwAuthHeaders = response.headers().getAll(WWW_AUTHENTICATE);
if (wwwAuthHeaders.isEmpty()) {
LOGGER.info("Can't handle 401 as response doesn't contain WWW-Authenticate headers");
return false;
}
// FIXME what's this???
future.setChannelState(ChannelState.NEW);
HttpHeaders requestHeaders = new DefaultHttpHeaders(false).add(request.getHeaders());
switch(realm.getScheme()) {
case BASIC:
if (getHeaderWithPrefix(wwwAuthHeaders, "Basic") == null) {
LOGGER.info("Can't handle 401 with Basic realm as WWW-Authenticate headers don't match");
return false;
}
if (realm.isUsePreemptiveAuth()) {
// FIXME do we need this, as future.getAndSetAuth
// was tested above?
// auth was already performed, most likely auth
// failed
LOGGER.info("Can't handle 401 with Basic realm as auth was preemptive and already performed");
return false;
}
// FIXME do we want to update the realm, or directly
// set the header?
Realm newBasicRealm = //
realm(realm).setUsePreemptiveAuth(//
true).build();
future.setRealm(newBasicRealm);
break;
case DIGEST:
String digestHeader = getHeaderWithPrefix(wwwAuthHeaders, "Digest");
if (digestHeader == null) {
LOGGER.info("Can't handle 401 with Digest realm as WWW-Authenticate headers don't match");
return false;
}
Realm newDigestRealm = //
realm(realm).setUri(//
request.getUri()).setMethodName(//
request.getMethod()).setUsePreemptiveAuth(//
true).parseWWWAuthenticateHeader(//
digestHeader).build();
future.setRealm(newDigestRealm);
break;
case NTLM:
String ntlmHeader = getHeaderWithPrefix(wwwAuthHeaders, "NTLM");
if (ntlmHeader == null) {
LOGGER.info("Can't handle 401 with NTLM realm as WWW-Authenticate headers don't match");
return false;
}
ntlmChallenge(ntlmHeader, request, requestHeaders, realm, future);
Realm newNtlmRealm = //
realm(realm).setUsePreemptiveAuth(//
true).build();
future.setRealm(newNtlmRealm);
break;
case KERBEROS:
case SPNEGO:
if (getHeaderWithPrefix(wwwAuthHeaders, NEGOTIATE) == null) {
LOGGER.info("Can't handle 401 with Kerberos or Spnego realm as WWW-Authenticate headers don't match");
return false;
}
try {
kerberosChallenge(channel, wwwAuthHeaders, request, requestHeaders, realm, future);
} catch (SpnegoEngineException e) {
// FIXME
String ntlmHeader2 = getHeaderWithPrefix(wwwAuthHeaders, "NTLM");
if (ntlmHeader2 != null) {
LOGGER.warn("Kerberos/Spnego auth failed, proceeding with NTLM");
ntlmChallenge(ntlmHeader2, request, requestHeaders, realm, future);
Realm newNtlmRealm2 = //
realm(realm).setScheme(//
AuthScheme.NTLM).setUsePreemptiveAuth(//
true).build();
future.setRealm(newNtlmRealm2);
} else {
requestSender.abort(channel, future, e);
return false;
}
}
break;
default:
throw new IllegalStateException("Invalid Authentication scheme " + realm.getScheme());
}
final Request nextRequest = new RequestBuilder(future.getCurrentRequest()).setHeaders(requestHeaders).build();
LOGGER.debug("Sending authentication to {}", request.getUri());
if (//
future.isKeepAlive() && //
!HttpUtil.isTransferEncodingChunked(httpRequest) && !HttpUtil.isTransferEncodingChunked(response)) {
future.setReuseChannel(true);
requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
} else {
channelManager.closeChannel(channel);
requestSender.sendNextRequest(nextRequest, future);
}
return true;
}
use of org.asynchttpclient.Realm in project camel by apache.
the class AhcComponent method createEndpoint.
@Override
protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
String addressUri = createAddressUri(uri, remaining);
// Do not set the HTTP URI because we still have all of the Camel internal
// parameters in the URI at this point.
AhcEndpoint endpoint = createAhcEndpoint(uri, this, null);
setEndpointHeaderFilterStrategy(endpoint);
endpoint.setClient(getClient());
endpoint.setClientConfig(getClientConfig());
endpoint.setBinding(getBinding());
endpoint.setSslContextParameters(getSslContextParameters());
setProperties(endpoint, parameters);
if (IntrospectionSupport.hasProperties(parameters, CLIENT_CONFIG_PREFIX)) {
DefaultAsyncHttpClientConfig.Builder builder = endpoint.getClientConfig() == null ? new DefaultAsyncHttpClientConfig.Builder() : AhcComponent.cloneConfig(endpoint.getClientConfig());
if (endpoint.getClient() != null) {
LOG.warn("The user explicitly set an AsyncHttpClient instance on the component or " + "endpoint, but this endpoint URI contains client configuration parameters. " + "Are you sure that this is what was intended? The AsyncHttpClient will be used" + " and the URI parameters will be ignored.");
} else if (endpoint.getClientConfig() != null) {
LOG.warn("The user explicitly set an AsyncHttpClientConfig instance on the component or " + "endpoint, but this endpoint URI contains client configuration parameters. " + "Are you sure that this is what was intended? The URI parameters will be applied" + " to a clone of the supplied AsyncHttpClientConfig in order to prevent unintended modification" + " of the explicitly configured AsyncHttpClientConfig. That is, the URI parameters override the" + " settings on the explicitly configured AsyncHttpClientConfig for this endpoint.");
}
// special for realm builder
Builder realmBuilder = null;
if (IntrospectionSupport.hasProperties(parameters, CLIENT_REALM_CONFIG_PREFIX)) {
// set and validate additional parameters on client config
Map<String, Object> realmParams = IntrospectionSupport.extractProperties(parameters, CLIENT_REALM_CONFIG_PREFIX);
// copy the parameters for the endpoint to have
endpoint.setClientConfigRealmOptions(new LinkedHashMap<>(realmParams));
Object principal = realmParams.remove("principal");
Object password = realmParams.remove("password");
if (ObjectHelper.isEmpty(principal)) {
throw new IllegalArgumentException(CLIENT_REALM_CONFIG_PREFIX + ".principal must be configured");
}
if (password == null) {
password = "";
}
realmBuilder = new Realm.Builder(principal.toString(), password.toString());
setProperties(realmBuilder, realmParams);
validateParameters(uri, realmParams, null);
}
// set and validate additional parameters on client config
Map<String, Object> clientParams = IntrospectionSupport.extractProperties(parameters, CLIENT_CONFIG_PREFIX);
// copy the parameters for the endpoint to have
endpoint.setClientConfigOptions(new LinkedHashMap<>(clientParams));
setProperties(builder, clientParams);
validateParameters(uri, clientParams, null);
if (realmBuilder != null) {
builder.setRealm(realmBuilder.build());
}
endpoint.setClientConfig(builder.build());
}
// restructure uri to be based on the parameters left as we dont want to include the Camel internal options
addressUri = UnsafeUriCharactersEncoder.encodeHttpURI(addressUri);
URI httpUri = URISupport.createRemainingURI(new URI(addressUri), parameters);
endpoint.setHttpUri(httpUri);
return endpoint;
}
Aggregations