Upgraded HttpCore dependency to version 5.0-beta2

This commit is contained in:
Oleg Kalnichevski 2018-01-12 13:02:42 +01:00
parent a7a70e8cd4
commit dee32207e3
10 changed files with 31 additions and 288 deletions

View File

@ -28,12 +28,12 @@ package org.apache.hc.client5.http.impl.cache;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
import org.apache.hc.client5.http.cache.HttpCacheEntry;
import org.apache.hc.client5.http.cache.Resource;
import org.apache.hc.client5.http.cache.ResourceIOException;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.util.LangUtils;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Factory;
@ -60,18 +60,26 @@ public class HttpCacheEntryMatcher extends BaseMatcher<HttpCacheEntry> {
}
final Date expectedRequestDate = expectedValue.getRequestDate();
final Date otherRequestDate = otherValue.getRequestDate();
if (!Objects.equals(expectedRequestDate, otherRequestDate)) {
if (!LangUtils.equals(expectedRequestDate, otherRequestDate)) {
return false;
}
final Date expectedResponseDate = expectedValue.getResponseDate();
final Date otherResponseDate = otherValue.getResponseDate();
if (!Objects.equals(expectedResponseDate, otherResponseDate)) {
if (!LangUtils.equals(expectedResponseDate, otherResponseDate)) {
return false;
}
final Header[] expectedHeaders = expectedValue.getAllHeaders();
final Header[] otherHeaders = otherValue.getAllHeaders();
if (!Arrays.deepEquals(expectedHeaders, otherHeaders)) {
if (expectedHeaders.length != otherHeaders.length) {
return false;
} else {
for (int i = 0; i < expectedHeaders.length; i++) {
final Header h1 = expectedHeaders[i];
final Header h2 = otherHeaders[i];
if (!h1.getName().equals(h2.getName()) || !LangUtils.equals(h1.getValue(), h2.getValue())) {
return false;
}
}
}
final Resource expectedResource = expectedValue.getResource();
final byte[] expectedContent = expectedResource != null ? expectedResource.get() : null;

View File

@ -59,12 +59,6 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<!-- TODO remove after upgrade to HttpCore 5.0b2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>

View File

@ -202,4 +202,14 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
}
}
@Test
public void testBadRequest() throws Exception {
final HttpHost target = start();
final Future<SimpleHttpResponse> future = httpclient.execute(
SimpleHttpRequest.get(target, "/random/boom"), null);
final SimpleHttpResponse response = future.get();
Assert.assertThat(response, CoreMatchers.notNullValue());
Assert.assertThat(response.getCode(), CoreMatchers.equalTo(400));
}
}

View File

@ -184,14 +184,4 @@ public class TestHttp1Async extends AbstractHttpAsyncFundamentalsTest<CloseableH
Assert.assertThat(body3.length(), CoreMatchers.equalTo(2048));
}
@Test
public void testBadRequest() throws Exception {
final HttpHost target = start();
final Future<SimpleHttpResponse> future = httpclient.execute(
SimpleHttpRequest.get(target, "/random/boom"), null);
final SimpleHttpResponse response = future.get();
Assert.assertThat(response, CoreMatchers.notNullValue());
Assert.assertThat(response.getCode(), CoreMatchers.equalTo(400));
}
}

View File

@ -200,7 +200,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
final HttpHost target = start();
final HttpClientContext context = HttpClientContext.create();
final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", "blah.:.blah.:.");
final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", "{{|boom|}}");
final ClassicHttpResponse response = this.httpclient.execute(target, request, context);
EntityUtils.consume(response.getEntity());
@ -208,7 +208,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
final HttpRequest reqWrapper = context.getRequest();
Assert.assertEquals("blah.:.blah.:.", reqWrapper.getRequestUri());
Assert.assertEquals("{{|boom|}}", reqWrapper.getRequestUri());
}
@Test

View File

