Java 1.8 upgrade
This commit is contained in:
parent
b704baf466
commit
bb04d078ad
|
@ -124,7 +124,7 @@ public class HttpCacheEntry implements MessageHeaders, Serializable {
|
||||||
*/
|
*/
|
||||||
public HttpCacheEntry(final Date requestDate, final Date responseDate, final int status,
|
public HttpCacheEntry(final Date requestDate, final Date responseDate, final int status,
|
||||||
final Header[] responseHeaders, final Resource resource) {
|
final Header[] responseHeaders, final Resource resource) {
|
||||||
this(requestDate, responseDate, status, responseHeaders, resource, new HashMap<String,String>());
|
this(requestDate, responseDate, status, responseHeaders, resource, new HashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -187,7 +187,7 @@ public abstract class AbstractSerializingAsyncCacheStorage<T, CAS> implements Ht
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void completed(final Boolean result) {
|
public void completed(final Boolean result) {
|
||||||
if (result) {
|
if (result.booleanValue()) {
|
||||||
callback.completed(result);
|
callback.completed(result);
|
||||||
} else {
|
} else {
|
||||||
if (!complexCancellable.isCancelled()) {
|
if (!complexCancellable.isCancelled()) {
|
||||||
|
|
|
@ -57,7 +57,6 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||||
import org.apache.hc.core5.concurrent.CancellableDependency;
|
import org.apache.hc.core5.concurrent.CancellableDependency;
|
||||||
import org.apache.hc.core5.concurrent.ComplexFuture;
|
import org.apache.hc.core5.concurrent.ComplexFuture;
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||||
import org.apache.hc.core5.function.Factory;
|
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.EntityDetails;
|
import org.apache.hc.core5.http.EntityDetails;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
|
@ -102,14 +101,8 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
|
||||||
super(config);
|
super(config);
|
||||||
this.responseCache = Args.notNull(cache, "Response cache");
|
this.responseCache = Args.notNull(cache, "Response cache");
|
||||||
this.cacheRevalidator = cacheRevalidator;
|
this.cacheRevalidator = cacheRevalidator;
|
||||||
this.conditionalRequestBuilder = new ConditionalRequestBuilder<>(new Factory<HttpRequest, HttpRequest>() {
|
this.conditionalRequestBuilder = new ConditionalRequestBuilder<>(request ->
|
||||||
|
BasicRequestBuilder.copy(request).build());
|
||||||
@Override
|
|
||||||
public HttpRequest create(final HttpRequest request) {
|
|
||||||
return BasicRequestBuilder.copy(request).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncCachingExec(
|
AsyncCachingExec(
|
||||||
|
@ -675,14 +668,7 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
|
||||||
cacheRevalidator.revalidateCacheEntry(
|
cacheRevalidator.revalidateCacheEntry(
|
||||||
responseCache.generateKey(target, request, entry),
|
responseCache.generateKey(target, request, entry),
|
||||||
asyncExecCallback,
|
asyncExecCallback,
|
||||||
new DefaultAsyncCacheRevalidator.RevalidationCall() {
|
asyncExecCallback1 -> revalidateCacheEntry(target, request, entityProducer, fork, chain, asyncExecCallback1, entry));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final AsyncExecCallback asyncExecCallback) {
|
|
||||||
revalidateCacheEntry(target, request, entityProducer, fork, chain, asyncExecCallback, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
triggerResponse(cacheResponse, scope, asyncExecCallback);
|
triggerResponse(cacheResponse, scope, asyncExecCallback);
|
||||||
} catch (final ResourceIOException ex) {
|
} catch (final ResourceIOException ex) {
|
||||||
asyncExecCallback.failed(ex);
|
asyncExecCallback.failed(ex);
|
||||||
|
@ -771,26 +757,12 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
|
||||||
recordCacheUpdate(scope.clientContext);
|
recordCacheUpdate(scope.clientContext);
|
||||||
}
|
}
|
||||||
if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
|
if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
|
||||||
return new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
|
return new AsyncExecCallbackWrapper(asyncExecCallback, () -> triggerUpdatedCacheEntryResponse(backendResponse, responseDate));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
triggerUpdatedCacheEntryResponse(backendResponse, responseDate);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
if (staleIfErrorAppliesTo(statusCode)
|
if (staleIfErrorAppliesTo(statusCode)
|
||||||
&& !staleResponseNotAllowed(request, cacheEntry, getCurrentDate())
|
&& !staleResponseNotAllowed(request, cacheEntry, getCurrentDate())
|
||||||
&& validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) {
|
&& validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) {
|
||||||
return new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
|
return new AsyncExecCallbackWrapper(asyncExecCallback, this::triggerResponseStaleCacheEntry);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
triggerResponseStaleCacheEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return new BackendResponseHandler(target, conditionalRequest, requestDate, responseDate, scope, asyncExecCallback);
|
return new BackendResponseHandler(target, conditionalRequest, requestDate, responseDate, scope, asyncExecCallback);
|
||||||
}
|
}
|
||||||
|
@ -809,57 +781,49 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
|
||||||
final HttpRequest unconditional = conditionalRequestBuilder.buildUnconditionalRequest(
|
final HttpRequest unconditional = conditionalRequestBuilder.buildUnconditionalRequest(
|
||||||
BasicRequestBuilder.copy(scope.originalRequest).build());
|
BasicRequestBuilder.copy(scope.originalRequest).build());
|
||||||
|
|
||||||
callback1 = new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
|
callback1 = new AsyncExecCallbackWrapper(asyncExecCallback, () -> chainProceed(unconditional, entityProducer, scope, chain, new AsyncExecCallback() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public AsyncDataConsumer handleResponse(
|
||||||
chainProceed(unconditional, entityProducer, scope, chain, new AsyncExecCallback() {
|
final HttpResponse backendResponse2,
|
||||||
|
final EntityDetails entityDetails1) throws HttpException, IOException {
|
||||||
@Override
|
final Date responseDate2 = getCurrentDate();
|
||||||
public AsyncDataConsumer handleResponse(
|
final AsyncExecCallback callback2 = evaluateResponse(backendResponse2, responseDate2);
|
||||||
final HttpResponse backendResponse2,
|
callbackRef.set(callback2);
|
||||||
final EntityDetails entityDetails) throws HttpException, IOException {
|
return callback2.handleResponse(backendResponse2, entityDetails1);
|
||||||
final Date responseDate2 = getCurrentDate();
|
|
||||||
final AsyncExecCallback callback2 = evaluateResponse(backendResponse2, responseDate2);
|
|
||||||
callbackRef.set(callback2);
|
|
||||||
return callback2.handleResponse(backendResponse2, entityDetails);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleInformationResponse(final HttpResponse response) throws HttpException, IOException {
|
|
||||||
final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
|
|
||||||
if (callback2 != null) {
|
|
||||||
callback2.handleInformationResponse(response);
|
|
||||||
} else {
|
|
||||||
asyncExecCallback.handleInformationResponse(response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void completed() {
|
|
||||||
final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
|
|
||||||
if (callback2 != null) {
|
|
||||||
callback2.completed();
|
|
||||||
} else {
|
|
||||||
asyncExecCallback.completed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void failed(final Exception cause) {
|
|
||||||
final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
|
|
||||||
if (callback2 != null) {
|
|
||||||
callback2.failed(cause);
|
|
||||||
} else {
|
|
||||||
asyncExecCallback.failed(cause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
@Override
|
||||||
|
public void handleInformationResponse(final HttpResponse response) throws HttpException, IOException {
|
||||||
|
final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
|
||||||
|
if (callback2 != null) {
|
||||||
|
callback2.handleInformationResponse(response);
|
||||||
|
} else {
|
||||||
|
asyncExecCallback.handleInformationResponse(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void completed() {
|
||||||
|
final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
|
||||||
|
if (callback2 != null) {
|
||||||
|
callback2.completed();
|
||||||
|
} else {
|
||||||
|
asyncExecCallback.completed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(final Exception cause) {
|
||||||
|
final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
|
||||||
|
if (callback2 != null) {
|
||||||
|
callback2.failed(cause);
|
||||||
|
} else {
|
||||||
|
asyncExecCallback.failed(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}));
|
||||||
} else {
|
} else {
|
||||||
callback1 = evaluateResponse(backendResponse1, responseDate1);
|
callback1 = evaluateResponse(backendResponse1, responseDate1);
|
||||||
}
|
}
|
||||||
|
@ -1036,49 +1000,21 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
|
||||||
final Header resultEtagHeader = backendResponse.getFirstHeader(HeaderConstants.ETAG);
|
final Header resultEtagHeader = backendResponse.getFirstHeader(HeaderConstants.ETAG);
|
||||||
if (resultEtagHeader == null) {
|
if (resultEtagHeader == null) {
|
||||||
LOG.warn("304 response did not contain ETag");
|
LOG.warn("304 response did not contain ETag");
|
||||||
callback = new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
|
callback = new AsyncExecCallbackWrapper(asyncExecCallback, () -> callBackend(target, request, entityProducer, scope, chain, asyncExecCallback));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
final String resultEtag = resultEtagHeader.getValue();
|
final String resultEtag = resultEtagHeader.getValue();
|
||||||
final Variant matchingVariant = variants.get(resultEtag);
|
final Variant matchingVariant = variants.get(resultEtag);
|
||||||
if (matchingVariant == null) {
|
if (matchingVariant == null) {
|
||||||
LOG.debug("304 response did not contain ETag matching one sent in If-None-Match");
|
LOG.debug("304 response did not contain ETag matching one sent in If-None-Match");
|
||||||
callback = new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
|
callback = new AsyncExecCallbackWrapper(asyncExecCallback, () -> callBackend(target, request, entityProducer, scope, chain, asyncExecCallback));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
if (revalidationResponseIsTooOld(backendResponse, matchingVariant.getEntry())) {
|
if (revalidationResponseIsTooOld(backendResponse, matchingVariant.getEntry())) {
|
||||||
final HttpRequest unconditional = conditionalRequestBuilder.buildUnconditionalRequest(
|
final HttpRequest unconditional = conditionalRequestBuilder.buildUnconditionalRequest(
|
||||||
BasicRequestBuilder.copy(request).build());
|
BasicRequestBuilder.copy(request).build());
|
||||||
scope.clientContext.setAttribute(HttpCoreContext.HTTP_REQUEST, unconditional);
|
scope.clientContext.setAttribute(HttpCoreContext.HTTP_REQUEST, unconditional);
|
||||||
callback = new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
|
callback = new AsyncExecCallbackWrapper(asyncExecCallback, () -> callBackend(target, request, entityProducer, scope, chain, asyncExecCallback));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
callback = new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
|
callback = new AsyncExecCallbackWrapper(asyncExecCallback, () -> updateVariantCacheEntry(backendResponse, responseDate, matchingVariant));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
updateVariantCacheEntry(backendResponse, responseDate, matchingVariant);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@ import java.util.Set;
|
||||||
import org.apache.hc.client5.http.cache.HeaderConstants;
|
import org.apache.hc.client5.http.cache.HeaderConstants;
|
||||||
import org.apache.hc.client5.http.cache.HttpAsyncCacheInvalidator;
|
import org.apache.hc.client5.http.cache.HttpAsyncCacheInvalidator;
|
||||||
import org.apache.hc.client5.http.cache.HttpAsyncCacheStorage;
|
import org.apache.hc.client5.http.cache.HttpAsyncCacheStorage;
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
|
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
|
import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
|
||||||
import org.apache.hc.client5.http.cache.ResourceFactory;
|
import org.apache.hc.client5.http.cache.ResourceFactory;
|
||||||
|
@ -211,14 +210,7 @@ class BasicHttpAsyncCache implements HttpAsyncCache {
|
||||||
@Override
|
@Override
|
||||||
public void completed(final Boolean result) {
|
public void completed(final Boolean result) {
|
||||||
storage.updateEntry(cacheKey,
|
storage.updateEntry(cacheKey,
|
||||||
new HttpCacheCASOperation() {
|
existing -> cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey),
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
return cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
new FutureCallback<Boolean>() {
|
new FutureCallback<Boolean>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -280,14 +272,7 @@ class BasicHttpAsyncCache implements HttpAsyncCache {
|
||||||
final String variantKey = cacheKeyGenerator.generateVariantKey(request, entry);
|
final String variantKey = cacheKeyGenerator.generateVariantKey(request, entry);
|
||||||
final String variantCacheKey = variant.getCacheKey();
|
final String variantCacheKey = variant.getCacheKey();
|
||||||
return storage.updateEntry(cacheKey,
|
return storage.updateEntry(cacheKey,
|
||||||
new HttpCacheCASOperation() {
|
existing -> cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(), existing, entry, variantKey, variantCacheKey),
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
return cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(), existing, entry, variantKey, variantCacheKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
new FutureCallback<Boolean>() {
|
new FutureCallback<Boolean>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -31,7 +31,6 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.cache.HeaderConstants;
|
import org.apache.hc.client5.http.cache.HeaderConstants;
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
|
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheInvalidator;
|
import org.apache.hc.client5.http.cache.HttpCacheInvalidator;
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheStorage;
|
import org.apache.hc.client5.http.cache.HttpCacheStorage;
|
||||||
|
@ -163,14 +162,7 @@ class BasicHttpCache implements HttpCache {
|
||||||
final String variantCacheKey = cacheKeyGenerator.generateKey(host, req, entry);
|
final String variantCacheKey = cacheKeyGenerator.generateKey(host, req, entry);
|
||||||
storeEntry(variantCacheKey, entry);
|
storeEntry(variantCacheKey, entry);
|
||||||
try {
|
try {
|
||||||
storage.updateEntry(cacheKey, new HttpCacheCASOperation() {
|
storage.updateEntry(cacheKey, existing -> cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey));
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
return cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
} catch (final HttpCacheUpdateException ex) {
|
} catch (final HttpCacheUpdateException ex) {
|
||||||
if (LOG.isWarnEnabled()) {
|
if (LOG.isWarnEnabled()) {
|
||||||
LOG.warn("Cannot update cache entry with key {}", cacheKey);
|
LOG.warn("Cannot update cache entry with key {}", cacheKey);
|
||||||
|
@ -194,14 +186,7 @@ class BasicHttpCache implements HttpCache {
|
||||||
final String variantCacheKey = variant.getCacheKey();
|
final String variantCacheKey = variant.getCacheKey();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
storage.updateEntry(cacheKey, new HttpCacheCASOperation() {
|
storage.updateEntry(cacheKey, existing -> cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(), existing, entry, variantKey, variantCacheKey));
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
return cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(), existing, entry, variantKey, variantCacheKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
} catch (final HttpCacheUpdateException ex) {
|
} catch (final HttpCacheUpdateException ex) {
|
||||||
if (LOG.isWarnEnabled()) {
|
if (LOG.isWarnEnabled()) {
|
||||||
LOG.warn("Cannot update cache entry with key {}", cacheKey);
|
LOG.warn("Cannot update cache entry with key {}", cacheKey);
|
||||||
|
|
|
@ -66,7 +66,7 @@ class BasicIdGenerator {
|
||||||
buffer.append(System.currentTimeMillis());
|
buffer.append(System.currentTimeMillis());
|
||||||
buffer.append('.');
|
buffer.append('.');
|
||||||
final Formatter formatter = new Formatter(buffer, Locale.ROOT);
|
final Formatter formatter = new Formatter(buffer, Locale.ROOT);
|
||||||
formatter.format("%1$016x-%2$08x", Long.valueOf(this.count), Integer.valueOf(rndnum));
|
formatter.format("%1$016x-%2$08x", this.count, rndnum);
|
||||||
formatter.close();
|
formatter.close();
|
||||||
buffer.append('.');
|
buffer.append('.');
|
||||||
buffer.append(this.hostname);
|
buffer.append(this.hostname);
|
||||||
|
|
|
@ -48,7 +48,6 @@ import org.apache.hc.client5.http.impl.ExecSupport;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.schedule.SchedulingStrategy;
|
import org.apache.hc.client5.http.schedule.SchedulingStrategy;
|
||||||
import org.apache.hc.client5.http.utils.DateUtils;
|
import org.apache.hc.client5.http.utils.DateUtils;
|
||||||
import org.apache.hc.core5.function.Factory;
|
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
|
@ -112,14 +111,8 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
|
||||||
super(config);
|
super(config);
|
||||||
this.responseCache = Args.notNull(cache, "Response cache");
|
this.responseCache = Args.notNull(cache, "Response cache");
|
||||||
this.cacheRevalidator = cacheRevalidator;
|
this.cacheRevalidator = cacheRevalidator;
|
||||||
this.conditionalRequestBuilder = new ConditionalRequestBuilder<>(new Factory<ClassicHttpRequest, ClassicHttpRequest>() {
|
this.conditionalRequestBuilder = new ConditionalRequestBuilder<>(classicHttpRequest ->
|
||||||
|
ClassicRequestBuilder.copy(classicHttpRequest).build());
|
||||||
@Override
|
|
||||||
public ClassicHttpRequest create(final ClassicHttpRequest classicHttpRequest) {
|
|
||||||
return ClassicRequestBuilder.copy(classicHttpRequest).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CachingExec(
|
CachingExec(
|
||||||
|
@ -294,14 +287,7 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
|
||||||
final SimpleHttpResponse response = generateCachedResponse(request, context, entry, now);
|
final SimpleHttpResponse response = generateCachedResponse(request, context, entry, now);
|
||||||
cacheRevalidator.revalidateCacheEntry(
|
cacheRevalidator.revalidateCacheEntry(
|
||||||
responseCache.generateKey(target, request, entry),
|
responseCache.generateKey(target, request, entry),
|
||||||
new DefaultCacheRevalidator.RevalidationCall() {
|
() -> revalidateCacheEntry(target, request, fork, chain, entry));
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClassicHttpResponse execute() throws HttpException, IOException {
|
|
||||||
return revalidateCacheEntry(target, request, fork, chain, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
return convert(response, scope);
|
return convert(response, scope);
|
||||||
}
|
}
|
||||||
return revalidateCacheEntry(target, request, scope, chain, entry);
|
return revalidateCacheEntry(target, request, scope, chain, entry);
|
||||||
|
|
|
@ -26,9 +26,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.http.impl.cache;
|
package org.apache.hc.client5.http.impl.cache;
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
|
||||||
|
@ -130,14 +128,7 @@ public class CachingH2AsyncClientBuilder extends H2AsyncClientBuilder {
|
||||||
} else {
|
} else {
|
||||||
final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
|
final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
|
||||||
if (this.deleteCache) {
|
if (this.deleteCache) {
|
||||||
addCloseable(new Closeable() {
|
addCloseable(managedStorage::shutdown);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
managedStorage.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
addCloseable(managedStorage);
|
addCloseable(managedStorage);
|
||||||
}
|
}
|
||||||
|
@ -153,14 +144,7 @@ public class CachingH2AsyncClientBuilder extends H2AsyncClientBuilder {
|
||||||
DefaultAsyncCacheRevalidator cacheRevalidator = null;
|
DefaultAsyncCacheRevalidator cacheRevalidator = null;
|
||||||
if (config.getAsynchronousWorkers() > 0) {
|
if (config.getAsynchronousWorkers() > 0) {
|
||||||
final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
|
final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
|
||||||
addCloseable(new Closeable() {
|
addCloseable(executorService::shutdownNow);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
executorService.shutdownNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
cacheRevalidator = new DefaultAsyncCacheRevalidator(
|
cacheRevalidator = new DefaultAsyncCacheRevalidator(
|
||||||
executorService,
|
executorService,
|
||||||
this.schedulingStrategy != null ? this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
|
this.schedulingStrategy != null ? this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
|
||||||
|
|
|
@ -26,9 +26,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.http.impl.cache;
|
package org.apache.hc.client5.http.impl.cache;
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
|
||||||
|
@ -130,14 +128,7 @@ public class CachingHttpAsyncClientBuilder extends HttpAsyncClientBuilder {
|
||||||
} else {
|
} else {
|
||||||
final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
|
final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
|
||||||
if (this.deleteCache) {
|
if (this.deleteCache) {
|
||||||
addCloseable(new Closeable() {
|
addCloseable(managedStorage::shutdown);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
managedStorage.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
addCloseable(managedStorage);
|
addCloseable(managedStorage);
|
||||||
}
|
}
|
||||||
|
@ -153,14 +144,7 @@ public class CachingHttpAsyncClientBuilder extends HttpAsyncClientBuilder {
|
||||||
DefaultAsyncCacheRevalidator cacheRevalidator = null;
|
DefaultAsyncCacheRevalidator cacheRevalidator = null;
|
||||||
if (config.getAsynchronousWorkers() > 0) {
|
if (config.getAsynchronousWorkers() > 0) {
|
||||||
final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
|
final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
|
||||||
addCloseable(new Closeable() {
|
addCloseable(executorService::shutdownNow);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
executorService.shutdownNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
cacheRevalidator = new DefaultAsyncCacheRevalidator(
|
cacheRevalidator = new DefaultAsyncCacheRevalidator(
|
||||||
executorService,
|
executorService,
|
||||||
this.schedulingStrategy != null ? this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
|
this.schedulingStrategy != null ? this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
|
||||||
|
|
|
@ -26,9 +26,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.http.impl.cache;
|
package org.apache.hc.client5.http.impl.cache;
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
|
||||||
|
@ -122,14 +120,7 @@ public class CachingHttpClientBuilder extends HttpClientBuilder {
|
||||||
} else {
|
} else {
|
||||||
final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
|
final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
|
||||||
if (this.deleteCache) {
|
if (this.deleteCache) {
|
||||||
addCloseable(new Closeable() {
|
addCloseable(managedStorage::shutdown);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
managedStorage.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
addCloseable(managedStorage);
|
addCloseable(managedStorage);
|
||||||
}
|
}
|
||||||
|
@ -145,14 +136,7 @@ public class CachingHttpClientBuilder extends HttpClientBuilder {
|
||||||
DefaultCacheRevalidator cacheRevalidator = null;
|
DefaultCacheRevalidator cacheRevalidator = null;
|
||||||
if (config.getAsynchronousWorkers() > 0) {
|
if (config.getAsynchronousWorkers() > 0) {
|
||||||
final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
|
final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
|
||||||
addCloseable(new Closeable() {
|
addCloseable(executorService::shutdownNow);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
executorService.shutdownNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
cacheRevalidator = new DefaultCacheRevalidator(
|
cacheRevalidator = new DefaultCacheRevalidator(
|
||||||
executorService,
|
executorService,
|
||||||
this.schedulingStrategy != null ? this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
|
this.schedulingStrategy != null ? this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class DefaultAsyncCacheInvalidator extends CacheInvalidatorBase implement
|
||||||
@Override
|
@Override
|
||||||
public void completed(final Boolean result) {
|
public void completed(final Boolean result) {
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
if (result) {
|
if (result.booleanValue()) {
|
||||||
LOG.debug("Cache entry with key {} successfully flushed", cacheKey);
|
LOG.debug("Cache entry with key {} successfully flushed", cacheKey);
|
||||||
} else {
|
} else {
|
||||||
LOG.debug("Cache entry with key {} could not be flushed", cacheKey);
|
LOG.debug("Cache entry with key {} could not be flushed", cacheKey);
|
||||||
|
|
|
@ -118,59 +118,52 @@ class DefaultAsyncCacheRevalidator extends CacheRevalidatorBase {
|
||||||
final String cacheKey ,
|
final String cacheKey ,
|
||||||
final AsyncExecCallback asyncExecCallback,
|
final AsyncExecCallback asyncExecCallback,
|
||||||
final RevalidationCall call) {
|
final RevalidationCall call) {
|
||||||
scheduleRevalidation(cacheKey, new Runnable() {
|
scheduleRevalidation(cacheKey, () -> call.execute(new AsyncExecCallback() {
|
||||||
|
|
||||||
@Override
|
private final AtomicReference<HttpResponse> responseRef = new AtomicReference<>(null);
|
||||||
public void run() {
|
|
||||||
call.execute(new AsyncExecCallback() {
|
|
||||||
|
|
||||||
private final AtomicReference<HttpResponse> responseRef = new AtomicReference<>(null);
|
@Override
|
||||||
|
public AsyncDataConsumer handleResponse(
|
||||||
|
final HttpResponse response,
|
||||||
|
final EntityDetails entityDetails) throws HttpException, IOException {
|
||||||
|
responseRef.set(response);
|
||||||
|
return asyncExecCallback.handleResponse(response, entityDetails);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncDataConsumer handleResponse(
|
public void handleInformationResponse(
|
||||||
final HttpResponse response,
|
final HttpResponse response) throws HttpException, IOException {
|
||||||
final EntityDetails entityDetails) throws HttpException, IOException {
|
asyncExecCallback.handleInformationResponse(response);
|
||||||
responseRef.set(response);
|
}
|
||||||
return asyncExecCallback.handleResponse(response, entityDetails);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleInformationResponse(
|
public void completed() {
|
||||||
final HttpResponse response) throws HttpException, IOException {
|
final HttpResponse httpResponse = responseRef.getAndSet(null);
|
||||||
asyncExecCallback.handleInformationResponse(response);
|
if (httpResponse != null && httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR && !isStale(httpResponse)) {
|
||||||
}
|
jobSuccessful(cacheKey);
|
||||||
|
} else {
|
||||||
|
jobFailed(cacheKey);
|
||||||
|
}
|
||||||
|
asyncExecCallback.completed();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void completed() {
|
public void failed(final Exception cause) {
|
||||||
final HttpResponse httpResponse = responseRef.getAndSet(null);
|
if (cause instanceof IOException) {
|
||||||
if (httpResponse != null && httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR && !isStale(httpResponse)) {
|
LOG.debug("Asynchronous revalidation failed due to I/O error", cause);
|
||||||
jobSuccessful(cacheKey);
|
} else if (cause instanceof HttpException) {
|
||||||
} else {
|
LOG.error("HTTP protocol exception during asynchronous revalidation", cause);
|
||||||
jobFailed(cacheKey);
|
} else {
|
||||||
}
|
LOG.error("Unexpected runtime exception thrown during asynchronous revalidation", cause);
|
||||||
asyncExecCallback.completed();
|
}
|
||||||
}
|
try {
|
||||||
|
jobFailed(cacheKey);
|
||||||
|
} finally {
|
||||||
|
asyncExecCallback.failed(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
}));
|
||||||
public void failed(final Exception cause) {
|
|
||||||
if (cause instanceof IOException) {
|
|
||||||
LOG.debug("Asynchronous revalidation failed due to I/O error", cause);
|
|
||||||
} else if (cause instanceof HttpException) {
|
|
||||||
LOG.error("HTTP protocol exception during asynchronous revalidation", cause);
|
|
||||||
} else {
|
|
||||||
LOG.error("Unexpected runtime exception thrown during asynchronous revalidation", cause);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
jobFailed(cacheKey);
|
|
||||||
} finally {
|
|
||||||
asyncExecCallback.failed(cause);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,30 +75,25 @@ class DefaultCacheRevalidator extends CacheRevalidatorBase {
|
||||||
public void revalidateCacheEntry(
|
public void revalidateCacheEntry(
|
||||||
final String cacheKey,
|
final String cacheKey,
|
||||||
final RevalidationCall call) {
|
final RevalidationCall call) {
|
||||||
scheduleRevalidation(cacheKey, new Runnable() {
|
scheduleRevalidation(cacheKey, () -> {
|
||||||
|
try (ClassicHttpResponse httpResponse = call.execute()) {
|
||||||
|
if (httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR && !isStale(httpResponse)) {
|
||||||
|
jobSuccessful(cacheKey);
|
||||||
|
} else {
|
||||||
|
jobFailed(cacheKey);
|
||||||
|
}
|
||||||
|
} catch (final IOException ex) {
|
||||||
|
jobFailed(cacheKey);
|
||||||
|
LOG.debug("Asynchronous revalidation failed due to I/O error", ex);
|
||||||
|
} catch (final HttpException ex) {
|
||||||
|
jobFailed(cacheKey);
|
||||||
|
LOG.error("HTTP protocol exception during asynchronous revalidation", ex);
|
||||||
|
} catch (final RuntimeException ex) {
|
||||||
|
jobFailed(cacheKey);
|
||||||
|
LOG.error("Unexpected runtime exception thrown during asynchronous revalidation", ex);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
});
|
||||||
public void run() {
|
|
||||||
try (ClassicHttpResponse httpResponse = call.execute()) {
|
|
||||||
if (httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR && !isStale(httpResponse)) {
|
|
||||||
jobSuccessful(cacheKey);
|
|
||||||
} else {
|
|
||||||
jobFailed(cacheKey);
|
|
||||||
}
|
|
||||||
} catch (final IOException ex) {
|
|
||||||
jobFailed(cacheKey);
|
|
||||||
LOG.debug("Asynchronous revalidation failed due to I/O error", ex);
|
|
||||||
} catch (final HttpException ex) {
|
|
||||||
jobFailed(cacheKey);
|
|
||||||
LOG.error("HTTP protocol exception during asynchronous revalidation", ex);
|
|
||||||
} catch (final RuntimeException ex) {
|
|
||||||
jobFailed(cacheKey);
|
|
||||||
LOG.error("Unexpected runtime exception thrown during asynchronous revalidation", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,10 +358,10 @@ class WarningValue {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (warnDate != null) {
|
if (warnDate != null) {
|
||||||
return String.format("%d %s %s \"%s\"", Integer.valueOf(warnCode),
|
return String.format("%d %s %s \"%s\"", warnCode,
|
||||||
warnAgent, warnText, DateUtils.formatDate(warnDate));
|
warnAgent, warnText, DateUtils.formatDate(warnDate));
|
||||||
} else {
|
} else {
|
||||||
return String.format("%d %s %s", Integer.valueOf(warnCode), warnAgent, warnText);
|
return String.format("%d %s %s", warnCode, warnAgent, warnText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,11 +47,7 @@ import net.spy.memcached.CASResponse;
|
||||||
import net.spy.memcached.CASValue;
|
import net.spy.memcached.CASValue;
|
||||||
import net.spy.memcached.MemcachedClient;
|
import net.spy.memcached.MemcachedClient;
|
||||||
import net.spy.memcached.internal.BulkFuture;
|
import net.spy.memcached.internal.BulkFuture;
|
||||||
import net.spy.memcached.internal.BulkGetCompletionListener;
|
|
||||||
import net.spy.memcached.internal.BulkGetFuture;
|
|
||||||
import net.spy.memcached.internal.GetCompletionListener;
|
|
||||||
import net.spy.memcached.internal.GetFuture;
|
import net.spy.memcached.internal.GetFuture;
|
||||||
import net.spy.memcached.internal.OperationCompletionListener;
|
|
||||||
import net.spy.memcached.internal.OperationFuture;
|
import net.spy.memcached.internal.OperationFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -160,21 +156,16 @@ public class MemcachedHttpAsyncCacheStorage extends AbstractBinaryAsyncCacheStor
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> Cancellable operation(final OperationFuture<T> operationFuture, final FutureCallback<T> callback) {
|
private <T> Cancellable operation(final OperationFuture<T> operationFuture, final FutureCallback<T> callback) {
|
||||||
operationFuture.addListener(new OperationCompletionListener() {
|
operationFuture.addListener(future -> {
|
||||||
|
try {
|
||||||
@Override
|
callback.completed(operationFuture.get());
|
||||||
public void onComplete(final OperationFuture<?> future) throws Exception {
|
} catch (final ExecutionException ex) {
|
||||||
try {
|
if (ex.getCause() instanceof Exception) {
|
||||||
callback.completed(operationFuture.get());
|
callback.failed((Exception) ex.getCause());
|
||||||
} catch (final ExecutionException ex) {
|
} else {
|
||||||
if (ex.getCause() instanceof Exception) {
|
callback.failed(ex);
|
||||||
callback.failed((Exception) ex.getCause());
|
|
||||||
} else {
|
|
||||||
callback.failed(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
return Operations.cancellable(operationFuture);
|
return Operations.cancellable(operationFuture);
|
||||||
}
|
}
|
||||||
|
@ -187,21 +178,16 @@ public class MemcachedHttpAsyncCacheStorage extends AbstractBinaryAsyncCacheStor
|
||||||
@Override
|
@Override
|
||||||
protected Cancellable restore(final String storageKey, final FutureCallback<byte[]> callback) {
|
protected Cancellable restore(final String storageKey, final FutureCallback<byte[]> callback) {
|
||||||
final GetFuture<Object> getFuture = client.asyncGet(storageKey);
|
final GetFuture<Object> getFuture = client.asyncGet(storageKey);
|
||||||
getFuture.addListener(new GetCompletionListener() {
|
getFuture.addListener(future -> {
|
||||||
|
try {
|
||||||
@Override
|
callback.completed(castAsByteArray(getFuture.get()));
|
||||||
public void onComplete(final GetFuture<?> future) throws Exception {
|
} catch (final ExecutionException ex) {
|
||||||
try {
|
if (ex.getCause() instanceof Exception) {
|
||||||
callback.completed(castAsByteArray(getFuture.get()));
|
callback.failed((Exception) ex.getCause());
|
||||||
} catch (final ExecutionException ex) {
|
} else {
|
||||||
if (ex.getCause() instanceof Exception) {
|
callback.failed(ex);
|
||||||
callback.failed((Exception) ex.getCause());
|
|
||||||
} else {
|
|
||||||
callback.failed(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
return Operations.cancellable(getFuture);
|
return Operations.cancellable(getFuture);
|
||||||
}
|
}
|
||||||
|
@ -242,17 +228,13 @@ public class MemcachedHttpAsyncCacheStorage extends AbstractBinaryAsyncCacheStor
|
||||||
@Override
|
@Override
|
||||||
protected Cancellable bulkRestore(final Collection<String> storageKeys, final FutureCallback<Map<String, byte[]>> callback) {
|
protected Cancellable bulkRestore(final Collection<String> storageKeys, final FutureCallback<Map<String, byte[]>> callback) {
|
||||||
final BulkFuture<Map<String, Object>> future = client.asyncGetBulk(storageKeys);
|
final BulkFuture<Map<String, Object>> future = client.asyncGetBulk(storageKeys);
|
||||||
future.addListener(new BulkGetCompletionListener() {
|
future.addListener(future1 -> {
|
||||||
|
final Map<String, ?> storageObjectMap = future1.get();
|
||||||
@Override
|
final Map<String, byte[]> resultMap = new HashMap<>(storageObjectMap.size());
|
||||||
public void onComplete(final BulkGetFuture<?> future) throws Exception {
|
for (final Map.Entry<String, ?> resultEntry: storageObjectMap.entrySet()) {
|
||||||
final Map<String, ?> storageObjectMap = future.get();
|
resultMap.put(resultEntry.getKey(), castAsByteArray(resultEntry.getValue()));
|
||||||
final Map<String, byte[]> resultMap = new HashMap<>(storageObjectMap.size());
|
|
||||||
for (final Map.Entry<String, ?> resultEntry: storageObjectMap.entrySet()) {
|
|
||||||
resultMap.put(resultEntry.getKey(), castAsByteArray(resultEntry.getValue()));
|
|
||||||
}
|
|
||||||
callback.completed(resultMap);
|
|
||||||
}
|
}
|
||||||
|
callback.completed(resultMap);
|
||||||
});
|
});
|
||||||
return Operations.cancellable(future);
|
return Operations.cancellable(future);
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,7 +217,7 @@ public class TestHttpCacheEntry {
|
||||||
public void canProvideVariantMap() {
|
public void canProvideVariantMap() {
|
||||||
new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
|
new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
|
||||||
new Header[]{}, mockResource,
|
new Header[]{}, mockResource,
|
||||||
new HashMap<String,String>());
|
new HashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -155,7 +155,7 @@ public abstract class AbstractProtocolTest {
|
||||||
EasyMock.expect(mockCache.getCacheEntry(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
|
EasyMock.expect(mockCache.getCacheEntry(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
|
||||||
.andReturn(null).anyTimes();
|
.andReturn(null).anyTimes();
|
||||||
EasyMock.expect(mockCache.getVariantCacheEntriesWithEtags(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
|
EasyMock.expect(mockCache.getVariantCacheEntriesWithEtags(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
|
||||||
.andReturn(new HashMap<String,Variant>()).anyTimes();
|
.andReturn(new HashMap<>()).anyTimes();
|
||||||
|
|
||||||
mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
|
mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
|
||||||
EasyMock.expectLastCall().anyTimes();
|
EasyMock.expectLastCall().anyTimes();
|
||||||
|
|
|
@ -35,7 +35,6 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
|
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
|
import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
|
import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
|
||||||
|
@ -52,7 +51,6 @@ import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
@ -90,16 +88,11 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
Mockito.when(impl.store(
|
Mockito.when(impl.store(
|
||||||
ArgumentMatchers.eq("bar"),
|
ArgumentMatchers.eq("bar"),
|
||||||
ArgumentMatchers.<byte[]>any(),
|
ArgumentMatchers.<byte[]>any(),
|
||||||
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
|
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<Boolean> callback = invocation.getArgument(2);
|
||||||
@Override
|
callback.completed(true);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<Boolean> callback = invocation.getArgument(2);
|
});
|
||||||
callback.completed(true);
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
impl.putEntry(key, value, operationCallback);
|
impl.putEntry(key, value, operationCallback);
|
||||||
|
|
||||||
|
@ -114,15 +107,10 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
final String key = "foo";
|
final String key = "foo";
|
||||||
|
|
||||||
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
||||||
Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer(new Answer<Cancellable>() {
|
Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<byte[]> callback = invocation.getArgument(1);
|
||||||
@Override
|
callback.completed(null);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<byte[]> callback = invocation.getArgument(1);
|
|
||||||
callback.completed(null);
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
impl.getEntry(key, cacheEntryCallback);
|
impl.getEntry(key, cacheEntryCallback);
|
||||||
|
@ -138,15 +126,10 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
final HttpCacheEntry value = HttpTestUtils.makeCacheEntry();
|
final HttpCacheEntry value = HttpTestUtils.makeCacheEntry();
|
||||||
|
|
||||||
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
||||||
Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer(new Answer<Cancellable>() {
|
Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<byte[]> callback = invocation.getArgument(1);
|
||||||
@Override
|
callback.completed(serialize(key, value));
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<byte[]> callback = invocation.getArgument(1);
|
|
||||||
callback.completed(serialize(key, value));
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
impl.getEntry(key, cacheEntryCallback);
|
impl.getEntry(key, cacheEntryCallback);
|
||||||
|
@ -162,15 +145,10 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
final String key = "foo";
|
final String key = "foo";
|
||||||
final HttpCacheEntry value = HttpTestUtils.makeCacheEntry();
|
final HttpCacheEntry value = HttpTestUtils.makeCacheEntry();
|
||||||
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
||||||
Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer(new Answer<Cancellable>() {
|
Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<byte[]> callback = invocation.getArgument(1);
|
||||||
@Override
|
callback.completed(serialize("not-foo", value));
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<byte[]> callback = invocation.getArgument(1);
|
|
||||||
callback.completed(serialize("not-foo", value));
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
impl.getEntry(key, cacheEntryCallback);
|
impl.getEntry(key, cacheEntryCallback);
|
||||||
|
@ -187,16 +165,11 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
||||||
Mockito.when(impl.delete(
|
Mockito.when(impl.delete(
|
||||||
ArgumentMatchers.eq("bar"),
|
ArgumentMatchers.eq("bar"),
|
||||||
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
|
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<Boolean> callback = invocation.getArgument(1);
|
||||||
@Override
|
callback.completed(true);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<Boolean> callback = invocation.getArgument(1);
|
});
|
||||||
callback.completed(true);
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
impl.removeEntry(key, operationCallback);
|
impl.removeEntry(key, operationCallback);
|
||||||
|
|
||||||
Mockito.verify(impl).delete("bar", operationCallback);
|
Mockito.verify(impl).delete("bar", operationCallback);
|
||||||
|
@ -209,38 +182,23 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
|
final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
|
||||||
|
|
||||||
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
||||||
Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(new Answer<Cancellable>() {
|
Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<byte[]> callback = invocation.getArgument(1);
|
||||||
@Override
|
callback.completed(null);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<byte[]> callback = invocation.getArgument(1);
|
|
||||||
callback.completed(null);
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
Mockito.when(impl.store(
|
Mockito.when(impl.store(
|
||||||
ArgumentMatchers.eq("bar"),
|
ArgumentMatchers.eq("bar"),
|
||||||
ArgumentMatchers.<byte[]>any(),
|
ArgumentMatchers.<byte[]>any(),
|
||||||
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
|
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<Boolean> callback = invocation.getArgument(2);
|
||||||
@Override
|
callback.completed(true);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<Boolean> callback = invocation.getArgument(2);
|
});
|
||||||
callback.completed(true);
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
impl.updateEntry(key, new HttpCacheCASOperation() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
Assert.assertThat(existing, CoreMatchers.nullValue());
|
|
||||||
return updatedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
impl.updateEntry(key, existing -> {
|
||||||
|
Assert.assertThat(existing, CoreMatchers.nullValue());
|
||||||
|
return updatedValue;
|
||||||
}, operationCallback);
|
}, operationCallback);
|
||||||
|
|
||||||
Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
|
Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
|
||||||
|
@ -255,40 +213,23 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
|
final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
|
||||||
|
|
||||||
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
||||||
Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(new Answer<Cancellable>() {
|
Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<String> callback = invocation.getArgument(1);
|
||||||
@Override
|
callback.completed("stuff");
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<String> callback = invocation.getArgument(1);
|
|
||||||
callback.completed("stuff");
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
|
Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
|
||||||
Mockito.when(impl.updateCAS(
|
Mockito.when(impl.updateCAS(
|
||||||
ArgumentMatchers.eq("bar"),
|
ArgumentMatchers.eq("bar"),
|
||||||
ArgumentMatchers.eq("stuff"),
|
ArgumentMatchers.eq("stuff"),
|
||||||
ArgumentMatchers.<byte[]>any(),
|
ArgumentMatchers.<byte[]>any(),
|
||||||
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
|
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<Boolean> callback = invocation.getArgument(3);
|
||||||
|
callback.completed(true);
|
||||||
|
return cancellable;
|
||||||
|
});
|
||||||
|
|
||||||
@Override
|
impl.updateEntry(key, existing -> updatedValue, operationCallback);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
|
||||||
final FutureCallback<Boolean> callback = invocation.getArgument(3);
|
|
||||||
callback.completed(true);
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
impl.updateEntry(key, new HttpCacheCASOperation() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
return updatedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, operationCallback);
|
|
||||||
|
|
||||||
Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
|
Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
|
||||||
Mockito.verify(impl).getStorageObject("stuff");
|
Mockito.verify(impl).getStorageObject("stuff");
|
||||||
|
@ -304,39 +245,24 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
|
|
||||||
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
||||||
Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
|
Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
|
||||||
new Answer<Cancellable>() {
|
(Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<String> callback = invocation.getArgument(1);
|
||||||
@Override
|
callback.completed("stuff");
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<String> callback = invocation.getArgument(1);
|
|
||||||
callback.completed("stuff");
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize("not-foo", existingValue));
|
Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize("not-foo", existingValue));
|
||||||
Mockito.when(impl.store(
|
Mockito.when(impl.store(
|
||||||
ArgumentMatchers.eq("bar"),
|
ArgumentMatchers.eq("bar"),
|
||||||
ArgumentMatchers.<byte[]>any(),
|
ArgumentMatchers.<byte[]>any(),
|
||||||
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
|
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<Boolean> callback = invocation.getArgument(2);
|
||||||
@Override
|
callback.completed(true);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<Boolean> callback = invocation.getArgument(2);
|
});
|
||||||
callback.completed(true);
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
impl.updateEntry(key, new HttpCacheCASOperation() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
Assert.assertThat(existing, CoreMatchers.nullValue());
|
|
||||||
return updatedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
impl.updateEntry(key, existing -> {
|
||||||
|
Assert.assertThat(existing, CoreMatchers.nullValue());
|
||||||
|
return updatedValue;
|
||||||
}, operationCallback);
|
}, operationCallback);
|
||||||
|
|
||||||
Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
|
Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
|
||||||
|
@ -355,15 +281,10 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
|
|
||||||
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
||||||
Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
|
Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
|
||||||
new Answer<Cancellable>() {
|
(Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<String> callback = invocation.getArgument(1);
|
||||||
@Override
|
callback.completed("stuff");
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<String> callback = invocation.getArgument(1);
|
|
||||||
callback.completed("stuff");
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
|
Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
|
||||||
final AtomicInteger count = new AtomicInteger(0);
|
final AtomicInteger count = new AtomicInteger(0);
|
||||||
|
@ -371,29 +292,17 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
ArgumentMatchers.eq("bar"),
|
ArgumentMatchers.eq("bar"),
|
||||||
ArgumentMatchers.eq("stuff"),
|
ArgumentMatchers.eq("stuff"),
|
||||||
ArgumentMatchers.<byte[]>any(),
|
ArgumentMatchers.<byte[]>any(),
|
||||||
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
|
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<Boolean> callback = invocation.getArgument(3);
|
||||||
|
if (count.incrementAndGet() == 1) {
|
||||||
|
callback.completed(false);
|
||||||
|
} else {
|
||||||
|
callback.completed(true);
|
||||||
|
}
|
||||||
|
return cancellable;
|
||||||
|
});
|
||||||
|
|
||||||
@Override
|
impl.updateEntry(key, existing -> updatedValue, operationCallback);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
|
||||||
final FutureCallback<Boolean> callback = invocation.getArgument(3);
|
|
||||||
if (count.incrementAndGet() == 1) {
|
|
||||||
callback.completed(false);
|
|
||||||
} else {
|
|
||||||
callback.completed(true);
|
|
||||||
}
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
impl.updateEntry(key, new HttpCacheCASOperation() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
return updatedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, operationCallback);
|
|
||||||
|
|
||||||
Mockito.verify(impl, Mockito.times(2)).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
|
Mockito.verify(impl, Mockito.times(2)).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
|
||||||
Mockito.verify(impl, Mockito.times(2)).getStorageObject("stuff");
|
Mockito.verify(impl, Mockito.times(2)).getStorageObject("stuff");
|
||||||
|
@ -410,15 +319,10 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
|
|
||||||
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
|
||||||
Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
|
Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
|
||||||
new Answer<Cancellable>() {
|
(Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<String> callback = invocation.getArgument(1);
|
||||||
@Override
|
callback.completed("stuff");
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<String> callback = invocation.getArgument(1);
|
|
||||||
callback.completed("stuff");
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
|
Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
|
||||||
final AtomicInteger count = new AtomicInteger(0);
|
final AtomicInteger count = new AtomicInteger(0);
|
||||||
|
@ -426,29 +330,17 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
ArgumentMatchers.eq("bar"),
|
ArgumentMatchers.eq("bar"),
|
||||||
ArgumentMatchers.eq("stuff"),
|
ArgumentMatchers.eq("stuff"),
|
||||||
ArgumentMatchers.<byte[]>any(),
|
ArgumentMatchers.<byte[]>any(),
|
||||||
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
|
ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<Boolean> callback = invocation.getArgument(3);
|
||||||
|
if (count.incrementAndGet() <= 3) {
|
||||||
|
callback.completed(false);
|
||||||
|
} else {
|
||||||
|
callback.completed(true);
|
||||||
|
}
|
||||||
|
return cancellable;
|
||||||
|
});
|
||||||
|
|
||||||
@Override
|
impl.updateEntry(key, existing -> updatedValue, operationCallback);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
|
||||||
final FutureCallback<Boolean> callback = invocation.getArgument(3);
|
|
||||||
if (count.incrementAndGet() <= 3) {
|
|
||||||
callback.completed(false);
|
|
||||||
} else {
|
|
||||||
callback.completed(true);
|
|
||||||
}
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
impl.updateEntry(key, new HttpCacheCASOperation() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
return updatedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, operationCallback);
|
|
||||||
|
|
||||||
Mockito.verify(impl, Mockito.times(3)).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
|
Mockito.verify(impl, Mockito.times(3)).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
|
||||||
Mockito.verify(impl, Mockito.times(3)).getStorageObject("stuff");
|
Mockito.verify(impl, Mockito.times(3)).getStorageObject("stuff");
|
||||||
|
@ -472,23 +364,19 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
|
|
||||||
when(impl.bulkRestore(
|
when(impl.bulkRestore(
|
||||||
ArgumentMatchers.<String>anyCollection(),
|
ArgumentMatchers.<String>anyCollection(),
|
||||||
ArgumentMatchers.<FutureCallback<Map<String, byte[]>>>any())).thenAnswer(new Answer<Cancellable>() {
|
ArgumentMatchers.<FutureCallback<Map<String, byte[]>>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final Collection<String> keys = invocation.getArgument(0);
|
||||||
@Override
|
final FutureCallback<Map<String, byte[]>> callback = invocation.getArgument(1);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
final Map<String, byte[]> resultMap = new HashMap<>();
|
||||||
final Collection<String> keys = invocation.getArgument(0);
|
if (keys.contains(storageKey1)) {
|
||||||
final FutureCallback<Map<String, byte[]>> callback = invocation.getArgument(1);
|
resultMap.put(storageKey1, serialize(key1, value1));
|
||||||
final Map<String, byte[]> resultMap = new HashMap<>();
|
}
|
||||||
if (keys.contains(storageKey1)) {
|
if (keys.contains(storageKey2)) {
|
||||||
resultMap.put(storageKey1, serialize(key1, value1));
|
resultMap.put(storageKey2, serialize(key2, value2));
|
||||||
}
|
}
|
||||||
if (keys.contains(storageKey2)) {
|
callback.completed(resultMap);
|
||||||
resultMap.put(storageKey2, serialize(key2, value2));
|
return cancellable;
|
||||||
}
|
});
|
||||||
callback.completed(resultMap);
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
impl.getEntries(Arrays.asList(key1, key2), bulkCacheEntryCallback);
|
impl.getEntries(Arrays.asList(key1, key2), bulkCacheEntryCallback);
|
||||||
final ArgumentCaptor<Map<String, HttpCacheEntry>> argumentCaptor = ArgumentCaptor.forClass(Map.class);
|
final ArgumentCaptor<Map<String, HttpCacheEntry>> argumentCaptor = ArgumentCaptor.forClass(Map.class);
|
||||||
|
@ -521,23 +409,19 @@ public class TestAbstractSerializingAsyncCacheStorage {
|
||||||
|
|
||||||
when(impl.bulkRestore(
|
when(impl.bulkRestore(
|
||||||
ArgumentMatchers.<String>anyCollection(),
|
ArgumentMatchers.<String>anyCollection(),
|
||||||
ArgumentMatchers.<FutureCallback<Map<String, byte[]>>>any())).thenAnswer(new Answer<Cancellable>() {
|
ArgumentMatchers.<FutureCallback<Map<String, byte[]>>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final Collection<String> keys = invocation.getArgument(0);
|
||||||
@Override
|
final FutureCallback<Map<String, byte[]>> callback = invocation.getArgument(1);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
final Map<String, byte[]> resultMap = new HashMap<>();
|
||||||
final Collection<String> keys = invocation.getArgument(0);
|
if (keys.contains(storageKey1)) {
|
||||||
final FutureCallback<Map<String, byte[]>> callback = invocation.getArgument(1);
|
resultMap.put(storageKey1, serialize(key1, value1));
|
||||||
final Map<String, byte[]> resultMap = new HashMap<>();
|
}
|
||||||
if (keys.contains(storageKey1)) {
|
if (keys.contains(storageKey2)) {
|
||||||
resultMap.put(storageKey1, serialize(key1, value1));
|
resultMap.put(storageKey2, serialize("not foo", value2));
|
||||||
}
|
}
|
||||||
if (keys.contains(storageKey2)) {
|
callback.completed(resultMap);
|
||||||
resultMap.put(storageKey2, serialize("not foo", value2));
|
return cancellable;
|
||||||
}
|
});
|
||||||
callback.completed(resultMap);
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
impl.getEntries(Arrays.asList(key1, key2), bulkCacheEntryCallback);
|
impl.getEntries(Arrays.asList(key1, key2), bulkCacheEntryCallback);
|
||||||
final ArgumentCaptor<Map<String, HttpCacheEntry>> argumentCaptor = ArgumentCaptor.forClass(Map.class);
|
final ArgumentCaptor<Map<String, HttpCacheEntry>> argumentCaptor = ArgumentCaptor.forClass(Map.class);
|
||||||
|
|
|
@ -35,7 +35,6 @@ import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
|
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
|
import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
|
import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
|
||||||
|
@ -48,7 +47,6 @@ import org.mockito.Answers;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
@SuppressWarnings("boxing") // test code
|
@SuppressWarnings("boxing") // test code
|
||||||
|
@ -143,14 +141,9 @@ public class TestAbstractSerializingCacheStorage {
|
||||||
when(impl.digestToStorageKey(key)).thenReturn("bar");
|
when(impl.digestToStorageKey(key)).thenReturn("bar");
|
||||||
when(impl.getForUpdateCAS("bar")).thenReturn(null);
|
when(impl.getForUpdateCAS("bar")).thenReturn(null);
|
||||||
|
|
||||||
impl.updateEntry(key, new HttpCacheCASOperation() {
|
impl.updateEntry(key, existing -> {
|
||||||
|
Assert.assertThat(existing, CoreMatchers.nullValue());
|
||||||
@Override
|
return updatedValue;
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
Assert.assertThat(existing, CoreMatchers.nullValue());
|
|
||||||
return updatedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
verify(impl).getForUpdateCAS("bar");
|
verify(impl).getForUpdateCAS("bar");
|
||||||
|
@ -168,14 +161,7 @@ public class TestAbstractSerializingCacheStorage {
|
||||||
when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
|
when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
|
||||||
when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(true);
|
when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(true);
|
||||||
|
|
||||||
impl.updateEntry(key, new HttpCacheCASOperation() {
|
impl.updateEntry(key, existing -> updatedValue);
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
return updatedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
verify(impl).getForUpdateCAS("bar");
|
verify(impl).getForUpdateCAS("bar");
|
||||||
verify(impl).getStorageObject("stuff");
|
verify(impl).getStorageObject("stuff");
|
||||||
|
@ -193,14 +179,9 @@ public class TestAbstractSerializingCacheStorage {
|
||||||
when(impl.getStorageObject("stuff")).thenReturn(serialize("not-foo", existingValue));
|
when(impl.getStorageObject("stuff")).thenReturn(serialize("not-foo", existingValue));
|
||||||
when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(true);
|
when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(true);
|
||||||
|
|
||||||
impl.updateEntry(key, new HttpCacheCASOperation() {
|
impl.updateEntry(key, existing -> {
|
||||||
|
Assert.assertThat(existing, CoreMatchers.nullValue());
|
||||||
@Override
|
return updatedValue;
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
Assert.assertThat(existing, CoreMatchers.nullValue());
|
|
||||||
return updatedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
verify(impl).getForUpdateCAS("bar");
|
verify(impl).getForUpdateCAS("bar");
|
||||||
|
@ -219,14 +200,7 @@ public class TestAbstractSerializingCacheStorage {
|
||||||
when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
|
when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
|
||||||
when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(false, true);
|
when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(false, true);
|
||||||
|
|
||||||
impl.updateEntry(key, new HttpCacheCASOperation() {
|
impl.updateEntry(key, existing -> updatedValue);
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
return updatedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
verify(impl, Mockito.times(2)).getForUpdateCAS("bar");
|
verify(impl, Mockito.times(2)).getForUpdateCAS("bar");
|
||||||
verify(impl, Mockito.times(2)).getStorageObject("stuff");
|
verify(impl, Mockito.times(2)).getStorageObject("stuff");
|
||||||
|
@ -245,14 +219,7 @@ public class TestAbstractSerializingCacheStorage {
|
||||||
when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(false, false, false, true);
|
when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(false, false, false, true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
impl.updateEntry(key, new HttpCacheCASOperation() {
|
impl.updateEntry(key, existing -> updatedValue);
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
|
|
||||||
return updatedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
Assert.fail("HttpCacheUpdateException expected");
|
Assert.fail("HttpCacheUpdateException expected");
|
||||||
} catch (final HttpCacheUpdateException ignore) {
|
} catch (final HttpCacheUpdateException ignore) {
|
||||||
}
|
}
|
||||||
|
@ -274,20 +241,16 @@ public class TestAbstractSerializingCacheStorage {
|
||||||
when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
|
when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
|
||||||
when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
|
when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
|
||||||
|
|
||||||
when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer(new Answer<Map<String, byte[]>>() {
|
when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer((Answer<Map<String, byte[]>>) invocation -> {
|
||||||
|
final Collection<String> keys = invocation.getArgument(0);
|
||||||
@Override
|
final Map<String, byte[]> resultMap = new HashMap<>();
|
||||||
public Map<String, byte[]> answer(final InvocationOnMock invocation) throws Throwable {
|
if (keys.contains(storageKey1)) {
|
||||||
final Collection<String> keys = invocation.getArgument(0);
|
resultMap.put(storageKey1, serialize(key1, value1));
|
||||||
final Map<String, byte[]> resultMap = new HashMap<>();
|
|
||||||
if (keys.contains(storageKey1)) {
|
|
||||||
resultMap.put(storageKey1, serialize(key1, value1));
|
|
||||||
}
|
|
||||||
if (keys.contains(storageKey2)) {
|
|
||||||
resultMap.put(storageKey2, serialize(key2, value2));
|
|
||||||
}
|
|
||||||
return resultMap;
|
|
||||||
}
|
}
|
||||||
|
if (keys.contains(storageKey2)) {
|
||||||
|
resultMap.put(storageKey2, serialize(key2, value2));
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
});
|
});
|
||||||
|
|
||||||
final Map<String, HttpCacheEntry> entryMap = impl.getEntries(Arrays.asList(key1, key2));
|
final Map<String, HttpCacheEntry> entryMap = impl.getEntries(Arrays.asList(key1, key2));
|
||||||
|
@ -312,20 +275,16 @@ public class TestAbstractSerializingCacheStorage {
|
||||||
when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
|
when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
|
||||||
when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
|
when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
|
||||||
|
|
||||||
when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer(new Answer<Map<String, byte[]>>() {
|
when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer((Answer<Map<String, byte[]>>) invocation -> {
|
||||||
|
final Collection<String> keys = invocation.getArgument(0);
|
||||||
@Override
|
final Map<String, byte[]> resultMap = new HashMap<>();
|
||||||
public Map<String, byte[]> answer(final InvocationOnMock invocation) throws Throwable {
|
if (keys.contains(storageKey1)) {
|
||||||
final Collection<String> keys = invocation.getArgument(0);
|
resultMap.put(storageKey1, serialize(key1, value1));
|
||||||
final Map<String, byte[]> resultMap = new HashMap<>();
|
|
||||||
if (keys.contains(storageKey1)) {
|
|
||||||
resultMap.put(storageKey1, serialize(key1, value1));
|
|
||||||
}
|
|
||||||
if (keys.contains(storageKey2)) {
|
|
||||||
resultMap.put(storageKey2, serialize("not foo", value2));
|
|
||||||
}
|
|
||||||
return resultMap;
|
|
||||||
}
|
}
|
||||||
|
if (keys.contains(storageKey2)) {
|
||||||
|
resultMap.put(storageKey2, serialize("not foo", value2));
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
});
|
});
|
||||||
|
|
||||||
final Map<String, HttpCacheEntry> entryMap = impl.getEntries(Arrays.asList(key1, key2));
|
final Map<String, HttpCacheEntry> entryMap = impl.getEntries(Arrays.asList(key1, key2));
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class TestCachedHttpResponseGenerator {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
entry = HttpTestUtils.makeCacheEntry(new HashMap<String, String>());
|
entry = HttpTestUtils.makeCacheEntry(new HashMap<>());
|
||||||
request = HttpTestUtils.makeDefaultRequest();
|
request = HttpTestUtils.makeDefaultRequest();
|
||||||
mockValidityPolicy = mock(CacheValidityPolicy.class);
|
mockValidityPolicy = mock(CacheValidityPolicy.class);
|
||||||
impl = new CachedHttpResponseGenerator(mockValidityPolicy);
|
impl = new CachedHttpResponseGenerator(mockValidityPolicy);
|
||||||
|
|
|
@ -170,7 +170,7 @@ public class TestCachingExec extends TestCachingExecChain {
|
||||||
mockImplMethods(CALL_BACKEND);
|
mockImplMethods(CALL_BACKEND);
|
||||||
requestPolicyAllowsCaching(true);
|
requestPolicyAllowsCaching(true);
|
||||||
getCacheEntryReturns(null);
|
getCacheEntryReturns(null);
|
||||||
getVariantCacheEntriesReturns(new HashMap<String,Variant>());
|
getVariantCacheEntriesReturns(new HashMap<>());
|
||||||
|
|
||||||
requestIsFatallyNonCompliant(null);
|
requestIsFatallyNonCompliant(null);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ import java.util.Map;
|
||||||
import org.apache.hc.client5.http.cache.HeaderConstants;
|
import org.apache.hc.client5.http.cache.HeaderConstants;
|
||||||
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
import org.apache.hc.client5.http.cache.HttpCacheEntry;
|
||||||
import org.apache.hc.client5.http.utils.DateUtils;
|
import org.apache.hc.client5.http.utils.DateUtils;
|
||||||
import org.apache.hc.core5.function.Factory;
|
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HeaderElement;
|
import org.apache.hc.core5.http.HeaderElement;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
import org.apache.hc.core5.http.HttpRequest;
|
||||||
|
@ -53,14 +52,7 @@ public class TestConditionalRequestBuilder {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
impl = new ConditionalRequestBuilder<>(new Factory<HttpRequest, HttpRequest>() {
|
impl = new ConditionalRequestBuilder<>(request -> BasicRequestBuilder.copy(request).build());
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpRequest create(final HttpRequest request) {
|
|
||||||
return BasicRequestBuilder.copy(request).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
request = new BasicHttpRequest("GET", "/");
|
request = new BasicHttpRequest("GET", "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,6 @@ import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
@ -83,14 +82,9 @@ public class TestDefaultAsyncCacheInvalidator {
|
||||||
now = new Date();
|
now = new Date();
|
||||||
tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||||
|
|
||||||
when(cacheKeyResolver.resolve(ArgumentMatchers.<URI>any())).thenAnswer(new Answer<String>() {
|
when(cacheKeyResolver.resolve(ArgumentMatchers.<URI>any())).thenAnswer((Answer<String>) invocation -> {
|
||||||
|
final URI uri = invocation.getArgument(0);
|
||||||
@Override
|
return HttpCacheSupport.normalize(uri).toASCIIString();
|
||||||
public String answer(final InvocationOnMock invocation) throws Throwable {
|
|
||||||
final URI uri = invocation.getArgument(0);
|
|
||||||
return HttpCacheSupport.normalize(uri).toASCIIString();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
host = new HttpHost("foo.example.com");
|
host = new HttpHost("foo.example.com");
|
||||||
|
@ -124,7 +118,7 @@ public class TestDefaultAsyncCacheInvalidator {
|
||||||
|
|
||||||
final URI uri = new URI("http://foo.example.com:80/");
|
final URI uri = new URI("http://foo.example.com:80/");
|
||||||
final String key = uri.toASCIIString();
|
final String key = uri.toASCIIString();
|
||||||
cacheEntryHasVariantMap(new HashMap<String,String>());
|
cacheEntryHasVariantMap(new HashMap<>());
|
||||||
|
|
||||||
cacheReturnsEntryForUri(key, mockEntry);
|
cacheReturnsEntryForUri(key, mockEntry);
|
||||||
|
|
||||||
|
@ -146,7 +140,7 @@ public class TestDefaultAsyncCacheInvalidator {
|
||||||
|
|
||||||
final URI uri = new URI("http://foo.example.com:80/");
|
final URI uri = new URI("http://foo.example.com:80/");
|
||||||
final String key = uri.toASCIIString();
|
final String key = uri.toASCIIString();
|
||||||
cacheEntryHasVariantMap(new HashMap<String,String>());
|
cacheEntryHasVariantMap(new HashMap<>());
|
||||||
|
|
||||||
cacheReturnsEntryForUri(key, mockEntry);
|
cacheReturnsEntryForUri(key, mockEntry);
|
||||||
|
|
||||||
|
@ -168,7 +162,7 @@ public class TestDefaultAsyncCacheInvalidator {
|
||||||
|
|
||||||
final URI uri = new URI("http://foo.example.com:80/");
|
final URI uri = new URI("http://foo.example.com:80/");
|
||||||
final String key = uri.toASCIIString();
|
final String key = uri.toASCIIString();
|
||||||
cacheEntryHasVariantMap(new HashMap<String,String>());
|
cacheEntryHasVariantMap(new HashMap<>());
|
||||||
|
|
||||||
cacheReturnsEntryForUri(key, mockEntry);
|
cacheReturnsEntryForUri(key, mockEntry);
|
||||||
|
|
||||||
|
@ -190,7 +184,7 @@ public class TestDefaultAsyncCacheInvalidator {
|
||||||
|
|
||||||
final URI uri = new URI("http://foo.example.com:80/");
|
final URI uri = new URI("http://foo.example.com:80/");
|
||||||
final String key = uri.toASCIIString();
|
final String key = uri.toASCIIString();
|
||||||
cacheEntryHasVariantMap(new HashMap<String,String>());
|
cacheEntryHasVariantMap(new HashMap<>());
|
||||||
|
|
||||||
cacheReturnsEntryForUri(key, mockEntry);
|
cacheReturnsEntryForUri(key, mockEntry);
|
||||||
|
|
||||||
|
@ -226,7 +220,7 @@ public class TestDefaultAsyncCacheInvalidator {
|
||||||
final HttpRequest request = new BasicHttpRequest("GET", uri);
|
final HttpRequest request = new BasicHttpRequest("GET", uri);
|
||||||
|
|
||||||
cacheEntryisForMethod("HEAD");
|
cacheEntryisForMethod("HEAD");
|
||||||
cacheEntryHasVariantMap(new HashMap<String, String>());
|
cacheEntryHasVariantMap(new HashMap<>());
|
||||||
cacheReturnsEntryForUri(key, mockEntry);
|
cacheReturnsEntryForUri(key, mockEntry);
|
||||||
|
|
||||||
impl.flushCacheEntriesInvalidatedByRequest(host, request, cacheKeyResolver, mockStorage, operationCallback);
|
impl.flushCacheEntriesInvalidatedByRequest(host, request, cacheKeyResolver, mockStorage, operationCallback);
|
||||||
|
@ -679,16 +673,11 @@ public class TestDefaultAsyncCacheInvalidator {
|
||||||
private void cacheReturnsEntryForUri(final String key, final HttpCacheEntry cacheEntry) {
|
private void cacheReturnsEntryForUri(final String key, final HttpCacheEntry cacheEntry) {
|
||||||
Mockito.when(mockStorage.getEntry(
|
Mockito.when(mockStorage.getEntry(
|
||||||
ArgumentMatchers.eq(key),
|
ArgumentMatchers.eq(key),
|
||||||
ArgumentMatchers.<FutureCallback<HttpCacheEntry>>any())).thenAnswer(new Answer<Cancellable>() {
|
ArgumentMatchers.<FutureCallback<HttpCacheEntry>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
|
||||||
|
final FutureCallback<HttpCacheEntry> callback = invocation.getArgument(1);
|
||||||
@Override
|
callback.completed(cacheEntry);
|
||||||
public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
|
return cancellable;
|
||||||
final FutureCallback<HttpCacheEntry> callback = invocation.getArgument(1);
|
});
|
||||||
callback.completed(cacheEntry);
|
|
||||||
return cancellable;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cacheEntryisForMethod(final String httpMethod) {
|
private void cacheEntryisForMethod(final String httpMethod) {
|
||||||
|
|
|
@ -53,7 +53,6 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentMatchers;
|
import org.mockito.ArgumentMatchers;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
@ -77,14 +76,9 @@ public class TestDefaultCacheInvalidator {
|
||||||
now = new Date();
|
now = new Date();
|
||||||
tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
|
||||||
|
|
||||||
when(cacheKeyResolver.resolve(ArgumentMatchers.<URI>any())).thenAnswer(new Answer<String>() {
|
when(cacheKeyResolver.resolve(ArgumentMatchers.<URI>any())).thenAnswer((Answer<String>) invocation -> {
|
||||||
|
final URI uri = invocation.getArgument(0);
|
||||||
@Override
|
return HttpCacheSupport.normalize(uri).toASCIIString();
|
||||||
public String answer(final InvocationOnMock invocation) throws Throwable {
|
|
||||||
final URI uri = invocation.getArgument(0);
|
|
||||||
return HttpCacheSupport.normalize(uri).toASCIIString();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
host = new HttpHost("foo.example.com");
|
host = new HttpHost("foo.example.com");
|
||||||
|
@ -118,7 +112,7 @@ public class TestDefaultCacheInvalidator {
|
||||||
|
|
||||||
final URI uri = new URI("http://foo.example.com:80/");
|
final URI uri = new URI("http://foo.example.com:80/");
|
||||||
final String key = uri.toASCIIString();
|
final String key = uri.toASCIIString();
|
||||||
cacheEntryHasVariantMap(new HashMap<String,String>());
|
cacheEntryHasVariantMap(new HashMap<>());
|
||||||
|
|
||||||
cacheReturnsEntryForUri(key);
|
cacheReturnsEntryForUri(key);
|
||||||
|
|
||||||
|
@ -140,7 +134,7 @@ public class TestDefaultCacheInvalidator {
|
||||||
|
|
||||||
final URI uri = new URI("http://foo.example.com:80/");
|
final URI uri = new URI("http://foo.example.com:80/");
|
||||||
final String key = uri.toASCIIString();
|
final String key = uri.toASCIIString();
|
||||||
cacheEntryHasVariantMap(new HashMap<String,String>());
|
cacheEntryHasVariantMap(new HashMap<>());
|
||||||
|
|
||||||
cacheReturnsEntryForUri(key);
|
cacheReturnsEntryForUri(key);
|
||||||
|
|
||||||
|
@ -162,7 +156,7 @@ public class TestDefaultCacheInvalidator {
|
||||||
|
|
||||||
final URI uri = new URI("http://foo.example.com:80/");
|
final URI uri = new URI("http://foo.example.com:80/");
|
||||||
final String key = uri.toASCIIString();
|
final String key = uri.toASCIIString();
|
||||||
cacheEntryHasVariantMap(new HashMap<String,String>());
|
cacheEntryHasVariantMap(new HashMap<>());
|
||||||
|
|
||||||
cacheReturnsEntryForUri(key);
|
cacheReturnsEntryForUri(key);
|
||||||
|
|
||||||
|
@ -184,7 +178,7 @@ public class TestDefaultCacheInvalidator {
|
||||||
|
|
||||||
final URI uri = new URI("http://foo.example.com:80/");
|
final URI uri = new URI("http://foo.example.com:80/");
|
||||||
final String key = uri.toASCIIString();
|
final String key = uri.toASCIIString();
|
||||||
cacheEntryHasVariantMap(new HashMap<String,String>());
|
cacheEntryHasVariantMap(new HashMap<>());
|
||||||
|
|
||||||
cacheReturnsEntryForUri(key);
|
cacheReturnsEntryForUri(key);
|
||||||
|
|
||||||
|
@ -220,7 +214,7 @@ public class TestDefaultCacheInvalidator {
|
||||||
final HttpRequest request = new BasicHttpRequest("GET", uri);
|
final HttpRequest request = new BasicHttpRequest("GET", uri);
|
||||||
|
|
||||||
cacheEntryisForMethod("HEAD");
|
cacheEntryisForMethod("HEAD");
|
||||||
cacheEntryHasVariantMap(new HashMap<String, String>());
|
cacheEntryHasVariantMap(new HashMap<>());
|
||||||
cacheReturnsEntryForUri(key);
|
cacheReturnsEntryForUri(key);
|
||||||
|
|
||||||
impl.flushCacheEntriesInvalidatedByRequest(host, request, cacheKeyResolver, mockStorage);
|
impl.flushCacheEntriesInvalidatedByRequest(host, request, cacheKeyResolver, mockStorage);
|
||||||
|
|
|
@ -41,12 +41,9 @@ public class TestPrefixKeyHashingScheme {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
scheme = new KeyHashingScheme() {
|
scheme = storageKey -> {
|
||||||
@Override
|
assertEquals(KEY, storageKey);
|
||||||
public String hash(final String storageKey) {
|
return "hash";
|
||||||
assertEquals(KEY, storageKey);
|
|
||||||
return "hash";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
impl = new PrefixKeyHashingScheme(PREFIX, scheme);
|
impl = new PrefixKeyHashingScheme(PREFIX, scheme);
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ public class Request {
|
||||||
builder = RequestConfig.custom();
|
builder = RequestConfig.custom();
|
||||||
}
|
}
|
||||||
if (this.useExpectContinue != null) {
|
if (this.useExpectContinue != null) {
|
||||||
builder.setExpectContinueEnabled(this.useExpectContinue);
|
builder.setExpectContinueEnabled(this.useExpectContinue.booleanValue());
|
||||||
}
|
}
|
||||||
if (this.connectTimeout != null) {
|
if (this.connectTimeout != null) {
|
||||||
builder.setConnectTimeout(this.connectTimeout);
|
builder.setConnectTimeout(this.connectTimeout);
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.http.examples.fluent;
|
package org.apache.hc.client5.http.examples.fluent;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
@ -37,11 +36,9 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||||
import org.apache.hc.client5.http.ClientProtocolException;
|
import org.apache.hc.client5.http.ClientProtocolException;
|
||||||
import org.apache.hc.client5.http.HttpResponseException;
|
import org.apache.hc.client5.http.HttpResponseException;
|
||||||
import org.apache.hc.client5.http.fluent.Request;
|
import org.apache.hc.client5.http.fluent.Request;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpEntity;
|
import org.apache.hc.core5.http.HttpEntity;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
@ -53,38 +50,33 @@ public class FluentResponseHandling {
|
||||||
|
|
||||||
public static void main(final String... args)throws Exception {
|
public static void main(final String... args)throws Exception {
|
||||||
final Document result = Request.get("http://somehost/content")
|
final Document result = Request.get("http://somehost/content")
|
||||||
.execute().handleResponse(new HttpClientResponseHandler<Document>() {
|
.execute().handleResponse(response -> {
|
||||||
|
final int status = response.getCode();
|
||||||
@Override
|
final HttpEntity entity = response.getEntity();
|
||||||
public Document handleResponse(final ClassicHttpResponse response) throws IOException {
|
if (status >= HttpStatus.SC_REDIRECTION) {
|
||||||
final int status = response.getCode();
|
throw new HttpResponseException(status, response.getReasonPhrase());
|
||||||
final HttpEntity entity = response.getEntity();
|
|
||||||
if (status >= HttpStatus.SC_REDIRECTION) {
|
|
||||||
throw new HttpResponseException(status, response.getReasonPhrase());
|
|
||||||
}
|
|
||||||
if (entity == null) {
|
|
||||||
throw new ClientProtocolException("Response contains no content");
|
|
||||||
}
|
|
||||||
final DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
|
|
||||||
try {
|
|
||||||
final DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
|
|
||||||
final ContentType contentType = ContentType.parseLenient(entity.getContentType());
|
|
||||||
if (!contentType.equals(ContentType.APPLICATION_XML)) {
|
|
||||||
throw new ClientProtocolException("Unexpected content type:" + contentType);
|
|
||||||
}
|
}
|
||||||
Charset charset = contentType.getCharset();
|
if (entity == null) {
|
||||||
if (charset == null) {
|
throw new ClientProtocolException("Response contains no content");
|
||||||
charset = StandardCharsets.ISO_8859_1;
|
|
||||||
}
|
}
|
||||||
return docBuilder.parse(entity.getContent(), charset.name());
|
final DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
|
||||||
} catch (final ParserConfigurationException ex) {
|
try {
|
||||||
throw new IllegalStateException(ex);
|
final DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
|
||||||
} catch (final SAXException ex) {
|
final ContentType contentType = ContentType.parseLenient(entity.getContentType());
|
||||||
throw new ClientProtocolException("Malformed XML document", ex);
|
if (!contentType.equals(ContentType.APPLICATION_XML)) {
|
||||||
}
|
throw new ClientProtocolException("Unexpected content type:" + contentType);
|
||||||
}
|
}
|
||||||
|
Charset charset = contentType.getCharset();
|
||||||
});
|
if (charset == null) {
|
||||||
|
charset = StandardCharsets.ISO_8859_1;
|
||||||
|
}
|
||||||
|
return docBuilder.parse(entity.getContent(), charset.name());
|
||||||
|
} catch (final ParserConfigurationException ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
} catch (final SAXException ex) {
|
||||||
|
throw new ClientProtocolException("Malformed XML document", ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
// Do something useful with the result
|
// Do something useful with the result
|
||||||
System.out.println(result);
|
System.out.println(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,6 @@ import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
||||||
import org.apache.hc.client5.testing.auth.Authenticator;
|
import org.apache.hc.client5.testing.auth.Authenticator;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
import org.apache.hc.core5.function.Decorator;
|
||||||
import org.apache.hc.core5.function.Supplier;
|
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
import org.apache.hc.core5.http.HttpHeaders;
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
|
@ -89,14 +88,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final HttpHost start() throws Exception {
|
public final HttpHost start() throws Exception {
|
||||||
return start(new Decorator<AsyncServerExchangeHandler>() {
|
return start(requestHandler -> new AuthenticatingAsyncDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")));
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler requestHandler) {
|
|
||||||
return new AuthenticatingAsyncDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm"));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final HttpHost start(
|
public final HttpHost start(
|
||||||
|
@ -150,14 +142,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationNoCreds() throws Exception {
|
public void testBasicAuthenticationNoCreds() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
||||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(null);
|
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(null);
|
||||||
|
@ -179,14 +164,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationFailure() throws Exception {
|
public void testBasicAuthenticationFailure() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
||||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||||
|
@ -209,14 +187,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccess() throws Exception {
|
public void testBasicAuthenticationSuccess() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
||||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||||
|
@ -240,14 +211,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationWithEntitySuccess() throws Exception {
|
public void testBasicAuthenticationWithEntitySuccess() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
||||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||||
|
@ -271,14 +235,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationExpectationFailure() throws Exception {
|
public void testBasicAuthenticationExpectationFailure() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
||||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||||
|
@ -300,14 +257,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationExpectationSuccess() throws Exception {
|
public void testBasicAuthenticationExpectationSuccess() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
||||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||||
|
@ -332,14 +282,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
public void testBasicAuthenticationCredentialsCaching() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final AtomicLong count = new AtomicLong(0);
|
final AtomicLong count = new AtomicLong(0);
|
||||||
setTargetAuthenticationStrategy(new DefaultAuthenticationStrategy() {
|
setTargetAuthenticationStrategy(new DefaultAuthenticationStrategy() {
|
||||||
|
@ -382,14 +325,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationUserinfoInRequestSuccess() throws Exception {
|
public void testAuthenticationUserinfoInRequestSuccess() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
@ -407,14 +343,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationUserinfoInRequestFailure() throws Exception {
|
public void testAuthenticationUserinfoInRequestFailure() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
@ -431,31 +360,17 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationUserinfoInRedirectSuccess() throws Exception {
|
public void testAuthenticationUserinfoInRedirectSuccess() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
server.register("/thatway", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("/thatway", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
protected SimpleHttpResponse handle(
|
||||||
return new AbstractSimpleServerExchangeHandler() {
|
final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
|
||||||
|
final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_MOVED_PERMANENTLY);
|
||||||
@Override
|
response.addHeader(new BasicHeader("Location", target.getSchemeName() + "://test:test@" + target.toHostString() + "/"));
|
||||||
protected SimpleHttpResponse handle(
|
return response;
|
||||||
final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
|
|
||||||
final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_MOVED_PERMANENTLY);
|
|
||||||
response.addHeader(new BasicHeader("Location", target.getSchemeName() + "://test:test@" + target.toHostString() + "/"));
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
@ -473,32 +388,18 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReauthentication() throws Exception {
|
public void testReauthentication() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
|
||||||
new UsernamePasswordCredentials("test", "test".toCharArray()));
|
new UsernamePasswordCredentials("test", "test".toCharArray()));
|
||||||
|
|
||||||
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
||||||
.register("MyBasic", new AuthSchemeFactory() {
|
.register("MyBasic", context -> new BasicScheme() {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthScheme create(final HttpContext context) {
|
public String getName() {
|
||||||
return new BasicScheme() {
|
return "MyBasic";
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "MyBasic";
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -520,19 +421,12 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
};
|
};
|
||||||
|
|
||||||
final HttpHost target = start(
|
final HttpHost target = start(
|
||||||
new Decorator<AsyncServerExchangeHandler>() {
|
exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||||
return new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
|
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
||||||
|
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
||||||
@Override
|
|
||||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
|
||||||
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
|
||||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -558,27 +452,13 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationFallback() throws Exception {
|
public void testAuthenticationFallback() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start(
|
final HttpHost target = start(
|
||||||
new Decorator<AsyncServerExchangeHandler>() {
|
exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||||
return new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
|
||||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -185,19 +185,14 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
|
||||||
final int threadNum = 5;
|
final int threadNum = 5;
|
||||||
final ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
|
final ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
|
||||||
for (int i = 0; i < threadNum; i++) {
|
for (int i = 0; i < threadNum; i++) {
|
||||||
executorService.execute(new Runnable() {
|
executorService.execute(() -> {
|
||||||
|
if (!Thread.currentThread().isInterrupted()) {
|
||||||
@Override
|
httpclient.execute(
|
||||||
public void run() {
|
SimpleRequestBuilder.get()
|
||||||
if (!Thread.currentThread().isInterrupted()) {
|
.setHttpHost(target)
|
||||||
httpclient.execute(
|
.setPath("/random/2048")
|
||||||
SimpleRequestBuilder.get()
|
.build(), callback);
|
||||||
.setHttpHost(target)
|
|
||||||
.setPath("/random/2048")
|
|
||||||
.build(), callback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
@ -46,9 +45,7 @@ import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
import org.apache.hc.client5.testing.redirect.Redirect;
|
import org.apache.hc.client5.testing.redirect.Redirect;
|
||||||
import org.apache.hc.client5.testing.redirect.RedirectResolver;
|
|
||||||
import org.apache.hc.core5.function.Decorator;
|
import org.apache.hc.core5.function.Decorator;
|
||||||
import org.apache.hc.core5.function.Supplier;
|
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
|
@ -100,16 +97,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300() throws Exception {
|
public void testBasicRedirect300() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)));
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
|
@ -128,16 +118,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301() throws Exception {
|
public void testBasicRedirect301() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)));
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
|
@ -156,16 +139,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302() throws Exception {
|
public void testBasicRedirect302() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
|
@ -184,27 +160,15 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302NoLocation() throws Exception {
|
public void testBasicRedirect302NoLocation() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
requestUri -> {
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
final String path = requestUri.getPath();
|
||||||
return new RedirectingAsyncDecorator(
|
if (path.startsWith("/oldlocation")) {
|
||||||
exchangeHandler,
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
|
||||||
new RedirectResolver() {
|
}
|
||||||
|
return null;
|
||||||
@Override
|
}));
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
|
||||||
final String path = requestUri.getPath();
|
|
||||||
if (path.startsWith("/oldlocation")) {
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
|
@ -222,16 +186,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect303() throws Exception {
|
public void testBasicRedirect303() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)));
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
|
@ -250,20 +207,12 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect304() throws Exception {
|
public void testBasicRedirect304() throws Exception {
|
||||||
server.register("/oldlocation/*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
protected SimpleHttpResponse handle(final SimpleHttpRequest request,
|
||||||
|
final HttpCoreContext context) throws HttpException {
|
||||||
return new AbstractSimpleServerExchangeHandler() {
|
return SimpleHttpResponse.create(HttpStatus.SC_NOT_MODIFIED, (String) null);
|
||||||
|
|
||||||
@Override
|
|
||||||
protected SimpleHttpResponse handle(final SimpleHttpRequest request,
|
|
||||||
final HttpCoreContext context) throws HttpException {
|
|
||||||
return SimpleHttpResponse.create(HttpStatus.SC_NOT_MODIFIED, (String) null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
@ -284,20 +233,12 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect305() throws Exception {
|
public void testBasicRedirect305() throws Exception {
|
||||||
server.register("/oldlocation/*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
protected SimpleHttpResponse handle(final SimpleHttpRequest request,
|
||||||
|
final HttpCoreContext context) throws HttpException {
|
||||||
return new AbstractSimpleServerExchangeHandler() {
|
return SimpleHttpResponse.create(HttpStatus.SC_USE_PROXY, (String) null);
|
||||||
|
|
||||||
@Override
|
|
||||||
protected SimpleHttpResponse handle(final SimpleHttpRequest request,
|
|
||||||
final HttpCoreContext context) throws HttpException {
|
|
||||||
return SimpleHttpResponse.create(HttpStatus.SC_USE_PROXY, (String) null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
@ -318,16 +259,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect307() throws Exception {
|
public void testBasicRedirect307() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
SimpleRequestBuilder.get()
|
SimpleRequestBuilder.get()
|
||||||
|
@ -346,17 +280,10 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test(expected=ExecutionException.class)
|
@Test(expected=ExecutionException.class)
|
||||||
public void testMaxRedirectCheck() throws Exception {
|
public void testMaxRedirectCheck() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(true)
|
.setCircularRedirectsAllowed(true)
|
||||||
|
@ -376,17 +303,10 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test(expected=ExecutionException.class)
|
@Test(expected=ExecutionException.class)
|
||||||
public void testCircularRedirect() throws Exception {
|
public void testCircularRedirect() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(false)
|
.setCircularRedirectsAllowed(false)
|
||||||
|
@ -407,16 +327,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRedirect() throws Exception {
|
public void testPostRedirect() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_TEMPORARY_REDIRECT));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
|
@ -437,16 +350,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRedirectSeeOther() throws Exception {
|
public void testPostRedirectSeeOther() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)));
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
|
@ -467,28 +373,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect() throws Exception {
|
public void testRelativeRedirect() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
requestUri -> {
|
||||||
|
final String path = requestUri.getPath();
|
||||||
|
if (path.startsWith("/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
return null;
|
||||||
return new RedirectingAsyncDecorator(
|
}));
|
||||||
exchangeHandler,
|
|
||||||
new RedirectResolver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
|
||||||
final String path = requestUri.getPath();
|
|
||||||
if (path.startsWith("/oldlocation")) {
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -509,28 +403,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect2() throws Exception {
|
public void testRelativeRedirect2() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
requestUri -> {
|
||||||
|
final String path = requestUri.getPath();
|
||||||
|
if (path.equals("/random/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
return null;
|
||||||
return new RedirectingAsyncDecorator(
|
}));
|
||||||
exchangeHandler,
|
|
||||||
new RedirectResolver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
|
||||||
final String path = requestUri.getPath();
|
|
||||||
if (path.equals("/random/oldlocation")) {
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -551,28 +433,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test(expected=ExecutionException.class)
|
@Test(expected=ExecutionException.class)
|
||||||
public void testRejectBogusRedirectLocation() throws Exception {
|
public void testRejectBogusRedirectLocation() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
requestUri -> {
|
||||||
|
final String path = requestUri.getPath();
|
||||||
|
if (path.equals("/oldlocation/")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
return null;
|
||||||
return new RedirectingAsyncDecorator(
|
}));
|
||||||
exchangeHandler,
|
|
||||||
new RedirectResolver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
|
||||||
final String path = requestUri.getPath();
|
|
||||||
if (path.equals("/oldlocation/")) {
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
|
@ -589,28 +459,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test(expected=ExecutionException.class)
|
@Test(expected=ExecutionException.class)
|
||||||
public void testRejectInvalidRedirectLocation() throws Exception {
|
public void testRejectInvalidRedirectLocation() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
|
requestUri -> {
|
||||||
|
final String path = requestUri.getPath();
|
||||||
|
if (path.equals("/oldlocation/")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
return null;
|
||||||
return new RedirectingAsyncDecorator(
|
}));
|
||||||
exchangeHandler,
|
|
||||||
new RedirectResolver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
|
||||||
final String path = requestUri.getPath();
|
|
||||||
if (path.equals("/oldlocation/")) {
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
|
@ -627,16 +485,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRedirectWithCookie() throws Exception {
|
public void testRedirectWithCookie() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final CookieStore cookieStore = new BasicCookieStore();
|
final CookieStore cookieStore = new BasicCookieStore();
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
@ -670,17 +521,12 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
final H2TestServer secondServer = new H2TestServer(IOReactorConfig.DEFAULT,
|
final H2TestServer secondServer = new H2TestServer(IOReactorConfig.DEFAULT,
|
||||||
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
|
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
|
||||||
try {
|
try {
|
||||||
secondServer.register("/random/*", new Supplier<AsyncServerExchangeHandler>() {
|
secondServer.register("/random/*", () -> {
|
||||||
|
if (isReactive()) {
|
||||||
@Override
|
return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
|
||||||
public AsyncServerExchangeHandler get() {
|
} else {
|
||||||
if (isReactive()) {
|
return new AsyncRandomHandler();
|
||||||
return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
|
|
||||||
} else {
|
|
||||||
return new AsyncRandomHandler();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
final InetSocketAddress address2;
|
final InetSocketAddress address2;
|
||||||
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
if (version.greaterEquals(HttpVersion.HTTP_2)) {
|
||||||
|
@ -690,31 +536,19 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
|
||||||
}
|
}
|
||||||
final HttpHost redirectTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
|
final HttpHost redirectTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
|
||||||
|
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
requestUri -> {
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
final String path = requestUri.getPath();
|
||||||
return new RedirectingAsyncDecorator(
|
if (path.equals("/oldlocation")) {
|
||||||
exchangeHandler,
|
final URI location = new URIBuilder(requestUri)
|
||||||
new RedirectResolver() {
|
.setHttpHost(redirectTarget)
|
||||||
|
.setPath("/random/100")
|
||||||
@Override
|
.build();
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
return new Redirect(HttpStatus.SC_MOVED_PERMANENTLY, location.toString());
|
||||||
final String path = requestUri.getPath();
|
}
|
||||||
if (path.equals("/oldlocation")) {
|
return null;
|
||||||
final URI location = new URIBuilder(requestUri)
|
}));
|
||||||
.setHttpHost(redirectTarget)
|
|
||||||
.setPath("/random/100")
|
|
||||||
.build();
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_PERMANENTLY, location.toString());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(
|
final Future<SimpleHttpResponse> future = httpclient.execute(
|
||||||
|
|
|
@ -67,7 +67,6 @@ import org.junit.Test;
|
||||||
import org.reactivestreams.Publisher;
|
import org.reactivestreams.Publisher;
|
||||||
|
|
||||||
import io.reactivex.Flowable;
|
import io.reactivex.Flowable;
|
||||||
import io.reactivex.functions.Consumer;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
|
||||||
public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase<T> {
|
public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase<T> {
|
||||||
|
@ -163,12 +162,7 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
final Flowable<ByteBuffer> flowable = Flowable.fromPublisher(result.getBody())
|
final Flowable<ByteBuffer> flowable = Flowable.fromPublisher(result.getBody())
|
||||||
.observeOn(Schedulers.io()); // Stream the data on an RxJava scheduler, not a client thread
|
.observeOn(Schedulers.io()); // Stream the data on an RxJava scheduler, not a client thread
|
||||||
ReactiveTestUtils.consumeStream(flowable)
|
ReactiveTestUtils.consumeStream(flowable)
|
||||||
.subscribe(new Consumer<StreamDescription>() {
|
.subscribe(responses::add);
|
||||||
@Override
|
|
||||||
public void accept(final StreamDescription streamDescription) {
|
|
||||||
responses.add(streamDescription);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void failed(final Exception ex) { }
|
public void failed(final Exception ex) { }
|
||||||
|
@ -227,13 +221,10 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
|
||||||
final int threadNum = 5;
|
final int threadNum = 5;
|
||||||
final ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
|
final ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
|
||||||
for (int i = 0; i < threadNum; i++) {
|
for (int i = 0; i < threadNum; i++) {
|
||||||
executorService.execute(new Runnable() {
|
executorService.execute(() -> {
|
||||||
@Override
|
if (!Thread.currentThread().isInterrupted()) {
|
||||||
public void run() {
|
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer(callback);
|
||||||
if (!Thread.currentThread().isInterrupted()) {
|
httpclient.execute(AsyncRequestBuilder.get(target + "/random/2048").build(), consumer, null);
|
||||||
final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer(callback);
|
|
||||||
httpclient.execute(AsyncRequestBuilder.get(target + "/random/2048").build(), consumer, null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,7 @@
|
||||||
package org.apache.hc.client5.testing.async;
|
package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
import org.apache.hc.core5.function.Supplier;
|
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
|
import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
import org.apache.hc.core5.testing.nio.H2TestServer;
|
import org.apache.hc.core5.testing.nio.H2TestServer;
|
||||||
|
@ -68,29 +66,19 @@ public abstract class AbstractServerTestBase {
|
||||||
.setSoTimeout(TIMEOUT)
|
.setSoTimeout(TIMEOUT)
|
||||||
.build(),
|
.build(),
|
||||||
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
|
scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
|
||||||
server.register("/echo/*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("/echo/*", () -> {
|
||||||
|
if (isReactive()) {
|
||||||
@Override
|
return new ReactiveServerExchangeHandler(new ReactiveEchoProcessor());
|
||||||
public AsyncServerExchangeHandler get() {
|
} else {
|
||||||
if (isReactive()) {
|
return new AsyncEchoHandler();
|
||||||
return new ReactiveServerExchangeHandler(new ReactiveEchoProcessor());
|
|
||||||
} else {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
server.register("/random/*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("/random/*", () -> {
|
||||||
|
if (isReactive()) {
|
||||||
@Override
|
return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
|
||||||
public AsyncServerExchangeHandler get() {
|
} else {
|
||||||
if (isReactive()) {
|
return new AsyncRandomHandler();
|
||||||
return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
|
|
||||||
} else {
|
|
||||||
return new AsyncRandomHandler();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
import org.apache.hc.client5.testing.redirect.Redirect;
|
import org.apache.hc.client5.testing.redirect.Redirect;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpHeaders;
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
@ -54,7 +53,6 @@ import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.HttpVersion;
|
import org.apache.hc.core5.http.HttpVersion;
|
||||||
import org.apache.hc.core5.http.URIScheme;
|
import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.message.BasicHeader;
|
import org.apache.hc.core5.http.message.BasicHeader;
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -125,17 +123,10 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
Redirect.ConnControl.CLOSE)));
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
|
||||||
Redirect.ConnControl.CLOSE));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
|
@ -152,17 +143,10 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301NoKeepAlive() throws Exception {
|
public void testBasicRedirect301NoKeepAlive() throws Exception {
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
Redirect.ConnControl.CLOSE)));
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
|
||||||
Redirect.ConnControl.CLOSE));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
|
||||||
.setHttpHost(target)
|
.setHttpHost(target)
|
||||||
|
@ -184,17 +168,10 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
|
||||||
defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
|
defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
|
||||||
clientBuilder.setDefaultHeaders(defaultHeaders);
|
clientBuilder.setDefaultHeaders(defaultHeaders);
|
||||||
|
|
||||||
final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
|
final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
|
||||||
|
exchangeHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
Redirect.ConnControl.CLOSE)));
|
||||||
return new RedirectingAsyncDecorator(
|
|
||||||
exchangeHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
|
|
||||||
Redirect.ConnControl.CLOSE));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ package org.apache.hc.client5.testing.async;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.HttpRoute;
|
|
||||||
import org.apache.hc.client5.http.UserTokenHandler;
|
import org.apache.hc.client5.http.UserTokenHandler;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
|
@ -41,7 +40,6 @@ import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBu
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
import org.apache.hc.core5.function.Supplier;
|
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.EndpointDetails;
|
import org.apache.hc.core5.http.EndpointDetails;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
|
@ -49,7 +47,6 @@ import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
import org.apache.hc.core5.http.protocol.HttpCoreContext;
|
||||||
|
@ -111,33 +108,19 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStatefulConnections() throws Exception {
|
public void testStatefulConnections() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
protected SimpleHttpResponse handle(
|
||||||
return new AbstractSimpleServerExchangeHandler() {
|
final SimpleHttpRequest request,
|
||||||
|
final HttpCoreContext context) throws HttpException {
|
||||||
@Override
|
final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
|
||||||
protected SimpleHttpResponse handle(
|
response.setBody("Whatever", ContentType.TEXT_PLAIN);
|
||||||
final SimpleHttpRequest request,
|
return response;
|
||||||
final HttpCoreContext context) throws HttpException {
|
|
||||||
final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
|
|
||||||
response.setBody("Whatever", ContentType.TEXT_PLAIN);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final UserTokenHandler userTokenHandler = new UserTokenHandler() {
|
final UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getUserToken(final HttpRoute route, final HttpContext context) {
|
|
||||||
return context.getAttribute("user");
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
clientBuilder.setUserTokenHandler(userTokenHandler);
|
clientBuilder.setUserTokenHandler(userTokenHandler);
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
||||||
|
@ -239,36 +222,22 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRouteSpecificPoolRecylcing() throws Exception {
|
public void testRouteSpecificPoolRecylcing() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", () -> new AbstractSimpleServerExchangeHandler() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler get() {
|
protected SimpleHttpResponse handle(
|
||||||
return new AbstractSimpleServerExchangeHandler() {
|
final SimpleHttpRequest request,
|
||||||
|
final HttpCoreContext context) throws HttpException {
|
||||||
@Override
|
final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
|
||||||
protected SimpleHttpResponse handle(
|
response.setBody("Whatever", ContentType.TEXT_PLAIN);
|
||||||
final SimpleHttpRequest request,
|
return response;
|
||||||
final HttpCoreContext context) throws HttpException {
|
|
||||||
final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
|
|
||||||
response.setBody("Whatever", ContentType.TEXT_PLAIN);
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// This tests what happens when a maxed connection pool needs
|
// This tests what happens when a maxed connection pool needs
|
||||||
// to kill the last idle connection to a route to build a new
|
// to kill the last idle connection to a route to build a new
|
||||||
// one to the same route.
|
// one to the same route.
|
||||||
final UserTokenHandler userTokenHandler = new UserTokenHandler() {
|
final UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getUserToken(final HttpRoute route, final HttpContext context) {
|
|
||||||
return context.getAttribute("user");
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
clientBuilder.setUserTokenHandler(userTokenHandler);
|
clientBuilder.setUserTokenHandler(userTokenHandler);
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
|
@ -46,8 +46,6 @@ import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
|
||||||
import org.apache.hc.core5.function.Supplier;
|
|
||||||
import org.apache.hc.core5.http.HeaderElements;
|
import org.apache.hc.core5.http.HeaderElements;
|
||||||
import org.apache.hc.core5.http.HttpHeaders;
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
@ -58,7 +56,6 @@ import org.apache.hc.core5.http.URIScheme;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
import org.apache.hc.core5.http.config.Lookup;
|
import org.apache.hc.core5.http.config.Lookup;
|
||||||
import org.apache.hc.core5.http.impl.HttpProcessors;
|
import org.apache.hc.core5.http.impl.HttpProcessors;
|
||||||
import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -136,29 +133,15 @@ public class TestHttp1ClientAuthentication extends AbstractHttpAsyncClientAuthen
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicAuthenticationSuccessNonPersistentConnection() throws Exception {
|
public void testBasicAuthenticationSuccessNonPersistentConnection() throws Exception {
|
||||||
server.register("*", new Supplier<AsyncServerExchangeHandler>() {
|
server.register("*", AsyncEchoHandler::new);
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncServerExchangeHandler get() {
|
|
||||||
return new AsyncEchoHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpHost target = start(
|
final HttpHost target = start(
|
||||||
HttpProcessors.server(),
|
HttpProcessors.server(),
|
||||||
new Decorator<AsyncServerExchangeHandler>() {
|
exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
|
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
||||||
return new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
|
|
||||||
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
Http1Config.DEFAULT);
|
Http1Config.DEFAULT);
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
package org.apache.hc.client5.testing.fluent;
|
package org.apache.hc.client5.testing.fluent;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
@ -35,17 +34,11 @@ import org.apache.hc.client5.http.ClientProtocolException;
|
||||||
import org.apache.hc.client5.http.fluent.Content;
|
import org.apache.hc.client5.http.fluent.Content;
|
||||||
import org.apache.hc.client5.http.fluent.Request;
|
import org.apache.hc.client5.http.fluent.Request;
|
||||||
import org.apache.hc.client5.testing.sync.LocalServerTestBase;
|
import org.apache.hc.client5.testing.sync.LocalServerTestBase;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpEntity;
|
import org.apache.hc.core5.http.HttpEntity;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
|
||||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -54,40 +47,22 @@ public class TestFluent extends LocalServerTestBase {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
this.server.registerHandler("/", new HttpRequestHandler() {
|
this.server.registerHandler("/", (request, response, context) -> response.setEntity(new StringEntity("All is well", ContentType.TEXT_PLAIN)));
|
||||||
|
this.server.registerHandler("/echo", (request, response, context) -> {
|
||||||
@Override
|
HttpEntity responseEntity = null;
|
||||||
public void handle(
|
final HttpEntity requestEntity = request.getEntity();
|
||||||
final ClassicHttpRequest request,
|
if (requestEntity != null) {
|
||||||
final ClassicHttpResponse response,
|
final String contentTypeStr = requestEntity.getContentType();
|
||||||
final HttpContext context) throws HttpException, IOException {
|
final ContentType contentType = contentTypeStr == null ? ContentType.DEFAULT_TEXT : ContentType.parse(contentTypeStr);
|
||||||
response.setEntity(new StringEntity("All is well", ContentType.TEXT_PLAIN));
|
if (ContentType.TEXT_PLAIN.getMimeType().equals(contentType.getMimeType())) {
|
||||||
}
|
responseEntity = new StringEntity(
|
||||||
|
EntityUtils.toString(requestEntity), ContentType.TEXT_PLAIN);
|
||||||
});
|
|
||||||
this.server.registerHandler("/echo", new HttpRequestHandler() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(
|
|
||||||
final ClassicHttpRequest request,
|
|
||||||
final ClassicHttpResponse response,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
HttpEntity responseEntity = null;
|
|
||||||
final HttpEntity requestEntity = request.getEntity();
|
|
||||||
if (requestEntity != null) {
|
|
||||||
final String contentTypeStr = requestEntity.getContentType();
|
|
||||||
final ContentType contentType = contentTypeStr == null ? ContentType.DEFAULT_TEXT : ContentType.parse(contentTypeStr);
|
|
||||||
if (ContentType.TEXT_PLAIN.getMimeType().equals(contentType.getMimeType())) {
|
|
||||||
responseEntity = new StringEntity(
|
|
||||||
EntityUtils.toString(requestEntity), ContentType.TEXT_PLAIN);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (responseEntity == null) {
|
|
||||||
responseEntity = new StringEntity("echo", ContentType.TEXT_PLAIN);
|
|
||||||
}
|
|
||||||
response.setEntity(responseEntity);
|
|
||||||
}
|
}
|
||||||
|
if (responseEntity == null) {
|
||||||
|
responseEntity = new StringEntity("echo", ContentType.TEXT_PLAIN);
|
||||||
|
}
|
||||||
|
response.setEntity(responseEntity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,15 +130,7 @@ public class TestFluent extends LocalServerTestBase {
|
||||||
Request.get(baseURL + "/").execute().returnContent();
|
Request.get(baseURL + "/").execute().returnContent();
|
||||||
Request.get(baseURL + "/").execute().returnResponse();
|
Request.get(baseURL + "/").execute().returnResponse();
|
||||||
Request.get(baseURL + "/").execute().discardContent();
|
Request.get(baseURL + "/").execute().discardContent();
|
||||||
Request.get(baseURL + "/").execute().handleResponse(new HttpClientResponseHandler<Object>() {
|
Request.get(baseURL + "/").execute().handleResponse(response -> null);
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object handleResponse(
|
|
||||||
final ClassicHttpResponse response) throws IOException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final File tmpFile = File.createTempFile("test", ".bin");
|
final File tmpFile = File.createTempFile("test", ".bin");
|
||||||
try {
|
try {
|
||||||
Request.get(baseURL + "/").execute().saveContent(tmpFile);
|
Request.get(baseURL + "/").execute().saveContent(tmpFile);
|
||||||
|
|
|
@ -39,11 +39,11 @@ import org.apache.hc.client5.http.auth.AuthCache;
|
||||||
import org.apache.hc.client5.http.auth.AuthChallenge;
|
import org.apache.hc.client5.http.auth.AuthChallenge;
|
||||||
import org.apache.hc.client5.http.auth.AuthScheme;
|
import org.apache.hc.client5.http.auth.AuthScheme;
|
||||||
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
|
||||||
import org.apache.hc.client5.http.auth.AuthScope;
|
import org.apache.hc.client5.http.auth.AuthScope;
|
||||||
import org.apache.hc.client5.http.auth.ChallengeType;
|
import org.apache.hc.client5.http.auth.ChallengeType;
|
||||||
import org.apache.hc.client5.http.auth.Credentials;
|
import org.apache.hc.client5.http.auth.Credentials;
|
||||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||||
|
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||||
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
|
@ -60,7 +60,6 @@ import org.apache.hc.client5.testing.BasicTestAuthenticator;
|
||||||
import org.apache.hc.client5.testing.auth.Authenticator;
|
import org.apache.hc.client5.testing.auth.Authenticator;
|
||||||
import org.apache.hc.client5.testing.classic.AuthenticatingDecorator;
|
import org.apache.hc.client5.testing.classic.AuthenticatingDecorator;
|
||||||
import org.apache.hc.client5.testing.classic.EchoHandler;
|
import org.apache.hc.client5.testing.classic.EchoHandler;
|
||||||
import org.apache.hc.core5.function.Decorator;
|
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.EndpointDetails;
|
import org.apache.hc.core5.http.EndpointDetails;
|
||||||
|
@ -74,7 +73,6 @@ import org.apache.hc.core5.http.config.Registry;
|
||||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||||
import org.apache.hc.core5.http.impl.HttpProcessors;
|
import org.apache.hc.core5.http.impl.HttpProcessors;
|
||||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
||||||
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
|
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.io.entity.InputStreamEntity;
|
import org.apache.hc.core5.http.io.entity.InputStreamEntity;
|
||||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
|
@ -91,14 +89,7 @@ import org.junit.Test;
|
||||||
public class TestClientAuthentication extends LocalServerTestBase {
|
public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
public HttpHost start(final Authenticator authenticator) throws IOException {
|
public HttpHost start(final Authenticator authenticator) throws IOException {
|
||||||
return super.start(null, new Decorator<HttpServerRequestHandler>() {
|
return super.start(null, requestHandler -> new AuthenticatingDecorator(requestHandler, authenticator));
|
||||||
|
|
||||||
@Override
|
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
|
||||||
return new AuthenticatingDecorator(requestHandler, authenticator);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -444,20 +435,12 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticationUserinfoInRedirectSuccess() throws Exception {
|
public void testAuthenticationUserinfoInRedirectSuccess() throws Exception {
|
||||||
this.server.registerHandler("/*", new EchoHandler());
|
this.server.registerHandler("/*", new EchoHandler());
|
||||||
this.server.registerHandler("/thatway", new HttpRequestHandler() {
|
this.server.registerHandler("/thatway", (request, response, context) -> {
|
||||||
|
final EndpointDetails endpoint = (EndpointDetails) context.getAttribute(HttpCoreContext.CONNECTION_ENDPOINT);
|
||||||
@Override
|
final InetSocketAddress socketAddress = (InetSocketAddress) endpoint.getLocalAddress();
|
||||||
public void handle(
|
final int port = socketAddress.getPort();
|
||||||
final ClassicHttpRequest request,
|
response.setCode(HttpStatus.SC_MOVED_PERMANENTLY);
|
||||||
final ClassicHttpResponse response,
|
response.addHeader(new BasicHeader("Location", "http://test:test@localhost:" + port + "/secure"));
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
final EndpointDetails endpoint = (EndpointDetails) context.getAttribute(HttpCoreContext.CONNECTION_ENDPOINT);
|
|
||||||
final InetSocketAddress socketAddress = (InetSocketAddress) endpoint.getLocalAddress();
|
|
||||||
final int port = socketAddress.getPort();
|
|
||||||
response.setCode(HttpStatus.SC_MOVED_PERMANENTLY);
|
|
||||||
response.addHeader(new BasicHeader("Location", "http://test:test@localhost:" + port + "/secure"));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final HttpHost target = start(new BasicTestAuthenticator("test:test", "test realm") {
|
final HttpHost target = start(new BasicTestAuthenticator("test:test", "test realm") {
|
||||||
|
@ -594,18 +577,11 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
final HttpHost target = start(
|
final HttpHost target = start(
|
||||||
HttpProcessors.server(),
|
HttpProcessors.server(),
|
||||||
new Decorator<HttpServerRequestHandler>() {
|
requestHandler -> new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
||||||
return new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
|
||||||
unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -676,19 +652,12 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
final HttpHost target = start(
|
final HttpHost target = start(
|
||||||
HttpProcessors.server(),
|
HttpProcessors.server(),
|
||||||
new Decorator<HttpServerRequestHandler>() {
|
requestHandler -> new AuthenticatingDecorator(requestHandler, authenticator) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
||||||
return new AuthenticatingDecorator(requestHandler, authenticator) {
|
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
||||||
|
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
||||||
@Override
|
|
||||||
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
|
||||||
unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
|
|
||||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -712,18 +681,11 @@ public class TestClientAuthentication extends LocalServerTestBase {
|
||||||
|
|
||||||
final HttpHost target = start(
|
final HttpHost target = start(
|
||||||
HttpProcessors.server(),
|
HttpProcessors.server(),
|
||||||
new Decorator<HttpServerRequestHandler>() {
|
requestHandler -> new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
||||||
return new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
|
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
|
|
||||||
unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,7 +38,6 @@ import org.apache.hc.client5.http.protocol.RedirectLocations;
|
||||||
import org.apache.hc.client5.http.utils.URIUtils;
|
import org.apache.hc.client5.http.utils.URIUtils;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.EntityDetails;
|
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
@ -112,17 +111,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
|
||||||
public void testAutoGeneratedHeaders() throws Exception {
|
public void testAutoGeneratedHeaders() throws Exception {
|
||||||
this.server.registerHandler("*", new SimpleService());
|
this.server.registerHandler("*", new SimpleService());
|
||||||
|
|
||||||
final HttpRequestInterceptor interceptor = new HttpRequestInterceptor() {
|
final HttpRequestInterceptor interceptor = (request, entityDetails, context) -> request.addHeader("my-header", "stuff");
|
||||||
|
|
||||||
@Override
|
|
||||||
public void process(
|
|
||||||
final HttpRequest request,
|
|
||||||
final EntityDetails entityDetails,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
request.addHeader("my-header", "stuff");
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
final HttpRequestRetryStrategy requestRetryStrategy = new HttpRequestRetryStrategy() {
|
final HttpRequestRetryStrategy requestRetryStrategy = new HttpRequestRetryStrategy() {
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.sync;
|
package org.apache.hc.client5.testing.sync;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -36,15 +35,10 @@ import org.apache.hc.client5.http.cookie.Cookie;
|
||||||
import org.apache.hc.client5.http.cookie.CookieStore;
|
import org.apache.hc.client5.http.cookie.CookieStore;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
|
||||||
import org.apache.hc.core5.http.HttpException;
|
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.message.BasicHeader;
|
import org.apache.hc.core5.http.message.BasicHeader;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -55,51 +49,44 @@ public class TestCookieVirtualHost extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCookieMatchingWithVirtualHosts() throws Exception {
|
public void testCookieMatchingWithVirtualHosts() throws Exception {
|
||||||
this.server.registerHandlerVirtual("app.mydomain.fr", "*", new HttpRequestHandler() {
|
this.server.registerHandlerVirtual("app.mydomain.fr", "*", (request, response, context) -> {
|
||||||
@Override
|
|
||||||
public void handle(
|
|
||||||
final ClassicHttpRequest request,
|
|
||||||
final ClassicHttpResponse response,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
|
|
||||||
final int n = Integer.parseInt(request.getFirstHeader("X-Request").getValue());
|
final int n = Integer.parseInt(request.getFirstHeader("X-Request").getValue());
|
||||||
switch (n) {
|
switch (n) {
|
||||||
case 1:
|
case 1:
|
||||||
// Assert Host is forwarded from URI
|
// Assert Host is forwarded from URI
|
||||||
Assert.assertEquals("app.mydomain.fr", request
|
Assert.assertEquals("app.mydomain.fr", request
|
||||||
.getFirstHeader("Host").getValue());
|
.getFirstHeader("Host").getValue());
|
||||||
|
|
||||||
response.setCode(HttpStatus.SC_OK);
|
response.setCode(HttpStatus.SC_OK);
|
||||||
// Respond with Set-Cookie on virtual host domain. This
|
// Respond with Set-Cookie on virtual host domain. This
|
||||||
// should be valid.
|
// should be valid.
|
||||||
response.addHeader(new BasicHeader("Set-Cookie",
|
response.addHeader(new BasicHeader("Set-Cookie",
|
||||||
"name1=value1; domain=mydomain.fr; path=/"));
|
"name1=value1; domain=mydomain.fr; path=/"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
// Assert Host is still forwarded from URI
|
// Assert Host is still forwarded from URI
|
||||||
Assert.assertEquals("app.mydomain.fr", request
|
Assert.assertEquals("app.mydomain.fr", request
|
||||||
.getFirstHeader("Host").getValue());
|
.getFirstHeader("Host").getValue());
|
||||||
|
|
||||||
// We should get our cookie back.
|
// We should get our cookie back.
|
||||||
Assert.assertNotNull("We must get a cookie header",
|
Assert.assertNotNull("We must get a cookie header",
|
||||||
request.getFirstHeader("Cookie"));
|
request.getFirstHeader("Cookie"));
|
||||||
response.setCode(HttpStatus.SC_OK);
|
response.setCode(HttpStatus.SC_OK);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
// Assert Host is forwarded from URI
|
// Assert Host is forwarded from URI
|
||||||
Assert.assertEquals("app.mydomain.fr", request
|
Assert.assertEquals("app.mydomain.fr", request
|
||||||
.getFirstHeader("Host").getValue());
|
.getFirstHeader("Host").getValue());
|
||||||
|
|
||||||
response.setCode(HttpStatus.SC_OK);
|
response.setCode(HttpStatus.SC_OK);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Assert.fail("Unexpected value: " + n);
|
Assert.fail("Unexpected value: " + n);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
|
|
@ -33,7 +33,6 @@ import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
|
@ -43,10 +42,8 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
|
||||||
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
||||||
import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
|
import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
|
||||||
import org.apache.hc.core5.http.io.HttpConnectionFactory;
|
import org.apache.hc.core5.http.io.HttpConnectionFactory;
|
||||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -91,28 +88,10 @@ public class TestMalformedServerResponse {
|
||||||
public void testNoContentResponseWithGarbage() throws Exception {
|
public void testNoContentResponseWithGarbage() throws Exception {
|
||||||
try (final HttpServer server = ServerBootstrap.bootstrap()
|
try (final HttpServer server = ServerBootstrap.bootstrap()
|
||||||
.setConnectionFactory(new BrokenServerConnectionFactory())
|
.setConnectionFactory(new BrokenServerConnectionFactory())
|
||||||
.register("/nostuff", new HttpRequestHandler() {
|
.register("/nostuff", (request, response, context) -> response.setCode(HttpStatus.SC_NO_CONTENT))
|
||||||
|
.register("/stuff", (request, response, context) -> {
|
||||||
@Override
|
response.setCode(HttpStatus.SC_OK);
|
||||||
public void handle(
|
response.setEntity(new StringEntity("Some important stuff"));
|
||||||
final ClassicHttpRequest request,
|
|
||||||
final ClassicHttpResponse response,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
response.setCode(HttpStatus.SC_NO_CONTENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.register("/stuff", new HttpRequestHandler() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handle(
|
|
||||||
final ClassicHttpRequest request,
|
|
||||||
final ClassicHttpResponse response,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
response.setCode(HttpStatus.SC_OK);
|
|
||||||
response.setEntity(new StringEntity("Some important stuff"));
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.create()) {
|
.create()) {
|
||||||
server.start();
|
server.start();
|
||||||
|
|
|
@ -28,7 +28,6 @@ package org.apache.hc.client5.testing.sync;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
@ -47,7 +46,6 @@ import org.apache.hc.client5.http.protocol.RedirectLocations;
|
||||||
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
import org.apache.hc.client5.testing.OldPathRedirectResolver;
|
||||||
import org.apache.hc.client5.testing.classic.RedirectingDecorator;
|
import org.apache.hc.client5.testing.classic.RedirectingDecorator;
|
||||||
import org.apache.hc.client5.testing.redirect.Redirect;
|
import org.apache.hc.client5.testing.redirect.Redirect;
|
||||||
import org.apache.hc.client5.testing.redirect.RedirectResolver;
|
|
||||||
import org.apache.hc.core5.function.Decorator;
|
import org.apache.hc.core5.function.Decorator;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
|
@ -58,7 +56,6 @@ import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
import org.apache.hc.core5.http.HttpRequest;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.ProtocolException;
|
import org.apache.hc.core5.http.ProtocolException;
|
||||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
|
||||||
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
|
import org.apache.hc.core5.http.io.HttpServerRequestHandler;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
|
@ -76,16 +73,9 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300() throws Exception {
|
public void testBasicRedirect300() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)));
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
||||||
|
@ -106,17 +96,10 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
public void testBasicRedirect300NoKeepAlive() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
Redirect.ConnControl.CLOSE)));
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
|
|
||||||
Redirect.ConnControl.CLOSE));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
final HttpGet httpget = new HttpGet("/oldlocation/100");
|
||||||
|
@ -137,16 +120,9 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect301() throws Exception {
|
public void testBasicRedirect301() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)));
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -172,16 +148,9 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302() throws Exception {
|
public void testBasicRedirect302() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -200,27 +169,15 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect302NoLocation() throws Exception {
|
public void testBasicRedirect302NoLocation() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
requestUri -> {
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
final String path = requestUri.getPath();
|
||||||
return new RedirectingDecorator(
|
if (path.startsWith("/oldlocation")) {
|
||||||
requestHandler,
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
|
||||||
new RedirectResolver() {
|
}
|
||||||
|
return null;
|
||||||
@Override
|
}));
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
|
||||||
final String path = requestUri.getPath();
|
|
||||||
if (path.startsWith("/oldlocation")) {
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -238,16 +195,9 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect303() throws Exception {
|
public void testBasicRedirect303() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)));
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -266,16 +216,9 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect304() throws Exception {
|
public void testBasicRedirect304() throws Exception {
|
||||||
this.server.registerHandler("/oldlocation/*", new HttpRequestHandler() {
|
this.server.registerHandler("/oldlocation/*", (request, response, context) -> {
|
||||||
|
response.setCode(HttpStatus.SC_NOT_MODIFIED);
|
||||||
@Override
|
response.addHeader(HttpHeaders.LOCATION, "/random/100");
|
||||||
public void handle(final ClassicHttpRequest request,
|
|
||||||
final ClassicHttpResponse response,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
response.setCode(HttpStatus.SC_NOT_MODIFIED);
|
|
||||||
response.addHeader(HttpHeaders.LOCATION, "/random/100");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
@ -301,16 +244,9 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect305() throws Exception {
|
public void testBasicRedirect305() throws Exception {
|
||||||
this.server.registerHandler("/oldlocation/*", new HttpRequestHandler() {
|
this.server.registerHandler("/oldlocation/*", (request, response, context) -> {
|
||||||
|
response.setCode(HttpStatus.SC_USE_PROXY);
|
||||||
@Override
|
response.addHeader(HttpHeaders.LOCATION, "/random/100");
|
||||||
public void handle(final ClassicHttpRequest request,
|
|
||||||
final ClassicHttpResponse response,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
response.setCode(HttpStatus.SC_USE_PROXY);
|
|
||||||
response.addHeader(HttpHeaders.LOCATION, "/random/100");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final HttpHost target = start();
|
final HttpHost target = start();
|
||||||
|
@ -336,16 +272,9 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicRedirect307() throws Exception {
|
public void testBasicRedirect307() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)));
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -364,17 +293,10 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test(expected = ClientProtocolException.class)
|
@Test(expected = ClientProtocolException.class)
|
||||||
public void testMaxRedirectCheck() throws Exception {
|
public void testMaxRedirectCheck() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(true)
|
.setCircularRedirectsAllowed(true)
|
||||||
|
@ -393,17 +315,10 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test(expected = ClientProtocolException.class)
|
@Test(expected = ClientProtocolException.class)
|
||||||
public void testCircularRedirect() throws Exception {
|
public void testCircularRedirect() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
|
|
||||||
HttpStatus.SC_MOVED_TEMPORARILY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final RequestConfig config = RequestConfig.custom()
|
final RequestConfig config = RequestConfig.custom()
|
||||||
.setCircularRedirectsAllowed(false)
|
.setCircularRedirectsAllowed(false)
|
||||||
|
@ -421,16 +336,9 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPostRedirectSeeOther() throws Exception {
|
public void testPostRedirectSeeOther() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)));
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -452,28 +360,16 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect() throws Exception {
|
public void testRelativeRedirect() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
|
requestUri -> {
|
||||||
|
final String path = requestUri.getPath();
|
||||||
|
if (path.startsWith("/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
return null;
|
||||||
return new RedirectingDecorator(
|
}));
|
||||||
requestHandler,
|
|
||||||
new RedirectResolver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
|
||||||
final String path = requestUri.getPath();
|
|
||||||
if (path.startsWith("/oldlocation")) {
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
final HttpGet httpget = new HttpGet("/oldlocation/stuff");
|
||||||
|
@ -491,28 +387,16 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRelativeRedirect2() throws Exception {
|
public void testRelativeRedirect2() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
|
requestUri -> {
|
||||||
|
final String path = requestUri.getPath();
|
||||||
|
if (path.equals("/random/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
return null;
|
||||||
return new RedirectingDecorator(
|
}));
|
||||||
requestHandler,
|
|
||||||
new RedirectResolver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
|
||||||
final String path = requestUri.getPath();
|
|
||||||
if (path.equals("/random/oldlocation")) {
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
@ -532,28 +416,16 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test(expected = ClientProtocolException.class)
|
@Test(expected = ClientProtocolException.class)
|
||||||
public void testRejectBogusRedirectLocation() throws Exception {
|
public void testRejectBogusRedirectLocation() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
|
requestUri -> {
|
||||||
|
final String path = requestUri.getPath();
|
||||||
|
if (path.equals("/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
return null;
|
||||||
return new RedirectingDecorator(
|
}));
|
||||||
requestHandler,
|
|
||||||
new RedirectResolver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
|
||||||
final String path = requestUri.getPath();
|
|
||||||
if (path.equals("/oldlocation")) {
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation");
|
final HttpGet httpget = new HttpGet("/oldlocation");
|
||||||
|
|
||||||
|
@ -568,28 +440,16 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test(expected = ClientProtocolException.class)
|
@Test(expected = ClientProtocolException.class)
|
||||||
public void testRejectInvalidRedirectLocation() throws Exception {
|
public void testRejectInvalidRedirectLocation() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
|
requestUri -> {
|
||||||
|
final String path = requestUri.getPath();
|
||||||
|
if (path.equals("/oldlocation")) {
|
||||||
|
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
|
||||||
|
|
||||||
@Override
|
}
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
return null;
|
||||||
return new RedirectingDecorator(
|
}));
|
||||||
requestHandler,
|
|
||||||
new RedirectResolver() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Redirect resolve(final URI requestUri) throws URISyntaxException {
|
|
||||||
final String path = requestUri.getPath();
|
|
||||||
if (path.equals("/oldlocation")) {
|
|
||||||
return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpGet httpget = new HttpGet("/oldlocation");
|
final HttpGet httpget = new HttpGet("/oldlocation");
|
||||||
|
|
||||||
|
@ -603,16 +463,9 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRedirectWithCookie() throws Exception {
|
public void testRedirectWithCookie() throws Exception {
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final CookieStore cookieStore = new BasicCookieStore();
|
final CookieStore cookieStore = new BasicCookieStore();
|
||||||
|
|
||||||
|
@ -644,16 +497,9 @@ public class TestRedirects extends LocalServerTestBase {
|
||||||
public void testDefaultHeadersRedirect() throws Exception {
|
public void testDefaultHeadersRedirect() throws Exception {
|
||||||
this.clientBuilder.setDefaultHeaders(Collections.singletonList(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client")));
|
this.clientBuilder.setDefaultHeaders(Collections.singletonList(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client")));
|
||||||
|
|
||||||
final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
|
final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
|
||||||
|
requestHandler,
|
||||||
@Override
|
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
|
||||||
public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
|
|
||||||
return new RedirectingDecorator(
|
|
||||||
requestHandler,
|
|
||||||
new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final HttpClientContext context = HttpClientContext.create();
|
final HttpClientContext context = HttpClientContext.create();
|
||||||
|
|
||||||
|
|
|
@ -33,13 +33,10 @@ import java.net.Socket;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
|
|
||||||
import javax.net.ssl.HostnameVerifier;
|
import javax.net.ssl.HostnameVerifier;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
import javax.net.ssl.SSLParameters;
|
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
|
|
||||||
|
@ -49,7 +46,6 @@ import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
|
||||||
import org.apache.hc.client5.http.ssl.TrustAllStrategy;
|
import org.apache.hc.client5.http.ssl.TrustAllStrategy;
|
||||||
import org.apache.hc.client5.http.ssl.TrustSelfSignedStrategy;
|
import org.apache.hc.client5.http.ssl.TrustSelfSignedStrategy;
|
||||||
import org.apache.hc.client5.testing.SSLTestContexts;
|
import org.apache.hc.client5.testing.SSLTestContexts;
|
||||||
import org.apache.hc.core5.function.Callback;
|
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
|
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
|
||||||
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
||||||
|
@ -190,14 +186,7 @@ public class TestSSLSocketFactory {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
this.server = ServerBootstrap.bootstrap()
|
this.server = ServerBootstrap.bootstrap()
|
||||||
.setSslContext(SSLTestContexts.createServerSSLContext())
|
.setSslContext(SSLTestContexts.createServerSSLContext())
|
||||||
.setSslSetupHandler(new Callback<SSLParameters>() {
|
.setSslSetupHandler(sslParameters -> sslParameters.setNeedClientAuth(true))
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final SSLParameters sslParameters) {
|
|
||||||
sslParameters.setNeedClientAuth(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.create();
|
.create();
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
this.server.start();
|
this.server.start();
|
||||||
|
@ -252,14 +241,7 @@ public class TestSSLSocketFactory {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSSLTrustVerificationOverrideWithCustsom() throws Exception {
|
public void testSSLTrustVerificationOverrideWithCustsom() throws Exception {
|
||||||
final TrustStrategy trustStrategy = new TrustStrategy() {
|
final TrustStrategy trustStrategy = (chain, authType) -> chain.length == 1;
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
|
|
||||||
return chain.length == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
testSSLTrustVerificationOverride(trustStrategy);
|
testSSLTrustVerificationOverride(trustStrategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,14 +289,7 @@ public class TestSSLSocketFactory {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
this.server = ServerBootstrap.bootstrap()
|
this.server = ServerBootstrap.bootstrap()
|
||||||
.setSslContext(SSLTestContexts.createServerSSLContext())
|
.setSslContext(SSLTestContexts.createServerSSLContext())
|
||||||
.setSslSetupHandler(new Callback<SSLParameters>() {
|
.setSslSetupHandler(sslParameters -> sslParameters.setProtocols(new String[] {"SSLv3"}))
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final SSLParameters sslParameters) {
|
|
||||||
sslParameters.setProtocols(new String[] {"SSLv3"});
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.create();
|
.create();
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
this.server.start();
|
this.server.start();
|
||||||
|
@ -362,14 +337,7 @@ public class TestSSLSocketFactory {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
this.server = ServerBootstrap.bootstrap()
|
this.server = ServerBootstrap.bootstrap()
|
||||||
.setSslContext(SSLTestContexts.createServerSSLContext())
|
.setSslContext(SSLTestContexts.createServerSSLContext())
|
||||||
.setSslSetupHandler(new Callback<SSLParameters>() {
|
.setSslSetupHandler(sslParameters -> sslParameters.setProtocols(new String[] {cipherSuite}))
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final SSLParameters sslParameters) {
|
|
||||||
sslParameters.setProtocols(new String[] {cipherSuite});
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
.create();
|
.create();
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
this.server.start();
|
this.server.start();
|
||||||
|
|
|
@ -28,7 +28,6 @@ package org.apache.hc.client5.testing.sync;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.HttpRoute;
|
|
||||||
import org.apache.hc.client5.http.UserTokenHandler;
|
import org.apache.hc.client5.http.UserTokenHandler;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
@ -80,14 +79,9 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
|
||||||
this.connManager.setMaxTotal(workerCount);
|
this.connManager.setMaxTotal(workerCount);
|
||||||
this.connManager.setDefaultMaxPerRoute(workerCount);
|
this.connManager.setDefaultMaxPerRoute(workerCount);
|
||||||
|
|
||||||
final UserTokenHandler userTokenHandler = new UserTokenHandler() {
|
final UserTokenHandler userTokenHandler = (route, context) -> {
|
||||||
|
final String id = (String) context.getAttribute("user");
|
||||||
@Override
|
return id;
|
||||||
public Object getUserToken(final HttpRoute route, final HttpContext context) {
|
|
||||||
final String id = (String) context.getAttribute("user");
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
this.clientBuilder.setUserTokenHandler(userTokenHandler);
|
this.clientBuilder.setUserTokenHandler(userTokenHandler);
|
||||||
|
|
||||||
|
@ -199,14 +193,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
|
||||||
this.connManager.setMaxTotal(maxConn);
|
this.connManager.setMaxTotal(maxConn);
|
||||||
this.connManager.setDefaultMaxPerRoute(maxConn);
|
this.connManager.setDefaultMaxPerRoute(maxConn);
|
||||||
|
|
||||||
final UserTokenHandler userTokenHandler = new UserTokenHandler() {
|
final UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getUserToken(final HttpRoute route, final HttpContext context) {
|
|
||||||
return context.getAttribute("user");
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
this.clientBuilder.setUserTokenHandler(userTokenHandler);
|
this.clientBuilder.setUserTokenHandler(userTokenHandler);
|
||||||
|
|
||||||
|
|
|
@ -26,28 +26,20 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.testing.sync;
|
package org.apache.hc.client5.testing.sync;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.auth.AuthScheme;
|
|
||||||
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
|
||||||
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
|
||||||
import org.apache.hc.client5.http.impl.win.WinHttpClients;
|
import org.apache.hc.client5.http.impl.win.WinHttpClients;
|
||||||
import org.apache.hc.client5.http.impl.win.WindowsNegotiateSchemeGetTokenFail;
|
import org.apache.hc.client5.http.impl.win.WindowsNegotiateSchemeGetTokenFail;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
|
||||||
import org.apache.hc.core5.http.HttpException;
|
|
||||||
import org.apache.hc.core5.http.HttpHeaders;
|
import org.apache.hc.core5.http.HttpHeaders;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.config.Registry;
|
import org.apache.hc.core5.http.config.Registry;
|
||||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -58,17 +50,9 @@ public class TestWindowsNegotiateScheme extends LocalServerTestBase {
|
||||||
|
|
||||||
@Test(timeout=30000) // this timeout (in ms) needs to be extended if you're actively debugging the code
|
@Test(timeout=30000) // this timeout (in ms) needs to be extended if you're actively debugging the code
|
||||||
public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
|
public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
|
||||||
this.server.registerHandler("/", new HttpRequestHandler() {
|
this.server.registerHandler("/", (request, response, context) -> {
|
||||||
|
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.SPNEGO);
|
||||||
@Override
|
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
||||||
public void handle(
|
|
||||||
final ClassicHttpRequest request,
|
|
||||||
final ClassicHttpResponse response,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
response.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.SPNEGO);
|
|
||||||
response.setCode(HttpStatus.SC_UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
Assume.assumeTrue("Test can only be run on Windows", WinHttpClients.isWinAuthAvailable());
|
Assume.assumeTrue("Test can only be run on Windows", WinHttpClients.isWinAuthAvailable());
|
||||||
|
|
||||||
|
@ -81,12 +65,7 @@ public class TestWindowsNegotiateScheme extends LocalServerTestBase {
|
||||||
// you can contact the server that authenticated you." is associated with SEC_E_DOWNGRADE_DETECTED.
|
// you can contact the server that authenticated you." is associated with SEC_E_DOWNGRADE_DETECTED.
|
||||||
|
|
||||||
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
|
||||||
.register(StandardAuthScheme.SPNEGO, new AuthSchemeFactory() {
|
.register(StandardAuthScheme.SPNEGO, context -> new WindowsNegotiateSchemeGetTokenFail(StandardAuthScheme.SPNEGO, "HTTP/example.com")).build();
|
||||||
@Override
|
|
||||||
public AuthScheme create(final HttpContext context) {
|
|
||||||
return new WindowsNegotiateSchemeGetTokenFail(StandardAuthScheme.SPNEGO, "HTTP/example.com");
|
|
||||||
}
|
|
||||||
}).build();
|
|
||||||
final CloseableHttpClient customClient = HttpClientBuilder.create()
|
final CloseableHttpClient customClient = HttpClientBuilder.create()
|
||||||
.setDefaultAuthSchemeRegistry(authSchemeRegistry).build();
|
.setDefaultAuthSchemeRegistry(authSchemeRegistry).build();
|
||||||
|
|
||||||
|
|
|
@ -55,11 +55,7 @@ public class Header implements Iterable<MimeField> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final String key = field.getName().toLowerCase(Locale.ROOT);
|
final String key = field.getName().toLowerCase(Locale.ROOT);
|
||||||
List<MimeField> values = this.fieldMap.get(key);
|
final List<MimeField> values = this.fieldMap.computeIfAbsent(key, k -> new LinkedList<>());
|
||||||
if (values == null) {
|
|
||||||
values = new LinkedList<>();
|
|
||||||
this.fieldMap.put(key, values);
|
|
||||||
}
|
|
||||||
values.add(field);
|
values.add(field);
|
||||||
this.fields.add(field);
|
this.fields.add(field);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,23 +54,20 @@ public final class IdleConnectionEvictor {
|
||||||
Args.notNull(connectionManager, "Connection manager");
|
Args.notNull(connectionManager, "Connection manager");
|
||||||
this.threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory("idle-connection-evictor", true);
|
this.threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory("idle-connection-evictor", true);
|
||||||
final TimeValue localSleepTime = sleepTime != null ? sleepTime : TimeValue.ofSeconds(5);
|
final TimeValue localSleepTime = sleepTime != null ? sleepTime : TimeValue.ofSeconds(5);
|
||||||
this.thread = this.threadFactory.newThread(new Runnable() {
|
this.thread = this.threadFactory.newThread(() -> {
|
||||||
@Override
|
try {
|
||||||
public void run() {
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
try {
|
localSleepTime.sleep();
|
||||||
while (!Thread.currentThread().isInterrupted()) {
|
connectionManager.closeExpired();
|
||||||
localSleepTime.sleep();
|
if (maxIdleTime != null) {
|
||||||
connectionManager.closeExpired();
|
connectionManager.closeIdle(maxIdleTime);
|
||||||
if (maxIdleTime != null) {
|
|
||||||
connectionManager.closeIdle(maxIdleTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (final InterruptedException ex) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
}
|
}
|
||||||
|
} catch (final InterruptedException ex) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
} catch (final Exception ex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,7 @@ import org.apache.hc.core5.concurrent.Cancellable;
|
||||||
*/
|
*/
|
||||||
public final class Operations {
|
public final class Operations {
|
||||||
|
|
||||||
private final static Cancellable NOOP_CANCELLABLE = new Cancellable() {
|
private final static Cancellable NOOP_CANCELLABLE = () -> false;
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean cancel() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents a {@link Future} in the completed state with a fixed result.
|
* This class represents a {@link Future} in the completed state with a fixed result.
|
||||||
|
@ -115,14 +108,7 @@ public final class Operations {
|
||||||
if (future instanceof Cancellable) {
|
if (future instanceof Cancellable) {
|
||||||
return (Cancellable) future;
|
return (Cancellable) future;
|
||||||
}
|
}
|
||||||
return new Cancellable() {
|
return () -> future.cancel(true);
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean cancel() {
|
|
||||||
return future.cancel(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,13 +66,7 @@ abstract class AbstractHttpAsyncClientBase extends CloseableHttpAsyncClient {
|
||||||
@Override
|
@Override
|
||||||
public final void start() {
|
public final void start() {
|
||||||
if (status.compareAndSet(Status.READY, Status.RUNNING)) {
|
if (status.compareAndSet(Status.READY, Status.RUNNING)) {
|
||||||
executorService.execute(new Runnable() {
|
executorService.execute(ioReactor::start);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
ioReactor.start();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,19 +51,7 @@ class AsyncExecChainElement {
|
||||||
final AsyncEntityProducer entityProducer,
|
final AsyncEntityProducer entityProducer,
|
||||||
final AsyncExecChain.Scope scope,
|
final AsyncExecChain.Scope scope,
|
||||||
final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
|
final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
|
||||||
handler.execute(request, entityProducer, scope, new AsyncExecChain() {
|
handler.execute(request, entityProducer, scope, next != null ? next::execute : null, asyncExecCallback);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void proceed(
|
|
||||||
final HttpRequest request,
|
|
||||||
final AsyncEntityProducer entityProducer,
|
|
||||||
final AsyncExecChain.Scope scope,
|
|
||||||
final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
|
|
||||||
next.execute(request, entityProducer, scope, asyncExecCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
}, asyncExecCallback);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -29,7 +29,6 @@ package org.apache.hc.client5.http.impl.async;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -44,8 +43,8 @@ import org.apache.hc.client5.http.HttpRequestRetryStrategy;
|
||||||
import org.apache.hc.client5.http.SchemePortResolver;
|
import org.apache.hc.client5.http.SchemePortResolver;
|
||||||
import org.apache.hc.client5.http.async.AsyncExecChainHandler;
|
import org.apache.hc.client5.http.async.AsyncExecChainHandler;
|
||||||
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
|
||||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||||
|
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
import org.apache.hc.client5.http.config.RequestConfig;
|
||||||
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
||||||
import org.apache.hc.client5.http.cookie.CookieSpecFactory;
|
import org.apache.hc.client5.http.cookie.CookieSpecFactory;
|
||||||
|
@ -75,24 +74,16 @@ import org.apache.hc.client5.http.routing.HttpRoutePlanner;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
import org.apache.hc.core5.annotation.Internal;
|
import org.apache.hc.core5.annotation.Internal;
|
||||||
import org.apache.hc.core5.concurrent.DefaultThreadFactory;
|
import org.apache.hc.core5.concurrent.DefaultThreadFactory;
|
||||||
import org.apache.hc.core5.function.Callback;
|
|
||||||
import org.apache.hc.core5.function.Resolver;
|
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
|
||||||
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
||||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||||
import org.apache.hc.core5.http.config.CharCodingConfig;
|
import org.apache.hc.core5.http.config.CharCodingConfig;
|
||||||
import org.apache.hc.core5.http.config.Lookup;
|
import org.apache.hc.core5.http.config.Lookup;
|
||||||
import org.apache.hc.core5.http.config.NamedElementChain;
|
import org.apache.hc.core5.http.config.NamedElementChain;
|
||||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
|
||||||
import org.apache.hc.core5.http.nio.HandlerFactory;
|
|
||||||
import org.apache.hc.core5.http.nio.command.ShutdownCommand;
|
import org.apache.hc.core5.http.nio.command.ShutdownCommand;
|
||||||
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||||
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
|
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
|
import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
|
||||||
import org.apache.hc.core5.http.protocol.RequestTargetHost;
|
import org.apache.hc.core5.http.protocol.RequestTargetHost;
|
||||||
|
@ -107,7 +98,6 @@ import org.apache.hc.core5.reactor.Command;
|
||||||
import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
|
import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
|
||||||
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
|
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
import org.apache.hc.core5.reactor.IOSession;
|
|
||||||
import org.apache.hc.core5.util.Args;
|
import org.apache.hc.core5.util.Args;
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
import org.apache.hc.core5.util.VersionInfo;
|
import org.apache.hc.core5.util.VersionInfo;
|
||||||
|
@ -710,14 +700,7 @@ public class H2AsyncClientBuilder {
|
||||||
final AsyncPushConsumerRegistry pushConsumerRegistry = new AsyncPushConsumerRegistry();
|
final AsyncPushConsumerRegistry pushConsumerRegistry = new AsyncPushConsumerRegistry();
|
||||||
final IOEventHandlerFactory ioEventHandlerFactory = new H2AsyncClientEventHandlerFactory(
|
final IOEventHandlerFactory ioEventHandlerFactory = new H2AsyncClientEventHandlerFactory(
|
||||||
new DefaultHttpProcessor(new H2RequestContent(), new H2RequestTargetHost(), new H2RequestConnControl()),
|
new DefaultHttpProcessor(new H2RequestContent(), new H2RequestTargetHost(), new H2RequestConnControl()),
|
||||||
new HandlerFactory<AsyncPushConsumer>() {
|
(request, context) -> pushConsumerRegistry.get(request),
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
|
|
||||||
return pushConsumerRegistry.get(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
h2Config != null ? h2Config : H2Config.DEFAULT,
|
h2Config != null ? h2Config : H2Config.DEFAULT,
|
||||||
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT);
|
charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT);
|
||||||
final DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(
|
final DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(
|
||||||
|
@ -727,14 +710,7 @@ public class H2AsyncClientBuilder {
|
||||||
LoggingIOSessionDecorator.INSTANCE,
|
LoggingIOSessionDecorator.INSTANCE,
|
||||||
LoggingExceptionCallback.INSTANCE,
|
LoggingExceptionCallback.INSTANCE,
|
||||||
null,
|
null,
|
||||||
new Callback<IOSession>() {
|
ioSession -> ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final IOSession ioSession) {
|
|
||||||
ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (execInterceptors != null) {
|
if (execInterceptors != null) {
|
||||||
for (final ExecInterceptorEntry entry: execInterceptors) {
|
for (final ExecInterceptorEntry entry: execInterceptors) {
|
||||||
|
@ -808,14 +784,7 @@ public class H2AsyncClientBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
final MultihomeConnectionInitiator connectionInitiator = new MultihomeConnectionInitiator(ioReactor, dnsResolver);
|
final MultihomeConnectionInitiator connectionInitiator = new MultihomeConnectionInitiator(ioReactor, dnsResolver);
|
||||||
final H2ConnPool connPool = new H2ConnPool(connectionInitiator, new Resolver<HttpHost, InetSocketAddress>() {
|
final H2ConnPool connPool = new H2ConnPool(connectionInitiator, host -> null, tlsStrategyCopy);
|
||||||
|
|
||||||
@Override
|
|
||||||
public InetSocketAddress resolve(final HttpHost host) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, tlsStrategyCopy);
|
|
||||||
|
|
||||||
List<Closeable> closeablesCopy = closeables != null ? new ArrayList<>(closeables) : null;
|
List<Closeable> closeablesCopy = closeables != null ? new ArrayList<>(closeables) : null;
|
||||||
if (closeablesCopy == null) {
|
if (closeablesCopy == null) {
|
||||||
|
@ -824,14 +793,7 @@ public class H2AsyncClientBuilder {
|
||||||
if (evictIdleConnections) {
|
if (evictIdleConnections) {
|
||||||
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor(connPool,
|
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor(connPool,
|
||||||
maxIdleTime != null ? maxIdleTime : TimeValue.ofSeconds(30L));
|
maxIdleTime != null ? maxIdleTime : TimeValue.ofSeconds(30L));
|
||||||
closeablesCopy.add(new Closeable() {
|
closeablesCopy.add(connectionEvictor::shutdown);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
connectionEvictor.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
connectionEvictor.start();
|
connectionEvictor.start();
|
||||||
}
|
}
|
||||||
closeablesCopy.add(connPool);
|
closeablesCopy.add(connPool);
|
||||||
|
@ -852,12 +814,7 @@ public class H2AsyncClientBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getProperty(final String key, final String defaultValue) {
|
private static String getProperty(final String key, final String defaultValue) {
|
||||||
return AccessController.doPrivileged(new PrivilegedAction<String>() {
|
return AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty(key, defaultValue));
|
||||||
@Override
|
|
||||||
public String run() {
|
|
||||||
return System.getProperty(key, defaultValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class IdleConnectionEvictor implements Closeable {
|
static class IdleConnectionEvictor implements Closeable {
|
||||||
|
@ -865,20 +822,17 @@ public class H2AsyncClientBuilder {
|
||||||
private final Thread thread;
|
private final Thread thread;
|
||||||
|
|
||||||
public IdleConnectionEvictor(final H2ConnPool connPool, final TimeValue maxIdleTime) {
|
public IdleConnectionEvictor(final H2ConnPool connPool, final TimeValue maxIdleTime) {
|
||||||
this.thread = new DefaultThreadFactory("idle-connection-evictor", true).newThread(new Runnable() {
|
this.thread = new DefaultThreadFactory("idle-connection-evictor", true).newThread(() -> {
|
||||||
@Override
|
try {
|
||||||
public void run() {
|
while (!Thread.currentThread().isInterrupted()) {
|
||||||
try {
|
maxIdleTime.sleep();
|
||||||
while (!Thread.currentThread().isInterrupted()) {
|
connPool.closeIdle(maxIdleTime);
|
||||||
maxIdleTime.sleep();
|
|
||||||
connPool.closeIdle(maxIdleTime);
|
|
||||||
}
|
|
||||||
} catch (final InterruptedException ex) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
} catch (final Exception ex) {
|
|
||||||
}
|
}
|
||||||
|
} catch (final InterruptedException ex) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
} catch (final Exception ex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
package org.apache.hc.client5.http.impl.async;
|
package org.apache.hc.client5.http.impl.async;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.ProxySelector;
|
import java.net.ProxySelector;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
|
@ -45,8 +44,8 @@ import org.apache.hc.client5.http.SchemePortResolver;
|
||||||
import org.apache.hc.client5.http.UserTokenHandler;
|
import org.apache.hc.client5.http.UserTokenHandler;
|
||||||
import org.apache.hc.client5.http.async.AsyncExecChainHandler;
|
import org.apache.hc.client5.http.async.AsyncExecChainHandler;
|
||||||
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
|
||||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||||
|
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||||
import org.apache.hc.client5.http.config.RequestConfig;
|
import org.apache.hc.client5.http.config.RequestConfig;
|
||||||
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
import org.apache.hc.client5.http.cookie.BasicCookieStore;
|
||||||
import org.apache.hc.client5.http.cookie.CookieSpecFactory;
|
import org.apache.hc.client5.http.cookie.CookieSpecFactory;
|
||||||
|
@ -85,11 +84,8 @@ import org.apache.hc.core5.concurrent.DefaultThreadFactory;
|
||||||
import org.apache.hc.core5.function.Callback;
|
import org.apache.hc.core5.function.Callback;
|
||||||
import org.apache.hc.core5.http.ConnectionReuseStrategy;
|
import org.apache.hc.core5.http.ConnectionReuseStrategy;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
|
||||||
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
|
||||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||||
import org.apache.hc.core5.http.config.CharCodingConfig;
|
import org.apache.hc.core5.http.config.CharCodingConfig;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
|
@ -97,11 +93,8 @@ import org.apache.hc.core5.http.config.Lookup;
|
||||||
import org.apache.hc.core5.http.config.NamedElementChain;
|
import org.apache.hc.core5.http.config.NamedElementChain;
|
||||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||||
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
|
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
|
||||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
|
||||||
import org.apache.hc.core5.http.nio.HandlerFactory;
|
|
||||||
import org.apache.hc.core5.http.nio.command.ShutdownCommand;
|
import org.apache.hc.core5.http.nio.command.ShutdownCommand;
|
||||||
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
|
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
|
import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
|
||||||
import org.apache.hc.core5.http.protocol.RequestTargetHost;
|
import org.apache.hc.core5.http.protocol.RequestTargetHost;
|
||||||
|
@ -117,7 +110,6 @@ import org.apache.hc.core5.reactor.Command;
|
||||||
import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
|
import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
|
||||||
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
|
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
import org.apache.hc.core5.reactor.IOSession;
|
|
||||||
import org.apache.hc.core5.util.Args;
|
import org.apache.hc.core5.util.Args;
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
import org.apache.hc.core5.util.VersionInfo;
|
import org.apache.hc.core5.util.VersionInfo;
|
||||||
|
@ -857,12 +849,7 @@ public class HttpAsyncClientBuilder {
|
||||||
if (proxy != null) {
|
if (proxy != null) {
|
||||||
routePlannerCopy = new DefaultProxyRoutePlanner(proxy, schemePortResolverCopy);
|
routePlannerCopy = new DefaultProxyRoutePlanner(proxy, schemePortResolverCopy);
|
||||||
} else if (systemProperties) {
|
} else if (systemProperties) {
|
||||||
final ProxySelector defaultProxySelector = AccessController.doPrivileged(new PrivilegedAction<ProxySelector>() {
|
final ProxySelector defaultProxySelector = AccessController.doPrivileged((PrivilegedAction<ProxySelector>) ProxySelector::getDefault);
|
||||||
@Override
|
|
||||||
public ProxySelector run() {
|
|
||||||
return ProxySelector.getDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
routePlannerCopy = new SystemDefaultRoutePlanner(
|
routePlannerCopy = new SystemDefaultRoutePlanner(
|
||||||
schemePortResolverCopy, defaultProxySelector);
|
schemePortResolverCopy, defaultProxySelector);
|
||||||
} else {
|
} else {
|
||||||
|
@ -890,14 +877,7 @@ public class HttpAsyncClientBuilder {
|
||||||
if (connManagerCopy instanceof ConnPoolControl) {
|
if (connManagerCopy instanceof ConnPoolControl) {
|
||||||
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor((ConnPoolControl<?>) connManagerCopy,
|
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor((ConnPoolControl<?>) connManagerCopy,
|
||||||
maxIdleTime, maxIdleTime);
|
maxIdleTime, maxIdleTime);
|
||||||
closeablesCopy.add(new Closeable() {
|
closeablesCopy.add(connectionEvictor::shutdown);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
connectionEvictor.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
connectionEvictor.start();
|
connectionEvictor.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -910,13 +890,7 @@ public class HttpAsyncClientBuilder {
|
||||||
if ("true".equalsIgnoreCase(s)) {
|
if ("true".equalsIgnoreCase(s)) {
|
||||||
reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
|
reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
|
||||||
} else {
|
} else {
|
||||||
reuseStrategyCopy = new ConnectionReuseStrategy() {
|
reuseStrategyCopy = (request, response, context) -> false;
|
||||||
@Override
|
|
||||||
public boolean keepAlive(
|
|
||||||
final HttpRequest request, final HttpResponse response, final HttpContext context) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
|
reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
|
||||||
|
@ -925,14 +899,7 @@ public class HttpAsyncClientBuilder {
|
||||||
final AsyncPushConsumerRegistry pushConsumerRegistry = new AsyncPushConsumerRegistry();
|
final AsyncPushConsumerRegistry pushConsumerRegistry = new AsyncPushConsumerRegistry();
|
||||||
final IOEventHandlerFactory ioEventHandlerFactory = new HttpAsyncClientEventHandlerFactory(
|
final IOEventHandlerFactory ioEventHandlerFactory = new HttpAsyncClientEventHandlerFactory(
|
||||||
new DefaultHttpProcessor(new H2RequestContent(), new H2RequestTargetHost(), new H2RequestConnControl()),
|
new DefaultHttpProcessor(new H2RequestContent(), new H2RequestTargetHost(), new H2RequestConnControl()),
|
||||||
new HandlerFactory<AsyncPushConsumer>() {
|
(request, context) -> pushConsumerRegistry.get(request),
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
|
|
||||||
return pushConsumerRegistry.get(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
|
versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
|
||||||
h2Config != null ? h2Config : H2Config.DEFAULT,
|
h2Config != null ? h2Config : H2Config.DEFAULT,
|
||||||
h1Config != null ? h1Config : Http1Config.DEFAULT,
|
h1Config != null ? h1Config : Http1Config.DEFAULT,
|
||||||
|
@ -945,14 +912,7 @@ public class HttpAsyncClientBuilder {
|
||||||
LoggingIOSessionDecorator.INSTANCE,
|
LoggingIOSessionDecorator.INSTANCE,
|
||||||
ioReactorExceptionCallback != null ? ioReactorExceptionCallback : LoggingExceptionCallback.INSTANCE,
|
ioReactorExceptionCallback != null ? ioReactorExceptionCallback : LoggingExceptionCallback.INSTANCE,
|
||||||
null,
|
null,
|
||||||
new Callback<IOSession>() {
|
ioSession -> ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE));
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final IOSession ioSession) {
|
|
||||||
ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (execInterceptors != null) {
|
if (execInterceptors != null) {
|
||||||
for (final ExecInterceptorEntry entry: execInterceptors) {
|
for (final ExecInterceptorEntry entry: execInterceptors) {
|
||||||
|
@ -1033,12 +993,7 @@ public class HttpAsyncClientBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getProperty(final String key, final String defaultValue) {
|
private String getProperty(final String key, final String defaultValue) {
|
||||||
return AccessController.doPrivileged(new PrivilegedAction<String>() {
|
return AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty(key, defaultValue));
|
||||||
@Override
|
|
||||||
public String run() {
|
|
||||||
return System.getProperty(key, defaultValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,11 @@ import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBu
|
||||||
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
|
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
|
||||||
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
|
||||||
import org.apache.hc.core5.concurrent.DefaultThreadFactory;
|
import org.apache.hc.core5.concurrent.DefaultThreadFactory;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
|
||||||
import org.apache.hc.core5.http.config.CharCodingConfig;
|
import org.apache.hc.core5.http.config.CharCodingConfig;
|
||||||
import org.apache.hc.core5.http.config.Http1Config;
|
import org.apache.hc.core5.http.config.Http1Config;
|
||||||
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
|
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
|
||||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
|
||||||
import org.apache.hc.core5.http.nio.HandlerFactory;
|
|
||||||
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||||
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
|
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||||
import org.apache.hc.core5.http.protocol.RequestUserAgent;
|
import org.apache.hc.core5.http.protocol.RequestUserAgent;
|
||||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||||
|
@ -157,14 +152,7 @@ public final class HttpAsyncClients {
|
||||||
return createMinimalHttpAsyncClientImpl(
|
return createMinimalHttpAsyncClientImpl(
|
||||||
new HttpAsyncClientEventHandlerFactory(
|
new HttpAsyncClientEventHandlerFactory(
|
||||||
createMinimalProtocolProcessor(),
|
createMinimalProtocolProcessor(),
|
||||||
new HandlerFactory<AsyncPushConsumer>() {
|
(request, context) -> pushConsumerRegistry.get(request),
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
|
|
||||||
return pushConsumerRegistry.get(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
versionPolicy,
|
versionPolicy,
|
||||||
h2Config,
|
h2Config,
|
||||||
h1Config,
|
h1Config,
|
||||||
|
@ -252,14 +240,7 @@ public final class HttpAsyncClients {
|
||||||
return createMinimalHttp2AsyncClientImpl(
|
return createMinimalHttp2AsyncClientImpl(
|
||||||
new H2AsyncClientEventHandlerFactory(
|
new H2AsyncClientEventHandlerFactory(
|
||||||
createMinimalProtocolProcessor(),
|
createMinimalProtocolProcessor(),
|
||||||
new HandlerFactory<AsyncPushConsumer>() {
|
(request, context) -> pushConsumerRegistry.get(request),
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
|
|
||||||
return pushConsumerRegistry.get(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
h2Config,
|
h2Config,
|
||||||
CharCodingConfig.DEFAULT),
|
CharCodingConfig.DEFAULT),
|
||||||
pushConsumerRegistry,
|
pushConsumerRegistry,
|
||||||
|
|
|
@ -70,7 +70,6 @@ import org.apache.hc.core5.http.nio.AsyncRequestProducer;
|
||||||
import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
|
import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
|
||||||
import org.apache.hc.core5.http.nio.DataStreamChannel;
|
import org.apache.hc.core5.http.nio.DataStreamChannel;
|
||||||
import org.apache.hc.core5.http.nio.HandlerFactory;
|
import org.apache.hc.core5.http.nio.HandlerFactory;
|
||||||
import org.apache.hc.core5.http.nio.RequestChannel;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.http.support.BasicRequestBuilder;
|
import org.apache.hc.core5.http.support.BasicRequestBuilder;
|
||||||
import org.apache.hc.core5.io.CloseMode;
|
import org.apache.hc.core5.io.CloseMode;
|
||||||
|
@ -176,181 +175,162 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
|
||||||
throw new CancellationException("Request execution cancelled");
|
throw new CancellationException("Request execution cancelled");
|
||||||
}
|
}
|
||||||
final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
|
final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
|
||||||
requestProducer.sendRequest(new RequestChannel() {
|
requestProducer.sendRequest((request, entityDetails, c) -> {
|
||||||
|
|
||||||
@Override
|
RequestConfig requestConfig = null;
|
||||||
public void sendRequest(
|
if (request instanceof Configurable) {
|
||||||
final HttpRequest request,
|
requestConfig = ((Configurable) request).getConfig();
|
||||||
final EntityDetails entityDetails,
|
}
|
||||||
final HttpContext context) throws HttpException, IOException {
|
if (requestConfig != null) {
|
||||||
|
clientContext.setRequestConfig(requestConfig);
|
||||||
|
}
|
||||||
|
final HttpRoute route = determineRoute(
|
||||||
|
httpHost != null ? httpHost : RoutingSupport.determineHost(request),
|
||||||
|
clientContext);
|
||||||
|
final String exchangeId = ExecSupport.getNextExchangeId();
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("{} preparing request execution", exchangeId);
|
||||||
|
}
|
||||||
|
final AsyncExecRuntime execRuntime = createAsyncExecRuntime(pushHandlerFactory);
|
||||||
|
|
||||||
RequestConfig requestConfig = null;
|
clientContext.setExchangeId(exchangeId);
|
||||||
if (request instanceof Configurable) {
|
setupContext(clientContext);
|
||||||
requestConfig = ((Configurable) request).getConfig();
|
|
||||||
}
|
|
||||||
if (requestConfig != null) {
|
|
||||||
clientContext.setRequestConfig(requestConfig);
|
|
||||||
}
|
|
||||||
final HttpRoute route = determineRoute(
|
|
||||||
httpHost != null ? httpHost : RoutingSupport.determineHost(request),
|
|
||||||
clientContext);
|
|
||||||
final String exchangeId = ExecSupport.getNextExchangeId();
|
|
||||||
if (LOG.isDebugEnabled()) {
|
|
||||||
LOG.debug("{} preparing request execution", exchangeId);
|
|
||||||
}
|
|
||||||
final AsyncExecRuntime execRuntime = createAsyncExecRuntime(pushHandlerFactory);
|
|
||||||
|
|
||||||
clientContext.setExchangeId(exchangeId);
|
final AsyncExecChain.Scheduler scheduler = this::executeScheduled;
|
||||||
setupContext(clientContext);
|
|
||||||
|
|
||||||
final AsyncExecChain.Scheduler scheduler = new AsyncExecChain.Scheduler() {
|
final AsyncExecChain.Scope scope = new AsyncExecChain.Scope(exchangeId, route, request, future,
|
||||||
|
clientContext, execRuntime, scheduler, new AtomicInteger(1));
|
||||||
|
final AtomicBoolean outputTerminated = new AtomicBoolean(false);
|
||||||
|
executeImmediate(
|
||||||
|
BasicRequestBuilder.copy(request).build(),
|
||||||
|
entityDetails != null ? new AsyncEntityProducer() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void scheduleExecution(final HttpRequest request,
|
public void releaseResources() {
|
||||||
final AsyncEntityProducer entityProducer,
|
requestProducer.releaseResources();
|
||||||
final AsyncExecChain.Scope scope,
|
}
|
||||||
final AsyncExecCallback asyncExecCallback,
|
|
||||||
final TimeValue delay) {
|
|
||||||
executeScheduled(request, entityProducer, scope, asyncExecCallback, delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
@Override
|
||||||
|
public void failed(final Exception cause) {
|
||||||
|
requestProducer.failed(cause);
|
||||||
|
}
|
||||||
|
|
||||||
final AsyncExecChain.Scope scope = new AsyncExecChain.Scope(exchangeId, route, request, future,
|
@Override
|
||||||
clientContext, execRuntime, scheduler, new AtomicInteger(1));
|
public boolean isRepeatable() {
|
||||||
final AtomicBoolean outputTerminated = new AtomicBoolean(false);
|
return requestProducer.isRepeatable();
|
||||||
executeImmediate(
|
}
|
||||||
BasicRequestBuilder.copy(request).build(),
|
|
||||||
entityDetails != null ? new AsyncEntityProducer() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void releaseResources() {
|
public long getContentLength() {
|
||||||
|
return entityDetails.getContentLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContentType() {
|
||||||
|
return entityDetails.getContentType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getContentEncoding() {
|
||||||
|
return entityDetails.getContentEncoding();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChunked() {
|
||||||
|
return entityDetails.isChunked();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getTrailerNames() {
|
||||||
|
return entityDetails.getTrailerNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() {
|
||||||
|
return requestProducer.available();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void produce(final DataStreamChannel channel) throws IOException {
|
||||||
|
if (outputTerminated.get()) {
|
||||||
|
channel.endStream();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
requestProducer.produce(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
} : null,
|
||||||
|
scope,
|
||||||
|
new AsyncExecCallback() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AsyncDataConsumer handleResponse(
|
||||||
|
final HttpResponse response,
|
||||||
|
final EntityDetails entityDetails) throws HttpException, IOException {
|
||||||
|
if (response.getCode() >= HttpStatus.SC_CLIENT_ERROR) {
|
||||||
|
outputTerminated.set(true);
|
||||||
requestProducer.releaseResources();
|
requestProducer.releaseResources();
|
||||||
}
|
}
|
||||||
|
responseConsumer.consumeResponse(response, entityDetails, c,
|
||||||
|
new FutureCallback<T>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void failed(final Exception cause) {
|
public void completed(final T result) {
|
||||||
requestProducer.failed(cause);
|
future.completed(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(final Exception ex) {
|
||||||
|
future.failed(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelled() {
|
||||||
|
future.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
return entityDetails != null ? responseConsumer : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleInformationResponse(
|
||||||
|
final HttpResponse response) throws HttpException, IOException {
|
||||||
|
responseConsumer.informationResponse(response, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void completed() {
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("{} message exchange successfully completed", exchangeId);
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
@Override
|
execRuntime.releaseEndpoint();
|
||||||
public boolean isRepeatable() {
|
} finally {
|
||||||
return requestProducer.isRepeatable();
|
responseConsumer.releaseResources();
|
||||||
|
requestProducer.releaseResources();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getContentLength() {
|
public void failed(final Exception cause) {
|
||||||
return entityDetails.getContentLength();
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("{} request failed: {}", exchangeId, cause.getMessage());
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
@Override
|
execRuntime.discardEndpoint();
|
||||||
public String getContentType() {
|
responseConsumer.failed(cause);
|
||||||
return entityDetails.getContentType();
|
} finally {
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getContentEncoding() {
|
|
||||||
return entityDetails.getContentEncoding();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isChunked() {
|
|
||||||
return entityDetails.isChunked();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<String> getTrailerNames() {
|
|
||||||
return entityDetails.getTrailerNames();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int available() {
|
|
||||||
return requestProducer.available();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void produce(final DataStreamChannel channel) throws IOException {
|
|
||||||
if (outputTerminated.get()) {
|
|
||||||
channel.endStream();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
requestProducer.produce(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
} : null,
|
|
||||||
scope,
|
|
||||||
new AsyncExecCallback() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AsyncDataConsumer handleResponse(
|
|
||||||
final HttpResponse response,
|
|
||||||
final EntityDetails entityDetails) throws HttpException, IOException {
|
|
||||||
if (response.getCode() >= HttpStatus.SC_CLIENT_ERROR) {
|
|
||||||
outputTerminated.set(true);
|
|
||||||
requestProducer.releaseResources();
|
|
||||||
}
|
|
||||||
responseConsumer.consumeResponse(response, entityDetails, context,
|
|
||||||
new FutureCallback<T>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void completed(final T result) {
|
|
||||||
future.completed(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void failed(final Exception ex) {
|
|
||||||
future.failed(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelled() {
|
|
||||||
future.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
return entityDetails != null ? responseConsumer : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleInformationResponse(
|
|
||||||
final HttpResponse response) throws HttpException, IOException {
|
|
||||||
responseConsumer.informationResponse(response, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void completed() {
|
|
||||||
if (LOG.isDebugEnabled()) {
|
|
||||||
LOG.debug("{} message exchange successfully completed", exchangeId);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
execRuntime.releaseEndpoint();
|
future.failed(cause);
|
||||||
} finally {
|
} finally {
|
||||||
responseConsumer.releaseResources();
|
responseConsumer.releaseResources();
|
||||||
requestProducer.releaseResources();
|
requestProducer.releaseResources();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
});
|
||||||
public void failed(final Exception cause) {
|
|
||||||
if (LOG.isDebugEnabled()) {
|
|
||||||
LOG.debug("{} request failed: {}", exchangeId, cause.getMessage());
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
execRuntime.discardEndpoint();
|
|
||||||
responseConsumer.failed(cause);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
future.failed(cause);
|
|
||||||
} finally {
|
|
||||||
responseConsumer.releaseResources();
|
|
||||||
requestProducer.releaseResources();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}, context);
|
}, context);
|
||||||
} catch (final HttpException | IOException | IllegalStateException ex) {
|
} catch (final HttpException | IOException | IllegalStateException ex) {
|
||||||
future.failed(ex);
|
future.failed(ex);
|
||||||
|
|
|
@ -261,12 +261,9 @@ class InternalHttpAsyncExecRuntime implements AsyncExecRuntime {
|
||||||
}
|
}
|
||||||
endpoint.execute(id, exchangeHandler, context);
|
endpoint.execute(id, exchangeHandler, context);
|
||||||
if (context.getRequestConfig().isHardCancellationEnabled()) {
|
if (context.getRequestConfig().isHardCancellationEnabled()) {
|
||||||
return new Cancellable() {
|
return () -> {
|
||||||
@Override
|
exchangeHandler.cancel();
|
||||||
public boolean cancel() {
|
return true;
|
||||||
exchangeHandler.cancel();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -33,7 +33,6 @@ import java.util.List;
|
||||||
import org.apache.hc.core5.http.EntityDetails;
|
import org.apache.hc.core5.http.EntityDetails;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.message.RequestLine;
|
import org.apache.hc.core5.http.message.RequestLine;
|
||||||
import org.apache.hc.core5.http.message.StatusLine;
|
import org.apache.hc.core5.http.message.StatusLine;
|
||||||
|
@ -69,20 +68,12 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void produceRequest(final RequestChannel channel, final HttpContext context) throws HttpException, IOException {
|
public void produceRequest(final RequestChannel channel, final HttpContext context) throws HttpException, IOException {
|
||||||
handler.produceRequest(new RequestChannel() {
|
handler.produceRequest((request, entityDetails, context1) -> {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
@Override
|
log.debug("{} send request {}, {}", exchangeId, new RequestLine(request),
|
||||||
public void sendRequest(
|
entityDetails != null ? "entity len " + entityDetails.getContentLength() : "null entity");
|
||||||
final HttpRequest request,
|
|
||||||
final EntityDetails entityDetails,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("{} send request {}, {}", exchangeId, new RequestLine(request),
|
|
||||||
entityDetails != null ? "entity len " + entityDetails.getContentLength() : "null entity");
|
|
||||||
}
|
|
||||||
channel.sendRequest(request, entityDetails, context);
|
|
||||||
}
|
}
|
||||||
|
channel.sendRequest(request, entityDetails, context1);
|
||||||
}, context);
|
}, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +85,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
@Override
|
@Override
|
||||||
public void produce(final DataStreamChannel channel) throws IOException {
|
public void produce(final DataStreamChannel channel) throws IOException {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("{} produce request data", exchangeId);
|
log.debug("{}: produce request data", exchangeId);
|
||||||
}
|
}
|
||||||
handler.produce(new DataStreamChannel() {
|
handler.produce(new DataStreamChannel() {
|
||||||
|
|
||||||
|
@ -106,7 +97,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
@Override
|
@Override
|
||||||
public int write(final ByteBuffer src) throws IOException {
|
public int write(final ByteBuffer src) throws IOException {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("{} produce request data, len {} bytes", exchangeId, src.remaining());
|
log.debug("{}: produce request data, len {} bytes", exchangeId, src.remaining());
|
||||||
}
|
}
|
||||||
return channel.write(src);
|
return channel.write(src);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +105,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
@Override
|
@Override
|
||||||
public void endStream() throws IOException {
|
public void endStream() throws IOException {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("{} end of request data", exchangeId);
|
log.debug("{}: end of request data", exchangeId);
|
||||||
}
|
}
|
||||||
channel.endStream();
|
channel.endStream();
|
||||||
}
|
}
|
||||||
|
@ -122,7 +113,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
@Override
|
@Override
|
||||||
public void endStream(final List<? extends Header> trailers) throws IOException {
|
public void endStream(final List<? extends Header> trailers) throws IOException {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("{} end of request data", exchangeId);
|
log.debug("{}: end of request data", exchangeId);
|
||||||
}
|
}
|
||||||
channel.endStream(trailers);
|
channel.endStream(trailers);
|
||||||
}
|
}
|
||||||
|
@ -135,7 +126,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
final HttpResponse response,
|
final HttpResponse response,
|
||||||
final HttpContext context) throws HttpException, IOException {
|
final HttpContext context) throws HttpException, IOException {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("{} information response {}", exchangeId, new StatusLine(response));
|
log.debug("{}: information response {}", exchangeId, new StatusLine(response));
|
||||||
}
|
}
|
||||||
handler.consumeInformation(response, context);
|
handler.consumeInformation(response, context);
|
||||||
}
|
}
|
||||||
|
@ -146,7 +137,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
final EntityDetails entityDetails,
|
final EntityDetails entityDetails,
|
||||||
final HttpContext context) throws HttpException, IOException {
|
final HttpContext context) throws HttpException, IOException {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("{} consume response {}, {}", exchangeId, new StatusLine(response), entityDetails != null ? "entity len " + entityDetails.getContentLength() : " null entity");
|
log.debug("{}: consume response {}, {}", exchangeId, new StatusLine(response), entityDetails != null ? "entity len " + entityDetails.getContentLength() : " null entity");
|
||||||
}
|
}
|
||||||
handler.consumeResponse(response, entityDetails, context);
|
handler.consumeResponse(response, entityDetails, context);
|
||||||
}
|
}
|
||||||
|
@ -154,23 +145,18 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
|
public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
|
||||||
handler.updateCapacity(new CapacityChannel() {
|
handler.updateCapacity(increment -> {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
@Override
|
log.debug("{} capacity update {}", exchangeId, increment);
|
||||||
public void update(final int increment) throws IOException {
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("{} capacity update {}", exchangeId, increment);
|
|
||||||
}
|
|
||||||
capacityChannel.update(increment);
|
|
||||||
}
|
}
|
||||||
|
capacityChannel.update(increment);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void consume(final ByteBuffer src) throws IOException {
|
public void consume(final ByteBuffer src) throws IOException {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("{} consume response data, len {} bytes", exchangeId, src.remaining());
|
log.debug("{}: consume response data, len {} bytes", exchangeId, src.remaining());
|
||||||
}
|
}
|
||||||
handler.consume(src);
|
handler.consume(src);
|
||||||
}
|
}
|
||||||
|
@ -178,7 +164,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
@Override
|
@Override
|
||||||
public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
|
public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("{} end of response data", exchangeId);
|
log.debug("{}: end of response data", exchangeId);
|
||||||
}
|
}
|
||||||
handler.streamEnd(trailers);
|
handler.streamEnd(trailers);
|
||||||
}
|
}
|
||||||
|
@ -186,7 +172,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
@Override
|
@Override
|
||||||
public void failed(final Exception cause) {
|
public void failed(final Exception cause) {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("{} execution failed: {}", exchangeId, cause.getMessage());
|
log.debug("{}: execution failed: {}", exchangeId, cause.getMessage());
|
||||||
}
|
}
|
||||||
handler.failed(cause);
|
handler.failed(cause);
|
||||||
}
|
}
|
||||||
|
@ -194,7 +180,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("{} execution cancelled", exchangeId);
|
log.debug("{}: execution cancelled", exchangeId);
|
||||||
}
|
}
|
||||||
handler.cancel();
|
handler.cancel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
package org.apache.hc.client5.http.impl.async;
|
package org.apache.hc.client5.http.impl.async;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
|
@ -47,13 +46,10 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||||
import org.apache.hc.core5.concurrent.Cancellable;
|
import org.apache.hc.core5.concurrent.Cancellable;
|
||||||
import org.apache.hc.core5.concurrent.ComplexCancellable;
|
import org.apache.hc.core5.concurrent.ComplexCancellable;
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||||
import org.apache.hc.core5.function.Callback;
|
|
||||||
import org.apache.hc.core5.function.Resolver;
|
|
||||||
import org.apache.hc.core5.http.EntityDetails;
|
import org.apache.hc.core5.http.EntityDetails;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
|
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
|
||||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
||||||
|
@ -106,31 +102,17 @@ public final class MinimalH2AsyncClient extends AbstractMinimalHttpAsyncClientBa
|
||||||
final DnsResolver dnsResolver,
|
final DnsResolver dnsResolver,
|
||||||
final TlsStrategy tlsStrategy) {
|
final TlsStrategy tlsStrategy) {
|
||||||
super(new DefaultConnectingIOReactor(
|
super(new DefaultConnectingIOReactor(
|
||||||
eventHandlerFactory,
|
eventHandlerFactory,
|
||||||
reactorConfig,
|
reactorConfig,
|
||||||
workerThreadFactory,
|
workerThreadFactory,
|
||||||
LoggingIOSessionDecorator.INSTANCE,
|
LoggingIOSessionDecorator.INSTANCE,
|
||||||
LoggingExceptionCallback.INSTANCE,
|
LoggingExceptionCallback.INSTANCE,
|
||||||
null,
|
null,
|
||||||
new Callback<IOSession>() {
|
ioSession -> ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE)),
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final IOSession ioSession) {
|
|
||||||
ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}),
|
|
||||||
pushConsumerRegistry,
|
pushConsumerRegistry,
|
||||||
threadFactory);
|
threadFactory);
|
||||||
this.connectionInitiator = new MultihomeConnectionInitiator(getConnectionInitiator(), dnsResolver);
|
this.connectionInitiator = new MultihomeConnectionInitiator(getConnectionInitiator(), dnsResolver);
|
||||||
this.connPool = new H2ConnPool(this.connectionInitiator, new Resolver<HttpHost, InetSocketAddress>() {
|
this.connPool = new H2ConnPool(this.connectionInitiator, object -> null, tlsStrategy);
|
||||||
|
|
||||||
@Override
|
|
||||||
public InetSocketAddress resolve(final HttpHost object) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, tlsStrategy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -144,137 +126,122 @@ public final class MinimalH2AsyncClient extends AbstractMinimalHttpAsyncClientBa
|
||||||
throw new CancellationException("Request execution cancelled");
|
throw new CancellationException("Request execution cancelled");
|
||||||
}
|
}
|
||||||
final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
|
final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
|
||||||
exchangeHandler.produceRequest(new RequestChannel() {
|
exchangeHandler.produceRequest((request, entityDetails, context1) -> {
|
||||||
|
RequestConfig requestConfig = null;
|
||||||
@Override
|
if (request instanceof Configurable) {
|
||||||
public void sendRequest(
|
requestConfig = ((Configurable) request).getConfig();
|
||||||
final HttpRequest request,
|
|
||||||
final EntityDetails entityDetails,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
RequestConfig requestConfig = null;
|
|
||||||
if (request instanceof Configurable) {
|
|
||||||
requestConfig = ((Configurable) request).getConfig();
|
|
||||||
}
|
|
||||||
if (requestConfig != null) {
|
|
||||||
clientContext.setRequestConfig(requestConfig);
|
|
||||||
} else {
|
|
||||||
requestConfig = clientContext.getRequestConfig();
|
|
||||||
}
|
|
||||||
final Timeout connectTimeout = requestConfig.getConnectTimeout();
|
|
||||||
final HttpHost target = new HttpHost(request.getScheme(), request.getAuthority());
|
|
||||||
|
|
||||||
final Future<IOSession> sessionFuture = connPool.getSession(target, connectTimeout,
|
|
||||||
new FutureCallback<IOSession>() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void completed(final IOSession session) {
|
|
||||||
final AsyncClientExchangeHandler internalExchangeHandler = new AsyncClientExchangeHandler() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void releaseResources() {
|
|
||||||
exchangeHandler.releaseResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void failed(final Exception cause) {
|
|
||||||
exchangeHandler.failed(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancel() {
|
|
||||||
failed(new RequestFailedException("Request aborted"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void produceRequest(
|
|
||||||
final RequestChannel channel,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
channel.sendRequest(request, entityDetails, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int available() {
|
|
||||||
return exchangeHandler.available();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void produce(final DataStreamChannel channel) throws IOException {
|
|
||||||
exchangeHandler.produce(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void consumeInformation(
|
|
||||||
final HttpResponse response,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
exchangeHandler.consumeInformation(response, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void consumeResponse(
|
|
||||||
final HttpResponse response,
|
|
||||||
final EntityDetails entityDetails,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
exchangeHandler.consumeResponse(response, entityDetails, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
|
|
||||||
exchangeHandler.updateCapacity(capacityChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void consume(final ByteBuffer src) throws IOException {
|
|
||||||
exchangeHandler.consume(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
|
|
||||||
exchangeHandler.streamEnd(trailers);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
if (LOG.isDebugEnabled()) {
|
|
||||||
final String exchangeId = ExecSupport.getNextExchangeId();
|
|
||||||
LOG.debug("{} executing message exchange {}", exchangeId, ConnPoolSupport.getId(session));
|
|
||||||
session.enqueue(
|
|
||||||
new RequestExecutionCommand(
|
|
||||||
new LoggingAsyncClientExchangeHandler(LOG, exchangeId, internalExchangeHandler),
|
|
||||||
pushHandlerFactory,
|
|
||||||
cancellable,
|
|
||||||
clientContext),
|
|
||||||
Command.Priority.NORMAL);
|
|
||||||
} else {
|
|
||||||
session.enqueue(
|
|
||||||
new RequestExecutionCommand(
|
|
||||||
internalExchangeHandler,
|
|
||||||
pushHandlerFactory,
|
|
||||||
cancellable,
|
|
||||||
clientContext),
|
|
||||||
Command.Priority.NORMAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void failed(final Exception ex) {
|
|
||||||
exchangeHandler.failed(ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelled() {
|
|
||||||
exchangeHandler.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
cancellable.setDependency(new Cancellable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean cancel() {
|
|
||||||
return sessionFuture.cancel(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
if (requestConfig != null) {
|
||||||
|
clientContext.setRequestConfig(requestConfig);
|
||||||
|
} else {
|
||||||
|
requestConfig = clientContext.getRequestConfig();
|
||||||
|
}
|
||||||
|
final Timeout connectTimeout = requestConfig.getConnectTimeout();
|
||||||
|
final HttpHost target = new HttpHost(request.getScheme(), request.getAuthority());
|
||||||
|
|
||||||
|
final Future<IOSession> sessionFuture = connPool.getSession(target, connectTimeout,
|
||||||
|
new FutureCallback<IOSession>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void completed(final IOSession session) {
|
||||||
|
final AsyncClientExchangeHandler internalExchangeHandler = new AsyncClientExchangeHandler() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void releaseResources() {
|
||||||
|
exchangeHandler.releaseResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(final Exception cause) {
|
||||||
|
exchangeHandler.failed(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
failed(new RequestFailedException("Request aborted"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void produceRequest(
|
||||||
|
final RequestChannel channel,
|
||||||
|
final HttpContext context1) throws HttpException, IOException {
|
||||||
|
channel.sendRequest(request, entityDetails, context1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() {
|
||||||
|
return exchangeHandler.available();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void produce(final DataStreamChannel channel) throws IOException {
|
||||||
|
exchangeHandler.produce(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consumeInformation(
|
||||||
|
final HttpResponse response,
|
||||||
|
final HttpContext context1) throws HttpException, IOException {
|
||||||
|
exchangeHandler.consumeInformation(response, context1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consumeResponse(
|
||||||
|
final HttpResponse response,
|
||||||
|
final EntityDetails entityDetails,
|
||||||
|
final HttpContext context1) throws HttpException, IOException {
|
||||||
|
exchangeHandler.consumeResponse(response, entityDetails, context1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
|
||||||
|
exchangeHandler.updateCapacity(capacityChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consume(final ByteBuffer src) throws IOException {
|
||||||
|
exchangeHandler.consume(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
|
||||||
|
exchangeHandler.streamEnd(trailers);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
final String exchangeId = ExecSupport.getNextExchangeId();
|
||||||
|
LOG.debug("{} executing message exchange {}", exchangeId, ConnPoolSupport.getId(session));
|
||||||
|
session.enqueue(
|
||||||
|
new RequestExecutionCommand(
|
||||||
|
new LoggingAsyncClientExchangeHandler(LOG, exchangeId, internalExchangeHandler),
|
||||||
|
pushHandlerFactory,
|
||||||
|
cancellable,
|
||||||
|
clientContext),
|
||||||
|
Command.Priority.NORMAL);
|
||||||
|
} else {
|
||||||
|
session.enqueue(
|
||||||
|
new RequestExecutionCommand(
|
||||||
|
internalExchangeHandler,
|
||||||
|
pushHandlerFactory,
|
||||||
|
cancellable,
|
||||||
|
clientContext),
|
||||||
|
Command.Priority.NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(final Exception ex) {
|
||||||
|
exchangeHandler.failed(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelled() {
|
||||||
|
exchangeHandler.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
cancellable.setDependency(() -> sessionFuture.cancel(true));
|
||||||
}, context);
|
}, context);
|
||||||
} catch (final HttpException | IOException | IllegalStateException ex) {
|
} catch (final HttpException | IOException | IllegalStateException ex) {
|
||||||
exchangeHandler.failed(ex);
|
exchangeHandler.failed(ex);
|
||||||
|
|
|
@ -54,12 +54,10 @@ import org.apache.hc.core5.concurrent.Cancellable;
|
||||||
import org.apache.hc.core5.concurrent.ComplexCancellable;
|
import org.apache.hc.core5.concurrent.ComplexCancellable;
|
||||||
import org.apache.hc.core5.concurrent.ComplexFuture;
|
import org.apache.hc.core5.concurrent.ComplexFuture;
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||||
import org.apache.hc.core5.function.Callback;
|
|
||||||
import org.apache.hc.core5.http.EntityDetails;
|
import org.apache.hc.core5.http.EntityDetails;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
|
||||||
|
@ -78,7 +76,6 @@ import org.apache.hc.core5.reactor.Command;
|
||||||
import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
|
import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
|
||||||
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
|
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
import org.apache.hc.core5.reactor.IOSession;
|
|
||||||
import org.apache.hc.core5.util.Args;
|
import org.apache.hc.core5.util.Args;
|
||||||
import org.apache.hc.core5.util.Asserts;
|
import org.apache.hc.core5.util.Asserts;
|
||||||
import org.apache.hc.core5.util.TimeValue;
|
import org.apache.hc.core5.util.TimeValue;
|
||||||
|
@ -116,20 +113,13 @@ public final class MinimalHttpAsyncClient extends AbstractMinimalHttpAsyncClient
|
||||||
final AsyncClientConnectionManager manager,
|
final AsyncClientConnectionManager manager,
|
||||||
final SchemePortResolver schemePortResolver) {
|
final SchemePortResolver schemePortResolver) {
|
||||||
super(new DefaultConnectingIOReactor(
|
super(new DefaultConnectingIOReactor(
|
||||||
eventHandlerFactory,
|
eventHandlerFactory,
|
||||||
reactorConfig,
|
reactorConfig,
|
||||||
workerThreadFactory,
|
workerThreadFactory,
|
||||||
LoggingIOSessionDecorator.INSTANCE,
|
LoggingIOSessionDecorator.INSTANCE,
|
||||||
LoggingExceptionCallback.INSTANCE,
|
LoggingExceptionCallback.INSTANCE,
|
||||||
null,
|
null,
|
||||||
new Callback<IOSession>() {
|
ioSession -> ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.NORMAL)),
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final IOSession ioSession) {
|
|
||||||
ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
}),
|
|
||||||
pushConsumerRegistry,
|
pushConsumerRegistry,
|
||||||
threadFactory);
|
threadFactory);
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
|
@ -259,180 +249,166 @@ public final class MinimalHttpAsyncClient extends AbstractMinimalHttpAsyncClient
|
||||||
throw new CancellationException("Request execution cancelled");
|
throw new CancellationException("Request execution cancelled");
|
||||||
}
|
}
|
||||||
final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
|
final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
|
||||||
exchangeHandler.produceRequest(new RequestChannel() {
|
exchangeHandler.produceRequest((request, entityDetails, context1) -> {
|
||||||
|
RequestConfig requestConfig = null;
|
||||||
|
if (request instanceof Configurable) {
|
||||||
|
requestConfig = ((Configurable) request).getConfig();
|
||||||
|
}
|
||||||
|
if (requestConfig != null) {
|
||||||
|
clientContext.setRequestConfig(requestConfig);
|
||||||
|
} else {
|
||||||
|
requestConfig = clientContext.getRequestConfig();
|
||||||
|
}
|
||||||
|
final Timeout connectionRequestTimeout = requestConfig.getConnectionRequestTimeout();
|
||||||
|
final Timeout connectTimeout = requestConfig.getConnectTimeout();
|
||||||
|
final Timeout responseTimeout = requestConfig.getResponseTimeout();
|
||||||
|
final HttpHost target = new HttpHost(request.getScheme(), request.getAuthority());
|
||||||
|
|
||||||
@Override
|
final Future<AsyncConnectionEndpoint> leaseFuture = leaseEndpoint(
|
||||||
public void sendRequest(
|
target,
|
||||||
final HttpRequest request,
|
connectionRequestTimeout,
|
||||||
final EntityDetails entityDetails,
|
connectTimeout,
|
||||||
final HttpContext context) throws HttpException, IOException {
|
clientContext,
|
||||||
RequestConfig requestConfig = null;
|
new FutureCallback<AsyncConnectionEndpoint>() {
|
||||||
if (request instanceof Configurable) {
|
|
||||||
requestConfig = ((Configurable) request).getConfig();
|
|
||||||
}
|
|
||||||
if (requestConfig != null) {
|
|
||||||
clientContext.setRequestConfig(requestConfig);
|
|
||||||
} else {
|
|
||||||
requestConfig = clientContext.getRequestConfig();
|
|
||||||
}
|
|
||||||
final Timeout connectionRequestTimeout = requestConfig.getConnectionRequestTimeout();
|
|
||||||
final Timeout connectTimeout = requestConfig.getConnectTimeout();
|
|
||||||
final Timeout responseTimeout = requestConfig.getResponseTimeout();
|
|
||||||
final HttpHost target = new HttpHost(request.getScheme(), request.getAuthority());
|
|
||||||
|
|
||||||
final Future<AsyncConnectionEndpoint> leaseFuture = leaseEndpoint(
|
@Override
|
||||||
target,
|
public void completed(final AsyncConnectionEndpoint connectionEndpoint) {
|
||||||
connectionRequestTimeout,
|
final InternalAsyncClientEndpoint endpoint = new InternalAsyncClientEndpoint(connectionEndpoint);
|
||||||
connectTimeout,
|
final AtomicInteger messageCountDown = new AtomicInteger(2);
|
||||||
clientContext,
|
final AsyncClientExchangeHandler internalExchangeHandler = new AsyncClientExchangeHandler() {
|
||||||
new FutureCallback<AsyncConnectionEndpoint>() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void completed(final AsyncConnectionEndpoint connectionEndpoint) {
|
public void releaseResources() {
|
||||||
final InternalAsyncClientEndpoint endpoint = new InternalAsyncClientEndpoint(connectionEndpoint);
|
try {
|
||||||
final AtomicInteger messageCountDown = new AtomicInteger(2);
|
exchangeHandler.releaseResources();
|
||||||
final AsyncClientExchangeHandler internalExchangeHandler = new AsyncClientExchangeHandler() {
|
} finally {
|
||||||
|
endpoint.releaseAndDiscard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void releaseResources() {
|
public void failed(final Exception cause) {
|
||||||
try {
|
try {
|
||||||
exchangeHandler.releaseResources();
|
exchangeHandler.failed(cause);
|
||||||
} finally {
|
} finally {
|
||||||
endpoint.releaseAndDiscard();
|
endpoint.releaseAndDiscard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
failed(new RequestFailedException("Request aborted"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void produceRequest(
|
||||||
|
final RequestChannel channel,
|
||||||
|
final HttpContext context1) throws HttpException, IOException {
|
||||||
|
channel.sendRequest(request, entityDetails, context1);
|
||||||
|
if (entityDetails == null) {
|
||||||
|
messageCountDown.decrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() {
|
||||||
|
return exchangeHandler.available();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void produce(final DataStreamChannel channel) throws IOException {
|
||||||
|
exchangeHandler.produce(new DataStreamChannel() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void requestOutput() {
|
||||||
|
channel.requestOutput();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void failed(final Exception cause) {
|
public int write(final ByteBuffer src) throws IOException {
|
||||||
try {
|
return channel.write(src);
|
||||||
exchangeHandler.failed(cause);
|
|
||||||
} finally {
|
|
||||||
endpoint.releaseAndDiscard();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancel() {
|
public void endStream(final List<? extends Header> trailers) throws IOException {
|
||||||
failed(new RequestFailedException("Request aborted"));
|
channel.endStream(trailers);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void produceRequest(
|
|
||||||
final RequestChannel channel,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
channel.sendRequest(request, entityDetails, context);
|
|
||||||
if (entityDetails == null) {
|
|
||||||
messageCountDown.decrementAndGet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int available() {
|
|
||||||
return exchangeHandler.available();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void produce(final DataStreamChannel channel) throws IOException {
|
|
||||||
exchangeHandler.produce(new DataStreamChannel() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void requestOutput() {
|
|
||||||
channel.requestOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int write(final ByteBuffer src) throws IOException {
|
|
||||||
return channel.write(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void endStream(final List<? extends Header> trailers) throws IOException {
|
|
||||||
channel.endStream(trailers);
|
|
||||||
if (messageCountDown.decrementAndGet() <= 0) {
|
|
||||||
endpoint.releaseAndReuse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void endStream() throws IOException {
|
|
||||||
channel.endStream();
|
|
||||||
if (messageCountDown.decrementAndGet() <= 0) {
|
|
||||||
endpoint.releaseAndReuse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void consumeInformation(
|
|
||||||
final HttpResponse response,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
exchangeHandler.consumeInformation(response, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void consumeResponse(
|
|
||||||
final HttpResponse response,
|
|
||||||
final EntityDetails entityDetails,
|
|
||||||
final HttpContext context) throws HttpException, IOException {
|
|
||||||
exchangeHandler.consumeResponse(response, entityDetails, context);
|
|
||||||
if (response.getCode() >= HttpStatus.SC_CLIENT_ERROR) {
|
|
||||||
messageCountDown.decrementAndGet();
|
|
||||||
}
|
|
||||||
if (entityDetails == null) {
|
|
||||||
if (messageCountDown.decrementAndGet() <= 0) {
|
if (messageCountDown.decrementAndGet() <= 0) {
|
||||||
endpoint.releaseAndReuse();
|
endpoint.releaseAndReuse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
|
public void endStream() throws IOException {
|
||||||
exchangeHandler.updateCapacity(capacityChannel);
|
channel.endStream();
|
||||||
}
|
if (messageCountDown.decrementAndGet() <= 0) {
|
||||||
|
endpoint.releaseAndReuse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
});
|
||||||
public void consume(final ByteBuffer src) throws IOException {
|
}
|
||||||
exchangeHandler.consume(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
|
public void consumeInformation(
|
||||||
|
final HttpResponse response,
|
||||||
|
final HttpContext context1) throws HttpException, IOException {
|
||||||
|
exchangeHandler.consumeInformation(response, context1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consumeResponse(
|
||||||
|
final HttpResponse response,
|
||||||
|
final EntityDetails entityDetails,
|
||||||
|
final HttpContext context1) throws HttpException, IOException {
|
||||||
|
exchangeHandler.consumeResponse(response, entityDetails, context1);
|
||||||
|
if (response.getCode() >= HttpStatus.SC_CLIENT_ERROR) {
|
||||||
|
messageCountDown.decrementAndGet();
|
||||||
|
}
|
||||||
|
if (entityDetails == null) {
|
||||||
if (messageCountDown.decrementAndGet() <= 0) {
|
if (messageCountDown.decrementAndGet() <= 0) {
|
||||||
endpoint.releaseAndReuse();
|
endpoint.releaseAndReuse();
|
||||||
}
|
}
|
||||||
exchangeHandler.streamEnd(trailers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
|
||||||
if (responseTimeout != null) {
|
|
||||||
endpoint.setSocketTimeout(responseTimeout);
|
|
||||||
}
|
}
|
||||||
endpoint.execute(internalExchangeHandler, pushHandlerFactory, clientContext);
|
|
||||||
|
@Override
|
||||||
|
public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
|
||||||
|
exchangeHandler.updateCapacity(capacityChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consume(final ByteBuffer src) throws IOException {
|
||||||
|
exchangeHandler.consume(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
|
||||||
|
if (messageCountDown.decrementAndGet() <= 0) {
|
||||||
|
endpoint.releaseAndReuse();
|
||||||
|
}
|
||||||
|
exchangeHandler.streamEnd(trailers);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
if (responseTimeout != null) {
|
||||||
|
endpoint.setSocketTimeout(responseTimeout);
|
||||||
}
|
}
|
||||||
|
endpoint.execute(internalExchangeHandler, pushHandlerFactory, clientContext);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void failed(final Exception ex) {
|
public void failed(final Exception ex) {
|
||||||
exchangeHandler.failed(ex);
|
exchangeHandler.failed(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cancelled() {
|
public void cancelled() {
|
||||||
exchangeHandler.cancel();
|
exchangeHandler.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
cancellable.setDependency(new Cancellable() {
|
cancellable.setDependency(() -> leaseFuture.cancel(true));
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean cancel() {
|
|
||||||
return leaseFuture.cancel(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}, context);
|
}, context);
|
||||||
|
|
||||||
} catch (final HttpException | IOException | IllegalStateException ex) {
|
} catch (final HttpException | IOException | IllegalStateException ex) {
|
||||||
|
|
|
@ -1260,7 +1260,7 @@ final class NTLMEngineImpl implements NTLMEngine {
|
||||||
|
|
||||||
Type1Message(final String domain, final String host, final Integer flags) {
|
Type1Message(final String domain, final String host, final Integer flags) {
|
||||||
super();
|
super();
|
||||||
this.flags = ((flags == null)?getDefaultFlags():flags);
|
this.flags = ((flags == null)?getDefaultFlags(): flags.intValue());
|
||||||
|
|
||||||
// See HTTPCLIENT-1662
|
// See HTTPCLIENT-1662
|
||||||
final String unqualifiedHost = host;
|
final String unqualifiedHost = host;
|
||||||
|
|
|
@ -91,11 +91,11 @@ public class AIMDBackoffManager implements BackoffManager {
|
||||||
final int curr = connPerRoute.getMaxPerRoute(route);
|
final int curr = connPerRoute.getMaxPerRoute(route);
|
||||||
final Long lastUpdate = getLastUpdate(lastRouteBackoffs, route);
|
final Long lastUpdate = getLastUpdate(lastRouteBackoffs, route);
|
||||||
final long now = clock.getCurrentTime();
|
final long now = clock.getCurrentTime();
|
||||||
if (now - lastUpdate.longValue() < coolDown.toMilliseconds()) {
|
if (now - lastUpdate < coolDown.toMilliseconds()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
connPerRoute.setMaxPerRoute(route, getBackedOffPoolSize(curr));
|
connPerRoute.setMaxPerRoute(route, getBackedOffPoolSize(curr));
|
||||||
lastRouteBackoffs.put(route, Long.valueOf(now));
|
lastRouteBackoffs.put(route, now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,19 +114,19 @@ public class AIMDBackoffManager implements BackoffManager {
|
||||||
final Long lastProbe = getLastUpdate(lastRouteProbes, route);
|
final Long lastProbe = getLastUpdate(lastRouteProbes, route);
|
||||||
final Long lastBackoff = getLastUpdate(lastRouteBackoffs, route);
|
final Long lastBackoff = getLastUpdate(lastRouteBackoffs, route);
|
||||||
final long now = clock.getCurrentTime();
|
final long now = clock.getCurrentTime();
|
||||||
if (now - lastProbe.longValue() < coolDown.toMilliseconds()
|
if (now - lastProbe < coolDown.toMilliseconds()
|
||||||
|| now - lastBackoff.longValue() < coolDown.toMilliseconds()) {
|
|| now - lastBackoff < coolDown.toMilliseconds()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
connPerRoute.setMaxPerRoute(route, max);
|
connPerRoute.setMaxPerRoute(route, max);
|
||||||
lastRouteProbes.put(route, Long.valueOf(now));
|
lastRouteProbes.put(route, now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Long getLastUpdate(final Map<HttpRoute, Long> updates, final HttpRoute route) {
|
private Long getLastUpdate(final Map<HttpRoute, Long> updates, final HttpRoute route) {
|
||||||
Long lastUpdate = updates.get(route);
|
Long lastUpdate = updates.get(route);
|
||||||
if (lastUpdate == null) {
|
if (lastUpdate == null) {
|
||||||
lastUpdate = Long.valueOf(0L);
|
lastUpdate = 0L;
|
||||||
}
|
}
|
||||||
return lastUpdate;
|
return lastUpdate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,16 +48,7 @@ class ExecChainElement {
|
||||||
public ClassicHttpResponse execute(
|
public ClassicHttpResponse execute(
|
||||||
final ClassicHttpRequest request,
|
final ClassicHttpRequest request,
|
||||||
final ExecChain.Scope scope) throws IOException, HttpException {
|
final ExecChain.Scope scope) throws IOException, HttpException {
|
||||||
return handler.execute(request, scope, new ExecChain() {
|
return handler.execute(request, scope, next != null ? next::execute : null);
|
||||||
|
|
||||||
@Override
|
|
||||||
public ClassicHttpResponse proceed(
|
|
||||||
final ClassicHttpRequest request,
|
|
||||||
final Scope scope) throws IOException, HttpException {
|
|
||||||
return next.execute(request, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
package org.apache.hc.client5.http.impl.classic;
|
package org.apache.hc.client5.http.impl.classic;
|
||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.ProxySelector;
|
import java.net.ProxySelector;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -43,8 +42,8 @@ import org.apache.hc.client5.http.HttpRequestRetryStrategy;
|
||||||
import org.apache.hc.client5.http.SchemePortResolver;
|
import org.apache.hc.client5.http.SchemePortResolver;
|
||||||
import org.apache.hc.client5.http.UserTokenHandler;
|
import org.apache.hc.client5.http.UserTokenHandler;
|
||||||
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
import org.apache.hc.client5.http.auth.AuthSchemeFactory;
|
||||||
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
|
||||||
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
import org.apache.hc.client5.http.auth.CredentialsProvider;
|
||||||
|
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||||
import org.apache.hc.client5.http.classic.BackoffManager;
|
import org.apache.hc.client5.http.classic.BackoffManager;
|
||||||
import org.apache.hc.client5.http.classic.ConnectionBackoffStrategy;
|
import org.apache.hc.client5.http.classic.ConnectionBackoffStrategy;
|
||||||
import org.apache.hc.client5.http.classic.ExecChainHandler;
|
import org.apache.hc.client5.http.classic.ExecChainHandler;
|
||||||
|
@ -87,9 +86,7 @@ import org.apache.hc.core5.annotation.Internal;
|
||||||
import org.apache.hc.core5.http.ConnectionReuseStrategy;
|
import org.apache.hc.core5.http.ConnectionReuseStrategy;
|
||||||
import org.apache.hc.core5.http.Header;
|
import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
|
||||||
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
import org.apache.hc.core5.http.HttpRequestInterceptor;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
|
||||||
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
import org.apache.hc.core5.http.HttpResponseInterceptor;
|
||||||
import org.apache.hc.core5.http.config.Lookup;
|
import org.apache.hc.core5.http.config.Lookup;
|
||||||
import org.apache.hc.core5.http.config.NamedElementChain;
|
import org.apache.hc.core5.http.config.NamedElementChain;
|
||||||
|
@ -98,7 +95,6 @@ import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||||
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
|
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
|
||||||
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
||||||
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
|
import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
import org.apache.hc.core5.http.protocol.HttpProcessor;
|
||||||
import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
|
import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
|
||||||
import org.apache.hc.core5.http.protocol.RequestContent;
|
import org.apache.hc.core5.http.protocol.RequestContent;
|
||||||
|
@ -748,13 +744,7 @@ public class HttpClientBuilder {
|
||||||
if ("true".equalsIgnoreCase(s)) {
|
if ("true".equalsIgnoreCase(s)) {
|
||||||
reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
|
reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
|
||||||
} else {
|
} else {
|
||||||
reuseStrategyCopy = new ConnectionReuseStrategy() {
|
reuseStrategyCopy = (request, response, context) -> false;
|
||||||
@Override
|
|
||||||
public boolean keepAlive(
|
|
||||||
final HttpRequest request, final HttpResponse response, final HttpContext context) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
|
reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
|
||||||
|
@ -985,18 +975,13 @@ public class HttpClientBuilder {
|
||||||
if (connManagerCopy instanceof ConnPoolControl) {
|
if (connManagerCopy instanceof ConnPoolControl) {
|
||||||
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor((ConnPoolControl<?>) connManagerCopy,
|
final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor((ConnPoolControl<?>) connManagerCopy,
|
||||||
maxIdleTime, maxIdleTime);
|
maxIdleTime, maxIdleTime);
|
||||||
closeablesCopy.add(new Closeable() {
|
closeablesCopy.add(() -> {
|
||||||
|
connectionEvictor.shutdown();
|
||||||
@Override
|
try {
|
||||||
public void close() throws IOException {
|
connectionEvictor.awaitTermination(Timeout.ofSeconds(1));
|
||||||
connectionEvictor.shutdown();
|
} catch (final InterruptedException interrupted) {
|
||||||
try {
|
Thread.currentThread().interrupt();
|
||||||
connectionEvictor.awaitTermination(Timeout.ofSeconds(1));
|
|
||||||
} catch (final InterruptedException interrupted) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
connectionEvictor.start();
|
connectionEvictor.start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,18 +159,15 @@ class ResponseEntityProxy extends HttpEntityWrapper implements EofSensorWatcher
|
||||||
public Supplier<List<? extends Header>> getTrailers() {
|
public Supplier<List<? extends Header>> getTrailers() {
|
||||||
try {
|
try {
|
||||||
final InputStream underlyingStream = super.getContent();
|
final InputStream underlyingStream = super.getContent();
|
||||||
return new Supplier<List<? extends Header>>() {
|
return () -> {
|
||||||
@Override
|
final Header[] footers;
|
||||||
public List<? extends Header> get() {
|
if (underlyingStream instanceof ChunkedInputStream) {
|
||||||
final Header[] footers;
|
final ChunkedInputStream chunkedInputStream = (ChunkedInputStream) underlyingStream;
|
||||||
if (underlyingStream instanceof ChunkedInputStream) {
|
footers = chunkedInputStream.getFooters();
|
||||||
final ChunkedInputStream chunkedInputStream = (ChunkedInputStream) underlyingStream;
|
} else {
|
||||||
footers = chunkedInputStream.getFooters();
|
footers = new Header[0];
|
||||||
} else {
|
|
||||||
footers = new Header[0];
|
|
||||||
}
|
|
||||||
return Arrays.asList(footers);
|
|
||||||
}
|
}
|
||||||
|
return Arrays.asList(footers);
|
||||||
};
|
};
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
throw new IllegalStateException("Unable to retrieve input stream", e);
|
throw new IllegalStateException("Unable to retrieve input stream", e);
|
||||||
|
|
|
@ -147,7 +147,7 @@ public class LaxExpiresHandler extends AbstractCookieAttributeHandler implements
|
||||||
final Matcher matcher = MONTH_PATTERN.matcher(content);
|
final Matcher matcher = MONTH_PATTERN.matcher(content);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
foundMonth = true;
|
foundMonth = true;
|
||||||
month = MONTHS.get(matcher.group(1).toLowerCase(Locale.ROOT));
|
month = MONTHS.get(matcher.group(1).toLowerCase(Locale.ROOT)).intValue();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ public class RFC6265CookieSpec implements CookieSpec {
|
||||||
if (cookies.size() > 1) {
|
if (cookies.size() > 1) {
|
||||||
// Create a mutable copy and sort the copy.
|
// Create a mutable copy and sort the copy.
|
||||||
sortedCookies = new ArrayList<>(cookies);
|
sortedCookies = new ArrayList<>(cookies);
|
||||||
Collections.sort(sortedCookies, CookiePriorityComparator.INSTANCE);
|
sortedCookies.sort(CookiePriorityComparator.INSTANCE);
|
||||||
} else {
|
} else {
|
||||||
sortedCookies = cookies;
|
sortedCookies = cookies;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ import org.apache.hc.core5.annotation.Internal;
|
||||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||||
import org.apache.hc.core5.concurrent.ComplexFuture;
|
import org.apache.hc.core5.concurrent.ComplexFuture;
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||||
import org.apache.hc.core5.function.Callback;
|
|
||||||
import org.apache.hc.core5.http.HttpHost;
|
import org.apache.hc.core5.http.HttpHost;
|
||||||
import org.apache.hc.core5.http.HttpVersion;
|
import org.apache.hc.core5.http.HttpVersion;
|
||||||
import org.apache.hc.core5.http.ProtocolVersion;
|
import org.apache.hc.core5.http.ProtocolVersion;
|
||||||
|
@ -250,19 +249,14 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
||||||
final TimeValue timeValue = PoolingAsyncClientConnectionManager.this.validateAfterInactivity;
|
final TimeValue timeValue = PoolingAsyncClientConnectionManager.this.validateAfterInactivity;
|
||||||
if (TimeValue.isNonNegative(timeValue) &&
|
if (TimeValue.isNonNegative(timeValue) &&
|
||||||
poolEntry.getUpdated() + timeValue.toMilliseconds() <= System.currentTimeMillis()) {
|
poolEntry.getUpdated() + timeValue.toMilliseconds() <= System.currentTimeMillis()) {
|
||||||
connection.submitCommand(new PingCommand(new BasicPingHandler(new Callback<Boolean>() {
|
connection.submitCommand(new PingCommand(new BasicPingHandler(result -> {
|
||||||
|
if (result == null || !result) {
|
||||||
@Override
|
if (LOG.isDebugEnabled()) {
|
||||||
public void execute(final Boolean result) {
|
LOG.debug("{} connection {} is stale", id, ConnPoolSupport.getId(connection));
|
||||||
if (result == null || !result) {
|
|
||||||
if (LOG.isDebugEnabled()) {
|
|
||||||
LOG.debug("{} connection {} is stale", id, ConnPoolSupport.getId(connection));
|
|
||||||
}
|
|
||||||
poolEntry.discardConnection(CloseMode.IMMEDIATE);
|
|
||||||
}
|
}
|
||||||
leaseCompleted(poolEntry);
|
poolEntry.discardConnection(CloseMode.IMMEDIATE);
|
||||||
}
|
}
|
||||||
|
leaseCompleted(poolEntry);
|
||||||
})), Command.Priority.IMMEDIATE);
|
})), Command.Priority.IMMEDIATE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,12 +81,9 @@ public class PlainConnectionSocketFactory implements ConnectionSocketFactory {
|
||||||
// Run this under a doPrivileged to support lib users that run under a SecurityManager this allows granting connect permissions
|
// Run this under a doPrivileged to support lib users that run under a SecurityManager this allows granting connect permissions
|
||||||
// only to this library
|
// only to this library
|
||||||
try {
|
try {
|
||||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
|
||||||
@Override
|
sock.connect(remoteAddress, TimeValue.isPositive(connectTimeout) ? connectTimeout.toMillisecondsIntBound() : 0);
|
||||||
public Object run() throws IOException {
|
return null;
|
||||||
sock.connect(remoteAddress, TimeValue.isPositive(connectTimeout) ? connectTimeout.toMillisecondsIntBound() : 0);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} catch (final PrivilegedActionException e) {
|
} catch (final PrivilegedActionException e) {
|
||||||
Asserts.check(e.getCause() instanceof IOException,
|
Asserts.check(e.getCause() instanceof IOException,
|
||||||
|
|
|
@ -47,10 +47,7 @@ import org.apache.hc.core5.http.ssl.TlsCiphers;
|
||||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||||
import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
|
import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
|
||||||
import org.apache.hc.core5.http2.ssl.H2TlsSupport;
|
import org.apache.hc.core5.http2.ssl.H2TlsSupport;
|
||||||
import org.apache.hc.core5.net.NamedEndpoint;
|
|
||||||
import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
|
import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
|
||||||
import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
|
|
||||||
import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
|
|
||||||
import org.apache.hc.core5.reactor.ssl.TlsDetails;
|
import org.apache.hc.core5.reactor.ssl.TlsDetails;
|
||||||
import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
|
import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
|
||||||
import org.apache.hc.core5.util.Args;
|
import org.apache.hc.core5.util.Args;
|
||||||
|
@ -93,56 +90,46 @@ abstract class AbstractClientTlsStrategy implements TlsStrategy {
|
||||||
final SocketAddress remoteAddress,
|
final SocketAddress remoteAddress,
|
||||||
final Object attachment,
|
final Object attachment,
|
||||||
final Timeout handshakeTimeout) {
|
final Timeout handshakeTimeout) {
|
||||||
tlsSession.startTls(sslContext, host, sslBufferManagement, new SSLSessionInitializer() {
|
tlsSession.startTls(sslContext, host, sslBufferManagement, (endpoint, sslEngine) -> {
|
||||||
|
|
||||||
@Override
|
final HttpVersionPolicy versionPolicy = attachment instanceof HttpVersionPolicy ?
|
||||||
public void initialize(final NamedEndpoint endpoint, final SSLEngine sslEngine) {
|
(HttpVersionPolicy) attachment : HttpVersionPolicy.NEGOTIATE;
|
||||||
|
|
||||||
final HttpVersionPolicy versionPolicy = attachment instanceof HttpVersionPolicy ?
|
final SSLParameters sslParameters = sslEngine.getSSLParameters();
|
||||||
(HttpVersionPolicy) attachment : HttpVersionPolicy.NEGOTIATE;
|
if (supportedProtocols != null) {
|
||||||
|
sslParameters.setProtocols(supportedProtocols);
|
||||||
final SSLParameters sslParameters = sslEngine.getSSLParameters();
|
} else if (versionPolicy != HttpVersionPolicy.FORCE_HTTP_1) {
|
||||||
if (supportedProtocols != null) {
|
sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
|
||||||
sslParameters.setProtocols(supportedProtocols);
|
}
|
||||||
} else if (versionPolicy != HttpVersionPolicy.FORCE_HTTP_1) {
|
if (supportedCipherSuites != null) {
|
||||||
sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
|
sslParameters.setCipherSuites(supportedCipherSuites);
|
||||||
}
|
} else if (versionPolicy == HttpVersionPolicy.FORCE_HTTP_2) {
|
||||||
if (supportedCipherSuites != null) {
|
sslParameters.setCipherSuites(TlsCiphers.excludeH2Blacklisted(sslParameters.getCipherSuites()));
|
||||||
sslParameters.setCipherSuites(supportedCipherSuites);
|
|
||||||
} else if (versionPolicy == HttpVersionPolicy.FORCE_HTTP_2) {
|
|
||||||
sslParameters.setCipherSuites(TlsCiphers.excludeH2Blacklisted(sslParameters.getCipherSuites()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (versionPolicy != HttpVersionPolicy.FORCE_HTTP_1) {
|
|
||||||
H2TlsSupport.setEnableRetransmissions(sslParameters, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
applyParameters(sslEngine, sslParameters, H2TlsSupport.selectApplicationProtocols(attachment));
|
|
||||||
|
|
||||||
initializeEngine(sslEngine);
|
|
||||||
|
|
||||||
if (LOG.isDebugEnabled()) {
|
|
||||||
LOG.debug("Enabled protocols: {}", Arrays.asList(sslEngine.getEnabledProtocols()));
|
|
||||||
LOG.debug("Enabled cipher suites:{}", Arrays.asList(sslEngine.getEnabledCipherSuites()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}, new SSLSessionVerifier() {
|
if (versionPolicy != HttpVersionPolicy.FORCE_HTTP_1) {
|
||||||
|
H2TlsSupport.setEnableRetransmissions(sslParameters, false);
|
||||||
@Override
|
|
||||||
public TlsDetails verify(final NamedEndpoint endpoint, final SSLEngine sslEngine) throws SSLException {
|
|
||||||
verifySession(host.getHostName(), sslEngine.getSession());
|
|
||||||
final TlsDetails tlsDetails = createTlsDetails(sslEngine);
|
|
||||||
final String negotiatedCipherSuite = sslEngine.getSession().getCipherSuite();
|
|
||||||
if (tlsDetails != null && ApplicationProtocol.HTTP_2.id.equals(tlsDetails.getApplicationProtocol())) {
|
|
||||||
if (TlsCiphers.isH2Blacklisted(negotiatedCipherSuite)) {
|
|
||||||
throw new SSLHandshakeException("Cipher suite `" + negotiatedCipherSuite
|
|
||||||
+ "` does not provide adequate security for HTTP/2");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tlsDetails;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyParameters(sslEngine, sslParameters, H2TlsSupport.selectApplicationProtocols(attachment));
|
||||||
|
|
||||||
|
initializeEngine(sslEngine);
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Enabled protocols: {}", Arrays.asList(sslEngine.getEnabledProtocols()));
|
||||||
|
LOG.debug("Enabled cipher suites:{}", Arrays.asList(sslEngine.getEnabledCipherSuites()));
|
||||||
|
}
|
||||||
|
}, (endpoint, sslEngine) -> {
|
||||||
|
verifySession(host.getHostName(), sslEngine.getSession());
|
||||||
|
final TlsDetails tlsDetails = createTlsDetails(sslEngine);
|
||||||
|
final String negotiatedCipherSuite = sslEngine.getSession().getCipherSuite();
|
||||||
|
if (tlsDetails != null && ApplicationProtocol.HTTP_2.id.equals(tlsDetails.getApplicationProtocol())) {
|
||||||
|
if (TlsCiphers.isH2Blacklisted(negotiatedCipherSuite)) {
|
||||||
|
throw new SSLHandshakeException("Cipher suite `" + negotiatedCipherSuite
|
||||||
|
+ "` does not provide adequate security for HTTP/2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tlsDetails;
|
||||||
}, handshakeTimeout);
|
}, handshakeTimeout);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,14 +171,11 @@ public class ClientTlsStrategyBuilder {
|
||||||
if (tlsDetailsFactory != null) {
|
if (tlsDetailsFactory != null) {
|
||||||
tlsDetailsFactoryCopy = tlsDetailsFactory;
|
tlsDetailsFactoryCopy = tlsDetailsFactory;
|
||||||
} else {
|
} else {
|
||||||
tlsDetailsFactoryCopy = new Factory<SSLEngine, TlsDetails>() {
|
tlsDetailsFactoryCopy = sslEngine -> {
|
||||||
@Override
|
final SSLSession sslSession = sslEngine.getSession();
|
||||||
public TlsDetails create(final SSLEngine sslEngine) {
|
final String applicationProtocol = ReflectionUtils.callGetter(sslEngine,
|
||||||
final SSLSession sslSession = sslEngine.getSession();
|
"ApplicationProtocol", String.class);
|
||||||
final String applicationProtocol = ReflectionUtils.callGetter(sslEngine,
|
return new TlsDetails(sslSession, applicationProtocol);
|
||||||
"ApplicationProtocol", String.class);
|
|
||||||
return new TlsDetails(sslSession, applicationProtocol);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return new DefaultClientTlsStrategy(
|
return new DefaultClientTlsStrategy(
|
||||||
|
|
|
@ -109,7 +109,7 @@ public class ConscryptClientTlsStrategy extends AbstractClientTlsStrategy {
|
||||||
try {
|
try {
|
||||||
final Class<?> clazz = Class.forName("org.conscrypt.Conscrypt");
|
final Class<?> clazz = Class.forName("org.conscrypt.Conscrypt");
|
||||||
final Method method = clazz.getMethod("isAvailable");
|
final Method method = clazz.getMethod("isAvailable");
|
||||||
return (Boolean) method.invoke(null);
|
return ((Boolean) method.invoke(null)).booleanValue();
|
||||||
} catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
} catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,14 +50,7 @@ public final class HttpsSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getProperty(final String key) {
|
private static String getProperty(final String key) {
|
||||||
return AccessController.doPrivileged(new PrivilegedAction<String>() {
|
return AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty(key));
|
||||||
|
|
||||||
@Override
|
|
||||||
public String run() {
|
|
||||||
return System.getProperty(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getSystemProtocols() {
|
public static String[] getSystemProtocols() {
|
||||||
|
|
|
@ -213,12 +213,9 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
|
||||||
// Run this under a doPrivileged to support lib users that run under a SecurityManager this allows granting connect permissions
|
// Run this under a doPrivileged to support lib users that run under a SecurityManager this allows granting connect permissions
|
||||||
// only to this library
|
// only to this library
|
||||||
try {
|
try {
|
||||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
|
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
|
||||||
@Override
|
sock.connect(remoteAddress, connectTimeout != null ? connectTimeout.toMillisecondsIntBound() : 0);
|
||||||
public Object run() throws IOException {
|
return null;
|
||||||
sock.connect(remoteAddress, connectTimeout != null ? connectTimeout.toMillisecondsIntBound() : 0);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} catch (final PrivilegedActionException e) {
|
} catch (final PrivilegedActionException e) {
|
||||||
Asserts.check(e.getCause() instanceof IOException,
|
Asserts.check(e.getCause() instanceof IOException,
|
||||||
|
|
|
@ -29,7 +29,6 @@ package org.apache.hc.client5.http.entity;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
@ -95,14 +94,7 @@ public class TestDecompressingEntity {
|
||||||
static class ChecksumEntity extends DecompressingEntity {
|
static class ChecksumEntity extends DecompressingEntity {
|
||||||
|
|
||||||
public ChecksumEntity(final HttpEntity wrapped, final Checksum checksum) {
|
public ChecksumEntity(final HttpEntity wrapped, final Checksum checksum) {
|
||||||
super(wrapped, new InputStreamFactory() {
|
super(wrapped, inStream -> new CheckedInputStream(inStream, checksum));
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream create(final InputStream inStream) throws IOException {
|
|
||||||
return new CheckedInputStream(inStream, checksum);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.http.examples;
|
package org.apache.hc.client5.http.examples;
|
||||||
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
@ -50,7 +49,6 @@ import org.apache.hc.core5.http.message.StatusLine;
|
||||||
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||||
import org.apache.hc.core5.io.CloseMode;
|
import org.apache.hc.core5.io.CloseMode;
|
||||||
import org.apache.hc.core5.ssl.SSLContexts;
|
import org.apache.hc.core5.ssl.SSLContexts;
|
||||||
import org.apache.hc.core5.ssl.TrustStrategy;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This example demonstrates how to create secure connections with a custom SSL
|
* This example demonstrates how to create secure connections with a custom SSL
|
||||||
|
@ -61,16 +59,9 @@ public class AsyncClientCustomSSL {
|
||||||
public static void main(final String[] args) throws Exception {
|
public static void main(final String[] args) throws Exception {
|
||||||
// Trust standard CA and those trusted by our custom strategy
|
// Trust standard CA and those trusted by our custom strategy
|
||||||
final SSLContext sslcontext = SSLContexts.custom()
|
final SSLContext sslcontext = SSLContexts.custom()
|
||||||
.loadTrustMaterial(new TrustStrategy() {
|
.loadTrustMaterial((chain, authType) -> {
|
||||||
|
final X509Certificate cert = chain[0];
|
||||||
@Override
|
return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
|
||||||
public boolean isTrusted(
|
|
||||||
final X509Certificate[] chain,
|
|
||||||
final String authType) throws CertificateException {
|
|
||||||
final X509Certificate cert = chain[0];
|
|
||||||
return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
|
final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
|
||||||
|
|
|
@ -35,14 +35,12 @@ import org.apache.hc.client5.http.async.methods.AbstractBinPushConsumer;
|
||||||
import org.apache.hc.client5.http.async.methods.AbstractCharResponseConsumer;
|
import org.apache.hc.client5.http.async.methods.AbstractCharResponseConsumer;
|
||||||
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||||
import org.apache.hc.core5.function.Supplier;
|
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
import org.apache.hc.core5.http.HttpRequest;
|
||||||
import org.apache.hc.core5.http.HttpResponse;
|
import org.apache.hc.core5.http.HttpResponse;
|
||||||
import org.apache.hc.core5.http.message.BasicHttpRequest;
|
import org.apache.hc.core5.http.message.BasicHttpRequest;
|
||||||
import org.apache.hc.core5.http.message.StatusLine;
|
import org.apache.hc.core5.http.message.StatusLine;
|
||||||
import org.apache.hc.core5.http.nio.AsyncPushConsumer;
|
|
||||||
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
|
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
|
||||||
import org.apache.hc.core5.http.support.BasicRequestBuilder;
|
import org.apache.hc.core5.http.support.BasicRequestBuilder;
|
||||||
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
import org.apache.hc.core5.http2.HttpVersionPolicy;
|
||||||
|
@ -74,43 +72,36 @@ public class AsyncClientH2ServerPush {
|
||||||
|
|
||||||
client.start();
|
client.start();
|
||||||
|
|
||||||
client.register("*", new Supplier<AsyncPushConsumer>() {
|
client.register("*", () -> new AbstractBinPushConsumer() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncPushConsumer get() {
|
protected void start(
|
||||||
return new AbstractBinPushConsumer() {
|
final HttpRequest promise,
|
||||||
|
final HttpResponse response,
|
||||||
|
final ContentType contentType) throws HttpException, IOException {
|
||||||
|
System.out.println(promise.getPath() + " (push)->" + new StatusLine(response));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void start(
|
protected int capacityIncrement() {
|
||||||
final HttpRequest promise,
|
return Integer.MAX_VALUE;
|
||||||
final HttpResponse response,
|
}
|
||||||
final ContentType contentType) throws HttpException, IOException {
|
|
||||||
System.out.println(promise.getPath() + " (push)->" + new StatusLine(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int capacityIncrement() {
|
protected void data(final ByteBuffer data, final boolean endOfStream) throws IOException {
|
||||||
return Integer.MAX_VALUE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void data(final ByteBuffer data, final boolean endOfStream) throws IOException {
|
protected void completed() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void completed() {
|
public void failed(final Exception cause) {
|
||||||
}
|
System.out.println("(push)->" + cause);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void failed(final Exception cause) {
|
public void releaseResources() {
|
||||||
System.out.println("(push)->" + cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void releaseResources() {
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,9 +33,6 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.async.AsyncExecCallback;
|
|
||||||
import org.apache.hc.client5.http.async.AsyncExecChain;
|
|
||||||
import org.apache.hc.client5.http.async.AsyncExecChainHandler;
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
|
@ -55,7 +52,6 @@ import org.apache.hc.core5.http.impl.BasicEntityDetails;
|
||||||
import org.apache.hc.core5.http.message.BasicHttpResponse;
|
import org.apache.hc.core5.http.message.BasicHttpResponse;
|
||||||
import org.apache.hc.core5.http.message.StatusLine;
|
import org.apache.hc.core5.http.message.StatusLine;
|
||||||
import org.apache.hc.core5.http.nio.AsyncDataConsumer;
|
import org.apache.hc.core5.http.nio.AsyncDataConsumer;
|
||||||
import org.apache.hc.core5.http.nio.AsyncEntityProducer;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||||
import org.apache.hc.core5.io.CloseMode;
|
import org.apache.hc.core5.io.CloseMode;
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
|
@ -93,29 +89,19 @@ public class AsyncClientInterceptors {
|
||||||
|
|
||||||
// Simulate a 404 response for some requests without passing the message down to the backend
|
// Simulate a 404 response for some requests without passing the message down to the backend
|
||||||
|
|
||||||
.addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", new AsyncExecChainHandler() {
|
.addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", (request, requestEntityProducer, scope, chain, asyncExecCallback) -> {
|
||||||
|
final Header idHeader = request.getFirstHeader("request-id");
|
||||||
@Override
|
if (idHeader != null && "13".equalsIgnoreCase(idHeader.getValue())) {
|
||||||
public void execute(
|
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
|
||||||
final HttpRequest request,
|
final ByteBuffer content = ByteBuffer.wrap("bad luck".getBytes(StandardCharsets.US_ASCII));
|
||||||
final AsyncEntityProducer requestEntityProducer,
|
final AsyncDataConsumer asyncDataConsumer = asyncExecCallback.handleResponse(
|
||||||
final AsyncExecChain.Scope scope,
|
response,
|
||||||
final AsyncExecChain chain,
|
new BasicEntityDetails(content.remaining(), ContentType.TEXT_PLAIN));
|
||||||
final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
|
asyncDataConsumer.consume(content);
|
||||||
final Header idHeader = request.getFirstHeader("request-id");
|
asyncDataConsumer.streamEnd(null);
|
||||||
if (idHeader != null && "13".equalsIgnoreCase(idHeader.getValue())) {
|
} else {
|
||||||
final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
|
chain.proceed(request, requestEntityProducer, scope, asyncExecCallback);
|
||||||
final ByteBuffer content = ByteBuffer.wrap("bad luck".getBytes(StandardCharsets.US_ASCII));
|
|
||||||
final AsyncDataConsumer asyncDataConsumer = asyncExecCallback.handleResponse(
|
|
||||||
response,
|
|
||||||
new BasicEntityDetails(content.remaining(), ContentType.TEXT_PLAIN));
|
|
||||||
asyncDataConsumer.consume(content);
|
|
||||||
asyncDataConsumer.streamEnd(null);
|
|
||||||
} else {
|
|
||||||
chain.proceed(request, requestEntityProducer, scope, asyncExecCallback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -27,12 +27,8 @@
|
||||||
|
|
||||||
package org.apache.hc.client5.http.examples;
|
package org.apache.hc.client5.http.examples;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.async.AsyncExecCallback;
|
|
||||||
import org.apache.hc.client5.http.async.AsyncExecChain;
|
|
||||||
import org.apache.hc.client5.http.async.AsyncExecChainHandler;
|
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
|
||||||
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
|
||||||
|
@ -43,10 +39,7 @@ import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
|
||||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
|
||||||
import org.apache.hc.core5.http.HttpRequest;
|
|
||||||
import org.apache.hc.core5.http.message.StatusLine;
|
import org.apache.hc.core5.http.message.StatusLine;
|
||||||
import org.apache.hc.core5.http.nio.AsyncEntityProducer;
|
|
||||||
import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
|
import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
|
||||||
import org.apache.hc.core5.io.CloseMode;
|
import org.apache.hc.core5.io.CloseMode;
|
||||||
import org.apache.hc.core5.reactor.IOReactorConfig;
|
import org.apache.hc.core5.reactor.IOReactorConfig;
|
||||||
|
@ -66,23 +59,13 @@ public class AsyncClientMessageTrailers {
|
||||||
|
|
||||||
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
|
final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
|
||||||
.setIOReactorConfig(ioReactorConfig)
|
.setIOReactorConfig(ioReactorConfig)
|
||||||
.addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", new AsyncExecChainHandler() {
|
.addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", (request, entityProducer, scope, chain, asyncExecCallback) -> {
|
||||||
|
// Send MD5 hash in a trailer by decorating the original entity producer
|
||||||
@Override
|
chain.proceed(
|
||||||
public void execute(
|
request,
|
||||||
final HttpRequest request,
|
entityProducer != null ? new DigestingEntityProducer("MD5", entityProducer) : null,
|
||||||
final AsyncEntityProducer entityProducer,
|
scope,
|
||||||
final AsyncExecChain.Scope scope,
|
asyncExecCallback);
|
||||||
final AsyncExecChain chain,
|
|
||||||
final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
|
|
||||||
// Send MD5 hash in a trailer by decorating the original entity producer
|
|
||||||
chain.proceed(
|
|
||||||
request,
|
|
||||||
entityProducer != null ? new DigestingEntityProducer("MD5", entityProducer) : null,
|
|
||||||
scope,
|
|
||||||
asyncExecCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.http.examples;
|
package org.apache.hc.client5.http.examples;
|
||||||
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
@ -44,7 +43,6 @@ import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
|
||||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
import org.apache.hc.core5.http.ssl.TLS;
|
import org.apache.hc.core5.http.ssl.TLS;
|
||||||
import org.apache.hc.core5.ssl.SSLContexts;
|
import org.apache.hc.core5.ssl.SSLContexts;
|
||||||
import org.apache.hc.core5.ssl.TrustStrategy;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This example demonstrates how to create secure connections with a custom SSL
|
* This example demonstrates how to create secure connections with a custom SSL
|
||||||
|
@ -55,16 +53,9 @@ public class ClientCustomSSL {
|
||||||
public final static void main(final String[] args) throws Exception {
|
public final static void main(final String[] args) throws Exception {
|
||||||
// Trust standard CA and those trusted by our custom strategy
|
// Trust standard CA and those trusted by our custom strategy
|
||||||
final SSLContext sslcontext = SSLContexts.custom()
|
final SSLContext sslcontext = SSLContexts.custom()
|
||||||
.loadTrustMaterial(new TrustStrategy() {
|
.loadTrustMaterial((chain, authType) -> {
|
||||||
|
final X509Certificate cert = chain[0];
|
||||||
@Override
|
return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
|
||||||
public boolean isTrusted(
|
|
||||||
final X509Certificate[] chain,
|
|
||||||
final String authType) throws CertificateException {
|
|
||||||
final X509Certificate cert = chain[0];
|
|
||||||
return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
// Allow TLSv1.2 protocol only
|
// Allow TLSv1.2 protocol only
|
||||||
|
|
|
@ -30,14 +30,11 @@ package org.apache.hc.client5.http.examples;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.classic.ExecChain;
|
|
||||||
import org.apache.hc.client5.http.classic.ExecChainHandler;
|
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.ChainElement;
|
import org.apache.hc.client5.http.impl.ChainElement;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.ContentType;
|
import org.apache.hc.core5.http.ContentType;
|
||||||
import org.apache.hc.core5.http.EntityDetails;
|
import org.apache.hc.core5.http.EntityDetails;
|
||||||
|
@ -77,24 +74,16 @@ public class ClientInterceptors {
|
||||||
|
|
||||||
// Simulate a 404 response for some requests without passing the message down to the backend
|
// Simulate a 404 response for some requests without passing the message down to the backend
|
||||||
|
|
||||||
.addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", new ExecChainHandler() {
|
.addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", (request, scope, chain) -> {
|
||||||
|
|
||||||
@Override
|
final Header idHeader = request.getFirstHeader("request-id");
|
||||||
public ClassicHttpResponse execute(
|
if (idHeader != null && "13".equalsIgnoreCase(idHeader.getValue())) {
|
||||||
final ClassicHttpRequest request,
|
final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
|
||||||
final ExecChain.Scope scope,
|
response.setEntity(new StringEntity("bad luck", ContentType.TEXT_PLAIN));
|
||||||
final ExecChain chain) throws IOException, HttpException {
|
return response;
|
||||||
|
} else {
|
||||||
final Header idHeader = request.getFirstHeader("request-id");
|
return chain.proceed(request, scope);
|
||||||
if (idHeader != null && "13".equalsIgnoreCase(idHeader.getValue())) {
|
|
||||||
final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
|
|
||||||
response.setEntity(new StringEntity("bad luck", ContentType.TEXT_PLAIN));
|
|
||||||
return response;
|
|
||||||
} else {
|
|
||||||
return chain.proceed(request, scope);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.build()) {
|
.build()) {
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hc.client5.http.examples;
|
package org.apache.hc.client5.http.examples;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
@ -41,7 +40,6 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuil
|
||||||
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||||
|
|
||||||
|
@ -60,12 +58,9 @@ public class ClientWithRequestFuture {
|
||||||
try (final FutureRequestExecutionService requestExecService = new FutureRequestExecutionService(
|
try (final FutureRequestExecutionService requestExecService = new FutureRequestExecutionService(
|
||||||
httpclient, execService)) {
|
httpclient, execService)) {
|
||||||
// Because things are asynchronous, you must provide a HttpClientResponseHandler
|
// Because things are asynchronous, you must provide a HttpClientResponseHandler
|
||||||
final HttpClientResponseHandler<Boolean> handler = new HttpClientResponseHandler<Boolean>() {
|
final HttpClientResponseHandler<Boolean> handler = response -> {
|
||||||
@Override
|
// simply return true if the status was OK
|
||||||
public Boolean handleResponse(final ClassicHttpResponse response) throws IOException {
|
return response.getCode() == HttpStatus.SC_OK;
|
||||||
// simply return true if the status was OK
|
|
||||||
return response.getCode() == HttpStatus.SC_OK;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Simple request ...
|
// Simple request ...
|
||||||
|
|
|
@ -27,13 +27,10 @@
|
||||||
|
|
||||||
package org.apache.hc.client5.http.examples;
|
package org.apache.hc.client5.http.examples;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.hc.client5.http.ClientProtocolException;
|
import org.apache.hc.client5.http.ClientProtocolException;
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
import org.apache.hc.client5.http.classic.methods.HttpGet;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
|
||||||
import org.apache.hc.core5.http.HttpEntity;
|
import org.apache.hc.core5.http.HttpEntity;
|
||||||
import org.apache.hc.core5.http.HttpStatus;
|
import org.apache.hc.core5.http.HttpStatus;
|
||||||
import org.apache.hc.core5.http.ParseException;
|
import org.apache.hc.core5.http.ParseException;
|
||||||
|
@ -53,24 +50,18 @@ public class ClientWithResponseHandler {
|
||||||
System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());
|
System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());
|
||||||
|
|
||||||
// Create a custom response handler
|
// Create a custom response handler
|
||||||
final HttpClientResponseHandler<String> responseHandler = new HttpClientResponseHandler<String>() {
|
final HttpClientResponseHandler<String> responseHandler = response -> {
|
||||||
|
final int status = response.getCode();
|
||||||
@Override
|
if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
|
||||||
public String handleResponse(
|
final HttpEntity entity = response.getEntity();
|
||||||
final ClassicHttpResponse response) throws IOException {
|
try {
|
||||||
final int status = response.getCode();
|
return entity != null ? EntityUtils.toString(entity) : null;
|
||||||
if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
|
} catch (final ParseException ex) {
|
||||||
final HttpEntity entity = response.getEntity();
|
throw new ClientProtocolException(ex);
|
||||||
try {
|
|
||||||
return entity != null ? EntityUtils.toString(entity) : null;
|
|
||||||
} catch (final ParseException ex) {
|
|
||||||
throw new ClientProtocolException(ex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new ClientProtocolException("Unexpected response status: " + status);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throw new ClientProtocolException("Unexpected response status: " + status);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
final String responseBody = httpclient.execute(httpget, responseHandler);
|
final String responseBody = httpclient.execute(httpget, responseHandler);
|
||||||
System.out.println("----------------------------------------");
|
System.out.println("----------------------------------------");
|
||||||
|
|
|
@ -50,10 +50,7 @@ import org.apache.hc.core5.util.Timeout;
|
||||||
import org.reactivestreams.Publisher;
|
import org.reactivestreams.Publisher;
|
||||||
|
|
||||||
import io.reactivex.Flowable;
|
import io.reactivex.Flowable;
|
||||||
import io.reactivex.Notification;
|
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.functions.Consumer;
|
|
||||||
import io.reactivex.functions.Function;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This example demonstrates a reactive, full-duplex HTTP/1.1 message exchange using RxJava.
|
* This example demonstrates a reactive, full-duplex HTTP/1.1 message exchange using RxJava.
|
||||||
|
@ -92,21 +89,13 @@ public class ReactiveClientFullDuplexExchange {
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
|
||||||
Observable.fromPublisher(streamingResponse.getBody())
|
Observable.fromPublisher(streamingResponse.getBody())
|
||||||
.map(new Function<ByteBuffer, String>() {
|
.map(byteBuffer -> {
|
||||||
@Override
|
final byte[] string = new byte[byteBuffer.remaining()];
|
||||||
public String apply(final ByteBuffer byteBuffer) throws Exception {
|
byteBuffer.get(string);
|
||||||
final byte[] string = new byte[byteBuffer.remaining()];
|
return new String(string);
|
||||||
byteBuffer.get(string);
|
|
||||||
return new String(string);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.materialize()
|
.materialize()
|
||||||
.forEach(new Consumer<Notification<String>>() {
|
.forEach(System.out::println);
|
||||||
@Override
|
|
||||||
public void accept(final Notification<String> byteBufferNotification) throws Exception {
|
|
||||||
System.out.println(byteBufferNotification);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
requestFuture.get(1, TimeUnit.MINUTES);
|
requestFuture.get(1, TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
|
|
@ -82,14 +82,14 @@ public final class MockConnPoolControl implements ConnPoolControl<HttpRoute> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMaxPerRoute(final HttpRoute route, final int max) {
|
public void setMaxPerRoute(final HttpRoute route, final int max) {
|
||||||
this.maxPerHostMap.put(route, Integer.valueOf(max));
|
this.maxPerHostMap.put(route, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxPerRoute(final HttpRoute route) {
|
public int getMaxPerRoute(final HttpRoute route) {
|
||||||
final Integer max = this.maxPerHostMap.get(route);
|
final Integer max = this.maxPerHostMap.get(route);
|
||||||
if (max != null) {
|
if (max != null) {
|
||||||
return max.intValue();
|
return max;
|
||||||
} else {
|
} else {
|
||||||
return this.defaultMax;
|
return this.defaultMax;
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,9 @@ import org.apache.hc.client5.http.HttpRoute;
|
||||||
import org.apache.hc.client5.http.RouteInfo;
|
import org.apache.hc.client5.http.RouteInfo;
|
||||||
import org.apache.hc.client5.http.auth.AuthChallenge;
|
import org.apache.hc.client5.http.auth.AuthChallenge;
|
||||||
import org.apache.hc.client5.http.auth.AuthScheme;
|
import org.apache.hc.client5.http.auth.AuthScheme;
|
||||||
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
|
||||||
import org.apache.hc.client5.http.auth.AuthScope;
|
import org.apache.hc.client5.http.auth.AuthScope;
|
||||||
import org.apache.hc.client5.http.auth.ChallengeType;
|
import org.apache.hc.client5.http.auth.ChallengeType;
|
||||||
|
import org.apache.hc.client5.http.auth.StandardAuthScheme;
|
||||||
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
|
||||||
import org.apache.hc.client5.http.classic.ExecChain;
|
import org.apache.hc.client5.http.classic.ExecChain;
|
||||||
import org.apache.hc.client5.http.classic.ExecRuntime;
|
import org.apache.hc.client5.http.classic.ExecRuntime;
|
||||||
|
@ -67,7 +67,6 @@ import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
@SuppressWarnings({"boxing","static-access"}) // test code
|
@SuppressWarnings({"boxing","static-access"}) // test code
|
||||||
|
@ -343,29 +342,17 @@ public class TestConnectExec {
|
||||||
|
|
||||||
private boolean connected;
|
private boolean connected;
|
||||||
|
|
||||||
public Answer connectAnswer() {
|
public Answer<?> connectAnswer() {
|
||||||
|
|
||||||
return new Answer() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
|
|
||||||
connected = true;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return invocationOnMock -> {
|
||||||
|
connected = true;
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Answer<Boolean> isConnectedAnswer() {
|
public Answer<Boolean> isConnectedAnswer() {
|
||||||
|
|
||||||
return new Answer<Boolean>() {
|
return invocationOnMock -> connected;
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean answer(final InvocationOnMock invocationOnMock) throws Throwable {
|
|
||||||
return connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,14 +45,10 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuil
|
||||||
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
||||||
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
import org.apache.hc.client5.http.protocol.HttpClientContext;
|
||||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
|
||||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
|
||||||
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
|
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
|
||||||
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
||||||
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
import org.apache.hc.core5.http.io.HttpClientResponseHandler;
|
||||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
|
||||||
import org.hamcrest.CoreMatchers;
|
import org.hamcrest.CoreMatchers;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
@ -76,23 +72,16 @@ public class TestFutureRequestExecutionService {
|
||||||
@Before
|
@Before
|
||||||
public void before() throws Exception {
|
public void before() throws Exception {
|
||||||
this.localServer = ServerBootstrap.bootstrap()
|
this.localServer = ServerBootstrap.bootstrap()
|
||||||
.register("/wait", new HttpRequestHandler() {
|
.register("/wait", (request, response, context) -> {
|
||||||
|
try {
|
||||||
@Override
|
while(blocked.get()) {
|
||||||
public void handle(
|
Thread.sleep(10);
|
||||||
final ClassicHttpRequest request,
|
}
|
||||||
final ClassicHttpResponse response,
|
} catch (final InterruptedException e) {
|
||||||
final HttpContext context) throws HttpException, IOException {
|
throw new IllegalStateException(e);
|
||||||
try {
|
|
||||||
while(blocked.get()) {
|
|
||||||
Thread.sleep(10);
|
|
||||||
}
|
}
|
||||||
} catch (final InterruptedException e) {
|
response.setCode(200);
|
||||||
throw new IllegalStateException(e);
|
}).create();
|
||||||
}
|
|
||||||
response.setCode(200);
|
|
||||||
}
|
|
||||||
}).create();
|
|
||||||
|
|
||||||
this.localServer.start();
|
this.localServer.start();
|
||||||
uri = "http://localhost:" + this.localServer.getLocalPort() + "/wait";
|
uri = "http://localhost:" + this.localServer.getLocalPort() + "/wait";
|
||||||
|
@ -117,7 +106,7 @@ public class TestFutureRequestExecutionService {
|
||||||
public void shouldExecuteSingleCall() throws InterruptedException, ExecutionException {
|
public void shouldExecuteSingleCall() throws InterruptedException, ExecutionException {
|
||||||
final FutureTask<Boolean> task = httpAsyncClientWithFuture.execute(
|
final FutureTask<Boolean> task = httpAsyncClientWithFuture.execute(
|
||||||
new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler());
|
new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler());
|
||||||
Assert.assertTrue("request should have returned OK", task.get().booleanValue());
|
Assert.assertTrue("request should have returned OK", task.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -154,7 +143,7 @@ public class TestFutureRequestExecutionService {
|
||||||
for (final Future<Boolean> task : tasks) {
|
for (final Future<Boolean> task : tasks) {
|
||||||
final Boolean b = task.get();
|
final Boolean b = task.get();
|
||||||
Assert.assertNotNull(b);
|
Assert.assertNotNull(b);
|
||||||
Assert.assertTrue("request should have returned OK", b.booleanValue());
|
Assert.assertTrue("request should have returned OK", b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +162,7 @@ public class TestFutureRequestExecutionService {
|
||||||
for (final Future<Boolean> task : tasks) {
|
for (final Future<Boolean> task : tasks) {
|
||||||
final Boolean b = task.get();
|
final Boolean b = task.get();
|
||||||
Assert.assertNotNull(b);
|
Assert.assertNotNull(b);
|
||||||
Assert.assertTrue("request should have returned OK", b.booleanValue());
|
Assert.assertTrue("request should have returned OK", b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,6 @@ package org.apache.hc.client5.http.impl.classic;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.classic.ExecChain;
|
|
||||||
import org.apache.hc.client5.http.classic.ExecChainHandler;
|
|
||||||
import org.apache.hc.client5.http.classic.ExecChain.Scope;
|
|
||||||
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
||||||
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
|
||||||
|
@ -40,8 +37,6 @@ import org.apache.hc.core5.http.Header;
|
||||||
import org.apache.hc.core5.http.HttpException;
|
import org.apache.hc.core5.http.HttpException;
|
||||||
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
|
import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
|
||||||
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
|
||||||
import org.apache.hc.core5.http.io.HttpRequestHandler;
|
|
||||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
|
||||||
import org.apache.hc.core5.io.CloseMode;
|
import org.apache.hc.core5.io.CloseMode;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
@ -58,20 +53,13 @@ public class TestHttpClientBuilderInterceptors {
|
||||||
@Before
|
@Before
|
||||||
public void before() throws Exception {
|
public void before() throws Exception {
|
||||||
this.localServer = ServerBootstrap.bootstrap()
|
this.localServer = ServerBootstrap.bootstrap()
|
||||||
.register("/test", new HttpRequestHandler() {
|
.register("/test", (request, response, context) -> {
|
||||||
|
final Header testInterceptorHeader = request.getHeader("X-Test-Interceptor");
|
||||||
@Override
|
if (testInterceptorHeader != null) {
|
||||||
public void handle(
|
response.setHeader(testInterceptorHeader);
|
||||||
final ClassicHttpRequest request,
|
}
|
||||||
final ClassicHttpResponse response,
|
response.setCode(200);
|
||||||
final HttpContext context) throws HttpException, IOException {
|
}).create();
|
||||||
final Header testInterceptorHeader = request.getHeader("X-Test-Interceptor");
|
|
||||||
if (testInterceptorHeader != null) {
|
|
||||||
response.setHeader(testInterceptorHeader);
|
|
||||||
}
|
|
||||||
response.setCode(200);
|
|
||||||
}
|
|
||||||
}).create();
|
|
||||||
|
|
||||||
this.localServer.start();
|
this.localServer.start();
|
||||||
uri = "http://localhost:" + this.localServer.getLocalPort() + "/test";
|
uri = "http://localhost:" + this.localServer.getLocalPort() + "/test";
|
||||||
|
@ -80,16 +68,9 @@ public class TestHttpClientBuilderInterceptors {
|
||||||
.build();
|
.build();
|
||||||
httpClient = HttpClientBuilder.create()
|
httpClient = HttpClientBuilder.create()
|
||||||
.setConnectionManager(cm)
|
.setConnectionManager(cm)
|
||||||
.addExecInterceptorLast("test-interceptor", new ExecChainHandler() {
|
.addExecInterceptorLast("test-interceptor", (request, scope, chain) -> {
|
||||||
|
request.setHeader("X-Test-Interceptor", "active");
|
||||||
@Override
|
return chain.proceed(request, scope);
|
||||||
public ClassicHttpResponse execute(
|
|
||||||
final ClassicHttpRequest request,
|
|
||||||
final Scope scope,
|
|
||||||
final ExecChain chain) throws IOException, HttpException {
|
|
||||||
request.setHeader("X-Test-Interceptor", "active");
|
|
||||||
return chain.proceed(request, scope);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,8 +55,6 @@ import org.junit.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
@SuppressWarnings({"boxing","static-access"}) // test code
|
@SuppressWarnings({"boxing","static-access"}) // test code
|
||||||
public class TestHttpRequestRetryExec {
|
public class TestHttpRequestRetryExec {
|
||||||
|
@ -231,21 +229,16 @@ public class TestHttpRequestRetryExec {
|
||||||
|
|
||||||
Mockito.when(chain.proceed(
|
Mockito.when(chain.proceed(
|
||||||
Mockito.<ClassicHttpRequest>any(),
|
Mockito.<ClassicHttpRequest>any(),
|
||||||
Mockito.<ExecChain.Scope>any())).thenAnswer(new Answer<Object>() {
|
Mockito.<ExecChain.Scope>any())).thenAnswer(invocationOnMock -> {
|
||||||
|
final Object[] args = invocationOnMock.getArguments();
|
||||||
@Override
|
final ClassicHttpRequest wrapper = (ClassicHttpRequest) args[0];
|
||||||
public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
|
final Header[] headers = wrapper.getHeaders();
|
||||||
final Object[] args = invocationOnMock.getArguments();
|
Assert.assertEquals(2, headers.length);
|
||||||
final ClassicHttpRequest wrapper = (ClassicHttpRequest) args[0];
|
Assert.assertEquals("this", headers[0].getValue());
|
||||||
final Header[] headers = wrapper.getHeaders();
|
Assert.assertEquals("that", headers[1].getValue());
|
||||||
Assert.assertEquals(2, headers.length);
|
wrapper.addHeader("Cookie", "monster");
|
||||||
Assert.assertEquals("this", headers[0].getValue());
|
throw new IOException("Ka-boom");
|
||||||
Assert.assertEquals("that", headers[1].getValue());
|
});
|
||||||
wrapper.addHeader("Cookie", "monster");
|
|
||||||
throw new IOException("Ka-boom");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
Mockito.when(retryStrategy.retryRequest(
|
Mockito.when(retryStrategy.retryRequest(
|
||||||
Mockito.<HttpRequest>any(),
|
Mockito.<HttpRequest>any(),
|
||||||
Mockito.<IOException>any(),
|
Mockito.<IOException>any(),
|
||||||
|
@ -304,17 +297,12 @@ public class TestHttpRequestRetryExec {
|
||||||
|
|
||||||
Mockito.when(chain.proceed(
|
Mockito.when(chain.proceed(
|
||||||
Mockito.<ClassicHttpRequest>any(),
|
Mockito.<ClassicHttpRequest>any(),
|
||||||
Mockito.<ExecChain.Scope>any())).thenAnswer(new Answer<Object>() {
|
Mockito.<ExecChain.Scope>any())).thenAnswer(invocationOnMock -> {
|
||||||
|
final Object[] args = invocationOnMock.getArguments();
|
||||||
@Override
|
final ClassicHttpRequest req = (ClassicHttpRequest) args[0];
|
||||||
public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
|
req.getEntity().writeTo(new ByteArrayOutputStream());
|
||||||
final Object[] args = invocationOnMock.getArguments();
|
throw new IOException("Ka-boom");
|
||||||
final ClassicHttpRequest req = (ClassicHttpRequest) args[0];
|
});
|
||||||
req.getEntity().writeTo(new ByteArrayOutputStream());
|
|
||||||
throw new IOException("Ka-boom");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
Mockito.when(retryStrategy.retryRequest(
|
Mockito.when(retryStrategy.retryRequest(
|
||||||
Mockito.<HttpRequest>any(),
|
Mockito.<HttpRequest>any(),
|
||||||
Mockito.<IOException>any(),
|
Mockito.<IOException>any(),
|
||||||
|
|
|
@ -53,7 +53,6 @@ import org.junit.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
@SuppressWarnings({"boxing","static-access"}) // test code
|
@SuppressWarnings({"boxing","static-access"}) // test code
|
||||||
|
@ -330,29 +329,17 @@ public class TestMainClientExec {
|
||||||
|
|
||||||
private boolean connected;
|
private boolean connected;
|
||||||
|
|
||||||
public Answer connectAnswer() {
|
public Answer<?> connectAnswer() {
|
||||||
|
|
||||||
return new Answer() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
|
|
||||||
connected = true;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return invocationOnMock -> {
|
||||||
|
connected = true;
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public Answer<Boolean> isConnectedAnswer() {
|
public Answer<Boolean> isConnectedAnswer() {
|
||||||
|
|
||||||
return new Answer<Boolean>() {
|
return invocationOnMock -> connected;
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean answer(final InvocationOnMock invocationOnMock) throws Throwable {
|
|
||||||
return connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,6 @@ import org.junit.Test;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
@SuppressWarnings({"static-access"}) // test code
|
@SuppressWarnings({"static-access"}) // test code
|
||||||
|
@ -317,17 +316,12 @@ public class TestProtocolExec {
|
||||||
|
|
||||||
Mockito.when(chain.proceed(
|
Mockito.when(chain.proceed(
|
||||||
Mockito.same(request),
|
Mockito.same(request),
|
||||||
Mockito.<ExecChain.Scope>any())).thenAnswer(new Answer<HttpResponse>() {
|
Mockito.<ExecChain.Scope>any())).thenAnswer((Answer<HttpResponse>) invocationOnMock -> {
|
||||||
|
final Object[] args = invocationOnMock.getArguments();
|
||||||
@Override
|
final ClassicHttpRequest requestEE = (ClassicHttpRequest) args[0];
|
||||||
public HttpResponse answer(final InvocationOnMock invocationOnMock) throws Throwable {
|
requestEE.getEntity().writeTo(new ByteArrayOutputStream());
|
||||||
final Object[] args = invocationOnMock.getArguments();
|
return response1;
|
||||||
final ClassicHttpRequest requestEE = (ClassicHttpRequest) args[0];
|
});
|
||||||
requestEE.getEntity().writeTo(new ByteArrayOutputStream());
|
|
||||||
return response1;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Mockito.when(targetAuthStrategy.select(
|
Mockito.when(targetAuthStrategy.select(
|
||||||
Mockito.eq(ChallengeType.TARGET),
|
Mockito.eq(ChallengeType.TARGET),
|
||||||
|
|
|
@ -438,19 +438,19 @@ public class TestRouteTracker {
|
||||||
Assert.assertTrue(hs.add(rt4));
|
Assert.assertTrue(hs.add(rt4));
|
||||||
Assert.assertTrue(hs.add(rt6));
|
Assert.assertTrue(hs.add(rt6));
|
||||||
|
|
||||||
Assert.assertTrue(hc0.add(Integer.valueOf(rt0.hashCode())));
|
Assert.assertTrue(hc0.add(rt0.hashCode()));
|
||||||
Assert.assertTrue(hc4.add(Integer.valueOf(rt4.hashCode())));
|
Assert.assertTrue(hc4.add(rt4.hashCode()));
|
||||||
Assert.assertTrue(hc6.add(Integer.valueOf(rt6.hashCode())));
|
Assert.assertTrue(hc6.add(rt6.hashCode()));
|
||||||
|
|
||||||
rt = (RouteTracker) rt0.clone();
|
rt = (RouteTracker) rt0.clone();
|
||||||
rt.connectTarget(false);
|
rt.connectTarget(false);
|
||||||
Assert.assertTrue(hs.add(rt));
|
Assert.assertTrue(hs.add(rt));
|
||||||
Assert.assertTrue(hc0.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc0.add(rt.hashCode()));
|
||||||
|
|
||||||
rt = (RouteTracker) rt0.clone();
|
rt = (RouteTracker) rt0.clone();
|
||||||
rt.connectTarget(true);
|
rt.connectTarget(true);
|
||||||
Assert.assertTrue(hs.add(rt));
|
Assert.assertTrue(hs.add(rt));
|
||||||
Assert.assertTrue(hc0.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc0.add(rt.hashCode()));
|
||||||
|
|
||||||
|
|
||||||
// proxy (insecure) -> tunnel (insecure) -> layer (secure)
|
// proxy (insecure) -> tunnel (insecure) -> layer (secure)
|
||||||
|
@ -458,15 +458,15 @@ public class TestRouteTracker {
|
||||||
rt.connectProxy(PROXY1, false);
|
rt.connectProxy(PROXY1, false);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
// this is not guaranteed to be unique...
|
// this is not guaranteed to be unique...
|
||||||
Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc4.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.tunnelTarget(false);
|
rt.tunnelTarget(false);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc4.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.layerProtocol(true);
|
rt.layerProtocol(true);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc4.add(rt.hashCode()));
|
||||||
|
|
||||||
|
|
||||||
// proxy (secure) -> tunnel (secure) -> layer (insecure)
|
// proxy (secure) -> tunnel (secure) -> layer (insecure)
|
||||||
|
@ -474,15 +474,15 @@ public class TestRouteTracker {
|
||||||
rt.connectProxy(PROXY1, true);
|
rt.connectProxy(PROXY1, true);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
// this is not guaranteed to be unique...
|
// this is not guaranteed to be unique...
|
||||||
Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc4.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.tunnelTarget(true);
|
rt.tunnelTarget(true);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc4.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.layerProtocol(false);
|
rt.layerProtocol(false);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc4.add(rt.hashCode()));
|
||||||
|
|
||||||
|
|
||||||
// PROXY1/i -> PROXY2/i -> tunnel/i -> layer/s
|
// PROXY1/i -> PROXY2/i -> tunnel/i -> layer/s
|
||||||
|
@ -490,20 +490,20 @@ public class TestRouteTracker {
|
||||||
rt.connectProxy(PROXY1, false);
|
rt.connectProxy(PROXY1, false);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
// this is not guaranteed to be unique...
|
// this is not guaranteed to be unique...
|
||||||
Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc6.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.tunnelProxy(PROXY2, false);
|
rt.tunnelProxy(PROXY2, false);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
// this is not guaranteed to be unique...
|
// this is not guaranteed to be unique...
|
||||||
Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc6.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.tunnelTarget(false);
|
rt.tunnelTarget(false);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc6.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.layerProtocol(true);
|
rt.layerProtocol(true);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc6.add(rt.hashCode()));
|
||||||
|
|
||||||
|
|
||||||
// PROXY1/s -> PROXY2/s -> tunnel/s -> layer/i
|
// PROXY1/s -> PROXY2/s -> tunnel/s -> layer/i
|
||||||
|
@ -511,20 +511,20 @@ public class TestRouteTracker {
|
||||||
rt.connectProxy(PROXY1, true);
|
rt.connectProxy(PROXY1, true);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
// this is not guaranteed to be unique...
|
// this is not guaranteed to be unique...
|
||||||
Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc6.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.tunnelProxy(PROXY2, true);
|
rt.tunnelProxy(PROXY2, true);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
// this is not guaranteed to be unique...
|
// this is not guaranteed to be unique...
|
||||||
Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc6.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.tunnelTarget(true);
|
rt.tunnelTarget(true);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc6.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.layerProtocol(false);
|
rt.layerProtocol(false);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc6.add(rt.hashCode()));
|
||||||
|
|
||||||
|
|
||||||
// PROXY2/i -> PROXY1/i -> tunnel/i -> layer/s
|
// PROXY2/i -> PROXY1/i -> tunnel/i -> layer/s
|
||||||
|
@ -532,7 +532,7 @@ public class TestRouteTracker {
|
||||||
rt.connectProxy(PROXY2, false);
|
rt.connectProxy(PROXY2, false);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
// this is not guaranteed to be unique...
|
// this is not guaranteed to be unique...
|
||||||
Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
|
Assert.assertTrue(hc6.add(rt.hashCode()));
|
||||||
|
|
||||||
rt.tunnelProxy(PROXY1, false);
|
rt.tunnelProxy(PROXY1, false);
|
||||||
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
|
||||||
|
|
|
@ -29,7 +29,6 @@ package org.apache.hc.client5.http.routing;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.hc.client5.http.HttpRoute;
|
import org.apache.hc.client5.http.HttpRoute;
|
||||||
|
@ -201,14 +200,14 @@ public class TestHttpRoute {
|
||||||
// we can't test hashCode in general due to its dependency
|
// we can't test hashCode in general due to its dependency
|
||||||
// on InetAddress and HttpHost, but we can check for the flags
|
// on InetAddress and HttpHost, but we can check for the flags
|
||||||
final Set<Integer> routecodes = new HashSet<>();
|
final Set<Integer> routecodes = new HashSet<>();
|
||||||
routecodes.add(Integer.valueOf(routefff.hashCode()));
|
routecodes.add(routefff.hashCode());
|
||||||
routecodes.add(Integer.valueOf(routefft.hashCode()));
|
routecodes.add(routefft.hashCode());
|
||||||
routecodes.add(Integer.valueOf(routeftf.hashCode()));
|
routecodes.add(routeftf.hashCode());
|
||||||
routecodes.add(Integer.valueOf(routeftt.hashCode()));
|
routecodes.add(routeftt.hashCode());
|
||||||
routecodes.add(Integer.valueOf(routetff.hashCode()));
|
routecodes.add(routetff.hashCode());
|
||||||
routecodes.add(Integer.valueOf(routetft.hashCode()));
|
routecodes.add(routetft.hashCode());
|
||||||
routecodes.add(Integer.valueOf(routettf.hashCode()));
|
routecodes.add(routettf.hashCode());
|
||||||
routecodes.add(Integer.valueOf(routettt.hashCode()));
|
routecodes.add(routettt.hashCode());
|
||||||
Assert.assertEquals("some flagged routes have same hashCode",
|
Assert.assertEquals("some flagged routes have same hashCode",
|
||||||
8, routecodes.size());
|
8, routecodes.size());
|
||||||
|
|
||||||
|
@ -394,9 +393,7 @@ public class TestHttpRoute {
|
||||||
Assert.assertEquals("some routes are equal", 11, routes.size());
|
Assert.assertEquals("some routes are equal", 11, routes.size());
|
||||||
|
|
||||||
// and a run of cloning over the set
|
// and a run of cloning over the set
|
||||||
final Iterator<HttpRoute> iter = routes.iterator();
|
for (final HttpRoute origin : routes) {
|
||||||
while (iter.hasNext()) {
|
|
||||||
final HttpRoute origin = iter.next();
|
|
||||||
final HttpRoute cloned = (HttpRoute) origin.clone();
|
final HttpRoute cloned = (HttpRoute) origin.clone();
|
||||||
Assert.assertEquals("clone of " + origin, origin, cloned);
|
Assert.assertEquals("clone of " + origin, origin, cloned);
|
||||||
Assert.assertTrue("clone of " + origin, routes.contains(cloned));
|
Assert.assertTrue("clone of " + origin, routes.contains(cloned));
|
||||||
|
|
4
pom.xml
4
pom.xml
|
@ -60,8 +60,8 @@
|
||||||
</distributionManagement>
|
</distributionManagement>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>1.7</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.7</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<httpcore.version>5.1.1</httpcore.version>
|
<httpcore.version>5.1.1</httpcore.version>
|
||||||
<log4j.version>2.9.1</log4j.version>
|
<log4j.version>2.9.1</log4j.version>
|
||||||
<commons-codec.version>1.15</commons-codec.version>
|
<commons-codec.version>1.15</commons-codec.version>
|
||||||
|
|
Loading…
Reference in New Issue