use of org.asynchttpclient.RequestBuilder in project async-http-client by AsyncHttpClient.
the class AsyncHttpClientCallFactoryTest method newCallShouldProduceExpectedResult.
@Test
void newCallShouldProduceExpectedResult() {
// given
val request = new Request.Builder().url("http://www.google.com/").build();
val httpClient = mock(AsyncHttpClient.class);
Consumer<Request> onRequestStart = createConsumer(new AtomicInteger());
Consumer<Throwable> onRequestFailure = createConsumer(new AtomicInteger());
Consumer<Response> onRequestSuccess = createConsumer(new AtomicInteger());
Consumer<RequestBuilder> requestCustomizer = createConsumer(new AtomicInteger());
// first call customizer
val customizer1Called = new AtomicInteger();
Consumer<AsyncHttpClientCall.AsyncHttpClientCallBuilder> callBuilderConsumer1 = builder -> {
builder.onRequestStart(onRequestStart).onRequestFailure(onRequestFailure).onRequestSuccess(onRequestSuccess);
customizer1Called.incrementAndGet();
};
// first call customizer
val customizer2Called = new AtomicInteger();
Consumer<AsyncHttpClientCall.AsyncHttpClientCallBuilder> callBuilderConsumer2 = builder -> {
builder.requestCustomizer(requestCustomizer);
customizer2Called.incrementAndGet();
};
// when: create call factory
val factory = AsyncHttpClientCallFactory.builder().httpClient(httpClient).callCustomizer(callBuilderConsumer1).callCustomizer(callBuilderConsumer2).build();
// then
assertTrue(factory.getHttpClient() == httpClient);
assertTrue(factory.getCallCustomizers().size() == 2);
assertTrue(customizer1Called.get() == 0);
assertTrue(customizer2Called.get() == 0);
// when
val call = (AsyncHttpClientCall) factory.newCall(request);
// then
assertNotNull(call);
assertTrue(customizer1Called.get() == 1);
assertTrue(customizer2Called.get() == 1);
assertTrue(call.request() == request);
assertTrue(call.getHttpClient() == httpClient);
assertEquals(call.getOnRequestStart().get(0), onRequestStart);
assertEquals(call.getOnRequestFailure().get(0), onRequestFailure);
assertEquals(call.getOnRequestSuccess().get(0), onRequestSuccess);
assertEquals(call.getRequestCustomizers().get(0), requestCustomizer);
}
use of org.asynchttpclient.RequestBuilder in project async-http-client by AsyncHttpClient.
the class ConnectSuccessInterceptor method exitAfterHandlingConnect.
public boolean exitAfterHandlingConnect(Channel channel, NettyResponseFuture<?> future, Request request, ProxyServer proxyServer) {
if (future.isKeepAlive())
future.attachChannel(channel, true);
Uri requestUri = request.getUri();
LOGGER.debug("Connecting to proxy {} for scheme {}", proxyServer, requestUri.getScheme());
channelManager.updatePipelineForHttpTunneling(channel.pipeline(), requestUri);
future.setReuseChannel(true);
future.setConnectAllowed(false);
requestSender.drainChannelAndExecuteNextRequest(channel, future, new RequestBuilder(future.getTargetRequest()).build());
return true;
}
use of org.asynchttpclient.RequestBuilder in project async-http-client by AsyncHttpClient.
the class Redirect30xInterceptor method exitAfterHandlingRedirect.
public boolean exitAfterHandlingRedirect(Channel channel, NettyResponseFuture<?> future, HttpResponse response, Request request, int statusCode, Realm realm) throws Exception {
if (followRedirect(config, request)) {
if (future.incrementAndGetCurrentRedirectCount() >= config.getMaxRedirects()) {
throw maxRedirectException;
} else {
// We must allow auth handling again.
future.setInAuth(false);
future.setInProxyAuth(false);
String originalMethod = request.getMethod();
boolean switchToGet = !originalMethod.equals(GET) && (statusCode == MOVED_PERMANENTLY_301 || statusCode == SEE_OTHER_303 || (statusCode == FOUND_302 && !config.isStrict302Handling()));
boolean keepBody = statusCode == TEMPORARY_REDIRECT_307 || statusCode == PERMANENT_REDIRECT_308 || (statusCode == FOUND_302 && config.isStrict302Handling());
final RequestBuilder requestBuilder = new RequestBuilder(switchToGet ? GET : originalMethod).setChannelPoolPartitioning(request.getChannelPoolPartitioning()).setFollowRedirect(true).setLocalAddress(request.getLocalAddress()).setNameResolver(request.getNameResolver()).setProxyServer(request.getProxyServer()).setRealm(request.getRealm()).setRequestTimeout(request.getRequestTimeout());
if (keepBody) {
requestBuilder.setCharset(request.getCharset());
if (isNonEmpty(request.getFormParams()))
requestBuilder.setFormParams(request.getFormParams());
else if (request.getStringData() != null)
requestBuilder.setBody(request.getStringData());
else if (request.getByteData() != null)
requestBuilder.setBody(request.getByteData());
else if (request.getByteBufferData() != null)
requestBuilder.setBody(request.getByteBufferData());
else if (request.getBodyGenerator() != null)
requestBuilder.setBody(request.getBodyGenerator());
}
requestBuilder.setHeaders(propagatedHeaders(request, realm, keepBody));
// in case of a redirect from HTTP to HTTPS, future
// attributes might change
final boolean initialConnectionKeepAlive = future.isKeepAlive();
final Object initialPartitionKey = future.getPartitionKey();
HttpHeaders responseHeaders = response.headers();
String location = responseHeaders.get(LOCATION);
Uri newUri = Uri.create(future.getUri(), location);
LOGGER.debug("Redirecting to {}", newUri);
CookieStore cookieStore = config.getCookieStore();
if (cookieStore != null) {
// Update request's cookies assuming that cookie store is already updated by Interceptors
List<Cookie> cookies = cookieStore.get(newUri);
if (!cookies.isEmpty())
for (Cookie cookie : cookies) requestBuilder.addOrReplaceCookie(cookie);
}
boolean sameBase = request.getUri().isSameBase(newUri);
if (sameBase) {
// we can only assume the virtual host is still valid if the baseUrl is the same
requestBuilder.setVirtualHost(request.getVirtualHost());
}
final Request nextRequest = requestBuilder.setUri(newUri).build();
future.setTargetRequest(nextRequest);
LOGGER.debug("Sending redirect to {}", newUri);
if (future.isKeepAlive() && !HttpUtil.isTransferEncodingChunked(response)) {
if (sameBase) {
future.setReuseChannel(true);
// we can't directly send the next request because we still have to received LastContent
requestSender.drainChannelAndExecuteNextRequest(channel, future, nextRequest);
} else {
channelManager.drainChannelAndOffer(channel, future, initialConnectionKeepAlive, initialPartitionKey);
requestSender.sendNextRequest(nextRequest, future);
}
} else {
// redirect + chunking = WAT
channelManager.closeChannel(channel);
requestSender.sendNextRequest(nextRequest, future);
}
return true;
}
}
return false;
}
use of org.asynchttpclient.RequestBuilder 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, Realm realm, 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, 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(request, requestHeaders);
} catch (SpnegoEngineException e) {
// FIXME
String ntlmHeader2 = getHeaderWithPrefix(wwwAuthHeaders, "NTLM");
if (ntlmHeader2 != null) {
LOGGER.warn("Kerberos/Spnego auth failed, proceeding with NTLM");
ntlmChallenge(ntlmHeader2, 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;
}
Aggregations