diff --git a/client/src/main/java/org/asynchttpclient/AdvancedConfig.java b/client/src/main/java/org/asynchttpclient/AdvancedConfig.java index 6692dd033a..75a02b5c63 100644 --- a/client/src/main/java/org/asynchttpclient/AdvancedConfig.java +++ b/client/src/main/java/org/asynchttpclient/AdvancedConfig.java @@ -25,12 +25,11 @@ import java.util.HashMap; import java.util.Map; -import org.asynchttpclient.channel.pool.ConnectionStrategy; +import org.asynchttpclient.channel.pool.KeepAliveStrategy; import org.asynchttpclient.netty.EagerNettyResponseBodyPart; import org.asynchttpclient.netty.LazyNettyResponseBodyPart; import org.asynchttpclient.netty.NettyResponseBodyPart; import org.asynchttpclient.netty.channel.pool.ChannelPool; -import org.asynchttpclient.netty.handler.DefaultConnectionStrategy; import org.asynchttpclient.netty.ws.NettyWebSocket; public class AdvancedConfig { @@ -44,7 +43,7 @@ public class AdvancedConfig { private final ChannelPool channelPool; private final Timer nettyTimer; private final NettyWebSocketFactory nettyWebSocketFactory; - private final ConnectionStrategy connectionStrategy; + private final KeepAliveStrategy connectionStrategy; public AdvancedConfig(// Map, Object> channelOptions,// @@ -56,7 +55,7 @@ public AdvancedConfig(// ChannelPool channelPool,// Timer nettyTimer,// NettyWebSocketFactory nettyWebSocketFactory,// - ConnectionStrategy connectionStrategy) { + KeepAliveStrategy connectionStrategy) { assertNotNull(responseBodyPartFactory, "responseBodyPartFactory"); assertNotNull(nettyWebSocketFactory, "nettyWebSocketFactory"); @@ -110,7 +109,7 @@ public NettyWebSocketFactory getNettyWebSocketFactory() { return nettyWebSocketFactory; } - public ConnectionStrategy getConnectionStrategy() { + public KeepAliveStrategy getKeepAliveStrategy() { return connectionStrategy; } @@ -125,7 +124,7 @@ public static class Builder { private ChannelPool channelPool; private Timer nettyTimer; private NettyWebSocketFactory nettyWebSocketFactory = new DefaultNettyWebSocketFactory(); - private ConnectionStrategy connectionStrategy = new DefaultConnectionStrategy(); + private KeepAliveStrategy keepAliveStrategy = KeepAliveStrategy.DefaultKeepAliveStrategy.INSTANCE; /** * @param name the name of the ChannelOption @@ -179,8 +178,8 @@ public Builder setNettyWebSocketFactory(NettyWebSocketFactory nettyWebSocketFact return this; } - public Builder setConnectionStrategy(ConnectionStrategy connectionStrategy) { - this.connectionStrategy = connectionStrategy; + public Builder setKeepAliveStrategy(KeepAliveStrategy keepAliveStrategy) { + this.keepAliveStrategy = keepAliveStrategy; return this; } @@ -195,7 +194,7 @@ public AdvancedConfig build() { channelPool,// nettyTimer,// nettyWebSocketFactory,// - connectionStrategy); + keepAliveStrategy); } } diff --git a/client/src/main/java/org/asynchttpclient/channel/pool/ConnectionStrategy.java b/client/src/main/java/org/asynchttpclient/channel/pool/ConnectionStrategy.java deleted file mode 100644 index 6995a7eec9..0000000000 --- a/client/src/main/java/org/asynchttpclient/channel/pool/ConnectionStrategy.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2014 AsyncHttpClient Project. All rights reserved. - * - * This program is licensed to you under the Apache License Version 2.0, - * and you may not use this file except in compliance with the Apache License Version 2.0. - * You may obtain a copy of the Apache License Version 2.0 at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the Apache License Version 2.0 is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. - */ -package org.asynchttpclient.channel.pool; - -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; - -import org.asynchttpclient.Request; - -/** - * Provides an interface for decisions about HTTP connections. - */ -public interface ConnectionStrategy { - - /** - * Determines whether the connection should be kept alive after this HTTP message exchange. - * @param ahcRequest the Request, as built by AHC - * @param nettyRequest the HTTP request sent to Netty - * @param nettyResponse the HTTP response received from Netty - * @return true if the connection should be kept alive, false if it should be closed. - */ - boolean keepAlive(Request ahcRequest, HttpRequest nettyRequest, HttpResponse nettyResponse); -} diff --git a/client/src/main/java/org/asynchttpclient/channel/pool/KeepAliveStrategy.java b/client/src/main/java/org/asynchttpclient/channel/pool/KeepAliveStrategy.java new file mode 100644 index 0000000000..1c498ddb88 --- /dev/null +++ b/client/src/main/java/org/asynchttpclient/channel/pool/KeepAliveStrategy.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014 AsyncHttpClient Project. All rights reserved. + * + * This program is licensed to you under the Apache License Version 2.0, + * and you may not use this file except in compliance with the Apache License Version 2.0. + * You may obtain a copy of the Apache License Version 2.0 at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the Apache License Version 2.0 is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. + */ +package org.asynchttpclient.channel.pool; + +import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION; +import static io.netty.handler.codec.http.HttpHeaders.Values.*; +import io.netty.handler.codec.http.HttpMessage; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import io.netty.handler.codec.http.HttpVersion; + +import org.asynchttpclient.Request; + +public interface KeepAliveStrategy { + + /** + * Determines whether the connection should be kept alive after this HTTP message exchange. + * @param ahcRequest the Request, as built by AHC + * @param nettyRequest the HTTP request sent to Netty + * @param nettyResponse the HTTP response received from Netty + * @return true if the connection should be kept alive, false if it should be closed. + */ + boolean keepAlive(Request ahcRequest, HttpRequest nettyRequest, HttpResponse nettyResponse); + + /** + * Connection strategy implementing standard HTTP 1.0/1.1 behaviour. + */ + enum DefaultKeepAliveStrategy implements KeepAliveStrategy { + + INSTANCE; + + /** + * Implemented in accordance with RFC 7230 section 6.1 + * https://tools.ietf.org/html/rfc7230#section-6.1 + */ + @Override + public boolean keepAlive(Request ahcRequest, HttpRequest request, HttpResponse response) { + + String responseConnectionHeader = connectionHeader(response); + + if (CLOSE.equalsIgnoreCase(responseConnectionHeader)) { + return false; + } else { + String requestConnectionHeader = connectionHeader(request); + + if (request.getProtocolVersion() == HttpVersion.HTTP_1_0) { + // only use keep-alive if both parties agreed upon it + return KEEP_ALIVE.equalsIgnoreCase(requestConnectionHeader) && KEEP_ALIVE.equalsIgnoreCase(responseConnectionHeader); + + } else { + // 1.1+, keep-alive is default behavior + return !CLOSE.equalsIgnoreCase(requestConnectionHeader); + } + } + } + + private String connectionHeader(HttpMessage message) { + return message.headers().get(CONNECTION); + } + } +} diff --git a/client/src/main/java/org/asynchttpclient/netty/handler/DefaultConnectionStrategy.java b/client/src/main/java/org/asynchttpclient/netty/handler/DefaultConnectionStrategy.java deleted file mode 100644 index 1233926e5d..0000000000 --- a/client/src/main/java/org/asynchttpclient/netty/handler/DefaultConnectionStrategy.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2014 AsyncHttpClient Project. All rights reserved. - * - * This program is licensed to you under the Apache License Version 2.0, - * and you may not use this file except in compliance with the Apache License Version 2.0. - * You may obtain a copy of the Apache License Version 2.0 at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the Apache License Version 2.0 is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under. - */ -package org.asynchttpclient.netty.handler; - -import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION; -import static io.netty.handler.codec.http.HttpHeaders.Values.*; -import io.netty.handler.codec.http.HttpMessage; -import io.netty.handler.codec.http.HttpRequest; -import io.netty.handler.codec.http.HttpResponse; -import io.netty.handler.codec.http.HttpVersion; - -import org.asynchttpclient.Request; -import org.asynchttpclient.channel.pool.ConnectionStrategy; - -/** - * Connection strategy implementing standard HTTP 1.0/1.1 behaviour. - */ -public class DefaultConnectionStrategy implements ConnectionStrategy { - - /** - * Implemented in accordance with RFC 7230 section 6.1 - * https://tools.ietf.org/html/rfc7230#section-6.1 - */ - @Override - public boolean keepAlive(Request ahcRequest, HttpRequest request, HttpResponse response) { - - String responseConnectionHeader = connectionHeader(response); - - if (CLOSE.equalsIgnoreCase(responseConnectionHeader)) { - return false; - } else { - String requestConnectionHeader = connectionHeader(request); - - if (request.getProtocolVersion() == HttpVersion.HTTP_1_0) { - // only use keep-alive if both parties agreed upon it - return KEEP_ALIVE.equalsIgnoreCase(requestConnectionHeader) && KEEP_ALIVE.equalsIgnoreCase(responseConnectionHeader); - - } else { - // 1.1+, keep-alive is default behavior - return !CLOSE.equalsIgnoreCase(requestConnectionHeader); - } - } - } - - private String connectionHeader(HttpMessage message) { - return message.headers().get(CONNECTION); - } -} diff --git a/client/src/main/java/org/asynchttpclient/netty/handler/HttpProtocol.java b/client/src/main/java/org/asynchttpclient/netty/handler/HttpProtocol.java index 2e18b31bc2..f9e168ef12 100755 --- a/client/src/main/java/org/asynchttpclient/netty/handler/HttpProtocol.java +++ b/client/src/main/java/org/asynchttpclient/netty/handler/HttpProtocol.java @@ -38,7 +38,7 @@ import org.asynchttpclient.Realm; import org.asynchttpclient.Request; import org.asynchttpclient.RequestBuilder; -import org.asynchttpclient.channel.pool.ConnectionStrategy; +import org.asynchttpclient.channel.pool.KeepAliveStrategy; import org.asynchttpclient.handler.StreamedAsyncHandler; import org.asynchttpclient.netty.Callback; import org.asynchttpclient.netty.NettyResponseBodyPart; @@ -56,12 +56,11 @@ public final class HttpProtocol extends Protocol { - private final ConnectionStrategy connectionStrategy; + private final KeepAliveStrategy connectionStrategy; public HttpProtocol(ChannelManager channelManager, AsyncHttpClientConfig config, AdvancedConfig advancedConfig, NettyRequestSender requestSender) { super(channelManager, config, advancedConfig, requestSender); - - connectionStrategy = advancedConfig.getConnectionStrategy(); + connectionStrategy = advancedConfig.getKeepAliveStrategy(); } private void kerberosChallenge(Channel channel,// diff --git a/client/src/test/java/org/asynchttpclient/BasicHttpsTest.java b/client/src/test/java/org/asynchttpclient/BasicHttpsTest.java index ac5edc0591..1b62dee48f 100644 --- a/client/src/test/java/org/asynchttpclient/BasicHttpsTest.java +++ b/client/src/test/java/org/asynchttpclient/BasicHttpsTest.java @@ -29,7 +29,7 @@ import javax.servlet.http.HttpServletResponse; -import org.asynchttpclient.channel.pool.ConnectionStrategy; +import org.asynchttpclient.channel.pool.KeepAliveStrategy; import org.asynchttpclient.test.EventCollectingHandler; import org.testng.annotations.Test; @@ -70,7 +70,7 @@ public void multipleSSLRequestsTest() throws Exception { @Test(groups = { "standalone", "default_provider" }) public void multipleSSLWithoutCacheTest() throws Exception { - AdvancedConfig advancedConfig = advancedConfig().setConnectionStrategy(new ConnectionStrategy() { + AdvancedConfig advancedConfig = advancedConfig().setKeepAliveStrategy(new KeepAliveStrategy() { @Override public boolean keepAlive(Request ahcRequest, HttpRequest nettyRequest, HttpResponse nettyResponse) {