From cf9df70935c128ddc394da0d797611c2d0a5adc6 Mon Sep 17 00:00:00 2001
From: Simone Bordet
Date: Mon, 4 May 2020 23:16:59 +0200
Subject: [PATCH 1/3] Fixes #4808 - Review HttpClient Request header APIs.
Introduced:
* Request Request.headers(Consumer).
This allows applications to modify the headers, and chain calls.
It also delegates the precise semantic of put/add/remove/clear to HttpFields, so there is no API duplication.
* HttpRequest.header(HttpField) to efficiently add fields while normalizing the request (only used in implementation).
* HttpResponse.header(HttpField) to efficiently add fields while parsing the response (only used in implementation).
This pairs with HttpResponse.trailer(HttpField).
* HttpResponse.headers(Consumer) to modify the fields after they have been populated (only used in tests).
Removed:
* Request.[set,add,put,remove], replaced by headers(Consumer).
Deprecated:
* Request.header(String, String)
* Request.header(HttpHeader, String)
Both replaced by headers(Consumer) with clearer semantic for add/put/remove.
All the rest is code cleanup to remove the usage of the deprecated header() methods.
Signed-off-by: Simone Bordet
---
.../jetty/embedded/ManyHandlersTest.java | 5 +-
.../embedded/SecuredHelloHandlerTest.java | 2 +-
.../client/AuthenticationProtocolHandler.java | 2 +-
.../org/eclipse/jetty/client/HttpClient.java | 8 ++--
.../eclipse/jetty/client/HttpConnection.java | 24 +++++-----
.../org/eclipse/jetty/client/HttpProxy.java | 9 ++--
.../eclipse/jetty/client/HttpReceiver.java | 4 +-
.../org/eclipse/jetty/client/HttpRequest.java | 46 +++++++-----------
.../eclipse/jetty/client/HttpResponse.java | 14 ++++--
.../org/eclipse/jetty/client/api/Request.java | 32 ++++---------
.../client/http/HttpConnectionOverHTTP.java | 11 ++---
.../client/http/HttpReceiverOverHTTP.java | 4 ++
.../client/util/BasicAuthentication.java | 2 +-
.../client/util/DigestAuthentication.java | 2 +-
.../client/util/FormContentProvider.java | 28 +----------
.../client/util/SPNEGOAuthentication.java | 2 +-
.../client/ClientConnectionCloseTest.java | 13 ++---
.../jetty/client/ConnectionPoolTest.java | 29 ++++--------
.../client/HttpClientCorrelationDataTest.java | 2 +-
.../client/HttpClientProxyProtocolTest.java | 3 +-
.../jetty/client/HttpClientProxyTest.java | 4 +-
.../jetty/client/HttpClientTLSTest.java | 5 +-
.../eclipse/jetty/client/HttpClientTest.java | 47 +++++++++----------
.../client/HttpConnectionLifecycleTest.java | 4 +-
.../eclipse/jetty/client/HttpCookieTest.java | 32 ++++++-------
.../client/NetworkTrafficListenerTest.java | 2 +-
.../org/eclipse/jetty/client/api/Usage.java | 2 +-
.../http/HttpDestinationOverHTTPTest.java | 4 +-
.../client/util/TypedContentProviderTest.java | 11 ++---
.../embedded/client/http/HTTPClientDocs.java | 9 ++--
.../client/http/HttpConnectionOverFCGI.java | 3 +-
.../server/proxy/FastCGIProxyServlet.java | 13 ++---
.../session/TestHazelcastSessions.java | 21 ++++-----
.../client/http/HttpConnectionOverHTTP2.java | 7 ++-
.../client/http/HttpReceiverOverHTTP2.java | 4 ++
.../session/TestMemcachedSessions.java | 17 ++++---
.../jetty/proxy/AbstractProxyServlet.java | 18 +++----
.../jetty/proxy/AsyncMiddleManServlet.java | 2 +-
.../proxy/AsyncMiddleManServletTest.java | 12 ++---
.../proxy/ForwardProxyTLSServerTest.java | 9 ++--
.../eclipse/jetty/proxy/ProxyServletTest.java | 17 +++----
.../org/eclipse/jetty/servlet/FormTest.java | 2 +-
.../servlet/GzipHandlerBreakEvenSizeTest.java | 3 +-
.../core/client/HttpUpgraderOverHTTP.java | 21 +++++----
.../core/client/HttpUpgraderOverHTTP2.java | 6 +--
.../core/WebSocketNegotiationTest.java | 2 +-
.../javax/tests/server/ConfiguratorTest.java | 6 +--
.../jetty/http/client/AsyncIOServletTest.java | 7 +--
.../http/client/ConnectionStatisticsTest.java | 3 +-
.../http/client/HttpClientContinueTest.java | 26 +++++-----
.../jetty/http/client/HttpClientLoadTest.java | 11 +++--
.../jetty/http/client/HttpClientTest.java | 2 +-
.../HttpClientTransportDynamicTest.java | 39 ++++++++-------
.../jetty/test/FailedSelectorTest.java | 5 +-
.../ClusteredSessionMigrationTest.java | 15 +++---
.../nosql/mongodb/AttributeNameTest.java | 12 ++---
.../AbstractClusteredOrphanedSessionTest.java | 13 +++--
.../AbstractWebAppObjectInSessionTest.java | 10 ++--
.../ClientCrossContextSessionTest.java | 13 +++--
.../session/DeleteUnloadableSessionTest.java | 22 ++++-----
.../server/session/DuplicateCookieTest.java | 18 +++----
61 files changed, 338 insertions(+), 383 deletions(-)
diff --git a/examples/embedded/src/test/java/org/eclipse/jetty/embedded/ManyHandlersTest.java b/examples/embedded/src/test/java/org/eclipse/jetty/embedded/ManyHandlersTest.java
index 9f4ebcf0993..6b0b2d7fa24 100644
--- a/examples/embedded/src/test/java/org/eclipse/jetty/embedded/ManyHandlersTest.java
+++ b/examples/embedded/src/test/java/org/eclipse/jetty/embedded/ManyHandlersTest.java
@@ -23,6 +23,7 @@ import java.util.Map;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Server;
@@ -59,7 +60,7 @@ public class ManyHandlersTest extends AbstractEmbeddedTest
ContentResponse response = client.newRequest(uri)
.method(HttpMethod.GET)
- .header(HttpHeader.ACCEPT_ENCODING, "gzip")
+ .headers(headers -> headers.put(HttpHeader.ACCEPT_ENCODING, HttpHeaderValue.GZIP))
.send();
assertThat("HTTP Response Status", response.getStatus(), is(HttpStatus.OK_200));
@@ -84,7 +85,7 @@ public class ManyHandlersTest extends AbstractEmbeddedTest
URI uri = server.getURI().resolve("/hello");
ContentResponse response = client.newRequest(uri)
.method(HttpMethod.GET)
- .header(HttpHeader.ACCEPT_ENCODING, "gzip")
+ .headers(headers -> headers.put(HttpHeader.ACCEPT_ENCODING, HttpHeaderValue.GZIP))
.send();
assertThat("HTTP Response Status", response.getStatus(), is(HttpStatus.OK_200));
diff --git a/examples/embedded/src/test/java/org/eclipse/jetty/embedded/SecuredHelloHandlerTest.java b/examples/embedded/src/test/java/org/eclipse/jetty/embedded/SecuredHelloHandlerTest.java
index 5b569fbaae6..92bec6ec4dd 100644
--- a/examples/embedded/src/test/java/org/eclipse/jetty/embedded/SecuredHelloHandlerTest.java
+++ b/examples/embedded/src/test/java/org/eclipse/jetty/embedded/SecuredHelloHandlerTest.java
@@ -72,7 +72,7 @@ public class SecuredHelloHandlerTest extends AbstractEmbeddedTest
String authEncoded = Base64.getEncoder().encodeToString("user:password".getBytes(UTF_8));
ContentResponse response = client.newRequest(uri)
.method(HttpMethod.GET)
- .header(HttpHeader.AUTHORIZATION, "Basic " + authEncoded)
+ .headers(headers -> headers.put(HttpHeader.AUTHORIZATION, "Basic " + authEncoded))
.send();
assertThat("HTTP Response Status", response.getStatus(), is(HttpStatus.OK_200));
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java
index 35067e47a26..494ba110379 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/AuthenticationProtocolHandler.java
@@ -256,7 +256,7 @@ public abstract class AuthenticationProtocolHandler implements ProtocolHandler
{
HttpField field = oldRequest.getHeaders().getField(header);
if (field != null && !newRequest.getHeaders().contains(header))
- newRequest.put(field);
+ newRequest.headers(headers -> headers.put(field));
}
private void forwardSuccessComplete(HttpRequest request, Response response)
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 f5270c93dc0..a662c16bbb1 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
@@ -444,7 +444,7 @@ public class HttpClient extends ContainerLifeCycle
protected Request copyRequest(HttpRequest oldRequest, URI newURI)
{
- Request newRequest = newHttpRequest(oldRequest.getConversation(), newURI);
+ HttpRequest newRequest = newHttpRequest(oldRequest.getConversation(), newURI);
newRequest.method(oldRequest.getMethod())
.version(oldRequest.getVersion())
.body(oldRequest.getBody())
@@ -471,10 +471,8 @@ public class HttpClient extends ContainerLifeCycle
HttpHeader.PROXY_AUTHORIZATION == header)
continue;
- String name = field.getName();
- String value = field.getValue();
- if (!newRequest.getHeaders().contains(name, value))
- newRequest.header(name, value);
+ if (!newRequest.getHeaders().contains(field))
+ newRequest.header(field);
}
return newRequest;
}
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 187a4f133e1..3546ce7192f 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
@@ -122,9 +122,9 @@ public abstract class HttpConnection implements IConnection
}
}
- protected void normalizeRequest(Request request)
+ protected void normalizeRequest(HttpRequest request)
{
- boolean normalized = ((HttpRequest)request).normalized();
+ boolean normalized = request.normalized();
if (LOG.isDebugEnabled())
LOG.debug("Normalizing {} {}", !normalized, request);
if (normalized)
@@ -153,7 +153,7 @@ public abstract class HttpConnection implements IConnection
if (version.getVersion() <= 11)
{
if (!headers.contains(HttpHeader.HOST))
- request.put(getHttpDestination().getHostField());
+ request.header(getHttpDestination().getHostField());
}
// Add content headers
@@ -167,22 +167,19 @@ public abstract class HttpConnection implements IConnection
if (!headers.contains(HttpHeader.CONTENT_TYPE))
{
String contentType = content.getContentType();
+ if (contentType == null)
+ contentType = getHttpClient().getDefaultRequestContentType();
if (contentType != null)
{
- request.put(new HttpField(HttpHeader.CONTENT_TYPE, contentType));
- }
- else
- {
- contentType = getHttpClient().getDefaultRequestContentType();
- if (contentType != null)
- request.put(new HttpField(HttpHeader.CONTENT_TYPE, contentType));
+ HttpField field = new HttpField(HttpHeader.CONTENT_TYPE, contentType);
+ request.header(field);
}
}
long contentLength = content.getLength();
if (contentLength >= 0)
{
if (!headers.contains(HttpHeader.CONTENT_LENGTH))
- request.put(new HttpField.LongValueHttpField(HttpHeader.CONTENT_LENGTH, contentLength));
+ request.header(new HttpField.LongValueHttpField(HttpHeader.CONTENT_LENGTH, contentLength));
}
}
@@ -195,7 +192,10 @@ public abstract class HttpConnection implements IConnection
cookies = convertCookies(HttpCookieStore.matchPath(uri, cookieStore.get(uri)), null);
cookies = convertCookies(request.getCookies(), cookies);
if (cookies != null)
- request.header(HttpHeader.COOKIE, cookies.toString());
+ {
+ HttpField cookieField = new HttpField(HttpHeader.COOKIE, cookies.toString());
+ request.header(cookieField);
+ }
}
// Authentication
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpProxy.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpProxy.java
index 64a2812a024..82b1918428d 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpProxy.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpProxy.java
@@ -200,9 +200,9 @@ public class HttpProxy extends ProxyConfiguration.Proxy
Origin.Address proxyAddress = destination.getConnectAddress();
HttpClient httpClient = destination.getHttpClient();
Request connect = new TunnelRequest(httpClient, proxyAddress)
- .method(HttpMethod.CONNECT)
- .path(target)
- .header(HttpHeader.HOST, target);
+ .method(HttpMethod.CONNECT)
+ .path(target)
+ .headers(headers -> headers.put(HttpHeader.HOST, target));
ProxyConfiguration.Proxy proxy = destination.getProxy();
if (proxy.isSecure())
connect.scheme(HttpScheme.HTTPS.asString());
@@ -262,8 +262,7 @@ public class HttpProxy extends ProxyConfiguration.Proxy
}
else
{
- HttpResponseException failure = new HttpResponseException("Unexpected " + response +
- " for " + response.getRequest(), response);
+ HttpResponseException failure = new HttpResponseException("Unexpected " + response + " for " + response.getRequest(), response);
tunnelFailed(endPoint, failure);
}
}
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 c39d75b1717..937e4e3679c 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
@@ -72,7 +72,7 @@ import org.slf4j.LoggerFactory;
*/
public abstract class HttpReceiver
{
- protected static final Logger LOG = LoggerFactory.getLogger(HttpReceiver.class);
+ private static final Logger LOG = LoggerFactory.getLogger(HttpReceiver.class);
private final AtomicReference responseState = new AtomicReference<>(ResponseState.IDLE);
private final HttpChannel channel;
@@ -242,7 +242,7 @@ public abstract class HttpReceiver
boolean process = notifier.notifyHeader(exchange.getConversation().getResponseListeners(), response, field);
if (process)
{
- response.getHeaderFieldsMutable().add(field);
+ response.header(field);
HttpHeader fieldHeader = field.getHeader();
if (fieldHeader != null)
{
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java
index 8d4e7a6eca8..30c9eb9b113 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpRequest.java
@@ -41,6 +41,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
+import java.util.function.Consumer;
import java.util.function.LongConsumer;
import java.util.function.Supplier;
@@ -305,34 +306,6 @@ public class HttpRequest implements Request
return this;
}
- @Override
- public Request set(HttpFields fields)
- {
- headers.clear().add(fields);
- return this;
- }
-
- @Override
- public Request remove(HttpHeader header)
- {
- headers.remove(header);
- return this;
- }
-
- @Override
- public Request put(HttpField field)
- {
- headers.put(field);
- return this;
- }
-
- @Override
- public Request add(HttpField field)
- {
- headers.add(field);
- return this;
- }
-
@Override
public Request header(String name, String value)
{
@@ -402,6 +375,19 @@ public class HttpRequest implements Request
return headers;
}
+ @Override
+ public Request headers(Consumer consumer)
+ {
+ consumer.accept(headers);
+ return this;
+ }
+
+ public HttpRequest header(HttpField header)
+ {
+ headers.add(header);
+ return this;
+ }
+
@Override
@SuppressWarnings("unchecked")
public List getRequestListeners(Class type)
@@ -707,7 +693,7 @@ public class HttpRequest implements Request
public Request content(ContentProvider content, String contentType)
{
if (contentType != null)
- header(HttpHeader.CONTENT_TYPE, contentType);
+ headers.put(HttpHeader.CONTENT_TYPE, contentType);
return body(ContentProvider.toRequestContent(content));
}
@@ -886,7 +872,7 @@ public class HttpRequest implements Request
* headers, etc.
*
* @return whether this request was already normalized
- * @see HttpConnection#normalizeRequest(Request)
+ * @see HttpConnection#normalizeRequest(HttpRequest)
*/
boolean normalized()
{
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponse.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponse.java
index 3d941c92827..28c0dcf0df6 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponse.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpResponse.java
@@ -20,6 +20,7 @@ package org.eclipse.jetty.client;
import java.util.ArrayList;
import java.util.List;
+import java.util.function.Consumer;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
@@ -91,9 +92,16 @@ public class HttpResponse implements Response
return headers.asImmutable();
}
- public HttpFields.Mutable getHeaderFieldsMutable()
+ public HttpResponse header(HttpField header)
{
- return headers;
+ headers.add(header);
+ return this;
+ }
+
+ public HttpResponse headers(Consumer consumer)
+ {
+ consumer.accept(headers);
+ return this;
}
@Override
@@ -110,7 +118,7 @@ public class HttpResponse implements Response
public HttpFields getTrailers()
{
- return trailers;
+ return trailers.asImmutable();
}
public HttpResponse trailer(HttpField trailer)
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java
index 7b2d14edb27..c1831b869ac 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/api/Request.java
@@ -31,10 +31,10 @@ import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.function.Consumer;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.util.InputStreamResponseListener;
-import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
@@ -166,38 +166,22 @@ public interface Request
*/
HttpFields getHeaders();
- /** Set the headers, clearing any existing headers
- * @param fields The fields to set
- * @return this request object
- */
- Request set(HttpFields fields);
-
/**
- * @param header the header to remove
+ * Modifies the headers of this request.
+ *
+ * @param consumer the code that modifies the headers of this request
* @return this request object
*/
- Request remove(HttpHeader header);
-
- /**
- * @param field the field to add
- * @return this request object
- * @see #header(HttpHeader, String)
- */
- Request add(HttpField field);
-
- /**
- * @param field the field to put
- * @return this request object
- * @see #header(HttpHeader, String)
- */
- Request put(HttpField field);
+ Request headers(Consumer consumer);
/**
* @param name the name of the header
* @param value the value of the header
* @return this request object
* @see #header(HttpHeader, String)
+ * @deprecated use {@link #headers(Consumer)} instead
*/
+ @Deprecated
Request header(String name, String value);
/**
@@ -208,7 +192,9 @@ public interface Request
* @param header the header name
* @param value the value of the header
* @return this request object
+ * @deprecated use {@link #headers(Consumer)} instead
*/
+ @Deprecated
Request header(HttpHeader header, String value);
/**
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java
index 1375d799458..f6bd5d11353 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpConnectionOverHTTP.java
@@ -261,7 +261,7 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne
@Override
public SendFailure send(HttpExchange exchange)
{
- Request request = exchange.getRequest();
+ HttpRequest request = exchange.getRequest();
normalizeRequest(request);
// Save the old idle timeout to restore it.
@@ -276,7 +276,7 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne
}
@Override
- protected void normalizeRequest(Request request)
+ protected void normalizeRequest(HttpRequest request)
{
super.normalizeRequest(request);
@@ -287,8 +287,7 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne
.idleTimeout(2 * connectTimeout, TimeUnit.MILLISECONDS);
}
- HttpRequest httpRequest = (HttpRequest)request;
- HttpConversation conversation = httpRequest.getConversation();
+ HttpConversation conversation = request.getConversation();
HttpUpgrader upgrader = (HttpUpgrader)conversation.getAttribute(HttpUpgrader.class.getName());
if (upgrader == null)
{
@@ -296,7 +295,7 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne
{
upgrader = ((HttpUpgrader.Factory)request).newHttpUpgrader(HttpVersion.HTTP_1_1);
conversation.setAttribute(HttpUpgrader.class.getName(), upgrader);
- upgrader.prepare(httpRequest);
+ upgrader.prepare(request);
}
else
{
@@ -305,7 +304,7 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne
{
upgrader = new ProtocolHttpUpgrader(getHttpDestination(), protocol);
conversation.setAttribute(HttpUpgrader.class.getName(), upgrader);
- upgrader.prepare(httpRequest);
+ upgrader.prepare(request);
}
}
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
index 4bd4307fed1..5047b482338 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
@@ -38,9 +38,13 @@ import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.io.RetainableByteBuffer;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.ResponseHandler
{
+ private static final Logger LOG = LoggerFactory.getLogger(HttpReceiverOverHTTP.class);
+
private final HttpParser parser;
private RetainableByteBuffer networkBuffer;
private boolean shutdown;
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/BasicAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/BasicAuthentication.java
index ed3665074f0..faa889a63f1 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/BasicAuthentication.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/BasicAuthentication.java
@@ -105,7 +105,7 @@ public class BasicAuthentication extends AbstractAuthentication
public void apply(Request request)
{
if (!request.getHeaders().contains(header, value))
- request.header(header, value);
+ request.headers(headers -> headers.add(header, value));
}
@Override
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java
index 466ea8168b6..dac81b63102 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/DigestAuthentication.java
@@ -204,7 +204,7 @@ public class DigestAuthentication extends AbstractAuthentication
}
value.append(", response=\"").append(hashA3).append("\"");
- request.header(header, value.toString());
+ request.headers(headers -> headers.add(header, value.toString()));
}
private String nextNonceCount()
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java
index 2bff3857e3a..356dfe75f6b 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/FormContentProvider.java
@@ -18,11 +18,8 @@
package org.eclipse.jetty.client.util;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
-import java.nio.charset.UnsupportedCharsetException;
import org.eclipse.jetty.client.api.ContentProvider;
import org.eclipse.jetty.util.Fields;
@@ -53,29 +50,6 @@ public class FormContentProvider extends StringContentProvider
public static String convert(Fields fields, Charset charset)
{
- // Assume 32 chars between name and value.
- StringBuilder builder = new StringBuilder(fields.getSize() * 32);
- for (Fields.Field field : fields)
- {
- for (String value : field.getValues())
- {
- if (builder.length() > 0)
- builder.append("&");
- builder.append(encode(field.getName(), charset)).append("=").append(encode(value, charset));
- }
- }
- return builder.toString();
- }
-
- private static String encode(String value, Charset charset)
- {
- try
- {
- return URLEncoder.encode(value, charset.name());
- }
- catch (UnsupportedEncodingException x)
- {
- throw new UnsupportedCharsetException(charset.name());
- }
+ return FormRequestContent.convert(fields, charset);
}
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java b/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java
index 5f3d7742604..a3398393372 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/util/SPNEGOAuthentication.java
@@ -307,7 +307,7 @@ public class SPNEGOAuthentication extends AbstractAuthentication
@Override
public void apply(Request request)
{
- request.header(header, value);
+ request.headers(headers -> headers.add(header, value));
}
}
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java
index 70cb83e408f..bd6c64dde53 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ClientConnectionCloseTest.java
@@ -86,7 +86,7 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
var request = client.newRequest(host, port)
.scheme(scenario.getScheme())
- .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString())
+ .headers(headers -> headers.put(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE))
.body(new StringRequestContent("0"))
.onRequestSuccess(r ->
{
@@ -126,7 +126,7 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
long idleTimeout = 1000;
var request = client.newRequest(host, port)
.scheme(scenario.getScheme())
- .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString())
+ .headers(headers -> headers.put(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE))
.idleTimeout(idleTimeout, TimeUnit.MILLISECONDS)
.onRequestSuccess(r ->
{
@@ -188,7 +188,7 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
CountDownLatch resultLatch = new CountDownLatch(1);
var request = client.newRequest(host, port)
.scheme(scenario.getScheme())
- .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString())
+ .headers(headers -> headers.put(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE))
.body(content)
.idleTimeout(idleTimeout, TimeUnit.MILLISECONDS)
.onRequestSuccess(r ->
@@ -242,7 +242,7 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
var request = client.newRequest(host, port)
.scheme(scenario.getScheme())
- .header(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString())
+ .headers(headers -> headers.put(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE))
.onRequestSuccess(r ->
{
HttpDestination destination = (HttpDestination)client.resolveDestination(r);
@@ -250,10 +250,7 @@ public class ClientConnectionCloseTest extends AbstractHttpClientServerTest
HttpConnectionOverHTTP connection = (HttpConnectionOverHTTP)connectionPool.getActiveConnections().iterator().next();
assertFalse(connection.getEndPoint().isOutputShutdown());
})
- .onResponseHeaders(r ->
- {
- ((HttpResponse)r).getHeaderFieldsMutable().remove(HttpHeader.CONNECTION);
- });
+ .onResponseHeaders(r -> ((HttpResponse)r).headers(headers -> headers.remove(HttpHeader.CONNECTION)));
ContentResponse response = request.send();
assertEquals(HttpStatus.OK_200, response.getStatus());
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java
index 08139dbf1d6..581d61a7c03 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/ConnectionPoolTest.java
@@ -19,7 +19,6 @@
package org.eclipse.jetty.client;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
@@ -36,6 +35,7 @@ import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.client.util.BytesRequestContent;
import org.eclipse.jetty.client.util.FutureResponseListener;
import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Handler;
@@ -45,7 +45,6 @@ import org.eclipse.jetty.util.IO;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -58,20 +57,10 @@ public class ConnectionPoolTest
private ServerConnector connector;
private HttpClient client;
- public static Stream pools()
+ public static Stream pools()
{
- List