@ -58,25 +58,7 @@ abstract class AbstractMinimalHttpAsyncClientBase extends AbstractHttpAsyncClien
execute(new BasicClientExchangeHandler<>(
requestProducer,
responseConsumer,
//TODO: eliminate this callback after upgrade to HttpCore 5.0b2
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();
}
}),
callback),
context, future, new Supplier<T>() {
@Override

View File

@ -43,6 +43,7 @@ import org.apache.hc.core5.http2.config.H2Config;
import org.apache.hc.core5.http2.frame.FramePrinter;
import org.apache.hc.core5.http2.frame.RawFrame;
import org.apache.hc.core5.http2.impl.nio.ClientHttp2StreamMultiplexerFactory;
import org.apache.hc.core5.http2.impl.nio.Http2OnlyClientProtocolNegotiator;
import org.apache.hc.core5.http2.impl.nio.Http2StreamListener;
import org.apache.hc.core5.reactor.IOEventHandler;
import org.apache.hc.core5.reactor.IOEventHandlerFactory;
@ -178,7 +179,7 @@ class Http2AsyncClientEventHandlerFactory implements IOEventHandlerFactory {
});
final LoggingIOSession loggingIOSession = new LoggingIOSession(ioSession, id, sessionLog, wireLog);
return new InternalHttp2ClientProtocolNegotiator(loggingIOSession, http2StreamHandlerFactory);
return new Http2OnlyClientProtocolNegotiator(loggingIOSession, http2StreamHandlerFactory, false);
} else {
final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory = new ClientHttp2StreamMultiplexerFactory(
httpProcessor,
@ -186,7 +187,7 @@ class Http2AsyncClientEventHandlerFactory implements IOEventHandlerFactory {
h2Config,
charCodingConfig,
null);
return new InternalHttp2ClientProtocolNegotiator(ioSession, http2StreamHandlerFactory);
return new Http2OnlyClientProtocolNegotiator(ioSession, http2StreamHandlerFactory, false);
}
}

View File

