From 87be7b15eb5c11326ee67b446b4a671a606dbfa9 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 13 May 2020 14:10:52 +0200 Subject: [PATCH 1/4] replace regex match with simple string comparisons Signed-off-by: Ludovic Orban --- .../src/main/java/org/eclipse/jetty/client/HttpClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index 54aa8edab8c..b181a46a915 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -1145,7 +1145,7 @@ public class HttpClient extends ContainerLifeCycle protected String normalizeHost(String host) { - if (host != null && host.matches("\\[.*\\]")) + if (host != null && host.startsWith("[") && host.endsWith("]")) return host.substring(1, host.length() - 1); return host; } From e7aa3c2e2302978df82eba1bee4724cef7a43d8b Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 13 May 2020 14:23:02 +0200 Subject: [PATCH 2/4] explicitly size the listeners array lists Signed-off-by: Ludovic Orban --- .../java/org/eclipse/jetty/client/HttpConversation.java | 2 +- .../main/java/org/eclipse/jetty/client/HttpReceiver.java | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java index 713b142d2f8..3e39039e944 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConversation.java @@ -117,9 +117,9 @@ public class HttpConversation extends AttributesMap // will notify a listener that may send a new request and trigger // another call to this method which will build different listeners // which may be iterated over when the iteration continues. - List listeners = new ArrayList<>(); HttpExchange firstExchange = exchanges.peekFirst(); HttpExchange lastExchange = exchanges.peekLast(); + List listeners = new ArrayList<>(firstExchange.getResponseListeners().size() + lastExchange.getResponseListeners().size()); if (firstExchange == lastExchange) { // We don't have a conversation, just a single request. diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java index d8961dc8f62..f14eda67106 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java @@ -21,6 +21,7 @@ package org.eclipse.jetty.client; import java.io.IOException; import java.net.URI; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -31,7 +32,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; import java.util.function.LongConsumer; import java.util.function.LongUnaryOperator; -import java.util.stream.Collectors; import org.eclipse.jetty.client.api.Response; import org.eclipse.jetty.client.api.Result; @@ -693,10 +693,11 @@ public abstract class HttpReceiver private ContentListeners(List responseListeners) { - listeners = responseListeners.stream() + listeners = new ArrayList<>(responseListeners.size()); + responseListeners.stream() .filter(Response.DemandedContentListener.class::isInstance) .map(Response.DemandedContentListener.class::cast) - .collect(Collectors.toList()); + .forEach(listeners::add); } private boolean isEmpty() From 7d80c8fc3909b341bae48234df81224a28f28611 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 13 May 2020 14:10:10 +0200 Subject: [PATCH 3/4] Add constructor to better align with 10.0.x Signed-off-by: Ludovic Orban --- .../java/org/eclipse/jetty/client/HttpClient.java | 14 +++++++++++++- .../websocket/common/test/BlockheadClient.java | 1 - 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index b181a46a915..545b13cf4b5 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -163,7 +163,7 @@ public class HttpClient extends ContainerLifeCycle */ public HttpClient() { - this(null); + this(new HttpClientTransportOverHTTP(), null); } /** @@ -178,6 +178,18 @@ public class HttpClient extends ContainerLifeCycle this(new HttpClientTransportOverHTTP(), sslContextFactory); } + /** + * Creates a {@link HttpClient} instance that can perform requests to non-TLS destinations only + * (that is, requests with the "http" scheme only, and not "https"). + * + * @param transport the {@link HttpClientTransport} + * @see #HttpClient(HttpClientTransport, SslContextFactory) to perform requests to TLS destinations. + */ + public HttpClient(HttpClientTransport transport) + { + this(transport, null); + } + public HttpClient(HttpClientTransport transport, SslContextFactory sslContextFactory) { this.transport = transport; diff --git a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java index 22e1a963ab8..d5fc0af0112 100644 --- a/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java +++ b/jetty-websocket/websocket-common/src/test/java/org/eclipse/jetty/websocket/common/test/BlockheadClient.java @@ -44,7 +44,6 @@ public class BlockheadClient extends HttpClient implements WebSocketContainerSco public BlockheadClient() { - super(null); setName("Blockhead-CLIENT"); this.extensionFactory = new WebSocketExtensionFactory(this); } From 1974b1b407c1d20496f4548457326511f30cd757 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Wed, 13 May 2020 17:35:10 +0200 Subject: [PATCH 4/4] avoid creating URI instances when possible Signed-off-by: Ludovic Orban --- .../jetty/client/HttpAuthenticationStore.java | 6 +++ .../eclipse/jetty/client/HttpConnection.java | 41 ++++++++++++++----- .../jetty/client/api/AuthenticationStore.java | 8 ++++ 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpAuthenticationStore.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpAuthenticationStore.java index 937bcac6b70..eadce9cee0f 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpAuthenticationStore.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpAuthenticationStore.java @@ -93,4 +93,10 @@ public class HttpAuthenticationStore implements AuthenticationStore } return null; } + + @Override + public boolean hasAuthenticationResults() + { + return !results.isEmpty(); + } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java index de07bd97afc..39b29e3ad56 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpConnection.java @@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.eclipse.jetty.client.api.Authentication; +import org.eclipse.jetty.client.api.AuthenticationStore; import org.eclipse.jetty.client.api.Connection; import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.client.api.Request; @@ -103,12 +104,14 @@ public abstract class HttpConnection implements Connection request.path(path); } - URI uri = request.getURI(); - - if (proxy instanceof HttpProxy && !HttpClient.isSchemeSecure(request.getScheme()) && uri != null) + if (proxy instanceof HttpProxy && !HttpClient.isSchemeSecure(request.getScheme())) { - path = uri.toString(); - request.path(path); + URI uri = request.getURI(); + if (uri != null) + { + path = uri.toString(); + request.path(path); + } } // If we are HTTP 1.1, add the Host header @@ -147,9 +150,10 @@ public abstract class HttpConnection implements Connection // Cookies CookieStore cookieStore = getHttpClient().getCookieStore(); - if (cookieStore != null) + if (cookieStore != null && cookieStore.getClass() != HttpCookieStore.Empty.class) { StringBuilder cookies = null; + URI uri = request.getURI(); if (uri != null) cookies = convertCookies(HttpCookieStore.matchPath(uri, cookieStore.get(uri)), null); cookies = convertCookies(request.getCookies(), cookies); @@ -158,8 +162,8 @@ public abstract class HttpConnection implements Connection } // Authentication - applyAuthentication(request, proxy != null ? proxy.getURI() : null); - applyAuthentication(request, uri); + applyProxyAuthentication(request, proxy); + applyRequestAuthentication(request); } private StringBuilder convertCookies(List cookies, StringBuilder builder) @@ -175,11 +179,26 @@ public abstract class HttpConnection implements Connection return builder; } - private void applyAuthentication(Request request, URI uri) + private void applyRequestAuthentication(Request request) { - if (uri != null) + AuthenticationStore authenticationStore = getHttpClient().getAuthenticationStore(); + if (authenticationStore.hasAuthenticationResults()) { - Authentication.Result result = getHttpClient().getAuthenticationStore().findAuthenticationResult(uri); + URI uri = request.getURI(); + if (uri != null) + { + Authentication.Result result = authenticationStore.findAuthenticationResult(uri); + if (result != null) + result.apply(request); + } + } + } + + private void applyProxyAuthentication(Request request, ProxyConfiguration.Proxy proxy) + { + if (proxy != null) + { + Authentication.Result result = getHttpClient().getAuthenticationStore().findAuthenticationResult(proxy.getURI()); if (result != null) result.apply(request); } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/AuthenticationStore.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/AuthenticationStore.java index 7c8429288dc..f0884f5bcc1 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/AuthenticationStore.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/AuthenticationStore.java @@ -75,4 +75,12 @@ public interface AuthenticationStore * @return the {@link Authentication.Result} that matches the given URI, or null */ Authentication.Result findAuthenticationResult(URI uri); + + /** + * @return false if there are no stored authentication results, true if there may be some. + */ + default boolean hasAuthenticationResults() + { + return true; + } }