Java 1.8 upgrade

This commit is contained in:
Oleg Kalnichevski 2020-12-20 15:22:42 +01:00
parent b704baf466
commit bb04d078ad
91 changed files with 1398 additions and 2980 deletions

View File

@ -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<>());
} }
/** /**

View File

@ -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()) {

View File

@ -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);
}
});
} }
} }
} }

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}
});
}
});
} }
} }

View File

@ -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);
}
}
});
} }
} }

View File

@ -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);
} }
} }

View File

@ -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);
} }

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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", "/");
} }

View File

@ -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) {

View File

@ -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);

View File

@ -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);
} }

View File

@ -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);

View File

@ -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);
} }

View File

@ -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");
}
};
} }
}); });

View File

@ -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);
}
} }
}); });
} }

View File

@ -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(

View File

@ -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);
}
} }
}); });
} }

View File

@ -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();
}
} }
}); });
} }

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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");
}
};
} }
}); });

View File

@ -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() {

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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);

View File

@ -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();

View File

@ -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);
} }

View File

@ -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) {
} }
}); });
} }

View File

@ -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);
}
};
} }
} }

View File

@ -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();
}
});
} }
} }

View File

@ -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

View File

@ -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) {
} }
}); });
} }

View File

@ -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);
}
});
} }
} }

View File

@ -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,

View File

@ -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);

View File

@ -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 {

View File

@ -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();
} }

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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;
} }

View File

@ -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

View File

@ -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();
} }

View File

@ -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);

View File

@ -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;
} }
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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,

View File

@ -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;
} }

View File

@ -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(

View File

@ -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;
} }

View File

@ -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() {

View File

@ -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,

View File

@ -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);
}
});
} }
} }

View File

@ -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()

View File

@ -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() {
}
};
} }
}); });

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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()) {

View File

@ -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 ...

View File

@ -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("----------------------------------------");

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;
}
};
} }
} }

View File

@ -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);
} }
} }

View File

@ -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();
} }

View File

@ -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(),

View File

@ -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;
}
};
} }
} }

View File

@ -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),

View File

@ -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()));

View File

@ -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));

View File

@ -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>