@ -33,13 +33,11 @@ import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.async.AsyncExecCallback;
import org.apache.hc.client5.http.async.AsyncExecChain;
import org.apache.hc.client5.http.async.AsyncExecRuntime;
import org.apache.hc.client5.http.async.methods.SimpleRequestProducer;
import org.apache.hc.client5.http.auth.AuthSchemeProvider;
import org.apache.hc.client5.http.auth.CredentialsProvider;
import org.apache.hc.client5.http.config.Configurable;
@ -168,7 +166,6 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
final AsyncExecChain.Scope scope = new AsyncExecChain.Scope(exchangeId, route, request, future,
clientContext, execRuntime);
final AtomicReference<T> resultRef = new AtomicReference<>(null);
final AtomicBoolean outputTerminated = new AtomicBoolean(false);
execChain.execute(
RequestCopier.INSTANCE.copy(request),
@ -186,8 +183,7 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
@Override
public boolean isRepeatable() {
//TODO: use AsyncRequestProducer#isRepeatable once available
return requestProducer instanceof SimpleRequestProducer;
return requestProducer.isRepeatable();
}
@Override
@ -242,12 +238,11 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
requestProducer.releaseResources();
}
responseConsumer.consumeResponse(response, entityDetails,
//TODO: eliminate this callback after upgrade to HttpCore 5.0b2
new FutureCallback<T>() {
@Override
public void completed(final T result) {
resultRef.set(result);
future.completed(result);
}
@Override
@ -271,7 +266,6 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
}
try {
execRuntime.releaseConnection();
future.completed(resultRef.getAndSet(null));
} finally {
responseConsumer.releaseResources();
requestProducer.releaseResources();

View File

@ -1,230 +0,0 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.hc.client5.http.impl.async;
import java.io.IOException;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import javax.net.ssl.SSLSession;
import org.apache.hc.core5.http.ConnectionClosedException;
import org.apache.hc.core5.http.EndpointDetails;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.ProtocolVersion;
import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
import org.apache.hc.core5.http.nio.command.ExecutionCommand;
import org.apache.hc.core5.http2.impl.nio.ClientHttp2IOEventHandler;
import org.apache.hc.core5.http2.impl.nio.ClientHttp2StreamMultiplexer;
import org.apache.hc.core5.http2.impl.nio.ClientHttp2StreamMultiplexerFactory;
import org.apache.hc.core5.http2.ssl.ApplicationProtocols;
import org.apache.hc.core5.io.ShutdownType;
import org.apache.hc.core5.reactor.Command;
import org.apache.hc.core5.reactor.IOEventHandler;
import org.apache.hc.core5.reactor.IOSession;
import org.apache.hc.core5.reactor.TlsCapableIOSession;
import org.apache.hc.core5.reactor.ssl.TlsDetails;
import org.apache.hc.core5.util.TextUtils;
/**
* TODO: replace with Http2OnlyClientProtocolNegotiator after HttpCore 5.0b2
*/
final class InternalHttp2ClientProtocolNegotiator implements HttpConnectionEventHandler {
// PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n
final static byte[] PREFACE = new byte[] {
0x50, 0x52, 0x49, 0x20, 0x2a, 0x20, 0x48, 0x54, 0x54, 0x50,
0x2f, 0x32, 0x2e, 0x30, 0x0d, 0x0a, 0x0d, 0x0a, 0x53, 0x4d,
0x0d, 0x0a, 0x0d, 0x0a};
private final TlsCapableIOSession ioSession;
private final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory;
private final ByteBuffer preface;
public InternalHttp2ClientProtocolNegotiator(
final TlsCapableIOSession ioSession,
final ClientHttp2StreamMultiplexerFactory http2StreamHandlerFactory) {
this.ioSession = ioSession;
this.http2StreamHandlerFactory = http2StreamHandlerFactory;
this.preface = ByteBuffer.wrap(PREFACE);
}
@Override
public void connected(final IOSession session) {
try {
final TlsDetails tlsDetails = ioSession.getTlsDetails();
if (tlsDetails != null) {
final String applicationProtocol = tlsDetails.getApplicationProtocol();
if (!TextUtils.isEmpty(applicationProtocol)) {
if (!ApplicationProtocols.HTTP_2.id.equals(applicationProtocol)) {
throw new HttpException("Unexpected application protocol: " + applicationProtocol);
}
}
}
writePreface(session);
} catch (final Exception ex) {
session.shutdown(ShutdownType.IMMEDIATE);
exception(session, ex);
}
}
private void writePreface(final IOSession session) throws IOException {
if (preface.hasRemaining()) {
final ByteChannel channel = session.channel();
channel.write(preface);
}
if (!preface.hasRemaining()) {
final ClientHttp2StreamMultiplexer streamMultiplexer = http2StreamHandlerFactory.create(ioSession);
final IOEventHandler newHandler = new ClientHttp2IOEventHandler(streamMultiplexer);
newHandler.connected(session);
session.setHandler(newHandler);
}
}
@Override
public void inputReady(final IOSession session) {
outputReady(session);
}
@Override
public void outputReady(final IOSession session) {
try {
if (preface != null) {
writePreface(session);
} else {
session.shutdown(ShutdownType.IMMEDIATE);
}
} catch (final IOException ex) {
session.shutdown(ShutdownType.IMMEDIATE);
exception(session, ex);
}
}
@Override
public void timeout(final IOSession session) {
exception(session, new SocketTimeoutException());
}
@Override
public void exception(final IOSession session, final Exception cause) {
try {
for (;;) {
final Command command = ioSession.getCommand();
if (command != null) {
if (command instanceof ExecutionCommand) {
final ExecutionCommand executionCommand = (ExecutionCommand) command;
final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
exchangeHandler.failed(cause);
exchangeHandler.releaseResources();
} else {
command.cancel();
}
} else {
break;
}
}
} finally {
session.shutdown(ShutdownType.IMMEDIATE);
}
}
@Override
public void disconnected(final IOSession session) {
for (;;) {
final Command command = ioSession.getCommand();
if (command != null) {
if (command instanceof ExecutionCommand) {
final ExecutionCommand executionCommand = (ExecutionCommand) command;
final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
exchangeHandler.failed(new ConnectionClosedException("Connection closed"));
exchangeHandler.releaseResources();
} else {
command.cancel();
}
} else {
break;
}
}
}
@Override
public SSLSession getSSLSession() {
final TlsDetails tlsDetails = ioSession.getTlsDetails();
return tlsDetails != null ? tlsDetails.getSSLSession() : null;
}
@Override
public EndpointDetails getEndpointDetails() {
return null;
}
@Override
public void setSocketTimeout(final int timeout) {
ioSession.setSocketTimeout(timeout);
}
@Override
public int getSocketTimeout() {
return ioSession.getSocketTimeout();
}
@Override
public ProtocolVersion getProtocolVersion() {
return null;
}
@Override
public SocketAddress getRemoteAddress() {
return ioSession.getRemoteAddress();
}
@Override
public SocketAddress getLocalAddress() {
return ioSession.getLocalAddress();
}
@Override
public boolean isOpen() {
return !ioSession.isClosed();
}
@Override
public void close() throws IOException {
ioSession.close();
}
@Override
public void shutdown(final ShutdownType shutdownType) {
ioSession.shutdown(shutdownType);
}
}

View File

@ -68,7 +68,7 @@
<properties>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<httpcore.version>5.0-beta1</httpcore.version>
<httpcore.version>5.0-beta2</httpcore.version>
<log4j.version>2.9.1</log4j.version>
<commons-codec.version>1.10</commons-codec.version>
<ehcache.version>3.4.0</ehcache.version>
@ -103,12 +103,6 @@
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- TODO remove after upgrade to HttpCore 5.0b2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>