diff --git a/NOTICE.md b/NOTICE.md
index b245c38..0388c31 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -70,7 +70,7 @@
 * Project: http://www.javassist.org/
 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
 
-Jackson JAX-RS Providers Version 2.18.0
+Jackson JAX-RS Providers Version 2.19.1
 * License: Apache License, 2.0
 * Project: https://github.com/FasterXML/jackson-jaxrs-providers
 * Copyright: (c) 2009-2024 FasterXML, LLC. All rights reserved unless otherwise indicated.
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/Expect100ContinueConnectorExtension.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/Expect100ContinueConnectorExtension.java
index 471321f..6072a52 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/Expect100ContinueConnectorExtension.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/Expect100ContinueConnectorExtension.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -30,20 +30,21 @@
 
 class Expect100ContinueConnectorExtension
         implements ConnectorExtension<HttpRequest, IOException> {
+
+    private final NettyConnectorProvider.Config.RW requestConfiguration;
+
+    Expect100ContinueConnectorExtension(NettyConnectorProvider.Config.RW requestConfiguration) {
+        this.requestConfiguration = requestConfiguration;
+    }
+
     private static final String EXCEPTION_MESSAGE = "Server rejected operation";
     @Override
     public void invoke(ClientRequest request, HttpRequest extensionParam) {
 
         final long length = request.getLengthLong();
-        final RequestEntityProcessing entityProcessing = request.resolveProperty(
-                ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.class);
-
-        final Boolean expectContinueActivated = request.resolveProperty(
-                ClientProperties.EXPECT_100_CONTINUE, Boolean.class);
-        final Long expectContinueSizeThreshold = request.resolveProperty(
-                ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE,
-                ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE);
-
+        final RequestEntityProcessing entityProcessing = requestConfiguration.requestEntityProcessing(request);
+        final Boolean expectContinueActivated = requestConfiguration.expect100Continue(request);
+        final long expectContinueSizeThreshold = requestConfiguration.expect100ContinueThreshold(request);
         final boolean allowStreaming = length > expectContinueSizeThreshold
                 || entityProcessing == RequestEntityProcessing.CHUNKED;
 
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java
index 7f5bb9b..1efebc2 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java
@@ -31,7 +31,6 @@
 import jakarta.ws.rs.core.MultivaluedMap;
 import jakarta.ws.rs.core.Response;
 
-import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.client.ClientRequest;
 import org.glassfish.jersey.client.ClientResponse;
 import org.glassfish.jersey.http.HttpHeaders;
@@ -56,17 +55,14 @@
  */
 class JerseyClientHandler extends SimpleChannelInboundHandler<HttpObject> {
 
-    private static final int DEFAULT_MAX_REDIRECTS = 5;
-
     // Modified only by the same thread. No need to synchronize it.
     private final Set<URI> redirectUriHistory;
     private final ClientRequest jerseyRequest;
     private final CompletableFuture<ClientResponse> responseAvailable;
     private final CompletableFuture<?> responseDone;
-    private final boolean followRedirects;
-    private final int maxRedirects;
     private final NettyConnector connector;
     private final NettyHttpRedirectController redirectController;
+    private final NettyConnectorProvider.Config.RW requestConfiguration;
 
     private NettyInputStream nis;
     private ClientResponse jerseyResponse;
@@ -74,19 +70,20 @@
     private boolean readTimedOut;
 
     JerseyClientHandler(ClientRequest request, CompletableFuture<ClientResponse> responseAvailable,
-                        CompletableFuture<?> responseDone, Set<URI> redirectUriHistory, NettyConnector connector) {
+                        CompletableFuture<?> responseDone, Set<URI> redirectUriHistory, NettyConnector connector,
+                        NettyConnectorProvider.Config.RW requestConfiguration) {
         this.redirectUriHistory = redirectUriHistory;
         this.jerseyRequest = request;
         this.responseAvailable = responseAvailable;
         this.responseDone = responseDone;
-        // Follow redirects by default
-        this.followRedirects = jerseyRequest.resolveProperty(ClientProperties.FOLLOW_REDIRECTS, true);
-        this.maxRedirects = jerseyRequest.resolveProperty(NettyClientProperties.MAX_REDIRECTS, DEFAULT_MAX_REDIRECTS);
+        this.requestConfiguration = requestConfiguration;
         this.connector = connector;
+        // Follow redirects by default
+        requestConfiguration.followRedirects(jerseyRequest);
+        requestConfiguration.maxRedirects(jerseyRequest);
 
-        final NettyHttpRedirectController customRedirectController = jerseyRequest
-                .resolveProperty(NettyClientProperties.HTTP_REDIRECT_CONTROLLER, NettyHttpRedirectController.class);
-        this.redirectController = customRedirectController == null ? new NettyHttpRedirectController() : customRedirectController;
+        this.redirectController = requestConfiguration.redirectController(jerseyRequest);
+        this.redirectController.init(requestConfiguration);
     }
 
     @Override
@@ -112,7 +109,7 @@
           ClientResponse cr = jerseyResponse;
           jerseyResponse = null;
           int responseStatus = cr.getStatus();
-          if (followRedirects
+          if (Boolean.TRUE.equals(requestConfiguration.followRedirects())
                   && (responseStatus == ResponseStatus.Redirect3xx.MOVED_PERMANENTLY_301.getStatusCode()
                           || responseStatus == ResponseStatus.Redirect3xx.FOUND_302.getStatusCode()
                           || responseStatus == ResponseStatus.Redirect3xx.SEE_OTHER_303.getStatusCode()
@@ -139,16 +136,17 @@
                           // infinite loop detection
                           responseAvailable.completeExceptionally(
                                   new RedirectException(LocalizationMessages.REDIRECT_INFINITE_LOOP()));
-                      } else if (redirectUriHistory.size() > maxRedirects) {
+                      } else if (redirectUriHistory.size() > requestConfiguration.maxRedirects.get()) {
                           // maximal number of redirection
-                          responseAvailable.completeExceptionally(
-                                  new RedirectException(LocalizationMessages.REDIRECT_LIMIT_REACHED(maxRedirects)));
+                          responseAvailable.completeExceptionally(new RedirectException(
+                                  LocalizationMessages.REDIRECT_LIMIT_REACHED(requestConfiguration.maxRedirects.get())));
                       } else {
                           ClientRequest newReq = new ClientRequest(jerseyRequest);
                           newReq.setUri(newUri);
                           ctx.close();
                           if (redirectController.prepareRedirect(newReq, cr)) {
-                              final NettyConnector newConnector = new NettyConnector(newReq.getClient());
+                              final NettyConnector newConnector =
+                                      new NettyConnector(newReq.getClient(), connector.clientConfiguration);
                               newConnector.execute(newReq, redirectUriHistory, new CompletableFuture<ClientResponse>() {
                                   @Override
                                   public boolean complete(ClientResponse value) {
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
index 4b2e4c9..7dc3495 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
@@ -73,6 +73,11 @@
     public static final String IDLE_CONNECTION_PRUNE_TIMEOUT = "jersey.config.client.idleConnectionPruneTimeout";
 
     /**
+     * Enable or disable the Netty logging by {@code LoggingHandler(Level.DEBUG)}. Disabled by default.
+     */
+    public static final String LOGGING_ENABLED = "jersey.config.client.netty.loggingEnabled";
+
+    /**
      *  <p>
      *    This property determines the maximum number of idle connections that will be simultaneously kept alive, per destination.
      *    The default is 5.
@@ -157,7 +162,8 @@
         DEFAULT_HEADER_SIZE = 8192;
 
     /**
-     * Parameter which allows extending of the initial line length for the Netty connector
+     * Parameter which allows extending of the first line length of the HTTP header for the Netty connector.
+     * Taken from {@link io.netty.handler.codec.http.HttpClientCodec#HttpClientCodec(int, int, int)}.
      *
      * @since 2.44
      */
@@ -166,12 +172,12 @@
 
     /**
      * Default initial line length for Netty Connector.
-     * Taken from {@link io.netty.handler.codec.http.HttpClientCodec#HttpClientCodec(int, int, int)}
+     * Typically, set this to the same value as {@link #MAX_HEADER_SIZE}.
      *
      * @since 2.44
      */
     public static final Integer
-        DEFAULT_INITIAL_LINE_LENGTH = 4096;
+        DEFAULT_INITIAL_LINE_LENGTH = 8192;
 
     /**
      * Parameter which allows extending of the chunk size for the Netty connector
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectionController.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectionController.java
new file mode 100644
index 0000000..5d8725c
--- /dev/null
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectionController.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.netty.connector;
+
+import org.glassfish.jersey.client.ClientRequest;
+
+import java.net.URI;
+
+/**
+ * Adjustable connection pooling controller.
+ */
+public class NettyConnectionController {
+    /**
+     * Get the group of connections to be pooled, purged idle, and reused together.
+     *
+     * @param clientRequest the HTTP client request.
+     * @param uri the uri for the HTTP client request.
+     * @param hostName the hostname for the request. Can differ from the hostname in the uri based on other request attributes.
+     * @param port the real port for the request. Can differ from the port in the uri based on other request attributes.
+     * @return the group of connections identifier.
+     */
+    public String getConnectionGroup(ClientRequest clientRequest, URI uri, String hostName, int port) {
+        return uri.getScheme() + "://" + hostName + ":" + port;
+    }
+}
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
index a65560c..ba80967 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
@@ -18,8 +18,6 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -36,7 +34,6 @@
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import java.util.function.Supplier;
 
 import javax.net.ssl.SSLContext;
 
@@ -56,10 +53,8 @@
 import io.netty.channel.socket.SocketChannel;
 import io.netty.channel.socket.nio.NioSocketChannel;
 import io.netty.handler.codec.http.DefaultFullHttpRequest;
-import io.netty.handler.codec.http.DefaultHttpHeaders;
 import io.netty.handler.codec.http.DefaultHttpRequest;
 import io.netty.handler.codec.http.HttpChunkedInput;
-import io.netty.handler.codec.http.HttpClientCodec;
 import io.netty.handler.codec.http.HttpContentDecompressor;
 import io.netty.handler.codec.http.HttpHeaderNames;
 import io.netty.handler.codec.http.HttpHeaders;
@@ -68,8 +63,8 @@
 import io.netty.handler.codec.http.HttpUtil;
 import io.netty.handler.codec.http.HttpVersion;
 import io.netty.handler.codec.http.LastHttpContent;
-import io.netty.handler.proxy.HttpProxyHandler;
-import io.netty.handler.proxy.ProxyHandler;
+import io.netty.handler.logging.LogLevel;
+import io.netty.handler.logging.LoggingHandler;
 import io.netty.handler.ssl.ApplicationProtocolConfig;
 import io.netty.handler.ssl.ClientAuth;
 import io.netty.handler.ssl.IdentityCipherSuiteFilter;
@@ -81,7 +76,6 @@
 import io.netty.handler.timeout.IdleStateHandler;
 import io.netty.resolver.NoopAddressResolverGroup;
 import io.netty.util.concurrent.GenericFutureListener;
-import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.client.ClientRequest;
 import org.glassfish.jersey.client.ClientResponse;
 import org.glassfish.jersey.client.innate.ClientProxy;
@@ -106,6 +100,7 @@
     final EventLoopGroup group;
     final Client client;
     final HashMap<String, ArrayList<Channel>> connections = new HashMap<>();
+    final NettyConnectorProvider.Config.RW clientConfiguration;
 
     private static final LazyValue<String> NETTY_VERSION = Values.lazy(
         (Value<String>) () -> {
@@ -118,63 +113,29 @@
             return "Netty " + nettyVersion;
         });
 
-    // If HTTP keepalive is enabled the value of "http.maxConnections" determines the maximum number
-    // of idle connections that will be simultaneously kept alive, per destination.
-    private static final String HTTP_KEEPALIVE_STRING = System.getProperty("http.keepAlive");
-    // http.keepalive (default: true)
-    private static final Boolean HTTP_KEEPALIVE =
-            HTTP_KEEPALIVE_STRING == null ? Boolean.TRUE : Boolean.parseBoolean(HTTP_KEEPALIVE_STRING);
-
-    // http.maxConnections (default: 5)
-    private static final int DEFAULT_MAX_POOL_SIZE = 5;
-    private static final int MAX_POOL_SIZE = Integer.getInteger("http.maxConnections", DEFAULT_MAX_POOL_SIZE);
-    private static final int DEFAULT_MAX_POOL_IDLE = 60; // seconds
-    private static final int DEFAULT_MAX_POOL_SIZE_TOTAL = 60; // connections
-
-
-    private final Integer maxPoolSize; // either from system property, or from Jersey config, or default
-    private final Integer maxPoolSizeTotal; //either from Jersey config, or default
-    private final Integer maxPoolIdle; // either from Jersey config, or default
-
     static final String INACTIVE_POOLED_CONNECTION_HANDLER = "inactive_pooled_connection_handler";
     private static final String PRUNE_INACTIVE_POOL = "prune_inactive_pool";
     private static final String READ_TIMEOUT_HANDLER = "read_timeout_handler";
     private static final String REQUEST_HANDLER = "request_handler";
     private static final String EXPECT_100_CONTINUE_HANDLER = "expect_100_continue_handler";
 
-    NettyConnector(Client client) {
+    NettyConnector(Client client, NettyConnectorProvider.Config.RW connectorConfiguration) {
+        this.client = client;
+        this.clientConfiguration = connectorConfiguration.fromClient(client);
 
         final Configuration configuration = client.getConfiguration();
-        final Map<String, Object> properties = configuration.getProperties();
-        final Object threadPoolSize = properties.get(ClientProperties.ASYNC_THREADPOOL_SIZE);
-
-        if (threadPoolSize != null && threadPoolSize instanceof Integer && (Integer) threadPoolSize > 0) {
-            executorService = VirtualThreadUtil.withConfig(configuration).newFixedThreadPool((Integer) threadPoolSize);
-            this.group = new NioEventLoopGroup((Integer) threadPoolSize);
+        final Integer threadPoolSize = this.clientConfiguration.asyncThreadPoolSize();
+        if (threadPoolSize != null && threadPoolSize > 0) {
+            executorService = VirtualThreadUtil
+                                .withConfig(clientConfiguration.prefixedConfiguration(configuration))
+                                .newFixedThreadPool(threadPoolSize);
+            this.group = new NioEventLoopGroup(threadPoolSize);
         } else {
-            executorService = VirtualThreadUtil.withConfig(configuration).newCachedThreadPool();
+            executorService = VirtualThreadUtil
+                                .withConfig(clientConfiguration.prefixedConfiguration(configuration))
+                                .newCachedThreadPool();
             this.group = new NioEventLoopGroup();
         }
-
-        this.client = client;
-
-        final Object maxPoolSizeTotalProperty = properties.get(NettyClientProperties.MAX_CONNECTIONS_TOTAL);
-        final Object maxPoolIdleProperty = properties.get(NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT);
-        final Object maxPoolSizeProperty = properties.get(NettyClientProperties.MAX_CONNECTIONS);
-
-        maxPoolSizeTotal = maxPoolSizeTotalProperty != null ? (Integer) maxPoolSizeTotalProperty : DEFAULT_MAX_POOL_SIZE_TOTAL;
-        maxPoolIdle = maxPoolIdleProperty != null ? (Integer) maxPoolIdleProperty : DEFAULT_MAX_POOL_IDLE;
-        maxPoolSize = maxPoolSizeProperty != null
-                ? (Integer) maxPoolSizeProperty
-                : (HTTP_KEEPALIVE ? MAX_POOL_SIZE : DEFAULT_MAX_POOL_SIZE);
-
-        if (maxPoolSizeTotal < 0) {
-            throw new ProcessingException(LocalizationMessages.WRONG_MAX_POOL_TOTAL(maxPoolSizeTotal));
-        }
-
-        if (maxPoolSize < 0) {
-            throw new ProcessingException(LocalizationMessages.WRONG_MAX_POOL_SIZE(maxPoolSize));
-        }
     }
 
     @Override
@@ -207,25 +168,31 @@
 
     protected void execute(final ClientRequest jerseyRequest, final Set<URI> redirectUriHistory,
             final CompletableFuture<ClientResponse> responseAvailable) {
-        Integer timeout = jerseyRequest.resolveProperty(ClientProperties.READ_TIMEOUT, 0);
-        final Integer expect100ContinueTimeout = jerseyRequest.resolveProperty(
-                NettyClientProperties.EXPECT_100_CONTINUE_TIMEOUT,
-                NettyClientProperties.DEFAULT_EXPECT_100_CONTINUE_TIMEOUT_VALUE);
-        if (timeout == null || timeout < 0) {
-            throw new ProcessingException(LocalizationMessages.WRONG_READ_TIMEOUT(timeout));
+        final NettyConnectorProvider.Config.RW requestConfiguration =
+                clientConfiguration
+                        .fromRequest(jerseyRequest)
+                        .readTimeout(jerseyRequest)
+                        .expect100ContinueTimeout(jerseyRequest);
+        final int readTimeout = requestConfiguration.readTimeout();
+        if (readTimeout < 0) {
+            throw new ProcessingException(LocalizationMessages.WRONG_READ_TIMEOUT(readTimeout));
         }
 
         final CompletableFuture<?> responseDone = new CompletableFuture<>();
 
         final URI requestUri = jerseyRequest.getUri();
-        String host = requestUri.getHost();
-        int port = requestUri.getPort() != -1 ? requestUri.getPort() : "https".equals(requestUri.getScheme()) ? 443 : 80;
+        final String host = requestUri.getHost();
+        final int port = requestUri.getPort() != -1
+                ? requestUri.getPort()
+                : "https".equalsIgnoreCase(requestUri.getScheme()) ? 443 : 80;
 
         try {
-            final SSLParamConfigurator sslConfig = SSLParamConfigurator.builder()
+            final SSLParamConfigurator sslConfig = SSLParamConfigurator.builder(requestConfiguration)
                     .request(jerseyRequest).setSNIAlways(true).setSNIHostName(jerseyRequest).build();
 
-            String key = requestUri.getScheme() + "://" + sslConfig.getSNIHostName() + ":" + port;
+            final String key = requestConfiguration
+                                .connectionController()
+                                .getConnectionGroup(jerseyRequest, requestUri, sslConfig.getSNIHostName(), port);
             ArrayList<Channel> conns;
             synchronized (connections) {
                conns = connections.get(key);
@@ -245,8 +212,8 @@
                   } catch (NoSuchElementException e) {
                       /*
                        *  Eat it.
-                       *  It could happen that the channel was closed, pipeline cleared and
-                       *  then it will fail to remove the names with this exception.
+                       *  It could happen that the channel was closed, pipeline cleared,
+                       *  and then it will fail to remove the names with this exception.
                        */
                   }
                   if (!chan.isOpen()) {
@@ -258,20 +225,15 @@
             final JerseyExpectContinueHandler expect100ContinueHandler = new JerseyExpectContinueHandler();
 
             if (chan == null) {
-               Integer connectTimeout = jerseyRequest.resolveProperty(ClientProperties.CONNECT_TIMEOUT, 0);
+               requestConfiguration.connectTimeout(jerseyRequest);
                Bootstrap b = new Bootstrap();
 
                // http proxy
-               Optional<ClientProxy> proxy = ClientProxy.proxyFromRequest(jerseyRequest);
-               if (!proxy.isPresent()) {
-                   proxy = ClientProxy.proxyFromProperties(requestUri);
-               }
-               proxy.ifPresent(clientProxy -> {
+               final Optional<ClientProxy> handlerProxy = requestConfiguration.proxy(jerseyRequest, requestUri);
+               handlerProxy.ifPresent(clientProxy -> {
                    b.resolver(NoopAddressResolverGroup.INSTANCE); // request hostname resolved by the HTTP proxy
                });
 
-               final Optional<ClientProxy> handlerProxy = proxy;
-
                b.group(group)
                 .channel(NioSocketChannel.class)
                 .handler(new ChannelInitializer<SocketChannel>() {
@@ -283,19 +245,14 @@
 
                      // http proxy
                      handlerProxy.ifPresent(clientProxy -> {
-                         final URI u = clientProxy.uri();
-                         InetSocketAddress proxyAddr = new InetSocketAddress(u.getHost(),
-                                 u.getPort() == -1 ? 8080 : u.getPort());
-                         ProxyHandler proxy1 = createProxyHandler(jerseyRequest, proxyAddr,
-                                 clientProxy.userName(), clientProxy.password(), connectTimeout);
-                         p.addLast(proxy1);
+                         p.addLast(requestConfiguration.createProxyHandler(clientProxy, jerseyRequest));
                      });
 
                      // Enable HTTPS if necessary.
                      if ("https".equals(requestUri.getScheme())) {
                          // making client authentication optional for now; it could be extracted to configurable property
                          JdkSslContext jdkSslContext = new JdkSslContext(
-                                 getSslContext(client, jerseyRequest),
+                                 requestConfiguration.sslContext(client, jerseyRequest),
                                  true,
                                  (Iterable) null,
                                  IdentityCipherSuiteFilter.INSTANCE,
@@ -310,8 +267,7 @@
                          final SslHandler sslHandler = jdkSslContext.newHandler(
                                  ch.alloc(), sslConfig.getSNIHostName(), port <= 0 ? 443 : port, executorService
                          );
-                         if (ClientProperties.getValue(config.getProperties(),
-                                                       NettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION, true)) {
+                         if (requestConfiguration.isSslHostnameVerificationEnabled(config.getProperties())) {
                              sslConfig.setEndpointIdentificationAlgorithm(sslHandler.engine());
                          }
 
@@ -320,16 +276,10 @@
                          p.addLast(sslHandler);
                      }
 
-                     final Integer maxHeaderSize = ClientProperties.getValue(config.getProperties(),
-                                NettyClientProperties.MAX_HEADER_SIZE,
-                                NettyClientProperties.DEFAULT_HEADER_SIZE);
-                     final Integer maxChunkSize = ClientProperties.getValue(config.getProperties(),
-                                NettyClientProperties.MAX_CHUNK_SIZE,
-                                NettyClientProperties.DEFAULT_CHUNK_SIZE);
-                     final Integer maxInitialLineLength = ClientProperties.getValue(config.getProperties(),
-                                NettyClientProperties.MAX_INITIAL_LINE_LENGTH,
-                                NettyClientProperties.DEFAULT_INITIAL_LINE_LENGTH);
-                     p.addLast(new HttpClientCodec(maxInitialLineLength, maxHeaderSize, maxChunkSize));
+                     if (requestConfiguration.loggingEnabled.get()) {
+                         p.addLast(new LoggingHandler(LogLevel.INFO));
+                     }
+                     p.addLast(requestConfiguration.createHttpClientCodec(config.getProperties()));
                      p.addLast(EXPECT_100_CONTINUE_HANDLER, expect100ContinueHandler);
                      p.addLast(new ChunkedWriteHandler());
                      p.addLast(new HttpContentDecompressor());
@@ -337,8 +287,8 @@
                 });
 
                // connect timeout
-               if (connectTimeout > 0) {
-                   b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout);
+               if (requestConfiguration.connectTimeout() > 0) {
+                   b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, requestConfiguration.connectTimeout());
                }
 
                // Make the connection attempt.
@@ -357,12 +307,12 @@
             // assert: it is ok to abort the entire response, if responseDone is completed exceptionally - in particular, nothing
             //         will leak
             final Channel ch = chan;
-            JerseyClientHandler clientHandler =
-                    new JerseyClientHandler(jerseyRequest, responseAvailable, responseDone, redirectUriHistory, this);
+            JerseyClientHandler clientHandler = new JerseyClientHandler(
+                    jerseyRequest, responseAvailable, responseDone, redirectUriHistory, this, requestConfiguration);
 
             // read timeout makes sense really as an inactivity timeout
             ch.pipeline().addLast(READ_TIMEOUT_HANDLER,
-                                  new IdleStateHandler(0, 0, timeout, TimeUnit.MILLISECONDS));
+                                  new IdleStateHandler(0, 0, requestConfiguration.readTimeout(), TimeUnit.MILLISECONDS));
             ch.pipeline().addLast(REQUEST_HANDLER, clientHandler);
 
             responseDone.whenComplete((_r, th) -> {
@@ -370,7 +320,8 @@
                ch.pipeline().remove(clientHandler);
 
                if (th == null) {
-                  ch.pipeline().addLast(INACTIVE_POOLED_CONNECTION_HANDLER, new IdleStateHandler(0, 0, maxPoolIdle));
+                  ch.pipeline().addLast(INACTIVE_POOLED_CONNECTION_HANDLER,
+                          new IdleStateHandler(0, 0, requestConfiguration.maxPoolIdle.get()));
                   ch.pipeline().addLast(PRUNE_INACTIVE_POOL, new PruneIdlePool(connections, key));
                   boolean added = true;
                   synchronized (connections) {
@@ -381,7 +332,9 @@
                         connections.put(key, conns1);
                      } else {
                         synchronized (conns1) {
-                           if ((maxPoolSizeTotal == 0 || connections.size() < maxPoolSizeTotal) && conns1.size() < maxPoolSize) {
+                           if ((requestConfiguration.maxPoolSizeTotal.get() == 0
+                                   || connections.size() < requestConfiguration.maxPoolSizeTotal.get())
+                                   && conns1.size() < requestConfiguration.maxPoolSize.get()) {
                               conns1.add(ch);
                            } else { // else do not add the Channel to the idle pool
                               added = false;
@@ -433,7 +386,7 @@
                     };
                 ch.closeFuture().addListener(closeListener);
 
-                final NettyEntityWriter entityWriter = nettyEntityWriter(jerseyRequest, ch);
+                final NettyEntityWriter entityWriter = nettyEntityWriter(jerseyRequest, ch, requestConfiguration);
                 switch (entityWriter.getType()) {
                     case CHUNKED:
                         HttpUtil.setTransferEncodingChunked(nettyRequest, true);
@@ -493,7 +446,7 @@
                 });
 
                 headersSet.await();
-                new Expect100ContinueConnectorExtension().invoke(jerseyRequest, nettyRequest);
+                new Expect100ContinueConnectorExtension(requestConfiguration).invoke(jerseyRequest, nettyRequest);
 
                 boolean continueExpected = HttpUtil.is100ContinueExpected(nettyRequest);
                 boolean expectationsFailed  = false;
@@ -503,7 +456,7 @@
                     expect100ContinueHandler.attachCountDownLatch(expect100ContinueLatch);
                     //send expect request, sync and wait till either response or timeout received
                     entityWriter.writeAndFlush(nettyRequest);
-                    expect100ContinueLatch.await(expect100ContinueTimeout, TimeUnit.MILLISECONDS);
+                    expect100ContinueLatch.await(requestConfiguration.expect100ContTimeout.get(), TimeUnit.MILLISECONDS);
                     try {
                         expect100ContinueHandler.processExpectationStatus();
                     } catch (TimeoutException e) {
@@ -543,13 +496,10 @@
         }
     }
 
-    /* package */ NettyEntityWriter nettyEntityWriter(ClientRequest clientRequest, Channel channel) {
-        return NettyEntityWriter.getInstance(clientRequest, channel);
-    }
-
-    private SSLContext getSslContext(Client client, ClientRequest request) {
-        Supplier<SSLContext> supplier = request.resolveProperty(ClientProperties.SSL_CONTEXT_SUPPLIER, Supplier.class);
-        return supplier == null ? client.getSslContext() : supplier.get();
+    /* package */ NettyEntityWriter nettyEntityWriter(
+            ClientRequest clientRequest, Channel channel, NettyConnectorProvider.Config.RW requestConfiguration) {
+        return NettyEntityWriter
+                .getInstance(clientRequest, channel, () -> requestConfiguration.requestEntityProcessing(clientRequest));
     }
 
     private String buildPathWithQueryParameters(URI requestUri) {
@@ -602,21 +552,7 @@
        }
     }
 
-    private static ProxyHandler createProxyHandler(ClientRequest jerseyRequest, SocketAddress proxyAddr,
-                                                   String userName, String password, long connectTimeout) {
-        final Boolean filter = jerseyRequest.resolveProperty(NettyClientProperties.FILTER_HEADERS_FOR_PROXY, Boolean.TRUE);
-        HttpHeaders httpHeaders = setHeaders(jerseyRequest, new DefaultHttpHeaders(), Boolean.TRUE.equals(filter));
-
-        ProxyHandler proxy = userName == null ? new HttpProxyHandler(proxyAddr, httpHeaders)
-                : new HttpProxyHandler(proxyAddr, userName, password, httpHeaders);
-        if (connectTimeout > 0) {
-            proxy.setConnectTimeoutMillis(connectTimeout);
-        }
-
-        return proxy;
-    }
-
-    private static HttpHeaders setHeaders(ClientRequest jerseyRequest, HttpHeaders headers, boolean proxyOnly) {
+    /* package */ static HttpHeaders setHeaders(ClientRequest jerseyRequest, HttpHeaders headers, boolean proxyOnly) {
         for (final Map.Entry<String, List<String>> e : jerseyRequest.getStringHeaders().entrySet()) {
             final String key = e.getKey();
             if (!proxyOnly || JerseyClientHandler.ProxyHeaders.INSTANCE.test(key) || additionalProxyHeadersToKeep(key)) {
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectorConfiguration.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectorConfiguration.java
new file mode 100644
index 0000000..99f763c
--- /dev/null
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectorConfiguration.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.netty.connector;
+
+import io.netty.handler.codec.http.DefaultHttpHeaders;
+import io.netty.handler.codec.http.HttpClientCodec;
+import io.netty.handler.codec.http.HttpHeaders;
+import io.netty.handler.proxy.HttpProxyHandler;
+import io.netty.handler.proxy.ProxyHandler;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientRequest;
+import org.glassfish.jersey.client.innate.ClientProxy;
+import org.glassfish.jersey.internal.util.collection.Ref;
+import org.glassfish.jersey.client.innate.ConnectorConfiguration;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.Map;
+
+class NettyConnectorConfiguration<N extends NettyConnectorConfiguration<N>> extends ConnectorConfiguration<N> {
+
+    /* package */ final NullableRef<NettyConnectionController> connectionController = NullableRef.empty();
+    /* package */ final NullableRef<Boolean> enableHostnameVerification = NullableRef.empty();
+    /* package */ final Ref<Integer> expect100ContTimeout = NullableRef.empty();
+    /* package */ final NullableRef<Boolean> filterHeadersForProxy = NullableRef.empty();
+    /* package */ final NullableRef<Integer> firstHttpHeaderLineLength = NullableRef.empty();
+    /* package */ final Ref<Boolean> loggingEnabled = NullableRef.empty();
+    /* package */ final NullableRef<Integer> maxChunkSize = NullableRef.empty();
+    /* package */ final NullableRef<Integer> maxHeaderSize = NullableRef.empty();
+    // either from Jersey config, or default
+    /* package */ final Ref<Integer> maxPoolSizeTotal = NullableRef.empty();
+    // either from Jersey config, or default
+    /* package */ final Ref<Integer> maxPoolIdle = NullableRef.empty();
+    // either from system property, or from Jersey config, or default
+    /* package */ final Ref<Integer> maxPoolSize = NullableRef.empty();
+    /* package */ final Ref<Integer> maxRedirects = NullableRef.empty();
+    /* package */ final NullableRef<Boolean> preserveMethodOnRedirect = NullableRef.empty();
+    /* package */ final NullableRef<NettyHttpRedirectController> redirectController = NullableRef.empty();
+
+    // If HTTP keepalive is enabled the value of "http.maxConnections" determines the maximum number
+    // of idle connections that will be simultaneously kept alive, per destination.
+    private static final String HTTP_KEEPALIVE_STRING = System.getProperty("http.keepAlive");
+    // http.keepalive (default: true)
+    private static final Boolean HTTP_KEEPALIVE =
+            HTTP_KEEPALIVE_STRING == null ? Boolean.TRUE : Boolean.parseBoolean(HTTP_KEEPALIVE_STRING);
+
+    // http.maxConnections (default: 5)
+    private static final int DEFAULT_MAX_POOL_SIZE = 5;
+    private static final int MAX_POOL_SIZE = Integer.getInteger("http.maxConnections", DEFAULT_MAX_POOL_SIZE);
+    private static final int DEFAULT_MAX_POOL_IDLE = 60; // seconds
+    private static final int DEFAULT_MAX_POOL_SIZE_TOTAL = 60; // connections
+
+    private static final int DEFAULT_MAX_REDIRECTS = 5;
+
+    /**
+     * Set the connection pooling controller for the Netty Connector.
+     *
+     * @param controller the connection pooling controller.
+     * @return updated configuration.
+     */
+    public N connectionController(NettyConnectionController controller) {
+        connectionController.set(controller);
+        return self();
+    }
+
+    /**
+     * This setting determines waiting time in milliseconds for 100-Continue response when 100-Continue is sent by the client.
+     * The property {@link NettyClientProperties#EXPECT_100_CONTINUE_TIMEOUT} has precedence over this setting.
+     *
+     * @param millis the timeout for 100-Continue response.
+     * @return updated configuration.
+     */
+    public N expect100ContinueTimeout(int millis) {
+        expect100ContTimeout.set(millis);
+        return self();
+    }
+
+    /**
+     * Enable or disable the endpoint identification algorithm to HTTPS. The property
+     * {@link NettyClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION} takes precedence over this setting.
+     *
+     * @param enable enable or disable the hostname verification.
+     * @return updated configuration.
+     */
+    public N enableSslHostnameVerification(boolean enable) {
+        enableHostnameVerification.set(enable);
+        return self();
+    }
+
+    /**
+     * Enable or disable the Netty logging by {@code LoggingHandler(Level.DEBUG)}. Disabled by default.
+     * The property {@link NettyClientProperties#LOGGING_ENABLED} takes precedence over this setting.
+     *
+     * @param enable to enable or disable.
+     * @return updated configuration.
+     */
+    public N enableLoggingHandler(boolean enable) {
+        loggingEnabled.set(enable);
+        return self();
+    }
+
+    /**
+     * Filter the HTTP headers for requests (CONNECT) towards the proxy except for PROXY-prefixed
+     * and HOST headers when {@code true}.
+     * The property {@link NettyClientProperties#FILTER_HEADERS_FOR_PROXY} has precedence over this setting.
+     *
+     * @param filter to filter or not. The default is {@code true}.
+     * @return updated configuration.
+     */
+    public N filterHeadersForProxy(boolean filter) {
+        filterHeadersForProxy.set(filter);
+        return self();
+    }
+
+    /**
+     * This property determines the number of seconds the idle connections are kept in the pool before pruned.
+     * The default is 60. Specify 0 to disable. The property {@link NettyClientProperties#IDLE_CONNECTION_PRUNE_TIMEOUT}
+     * has precedence over this setting.
+     *
+     * @param seconds the timeout in seconds.
+     * @return updated configuration.
+     */
+    public N idleConnectionPruneTimeout(int seconds) {
+        maxPoolIdle.set(seconds);
+        return self();
+    }
+
+    /**
+     * Set the maximum length of the first line of the HTTP header.
+     * The property {@link NettyClientProperties#MAX_INITIAL_LINE_LENGTH} has precedence over this setting.
+     *
+     * @param length the length of the first line of the HTTP header.
+     * @return updated configuration.
+     */
+    public N initialHttpHeaderLineLength(int length) {
+        firstHttpHeaderLineLength.set(length);
+        return self();
+    }
+
+    /**
+     * Set the maximum chunk size for the Netty connector. The property {@link NettyClientProperties#MAX_CHUNK_SIZE}
+     * has precedence over this setting.
+     *
+     * @param size the new size of chunks.
+     * @return updated configuration.
+     */
+    public N maxChunkSize(int size) {
+        maxChunkSize.set(size);
+        return self();
+    }
+
+    /**
+     * This setting determines the maximum number of idle connections that will be simultaneously kept alive, per destination.
+     * The default is 5. The property {@link NettyClientProperties#MAX_CONNECTIONS} takes precedence over this setting.
+     *
+     * @param maxCount maximum number of idle connections per destination.
+     * @return updated configuration.
+     */
+    public N maxConnectionsPerDestination(int maxCount) {
+        maxPoolSize.set(maxCount);
+        return self();
+    }
+
+    /**
+     * Set the maximum header size in bytes for the HTTP headers processed by Netty.
+     * The property {@link NettyClientProperties#MAX_HEADER_SIZE} has precedence over this setting.
+     *
+     * @param size the new maximum header size.
+     * @return updated configuration.
+     */
+    public N maxHeaderSize(int size) {
+        maxHeaderSize.set(size);
+        return self();
+    }
+
+    /**
+     * Set the maximum number of redirects to prevent infinite redirect loop. The default is 5.
+     * The property {@link NettyClientProperties#MAX_REDIRECTS} has precedence over this setting.
+     *
+     * @param max the maximum number of redirects.
+     * @return updated configuration.
+     */
+    public N maxRedirects(int max) {
+        maxRedirects.set(max);
+        return self();
+    }
+
+    /**
+     * Set the maximum number of idle connections that will be simultaneously kept alive. The property
+     * {@link NettyClientProperties#MAX_CONNECTIONS_TOTAL} has precedence over this setting.
+     *
+     * @param max the maximum number of idle connections.
+     * @return updated configuration.
+     */
+    public N maxTotalConnections(int max) {
+        maxPoolSizeTotal.set(max);
+        return self();
+    }
+
+    /**
+     * Set the preservation of methods during HTTP redirect.
+     * By default, the HTTP POST request are not transformed into HTTP GET for status 301 & 302.
+     * The property {@link NettyClientProperties#PRESERVE_METHOD_ON_REDIRECT} has precedence over this setting.
+     *
+     * @param preserve to preserve or not to preserve.
+     * @return updated configuration.
+     */
+    public N preserveMethodOnRedirect(boolean preserve) {
+        preserveMethodOnRedirect.set(preserve);
+        return self();
+    }
+
+    /**
+     * Set the Netty Connector HTTP redirect controller.
+     * The property {@link NettyClientProperties#HTTP_REDIRECT_CONTROLLER} has precedence over this setting.
+     *
+     * @param controller the HTTP redirect controller.
+     * @return updated configuration.
+     */
+    public N redirectController(NettyHttpRedirectController controller) {
+        redirectController.set(controller);
+        return self();
+    }
+
+    @SuppressWarnings("unchecked")
+    protected N self() {
+        return (N) this;
+    }
+
+    abstract static class ReadWrite<N extends ReadWrite<N>>
+            extends NettyConnectorConfiguration<N>
+            implements ConnectorConfiguration.Read<N> {
+
+        @Override
+        public <X extends ConnectorConfiguration<?>> void setNonEmpty(X otherCC) {
+            NettyConnectorConfiguration<?> other = (NettyConnectorConfiguration<?>) otherCC;
+            ConnectorConfiguration.Read.super.setNonEmpty(other);
+            this.connectionController.setNonEmpty(other.connectionController);
+            this.redirectController.setNonEmpty(other.redirectController);
+            this.connectionController.setNonEmpty(other.connectionController);
+            this.enableHostnameVerification.setNonEmpty(other.enableHostnameVerification);
+            ((NullableRef<Integer>) this.expect100ContTimeout).setNonEmpty((NullableRef<Integer>) other.expect100ContTimeout);
+            this.filterHeadersForProxy.setNonEmpty(other.filterHeadersForProxy);
+            this.firstHttpHeaderLineLength.setNonEmpty(other.firstHttpHeaderLineLength);
+            ((NullableRef<Boolean>) this.loggingEnabled).setNonEmpty((NullableRef<Boolean>) other.loggingEnabled);
+            this.maxChunkSize.setNonEmpty(other.maxChunkSize);
+            this.maxHeaderSize.setNonEmpty(other.maxHeaderSize);
+            ((NullableRef<Integer>) this.maxPoolIdle).setNonEmpty((NullableRef<Integer>) other.maxPoolIdle);
+            ((NullableRef<Integer>) this.maxPoolSize).setNonEmpty((NullableRef<Integer>) other.maxPoolSize);
+            ((NullableRef<Integer>) this.maxPoolSizeTotal).setNonEmpty((NullableRef<Integer>) other.maxPoolSizeTotal);
+            ((NullableRef<Integer>) this.maxRedirects).setNonEmpty((NullableRef<Integer>) other.maxRedirects);
+            this.preserveMethodOnRedirect.setNonEmpty(other.preserveMethodOnRedirect);
+            this.redirectController.setNonEmpty(other.redirectController);
+        }
+
+        @Override
+        public N init() {
+            Read.super.init();
+            enableSslHostnameVerification(Boolean.TRUE);
+            expect100ContinueTimeout(NettyClientProperties.DEFAULT_EXPECT_100_CONTINUE_TIMEOUT_VALUE);
+            filterHeadersForProxy(Boolean.TRUE);
+            initialHttpHeaderLineLength(NettyClientProperties.DEFAULT_INITIAL_LINE_LENGTH);
+            enableLoggingHandler(Boolean.FALSE);
+            maxChunkSize(NettyClientProperties.DEFAULT_CHUNK_SIZE);
+            maxHeaderSize(NettyClientProperties.DEFAULT_HEADER_SIZE);
+            // either from Jersey config, or default
+            maxTotalConnections(DEFAULT_MAX_POOL_SIZE_TOTAL);
+            // either from Jersey config, or default
+            maxPoolIdle.set(DEFAULT_MAX_POOL_IDLE);
+            // either from system property, or from Jersey config, or default
+            maxPoolSize.set(HTTP_KEEPALIVE ? MAX_POOL_SIZE : DEFAULT_MAX_POOL_SIZE);
+            maxRedirects(DEFAULT_MAX_REDIRECTS);
+            preserveMethodOnRedirect(Boolean.TRUE);
+            return self();
+        }
+
+        /**
+         * Get the preset {@link NettyConnectionController} or create an instance of the default one, if not preset.
+         * @return the {@link NettyConnectionController} instance.
+         */
+        /* package */ NettyConnectionController connectionController() {
+            return connectionController.isPresent() ? connectionController.get() : new NettyConnectionController();
+        }
+
+        /**
+         * Update {@link #expect100ContinueTimeout(int) expect 100-Continue timeout} based on current http request properties.
+         *
+         * @param clientRequest the current http client request.
+         * @return updated configuration.
+         */
+        /* package */ N expect100ContinueTimeout(ClientRequest clientRequest) {
+            expect100ContTimeout.set(
+                    clientRequest.resolveProperty(
+                            prefixed(NettyClientProperties.EXPECT_100_CONTINUE_TIMEOUT), expect100ContTimeout.get()));
+            return this.self();
+        }
+
+        /**
+         * Return value of {@link #enableSslHostnameVerification(boolean)} setting either from the configuration of from the
+         * HTTP client request properties. The default is {@code true}.
+         *
+         * @param properties the HTTP client request properties.
+         * @return the value of SSL hostname verification setting.
+         */
+        /* package */ boolean isSslHostnameVerificationEnabled(Map<String, Object> properties) {
+            return ClientProperties.getValue(properties,
+                    prefixed(NettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION),
+                    enableHostnameVerification.get());
+        }
+
+        /**
+         * Update {@link #maxRedirects(int)} value from the HTTP Client request.
+         * @param request the HTTP Client request.
+         * @return maximum redirects value.
+         */
+        /* package */ int maxRedirects(ClientRequest request) {
+            maxRedirects.set(
+                    request.resolveProperty(prefixed(NettyClientProperties.MAX_REDIRECTS), maxRedirects.get()));
+            return maxRedirects.get();
+        }
+
+        /**
+         * Update the {@link #preserveMethodOnRedirect(boolean) preservation} of HTTP method during HTTP redirect
+         * by HTTP client request properties.
+         *
+         * @param request HTTP client request.
+         * @return the value of preservation.
+         */
+        /* package */ boolean preserveMethodOnRedirect(ClientRequest request) {
+            preserveMethodOnRedirect.set(
+                    request.resolveProperty(
+                            prefixed(NettyClientProperties.PRESERVE_METHOD_ON_REDIRECT), preserveMethodOnRedirect.get()));
+            return preserveMethodOnRedirect.get();
+        }
+
+        /**
+         * Get the instance of preset {@link NettyHttpRedirectController} either from configuration,
+         * or from the HTTP client request, or the default if non set.
+         * @param request the HTTP client request.
+         * @return an instance of {@link NettyHttpRedirectController}.
+         */
+        /* package */ NettyHttpRedirectController redirectController(ClientRequest request) {
+            NettyHttpRedirectController customRedirectController =
+                    request.resolveProperty(
+                            prefixed(NettyClientProperties.HTTP_REDIRECT_CONTROLLER), NettyHttpRedirectController.class);
+            if (customRedirectController == null) {
+                customRedirectController = redirectController.get();
+            }
+            if (customRedirectController == null) {
+                customRedirectController = new NettyHttpRedirectController();
+            }
+
+            return customRedirectController;
+        }
+
+        /**
+         * <p>
+         *  Return a new instance of configuration updated by the merged settings from this and client properties.
+         *  Only properties unresolved during the request are updated.
+         * </p><p>
+         *  {@code This} is meant to be settings from the connector.
+         *  The priorities should go DEFAULTS -> CONNECTOR -> CLIENT -> REQUEST.
+         * </p>
+         *
+         * @param client the REST client.
+         * @return a new instance of configuration.
+         */
+        /* package */ N fromClient(Client client) {
+            final Map<String, Object> properties = client.getConfiguration().getProperties();
+            final N clientConfiguration = copyFromClient(client.getConfiguration());
+
+            final Object threadPoolSize = properties.get(clientConfiguration.prefixed(ClientProperties.ASYNC_THREADPOOL_SIZE));
+            if (threadPoolSize instanceof Integer && (Integer) threadPoolSize > 0) {
+                clientConfiguration.asyncThreadPoolSize((Integer) threadPoolSize);
+            }
+
+            final Object maxPoolSizeTotalProperty = properties.get(
+                    clientConfiguration.prefixed(NettyClientProperties.MAX_CONNECTIONS_TOTAL));
+            final Object maxPoolIdleProperty = properties.get(
+                    clientConfiguration.prefixed(NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT));
+            final Object maxPoolSizeProperty = properties.get(
+                    clientConfiguration.prefixed(NettyClientProperties.MAX_CONNECTIONS));
+
+            if (maxPoolSizeTotalProperty != null) {
+                clientConfiguration.maxPoolSizeTotal.set((Integer) maxPoolSizeTotalProperty);
+            }
+
+            if (maxPoolIdleProperty != null) {
+                clientConfiguration.maxPoolIdle.set((Integer) maxPoolIdleProperty);
+            }
+
+            if (maxPoolSizeProperty != null) {
+                clientConfiguration.maxPoolSize.set((Integer) maxPoolSizeProperty);
+            }
+
+            if (clientConfiguration.maxPoolSizeTotal.get() < 0) {
+                throw new ProcessingException(LocalizationMessages.WRONG_MAX_POOL_TOTAL(maxPoolSizeTotal.get()));
+            }
+
+            if (clientConfiguration.maxPoolSize.get() < 0) {
+                throw new ProcessingException(LocalizationMessages.WRONG_MAX_POOL_SIZE(maxPoolSize.get()));
+            }
+
+            final Object logging = properties.get(clientConfiguration.prefixed(NettyClientProperties.LOGGING_ENABLED));
+            if (logging instanceof Boolean) {
+                clientConfiguration.loggingEnabled.set((Boolean) logging);
+            } else if (logging instanceof String) {
+                clientConfiguration.loggingEnabled.set(Boolean.valueOf((String) logging));
+            }
+
+            return clientConfiguration;
+        }
+
+        /**
+         * <p>
+         *  Return a new instance of configuration updated by the merged settings from this and HTTP client request properties.
+         *  Only properties unresolved during the request are updated.
+         * </p><p>
+         *  {@code This} is meant to be settings from the connector.
+         *  The priorities should go DEFAULTS -> CONNECTOR -> CLIENT -> REQUEST.
+         * </p>
+
+         * @param request the HTTP client request.
+         * @return a new instance of configuration.
+         */
+        /* package */ N fromRequest(ClientRequest request) {
+            final N requestConfiguration = copyFromRequest(request);
+
+            final Boolean logging = request.resolveProperty(prefixed(NettyClientProperties.LOGGING_ENABLED), Boolean.class);
+            if (logging != null) {
+                requestConfiguration.loggingEnabled.set(logging);
+            }
+
+            return requestConfiguration;
+        }
+
+
+        /**
+         * Create an instance of {@link HttpClientCodec} based on preset settings {@link #initialHttpHeaderLineLength(int)},
+         * {@link #maxHeaderSize} and {@link #maxChunkSize}. The settings can be preset in the configuration or
+         * on the HTTP client request.
+         *
+         * @param properties The HTTP client request properties.
+         * @return the {@link HttpClientCodec} instance.
+         */
+        /* package */ HttpClientCodec createHttpClientCodec(Map<String, Object> properties) {
+            firstHttpHeaderLineLength.set(ClientProperties.getValue(properties,
+                    prefixed(NettyClientProperties.MAX_INITIAL_LINE_LENGTH), firstHttpHeaderLineLength.get()));
+            maxHeaderSize.set(
+                    ClientProperties.getValue(properties, prefixed(NettyClientProperties.MAX_HEADER_SIZE), maxHeaderSize.get()));
+            maxChunkSize.set(
+                    ClientProperties.getValue(properties, prefixed(NettyClientProperties.MAX_CHUNK_SIZE), maxChunkSize.get()));
+
+            return new HttpClientCodec(firstHttpHeaderLineLength.get(), maxHeaderSize.get(), maxChunkSize.get());
+        }
+
+        /**
+         * Create an instance of {@link ProxyHandler} based on HTTP request URI's port and address,
+         * the preset proxy {@link #proxyUri(URI) uri}, {@link #proxyUserName(String) username},
+         * and {@link #proxyPassword(String) password}.
+         *
+         * Can filter headers {@link #filterHeadersForProxy(boolean)}.
+         *
+         * @param clientProxy the Jersey {@link ClientProxy} instance.
+         * @param jerseyRequest the HTTP client request containing HTTP headers to be filtered.
+         * @return a Netty {@link ProxyHandler} instance.
+         */
+        /* package */ ProxyHandler createProxyHandler(ClientProxy clientProxy, ClientRequest jerseyRequest) {
+            final URI u = clientProxy.uri();
+            InetSocketAddress proxyAddr = new InetSocketAddress(u.getHost(), u.getPort() == -1 ? 8080 : u.getPort());
+
+            filterHeadersForProxy.set(jerseyRequest
+                    .resolveProperty(prefixed(NettyClientProperties.FILTER_HEADERS_FOR_PROXY), filterHeadersForProxy.get()));
+            HttpHeaders httpHeaders = NettyConnector.setHeaders(
+                    jerseyRequest, new DefaultHttpHeaders(), Boolean.TRUE.equals(filterHeadersForProxy.get()));
+
+            ProxyHandler proxy = clientProxy.userName() == null ? new HttpProxyHandler(proxyAddr, httpHeaders)
+                    : new HttpProxyHandler(proxyAddr, clientProxy.userName(), clientProxy.password(), httpHeaders);
+            if (connectTimeout.get() > 0) {
+                proxy.setConnectTimeoutMillis(connectTimeout.get());
+            }
+
+            return proxy;
+        }
+    }
+
+}
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectorProvider.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectorProvider.java
index cdf90dd..46f27a7 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectorProvider.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnectorProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -51,8 +51,53 @@
 @Beta
 public class NettyConnectorProvider implements ConnectorProvider {
 
+    private final Config config;
+
+    public NettyConnectorProvider() {
+        this.config = config();
+    }
+
+    private NettyConnectorProvider(Config config) {
+        this.config = config;
+    }
+
     @Override
     public Connector getConnector(Client client, Configuration runtimeConfig) {
-        return new NettyConnector(client);
+        return new NettyConnector(client, config.rw());
+    }
+
+    /**
+     * Instantiate a builder allowing to configure the NettyConnectorProvider.
+     * @return a new {@link Config} instance.
+     */
+    public static Config config() {
+        return new Config();
+    }
+
+    public static final class Config extends NettyConnectorConfiguration<Config> {
+
+        private Config() {
+        }
+
+        /* package */ RW rw() {
+            RW rw = new RW();
+            rw.setNonEmpty(this);
+            return rw;
+        }
+
+        public NettyConnectorProvider build() {
+            return new NettyConnectorProvider(this);
+        }
+
+        /* package */ static class RW extends ReadWrite<RW> {
+            @Override
+            public RW instance() {
+                return new RW();
+            }
+
+            public RW me() {
+                return this;
+            }
+        }
     }
 }
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyHttpRedirectController.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyHttpRedirectController.java
index 670be3e..6c4c41c 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyHttpRedirectController.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyHttpRedirectController.java
@@ -34,9 +34,15 @@
  */
 public class NettyHttpRedirectController {
 
+    private NettyConnectorProvider.Config.RW configuration;
+
+    /* package */ void init(NettyConnectorProvider.Config.RW configuration) {
+        this.configuration = configuration;
+    }
+
     /**
      * Configure the HTTP request after HTTP Redirect response has been received.
-     * By default, the HTTP POST request is transformed into HTTP GET for status 301 & 302.
+     * By default, the HTTP POST request is not transformed into HTTP GET for status 301 & 302.
      * Also, HTTP Headers described by RFC 9110 Section 15.4 are removed from the new HTTP Request.
      *
      * @param request The new {@link ClientRequest} to be sent to the redirected URI.
@@ -44,7 +50,7 @@
      * @return {@code true} when the new request should be sent.
      */
     public boolean prepareRedirect(ClientRequest request, ClientResponse response) {
-        final Boolean keepMethod = request.resolveProperty(NettyClientProperties.PRESERVE_METHOD_ON_REDIRECT, Boolean.TRUE);
+        final boolean keepMethod = configuration.preserveMethodOnRedirect(request);
 
         if (Boolean.FALSE.equals(keepMethod) && request.getMethod().equals(HttpMethod.POST)) {
             switch (response.getStatus()) {
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/internal/NettyEntityWriter.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/internal/NettyEntityWriter.java
index bcd3fd8..f758f95 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/internal/NettyEntityWriter.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/internal/NettyEntityWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,9 +16,9 @@
 
 package org.glassfish.jersey.netty.connector.internal;
 
+import io.netty.buffer.ByteBuf;
 import io.netty.channel.Channel;
 import io.netty.handler.stream.ChunkedInput;
-import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.client.ClientRequest;
 import org.glassfish.jersey.client.RequestEntityProcessing;
 
@@ -28,6 +28,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Supplier;
 
 /**
  * The Entity Writer is used to write entity in Netty. One implementation is delayed,
@@ -60,7 +61,7 @@
 
     /**
      * Flushes the writen objects. Can throw IOException.
-     * @throws IOException
+     * @throws IOException exception.
      */
     void flush() throws IOException;
 
@@ -68,7 +69,7 @@
      * Get the netty Chunked Input to be written.
      * @return The Chunked input instance
      */
-    ChunkedInput getChunkedInput();
+    ChunkedInput<ByteBuf> getChunkedInput();
 
     /**
      * Get the {@link OutputStream} used to write an entity
@@ -78,20 +79,20 @@
 
     /**
      * Get the length of the entity written to the {@link OutputStream}
-     * @return
+     * @return length of the entity.
      */
     long getLength();
 
     /**
-     * Return Type of
-     * @return
+     * Return Type of the {@link NettyEntityWriter}.
+     * @return type of the writer.
      */
     Type getType();
 
-    static NettyEntityWriter getInstance(ClientRequest clientRequest, Channel channel) {
+    static NettyEntityWriter getInstance(
+            ClientRequest clientRequest, Channel channel, Supplier<RequestEntityProcessing> requestEntityProcessingSupplier) {
         final long lengthLong = clientRequest.getLengthLong();
-        final RequestEntityProcessing entityProcessing = clientRequest.resolveProperty(
-                ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.class);
+        final RequestEntityProcessing entityProcessing = requestEntityProcessingSupplier.get();
 
         if ((entityProcessing == null && lengthLong == -1) || entityProcessing == RequestEntityProcessing.CHUNKED) {
             return new DirectEntityWriter(channel, Type.CHUNKED);
@@ -129,7 +130,7 @@
         }
 
         @Override
-        public ChunkedInput getChunkedInput() {
+        public ChunkedInput<ByteBuf> getChunkedInput() {
             return stream;
         }
 
@@ -203,7 +204,7 @@
         }
 
         @Override
-        public ChunkedInput getChunkedInput() {
+        public ChunkedInput<ByteBuf> getChunkedInput() {
             return writer.getChunkedInput();
         }
 
@@ -226,7 +227,7 @@
         private class DelayedOutputStream extends OutputStream {
             private final List<WriteAction> actions = new ArrayList<>();
             private int writeLen = 0;
-            private AtomicBoolean streamFlushed = new AtomicBoolean(false);
+            private final AtomicBoolean streamFlushed = new AtomicBoolean(false);
 
             @Override
             public void write(int b) throws IOException {
diff --git a/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ChunkedInputClosedOnErrorTest.java b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ChunkedInputClosedOnErrorTest.java
index 1d0135d..22ce8d3 100644
--- a/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ChunkedInputClosedOnErrorTest.java
+++ b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ChunkedInputClosedOnErrorTest.java
@@ -83,10 +83,11 @@
         ConnectorProvider provider = new ConnectorProvider() {
             @Override
             public Connector getConnector(Client client, Configuration runtimeConfig) {
-                return new NettyConnector(client) {
+                return new NettyConnector(client, NettyConnectorProvider.config().rw()) {
                     @Override
-                    NettyEntityWriter nettyEntityWriter(ClientRequest clientRequest, Channel channel) {
-                        writer.set(super.nettyEntityWriter(clientRequest, channel));
+                    NettyEntityWriter nettyEntityWriter(ClientRequest clientRequest, Channel channel,
+                                                        NettyConnectorProvider.Config.RW config) {
+                        writer.set(super.nettyEntityWriter(clientRequest, channel, config));
                         writerSetLatch.countDown();
                         return new NettyEntityWriter() {
                             private boolean slept = false;
diff --git a/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ChunkedInputWriteErrorSimulationTest.java b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ChunkedInputWriteErrorSimulationTest.java
index 78a3448..fed5f61 100644
--- a/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ChunkedInputWriteErrorSimulationTest.java
+++ b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ChunkedInputWriteErrorSimulationTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -223,9 +223,12 @@
         return new ConnectorProvider() {
             @Override
             public Connector getConnector(Client client, Configuration runtimeConfig) {
-                return new NettyConnector(client) {
-                    NettyEntityWriter nettyEntityWriter(ClientRequest clientRequest, Channel channel) {
-                        NettyEntityWriter wrapped = NettyEntityWriter.getInstance(clientRequest, channel);
+                return new NettyConnector(client, NettyConnectorProvider.config().rw()) {
+                    @Override
+                    NettyEntityWriter nettyEntityWriter(
+                            ClientRequest clientRequest, Channel channel, NettyConnectorProvider.Config.RW config) {
+                        NettyEntityWriter wrapped = NettyEntityWriter.getInstance(
+                                clientRequest, channel, () -> config.requestEntityProcessing(clientRequest));
 
                         JerseyChunkedInput chunkedInput = (JerseyChunkedInput) wrapped.getChunkedInput();
                         try {
diff --git a/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ConnectorConfigTest.java b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ConnectorConfigTest.java
new file mode 100644
index 0000000..6dd9b03
--- /dev/null
+++ b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/ConnectorConfigTest.java
@@ -0,0 +1,1683 @@
+/*
+ * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.netty.connector;
+
+import io.netty.handler.codec.http.HttpClientCodec;
+import io.netty.handler.codec.http.HttpRequest;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientRequest;
+import org.glassfish.jersey.client.ClientResponse;
+import org.glassfish.jersey.client.RequestEntityProcessing;
+import org.glassfish.jersey.client.innate.ClientProxy;
+import org.glassfish.jersey.http.HttpHeaders;
+import org.glassfish.jersey.internal.MapPropertiesDelegate;
+import org.glassfish.jersey.internal.util.collection.Ref;
+import org.glassfish.jersey.client.innate.ConnectorConfiguration;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import javax.net.ssl.SSLContext;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.Configuration;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+public class ConnectorConfigTest {
+
+    private static final String PREFIX = "test.";
+
+    private static ClientRequest createRequest(Client client) {
+        return new ClientRequest(URI.create("http://localhost:8080"),
+                (ClientConfig) client.getConfiguration(), new MapPropertiesDelegate()) {
+        };
+    }
+
+    @Test
+    public void testPrefixedConfig() {
+        ConnectorConfig.RW r = new ConnectorConfig.RW();
+        Configuration prefixed, unprefixed;
+
+        unprefixed = r.config();
+        unprefixed.getProperties().put(ClientProperties.CONNECT_TIMEOUT, 1000);
+        prefixed = r.prefix(PREFIX).prefixedConfiguration(unprefixed);
+        Assertions.assertNull(prefixed.getProperty(ClientProperties.CONNECT_TIMEOUT));
+        Assertions.assertNull(prefixed.getProperties().get(ClientProperties.CONNECT_TIMEOUT));
+
+        unprefixed = r.config();
+        unprefixed.getProperties().put(PREFIX + ClientProperties.CONNECT_TIMEOUT, 2000);
+        prefixed = r.prefix(PREFIX).prefixedConfiguration(unprefixed);
+        Assertions.assertEquals(2000, prefixed.getProperty(ClientProperties.CONNECT_TIMEOUT));
+        Assertions.assertEquals(2000, prefixed.getProperties().get(ClientProperties.CONNECT_TIMEOUT));
+
+        unprefixed = r.config();
+        prefixed = r.prefix(PREFIX).prefixedConfiguration(unprefixed);
+        unprefixed.getProperties().put(ClientProperties.CONNECT_TIMEOUT, 2000);
+        prefixed.getProperties().putAll(unprefixed.getProperties());
+        Assertions.assertNull(prefixed.getProperty(ClientProperties.CONNECT_TIMEOUT));
+        Assertions.assertNull(prefixed.getProperties().get(ClientProperties.CONNECT_TIMEOUT));
+
+        unprefixed = r.config();
+        prefixed = r.prefix(PREFIX).prefixedConfiguration(unprefixed);
+        unprefixed.getProperties().put(PREFIX + ClientProperties.CONNECT_TIMEOUT, 2000);
+        prefixed.getProperties().putAll(unprefixed.getProperties());
+        Assertions.assertEquals(2000, prefixed.getProperty(ClientProperties.CONNECT_TIMEOUT));
+        Assertions.assertEquals(2000, prefixed.getProperties().get(ClientProperties.CONNECT_TIMEOUT));
+
+        unprefixed = r.config();
+        prefixed = r.prefix(PREFIX).prefixedConfiguration(unprefixed);
+        prefixed.getProperties().put(PREFIX + ClientProperties.PROXY_USERNAME, "USERNAME");
+        Assertions.assertEquals("USERNAME", prefixed.getProperty(ClientProperties.PROXY_USERNAME));
+        prefixed.getProperties().put(ClientProperties.PROXY_PASSWORD, "PASSWORD");
+        Assertions.assertNull(prefixed.getProperty(ClientProperties.PROXY_PASSWORD));
+    }
+
+    @Test
+    public void testAsyncThreadPoolSize() {
+        AtomicInteger result = new AtomicInteger(0);
+        class RWAsync extends RW {
+            @Override
+            public Integer asyncThreadPoolSize() {
+                result.set(super.asyncThreadPoolSize());
+                return super.asyncThreadPoolSize();
+            }
+
+            @Override
+            public RWAsync instance() {
+                return new RWAsync();
+            }
+        }
+
+        Client client = ClientBuilder.newClient();
+        NettyConnectorProvider.Config.RW rw0 = new RWAsync().asyncThreadPoolSize(10);
+        new NettyConnector(client, rw0);
+        Assertions.assertEquals(10, result.get());
+
+        result.set(0);
+        NettyConnectorProvider.Config.RW rw1 = new RWAsync().asyncThreadPoolSize(20);
+        client.property(ClientProperties.CONNECTOR_CONFIGURATION, rw1);
+        new NettyConnector(client, rw0);
+        Assertions.assertEquals(20, result.get());
+
+        result.set(0);
+        client.property(ClientProperties.ASYNC_THREADPOOL_SIZE, 30);
+        new NettyConnector(client, rw0);
+        Assertions.assertEquals(30, result.get());
+    }
+
+    @Test
+    public void testConnectTimeout() {
+        final AtomicInteger result = new AtomicInteger(0);
+        class RWConnect extends NettyConnectorProvider.Config.RW {
+            @Override
+            public int connectTimeout() {
+                result.set(super.connectTimeout());
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public RWConnect instance() {
+                return new RWConnect();
+            }
+        }
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000)).request().apply();
+        Assertions.assertEquals(1000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECT_TIMEOUT, 3000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
+                .request().apply();
+        Assertions.assertEquals(3000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECT_TIMEOUT, 3000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(3000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(4000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(4000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECT_TIMEOUT, 5000))
+                .apply();
+        Assertions.assertEquals(5000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect().prefix(PREFIX)).rw(rw -> rw.connectTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWConnect().connectTimeout(2000).prefix(PREFIX)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWConnect().connectTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000).prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWConnect().connectTimeout(4000).prefix(PREFIX)))
+                .request(r -> r.setProperty(ClientProperties.CONNECT_TIMEOUT, 5000))
+                .apply();
+        Assertions.assertEquals(4000, result.get());
+    }
+
+    @Test
+    public void testExpect100Continue() {
+        final AtomicReference<Boolean> result = new AtomicReference<>();
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWExpect extends RW {
+
+            @Override
+            public Boolean expect100Continue(ClientRequest request) {
+                result.set(super.expect100Continue(request));
+                return result.get();
+            }
+
+            @Override
+            public int connectTimeout() {
+                config.set(this);
+                return super.connectTimeout();
+            }
+
+            @Override
+            public RWExpect instance() {
+                return new RWExpect();
+            }
+        }
+
+        Request req = new TestClient(new RWExpect()).request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertNull(result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().expect100Continue(true)).request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(true, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().expect100Continue(true).prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.EXPECT_100_CONTINUE, false))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(false, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().expect100Continue(true).prefix(PREFIX))
+                .request(r -> r.setProperty(
+                        PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100Continue(false)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(false, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect())
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100Continue(true)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100Continue(false)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(false, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + ClientProperties.EXPECT_100_CONTINUE, true))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWExpect().expect100Continue(false)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(true, result.get());
+    }
+
+    @Test
+    public void testExpect100ContinueThreshold() {
+        final AtomicReference<Long> result = new AtomicReference<>();
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWExpect extends RW {
+
+            @Override
+            public long expect100ContinueThreshold(ClientRequest request) {
+                result.set(super.expect100ContinueThreshold(request));
+                return result.get();
+            }
+
+            @Override
+            public int connectTimeout() {
+                config.set(this);
+                return super.connectTimeout();
+            }
+
+            @Override
+            public RWExpect instance() {
+                return new RWExpect();
+            }
+        }
+
+        Request req = new TestClient(new RWExpect()).request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().expect100ContinueThreshold(1000)).request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(1000, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().expect100ContinueThreshold(1000).prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE, 2000))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().expect100ContinueThreshold(1000).prefix(PREFIX))
+                .request(r -> r.setProperty(
+                        PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100ContinueThreshold(2000)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect())
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWExpect().expect100ContinueThreshold(1000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWExpect().expect100ContinueThreshold(2000)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE, 1000))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWExpect().expect100ContinueThreshold(2000)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(1000, result.get());
+    }
+
+    @Test
+    public void testExpect100ContinueTimeout() {
+        final AtomicReference<Integer> result = new AtomicReference<>();
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWExpect extends RW {
+
+            @Override
+            public NettyConnectorProvider.Config.RW expect100ContinueTimeout(ClientRequest request) {
+                super.expect100ContinueTimeout(request);
+                result.set(this.expect100ContTimeout.get());
+                return this;
+            }
+
+            @Override
+            public int connectTimeout() {
+                config.set(this);
+                return super.connectTimeout();
+            }
+
+            @Override
+            public RWExpect instance() {
+                return new RWExpect();
+            }
+        }
+
+        Request req = new TestClient(new RWExpect()).request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(NettyClientProperties.DEFAULT_EXPECT_100_CONTINUE_TIMEOUT_VALUE, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().expect100ContinueTimeout(1000)).request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(1000, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().expect100ContinueTimeout(1000).prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + NettyClientProperties.EXPECT_100_CONTINUE_TIMEOUT, 2000))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().expect100ContinueTimeout(1000).prefix(PREFIX))
+                .request(r -> r.setProperty(
+                        PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100ContinueTimeout(2000)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, (HttpRequest) null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect())
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWExpect().expect100ContinueTimeout(1000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWExpect().expect100ContinueTimeout(2000)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWExpect().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.EXPECT_100_CONTINUE_TIMEOUT, 1000))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWExpect().expect100ContinueTimeout(2000)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            new Expect100ContinueConnectorExtension(config.get()).invoke(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(1000, result.get());
+    }
+
+    @Test
+    public void testFollowRedirects() {
+        final AtomicReference<Boolean> result = new AtomicReference<>();
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWFollow extends RW {
+
+            @Override
+            public boolean followRedirects() {
+                result.set(super.followRedirects());
+                return result.get();
+            }
+
+            @Override
+            public int connectTimeout() {
+                config.set(this);
+                return super.connectTimeout();
+            }
+
+            @Override
+            public RWFollow instance() {
+                return new RWFollow();
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWFollow()).request().apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        config.get().followRedirects();
+        Assertions.assertEquals(new RWFollow().copy().followRedirects(), result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFollow().followRedirects(false)).request().apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        config.get().followRedirects();
+        Assertions.assertEquals(false, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFollow().followRedirects(false).prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.FOLLOW_REDIRECTS, true))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        config.get().followRedirects();
+        Assertions.assertEquals(true, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFollow().followRedirects(false).prefix(PREFIX))
+                .request(r -> r.setProperty(
+                        PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWFollow().followRedirects(true)))
+                .apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        config.get().followRedirects();
+        Assertions.assertEquals(true, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFollow())
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWFollow().followRedirects(false)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWFollow().followRedirects(true)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        config.get().followRedirects();
+        Assertions.assertEquals(true, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFollow().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + ClientProperties.FOLLOW_REDIRECTS, false))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWFollow().followRedirects(true)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        config.get().followRedirects();
+        Assertions.assertEquals(false, result.get());
+    }
+
+    @Test
+    public void testProxy() {
+        final AtomicReference<ClientProxy> result = new AtomicReference<>();
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWProxy extends RW {
+
+            @Override
+            public Optional<ClientProxy> proxy(ClientRequest request, URI requestUri) {
+                Optional<ClientProxy> proxy = super.proxy(request, requestUri);
+                result.set(proxy.orElse(null));
+                return proxy;
+            }
+
+            @Override
+            public RWProxy instance() {
+                return new RWProxy();
+            }
+        }
+        String proxyUri = "http://proxy.org:8080";
+        String userName = "USERNAME";
+        String password = "PASSWORD";
+
+        new TestClient(new RWProxy()).request().apply();
+        Assertions.assertNull(result.get());
+
+        result.set(null);
+        new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)).request().apply();
+        Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
+        Assertions.assertEquals(userName, result.get().userName());
+        Assertions.assertEquals(password, result.get().password());
+
+        result.set(null);
+        new TestClient(new RWProxy().prefix(PREFIX).proxyUri(proxyUri).proxyUserName("XXX").proxyPassword(password))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.PROXY_USERNAME, userName))
+                .request(r -> r.setProperty(ClientProperties.PROXY_PASSWORD, "XXX"))
+                .apply();
+        Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
+        Assertions.assertEquals(userName, result.get().userName());
+        Assertions.assertEquals(password, result.get().password());
+
+        result.set(null);
+        new TestClient(new RWProxy().prefix(PREFIX).proxyUri(proxyUri).proxyUserName("XXX").proxyPassword(password))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWProxy().proxyUserName(userName).proxyPassword(null)))
+                .apply();
+        Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
+        Assertions.assertEquals(userName, result.get().userName());
+        Assertions.assertNull(result.get().password());
+
+        result.set(null);
+        new TestClient(new RWProxy().prefix(PREFIX)
+                .proxy(new java.net.Proxy(java.net.Proxy.Type.HTTP,
+                        new InetSocketAddress(proxyUri.split("g:")[0] + "g", Integer.parseInt(proxyUri.split("g:")[1])))))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWProxy().proxyUserName(userName).proxyPassword(password).prefix(PREFIX)))
+                .apply();
+        Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
+        Assertions.assertEquals(userName, result.get().userName());
+        Assertions.assertEquals(password, result.get().password());
+    }
+
+    @Test
+    public void testReadTimeout() {
+        final AtomicInteger result = new AtomicInteger(0);
+        class RWRead extends NettyConnectorProvider.Config.RW {
+
+            @Override
+            public int readTimeout() {
+                result.set(super.readTimeout());
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public RWRead instance() {
+                return new RWRead();
+            }
+        }
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000)).request().apply();
+        Assertions.assertEquals(1000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
+                .client(c -> c.property(ClientProperties.READ_TIMEOUT, 3000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
+                .request().apply();
+        Assertions.assertEquals(3000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
+                .client(c -> c.property(ClientProperties.READ_TIMEOUT, 3000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().connectTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(3000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(4000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(4000)))
+                .request(r -> r.setProperty(ClientProperties.READ_TIMEOUT, 5000))
+                .apply();
+        Assertions.assertEquals(5000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000).prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWRead().readTimeout(2000).prefix(PREFIX)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWRead().readTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000).prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWRead().readTimeout(4000).prefix(PREFIX)))
+                .request(r -> r.setProperty(ClientProperties.READ_TIMEOUT, 5000))
+                .apply();
+        Assertions.assertEquals(4000, result.get());
+    }
+
+    @Test
+    public void testRequestEntityProcessing() {
+        final AtomicReference<RequestEntityProcessing> result = new AtomicReference<>();
+        final AtomicReference<RW> config = new AtomicReference<>();
+        class RWRP extends RW {
+
+            @Override
+            public RequestEntityProcessing requestEntityProcessing(ClientRequest request) {
+               result.set(super.requestEntityProcessing(request));
+               return result.get();
+            }
+
+            @Override
+            public RWRP instance() {
+                config.set(new RWRP());
+                return (RWRP) config.get();
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWRP().requestEntityProcessing(RequestEntityProcessing.CHUNKED))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        try {
+            req.connector.nettyEntityWriter(req.request, null, config.get());
+        } catch (NullPointerException ignore) {
+        }
+        Assertions.assertEquals(RequestEntityProcessing.CHUNKED, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWRP().prefix(PREFIX).requestEntityProcessing(RequestEntityProcessing.CHUNKED))
+                .request(r -> r.setEntity(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWRP().requestEntityProcessing(RequestEntityProcessing.BUFFERED).prefix(PREFIX)))
+                .apply();
+        try {
+            req.connector.nettyEntityWriter(req.request, null, config.get());
+        } catch (NullPointerException ignore) {
+        }
+        Assertions.assertEquals(RequestEntityProcessing.BUFFERED, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWRP().prefix(PREFIX).requestEntityProcessing(RequestEntityProcessing.CHUNKED))
+                .request(r -> r.setEntity(PREFIX))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.REQUEST_ENTITY_PROCESSING,
+                        RequestEntityProcessing.BUFFERED))
+                .apply();
+        try {
+            req.connector.nettyEntityWriter(req.request, null, config.get());
+        } catch (NullPointerException ignore) {
+        }
+        Assertions.assertEquals(RequestEntityProcessing.BUFFERED, result.get());
+    }
+
+    @Test
+    public void testSniHostName() {
+        final String sniHost = "sun.oracle.com";
+        final AtomicReference<String> sniRef = new AtomicReference<>();
+        final NettyConnectionController controller = new NettyConnectionController() {
+            @Override
+            public String getConnectionGroup(ClientRequest clientRequest, URI uri, String hostName, int port) {
+                sniRef.set(hostName);
+                return super.getConnectionGroup(clientRequest, uri, hostName, port);
+            }
+        };
+
+        final class RWSni extends RW {
+            @Override
+            public RWSni instance() {
+                return new RWSni();
+            }
+        }
+
+        new TestClient(new RWSni().connectionController(controller))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, sniHost))
+                .apply();
+        Assertions.assertEquals(sniHost, sniRef.get());
+
+        new TestClient(new RWSni().connectionController(controller).sniHostName(sniHost))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, "moon.oracle.com"))
+                .apply();
+        Assertions.assertEquals(sniHost, sniRef.get());
+
+        new TestClient(new RWSni().connectionController(controller).prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().sniHostName("moon.oracle.com")))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, sniHost))
+                .apply();
+        Assertions.assertEquals(sniHost, sniRef.get());
+
+        new TestClient(new RWSni().connectionController(controller).prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().sniHostName(sniHost).prefix(PREFIX)))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, "moon.oracle.com"))
+                .apply();
+        Assertions.assertEquals(sniHost, sniRef.get());
+
+        new TestClient(new RWSni().connectionController(controller).prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().sniHostName("moon.oracle.com")))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, sniHost))
+                .apply();
+        Assertions.assertEquals(sniHost, sniRef.get());
+
+        new TestClient(new RWSni().connectionController(controller).prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().sniHostName(sniHost).prefix(PREFIX)))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.HOST, "moon.oracle.com"))
+                .apply();
+        Assertions.assertEquals(sniHost, sniRef.get());
+    }
+
+    @Test
+    public void testSslContext() {
+        final SSLContext testContext = new SSLContext(null, null, null){};
+        final AtomicReference<SSLContext> result = new AtomicReference<>();
+        final AtomicReference<RW> config = new AtomicReference<>();
+        class RWSsl extends RW {
+
+            @Override
+            public SSLContext sslContext(Client client, ClientRequest request) {
+                result.set(super.sslContext(client, request));
+                return result.get();
+            }
+
+            @Override
+            public RWSsl instance() {
+                RWSsl rw = new RWSsl();
+                config.set(rw);
+                return rw;
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWSsl().sslContextSupplier(() -> testContext)).request().apply();
+        config.get().sslContext(req.client, req.request);
+        Assertions.assertEquals(testContext, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSsl().prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.SSL_CONTEXT_SUPPLIER,
+                        (Supplier<SSLContext>) () -> testContext)).apply();
+        config.get().sslContext(req.client, req.request);
+        Assertions.assertEquals(testContext, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSsl().prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWSsl().prefix(PREFIX).sslContextSupplier(() -> testContext))).apply();
+        config.get().sslContext(req.client, req.request);
+        Assertions.assertEquals(testContext, result.get());
+    }
+
+    @Test
+    public void testConnectionController() {
+        final NettyConnectionController connectionController = new NettyConnectionController();
+        final AtomicReference<NettyConnectionController> result = new AtomicReference<>();
+
+        class RWController extends RW {
+
+            @Override
+            NettyConnectionController connectionController() {
+                result.set(super.connectionController());
+                return result.get();
+            }
+
+            @Override
+            public RWController instance() {
+                return new RWController();
+            }
+        }
+
+        new TestClient(new RWController().connectionController(connectionController)).request().apply();
+        Assertions.assertEquals(connectionController, result.get());
+
+        result.set(null);
+        new TestClient(new RWController().prefix(PREFIX).connectionController(new NettyConnectionController()))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWController().connectionController(connectionController).prefix(PREFIX))).apply();
+        Assertions.assertEquals(connectionController, result.get());
+    }
+
+    @Test
+    public void testEnableSslHostnameVerification() {
+        final AtomicReference<Boolean> result = new AtomicReference<>();
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWEnabled extends RW {
+
+            @Override
+            boolean isSslHostnameVerificationEnabled(Map<String, Object> properties) {
+               result.set(super.isSslHostnameVerificationEnabled(properties));
+               return result.get();
+            }
+
+            @Override
+            public RWEnabled instance() {
+                RWEnabled enabled = new RWEnabled();
+                config.set(enabled);
+                return enabled;
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWEnabled()).request().apply();
+        config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(new RWEnabled().copy().followRedirects(), result.get());
+
+        result.set(null);
+        req = new TestClient(new RWEnabled().enableSslHostnameVerification(false)).request().apply();
+        config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(false, result.get());
+
+//        NOT PER REQUEST
+//        result.set(null);
+//        req = new TestClient(new RWEnabled().enableSslHostnameVerification(false).prefix(PREFIX))
+//                .request(r -> r.setProperty(PREFIX + NettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION, true))
+//                .apply();
+//        config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
+//        Assertions.assertEquals(true, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWEnabled().enableSslHostnameVerification(false).prefix(PREFIX))
+                .request(r -> r.setProperty(
+                        PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWEnabled().enableSslHostnameVerification(true)))
+                .apply();
+        config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(true, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWEnabled())
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWEnabled().enableSslHostnameVerification(false)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWEnabled().enableSslHostnameVerification(true)))
+                .apply();
+        config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(true, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWEnabled().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION, false))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWEnabled().enableSslHostnameVerification(true)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        config.get().isSslHostnameVerificationEnabled(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(false, result.get());
+    }
+
+    @Test
+    public void testMaxRedirects() {
+        final AtomicReference<Integer> result = new AtomicReference<>();
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWMaxRed extends RW {
+
+            @Override
+            int maxRedirects(ClientRequest request) {
+                result.set(super.maxRedirects(request));
+                return result.get();
+            }
+
+            @Override
+            public RWMaxRed instance() {
+                RWMaxRed max = new RWMaxRed();
+                config.set(max);
+                return max;
+            }
+        }
+
+        Request req = new TestClient(new RWMaxRed()).request().apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        Assertions.assertEquals(new RWMaxRed().copy().maxRedirects(req.request), result.get());
+
+        result.set(null);
+        req = new TestClient(new RWMaxRed().maxRedirects(2)).request().apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        Assertions.assertEquals(2, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWMaxRed().maxRedirects(2).prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + NettyClientProperties.MAX_REDIRECTS, 3))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        Assertions.assertEquals(3, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWMaxRed().maxRedirects(2).prefix(PREFIX))
+                .request(r -> r.setProperty(
+                        PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWMaxRed().maxRedirects(3)))
+                .apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        Assertions.assertEquals(3, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWMaxRed())
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWMaxRed().maxRedirects(2)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWMaxRed().maxRedirects(3)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        Assertions.assertEquals(3, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWMaxRed().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.MAX_REDIRECTS, 2))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWMaxRed().maxRedirects(3)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        Assertions.assertEquals(2, result.get());
+    }
+
+    @Test
+    public void testRedirectController() {
+        final NettyHttpRedirectController controller = new NettyHttpRedirectController();
+        final AtomicReference<NettyHttpRedirectController> result = new AtomicReference<>();
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWController extends RW {
+
+            @Override
+            NettyHttpRedirectController redirectController(ClientRequest request) {
+                result.set(super.redirectController(request));
+                return result.get();
+            }
+
+            @Override
+            public RWController instance() {
+                RWController max = new RWController();
+                config.set(max);
+                return max;
+            }
+        }
+
+        Request req;
+
+        result.set(null);
+        req = new TestClient(new RWController().redirectController(controller)).request().apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        config.get().redirectController(req.request);
+        Assertions.assertEquals(controller, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWController().redirectController(new NettyHttpRedirectController()).prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + NettyClientProperties.HTTP_REDIRECT_CONTROLLER, controller))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        config.get().redirectController(req.request);
+        Assertions.assertEquals(controller, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWController().redirectController(new NettyHttpRedirectController()).prefix(PREFIX))
+                .request(r -> r.setProperty(
+                        PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWController().redirectController(controller)))
+                .apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        config.get().redirectController(req.request);
+        Assertions.assertEquals(controller, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWController())
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWController().redirectController(new NettyHttpRedirectController())))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWController().redirectController(controller)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+//        config.get().redirectController(req.request);
+        Assertions.assertEquals(controller, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWController().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.HTTP_REDIRECT_CONTROLLER, controller))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWController().redirectController(new NettyHttpRedirectController())))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+//        config.get().redirectController(req.request);
+        Assertions.assertEquals(controller, result.get());
+    }
+
+    @Test
+    public void testPreserveMethodOnRedirect() {
+        final AtomicReference<Boolean> result = new AtomicReference<>();
+        final AtomicReference<NettyHttpRedirectController> controller = new AtomicReference<>();
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWController extends RW {
+
+            @Override
+            boolean preserveMethodOnRedirect(ClientRequest request) {
+                result.set(super.preserveMethodOnRedirect(request));
+                return result.get();
+            }
+
+            @Override
+            NettyHttpRedirectController redirectController(ClientRequest request) {
+                controller.set(super.redirectController(request));
+                return controller.get();
+            }
+
+            @Override
+            public RWController instance() {
+                RWController max = new RWController();
+                config.set(max);
+                return max;
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWController()).request().apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        try {
+            controller.get().prepareRedirect(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(new RWController().copy().preserveMethodOnRedirect(req.request), result.get());
+
+        result.set(null);
+        req = new TestClient(new RWController().preserveMethodOnRedirect(false)).request().apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        try {
+            controller.get().prepareRedirect(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(false, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWController().preserveMethodOnRedirect(true).prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + NettyClientProperties.PRESERVE_METHOD_ON_REDIRECT, false))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        try {
+            controller.get().prepareRedirect(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(false, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWController().preserveMethodOnRedirect(true).prefix(PREFIX))
+                .request(r -> r.setProperty(
+                        PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWController().preserveMethodOnRedirect(false)))
+                .apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        try {
+            controller.get().prepareRedirect(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(false, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWController())
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWController().preserveMethodOnRedirect(true)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWController().preserveMethodOnRedirect(false)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        try {
+            controller.get().prepareRedirect(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(false, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWController().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.PRESERVE_METHOD_ON_REDIRECT, false))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWController().preserveMethodOnRedirect(true)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        new JerseyClientHandler(req.request, new CompletableFuture<ClientResponse>(),
+                new CompletableFuture<Object>(), new HashSet<>(), req.connector, config.get());
+        try {
+            controller.get().prepareRedirect(req.request, null);
+        } catch (NullPointerException expected) {
+        }
+        Assertions.assertEquals(false, result.get());
+    }
+
+    @Test
+    public void testFilterHeadersForProxy() {
+        final AtomicReference<ClientProxy> proxy = new AtomicReference<>();
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWProxy extends RW {
+            @Override
+            public Optional<ClientProxy> proxy(ClientRequest request, URI requestUri) {
+                Optional<ClientProxy> oProxy = super.proxy(request, requestUri);
+                proxy.set(oProxy.orElse(null));
+                return oProxy;
+            }
+
+            @Override
+            public RWProxy instance() {
+                RWProxy rw = new RWProxy();
+                config.set(rw);
+                return rw;
+            }
+        }
+        String proxyUri = "http://proxy.org:8080";
+        String userName = "USERNAME";
+        String password = "PASSWORD";
+
+        Request req;
+        req = new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)).request().apply();
+        config.get().createProxyHandler(proxy.get(), req.request);
+        Assertions.assertEquals(((Ref<Boolean>) new RWProxy().copy().filterHeadersForProxy).get(),
+                ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
+
+        config.set(null);
+        req = new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)
+                .filterHeadersForProxy(false)).request().apply();
+        config.get().createProxyHandler(proxy.get(), req.request);
+        Assertions.assertEquals(false, ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
+
+        config.set(null);
+        req = new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)
+                .prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + NettyClientProperties.FILTER_HEADERS_FOR_PROXY, false))
+                .apply();
+        config.get().createProxyHandler(proxy.get(), req.request);
+        Assertions.assertEquals(false, ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
+
+        config.set(null);
+        new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)
+                .prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.FILTER_HEADERS_FOR_PROXY, false))
+                .request().apply();
+        config.get().createProxyHandler(proxy.get(), req.request);
+        Assertions.assertEquals(false, ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
+
+        config.set(null);
+        new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)
+                .prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().filterHeadersForProxy(false).prefix(PREFIX)))
+                .request().apply();
+        config.get().createProxyHandler(proxy.get(), req.request);
+        Assertions.assertEquals(false, ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
+
+        config.set(null);
+        new TestClient(new RWProxy().proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password)
+                .prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().filterHeadersForProxy(false).prefix(PREFIX)))
+                .apply();
+        config.get().createProxyHandler(proxy.get(), req.request);
+        Assertions.assertEquals(false, ((Ref<Boolean>) config.get().filterHeadersForProxy).get());
+    }
+
+    @Test
+    public void testFirstHttpHeaderLineLength() {
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        final AtomicReference<Integer> result = new AtomicReference<>();
+        class RWFHHLL extends RW {
+
+            @Override
+            HttpClientCodec createHttpClientCodec(Map<String, Object> properties) {
+                HttpClientCodec codec = super.createHttpClientCodec(properties);
+                result.set(firstHttpHeaderLineLength.get());
+                return codec;
+            }
+
+            @Override
+            public RWFHHLL instance() {
+                RWFHHLL rw = new RWFHHLL();
+                config.set(rw);
+                return rw;
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWFHHLL()).request().apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(NettyClientProperties.DEFAULT_INITIAL_LINE_LENGTH, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFHHLL().initialHttpHeaderLineLength(5555)).request().apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFHHLL().initialHttpHeaderLineLength(1111).prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWFHHLL().initialHttpHeaderLineLength(5555).prefix(PREFIX))).apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFHHLL().initialHttpHeaderLineLength(1111).prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.MAX_INITIAL_LINE_LENGTH, 5555))
+                .request().apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFHHLL().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.MAX_INITIAL_LINE_LENGTH, 5555))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWFHHLL().initialHttpHeaderLineLength(8888).prefix(PREFIX)))
+                .apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+    }
+
+    @Test
+    public void testLoggingHandler() {
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        class RWLog extends RW {
+            @Override
+            public RWLog instance() {
+                RWLog rw = new RWLog();
+                config.set(rw);
+                return rw;
+            }
+        }
+
+        new TestClient(new RWLog()).request().apply();
+        Assertions.assertFalse(config.get().loggingEnabled.get());
+
+        new TestClient(new RWLog().enableLoggingHandler(true)).request().apply();
+        Assertions.assertTrue(config.get().loggingEnabled.get());
+
+        new TestClient(new RWLog().enableLoggingHandler(false).prefix(PREFIX))
+                .request(r -> r.setProperty(NettyClientProperties.LOGGING_ENABLED, true))
+                .apply();
+        Assertions.assertFalse(config.get().loggingEnabled.get());
+
+        new TestClient(new RWLog().enableLoggingHandler(false).prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.LOGGING_ENABLED, true))
+                .request()
+                .apply();
+        Assertions.assertTrue(config.get().loggingEnabled.get());
+
+        new TestClient(new RWLog().enableLoggingHandler(false).prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + NettyClientProperties.LOGGING_ENABLED, true))
+                .apply();
+        Assertions.assertTrue(config.get().loggingEnabled.get());
+
+        new TestClient(new RWLog().enableLoggingHandler(false).prefix(PREFIX))
+                .client(c -> c.property(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWLog().enableLoggingHandler(true)))
+                .request()
+                .apply();
+        Assertions.assertTrue(config.get().loggingEnabled.get());
+
+        new TestClient(new RWLog().enableLoggingHandler(false).prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWLog().enableLoggingHandler(true).prefix(PREFIX)))
+                .apply();
+        Assertions.assertTrue(config.get().loggingEnabled.get());
+    }
+
+    @Test
+    public void testMaxHeaderSize() {
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        final AtomicReference<Integer> result = new AtomicReference<>();
+        class RWSize extends RW {
+
+            @Override
+            HttpClientCodec createHttpClientCodec(Map<String, Object> properties) {
+                HttpClientCodec codec = super.createHttpClientCodec(properties);
+                result.set(maxHeaderSize.get());
+                return codec;
+            }
+
+            @Override
+            public RWSize instance() {
+                RWSize rw = new RWSize();
+                config.set(rw);
+                return rw;
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWSize()).request().apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(NettyClientProperties.DEFAULT_HEADER_SIZE, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSize().maxHeaderSize(5555)).request().apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSize().maxHeaderSize(1111).prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWSize().maxHeaderSize(5555).prefix(PREFIX))).apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSize().maxHeaderSize(1111).prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.MAX_HEADER_SIZE, 5555))
+                .request().apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSize().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.MAX_HEADER_SIZE, 5555))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWSize().maxHeaderSize(8888).prefix(PREFIX)))
+                .apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+    }
+
+    @Test
+    public void testMaxChunkSize() {
+        final AtomicReference<NettyConnectorProvider.Config.RW> config = new AtomicReference<>();
+        final AtomicReference<Integer> result = new AtomicReference<>();
+        class RWSize extends RW {
+
+            @Override
+            HttpClientCodec createHttpClientCodec(Map<String, Object> properties) {
+                HttpClientCodec codec = super.createHttpClientCodec(properties);
+                result.set(maxChunkSize.get());
+                return codec;
+            }
+
+            @Override
+            public RWSize instance() {
+                RWSize rw = new RWSize();
+                config.set(rw);
+                return rw;
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWSize()).request().apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(NettyClientProperties.DEFAULT_CHUNK_SIZE, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSize().maxChunkSize(5555)).request().apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSize().maxChunkSize(1111).prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWSize().maxChunkSize(5555).prefix(PREFIX))).apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSize().maxChunkSize(1111).prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.MAX_CHUNK_SIZE, 5555))
+                .request().apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSize().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.MAX_CHUNK_SIZE, 5555))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWSize().maxChunkSize(8888).prefix(PREFIX)))
+                .apply();
+        config.get().createHttpClientCodec(req.request.getConfiguration().getProperties());
+        Assertions.assertEquals(5555, result.get());
+    }
+
+    @Test
+    public void testMaxTotalConnections() {
+        final AtomicReference<Integer> result = new AtomicReference<>();
+        class RWConn extends RW {
+
+            @Override
+            NettyConnectorProvider.Config.RW fromClient(Client client) {
+                NettyConnectorProvider.Config.RW rw = super.fromClient(client);
+                result.set(rw.maxPoolSizeTotal.get());
+                return rw;
+            }
+
+            @Override
+            public RWConn instance() {
+                return new RWConn();
+            }
+        }
+
+        new TestClient(new RWConn().maxTotalConnections(55)).request().apply();
+        Assertions.assertEquals(55, result.get());
+
+        result.set(null);
+        new TestClient(new RWConn().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.MAX_CONNECTIONS_TOTAL, 55))
+                .request().apply();
+        Assertions.assertEquals(55, result.get());
+
+        result.set(null);
+        new TestClient(new RWConn().prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().prefix(PREFIX).maxTotalConnections(55)))
+                .request().apply();
+        Assertions.assertEquals(55, result.get());
+
+        result.set(null);
+        new TestClient(new RWConn().prefix(PREFIX))
+                // NOT PER REQUEST
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().prefix(PREFIX).maxTotalConnections(55)))
+                .apply();
+        Assertions.assertEquals(new RWConn().copy().maxPoolSizeTotal.get(), result.get());
+    }
+
+    @Test
+    public void testMaxConnectionsPerDestination() {
+        final AtomicReference<Integer> result = new AtomicReference<>();
+        class RWConn extends RW {
+
+            @Override
+            NettyConnectorProvider.Config.RW fromClient(Client client) {
+                NettyConnectorProvider.Config.RW rw = super.fromClient(client);
+                result.set(rw.maxPoolSize.get());
+                return rw;
+            }
+
+            @Override
+            public RWConn instance() {
+                return new RWConn();
+            }
+        }
+
+        new TestClient(new RWConn().maxConnectionsPerDestination(15)).request().apply();
+        Assertions.assertEquals(15, result.get());
+
+        result.set(null);
+        new TestClient(new RWConn().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.MAX_CONNECTIONS, 15))
+                .request().apply();
+        Assertions.assertEquals(15, result.get());
+
+        result.set(null);
+        new TestClient(new RWConn().prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().prefix(PREFIX).maxConnectionsPerDestination(15)))
+                .request().apply();
+        Assertions.assertEquals(15, result.get());
+
+        result.set(null);
+        new TestClient(new RWConn().prefix(PREFIX))
+                // NOT PER REQUEST
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().prefix(PREFIX).maxConnectionsPerDestination(15)))
+                .apply();
+        Assertions.assertEquals(new RWConn().copy().maxPoolSize.get(), result.get());
+    }
+
+    @Test
+    public void testIdleConnectionPruneTimeout() {
+        final AtomicReference<Integer> result = new AtomicReference<>();
+        class RWConn extends RW {
+
+            @Override
+            NettyConnectorProvider.Config.RW fromClient(Client client) {
+                NettyConnectorProvider.Config.RW rw = super.fromClient(client);
+                result.set(rw.maxPoolIdle.get());
+                return rw;
+            }
+
+            @Override
+            public RWConn instance() {
+                return new RWConn();
+            }
+        }
+
+        new TestClient(new RWConn().idleConnectionPruneTimeout(15)).request().apply();
+        Assertions.assertEquals(15, result.get());
+
+        result.set(null);
+        new TestClient(new RWConn().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT, 15))
+                .request().apply();
+        Assertions.assertEquals(15, result.get());
+
+        result.set(null);
+        new TestClient(new RWConn().prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().prefix(PREFIX).idleConnectionPruneTimeout(15)))
+                .request().apply();
+        Assertions.assertEquals(15, result.get());
+
+        result.set(null);
+        new TestClient(new RWConn().prefix(PREFIX))
+                // NOT PER REQUEST
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        NettyConnectorProvider.config().prefix(PREFIX).idleConnectionPruneTimeout(15)))
+                .apply();
+        Assertions.assertEquals(new RWConn().copy().maxPoolIdle.get(), result.get());
+    }
+
+    @Test
+    public void testPrecedence() {
+        NettyConnectorProvider.Config.RW builderLower = NettyConnectorProvider.config().rw();
+        builderLower.maxTotalConnections(55);
+
+        NettyConnectorProvider.Config.RW builderUpper = builderLower.copy();
+        builderUpper.maxTotalConnections(56);
+        Assertions.assertEquals(56, builderUpper.maxPoolSizeTotal.get());
+
+        Client client = ClientBuilder.newClient();
+        client.property(NettyClientProperties.MAX_CONNECTIONS_TOTAL, 57);
+        NettyConnectorProvider.Config.RW result = builderUpper.fromClient(client);
+        Assertions.assertEquals(57, result.maxPoolSizeTotal.get());
+        Assertions.assertEquals(60, result.maxPoolIdle.get());
+    }
+
+    private static class ConnectorConfig extends ConnectorConfiguration<ConnectorConfig> {
+        private static class RW extends ConnectorConfiguration<RW> implements Read<RW> {
+            @Override
+            public RW instance() {
+                return new RW();
+            }
+
+            @Override
+            public RW me() {
+                return this;
+            }
+
+            public Configuration config() {
+                Map<String, Object> empty = new HashMap<>();
+                Configuration configuration = (Configuration) Proxy.newProxyInstance(
+                        getClass().getClassLoader(),
+                        new Class[]{Configuration.class}, new InvocationHandler() {
+                            @Override
+                            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+                                switch (method.getName()) {
+                                    case "getProperties":
+                                        return empty;
+                                    case "getProperty":
+                                        return empty.get(args[0]);
+                                }
+                                return null;
+                            }
+                        });
+
+                return configuration;
+            }
+        }
+    }
+
+    private static class RW extends NettyConnectorProvider.Config.RW {
+        @Override
+        public int connectTimeout() {
+            throw new IllegalStateException();
+        }
+    }
+
+
+    private static class TestClient {
+        private final NettyConnectorProvider.Config.RW rw;
+        private final Client client;
+
+        private TestClient(NettyConnectorProvider.Config.RW rw) {
+            this.rw = rw;
+            this.client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new NettyConnectorProvider()));
+        }
+
+        public TestClient client(Consumer<Client> consumer) {
+            consumer.accept(client);
+            return this;
+        }
+
+        public TestClient rw(Consumer<NettyConnectorProvider.Config.RW> consumer) {
+            consumer.accept(rw);
+            return this;
+        }
+
+        public Request request() {
+            return new Request(client, rw);
+        }
+
+        public Request request(Consumer<ClientRequest> consumer) {
+            return request().request(consumer);
+        }
+    }
+
+    private static class Request {
+        final ClientRequest request;
+        final Client client;
+        final NettyConnectorProvider.Config.RW rw;
+        NettyConnector connector;
+
+        Request(Client client, NettyConnectorProvider.Config.RW rw) {
+            this.client = client;
+            this.rw = rw;
+            request = createRequest(client);
+        }
+
+        public Request request(Consumer<ClientRequest> consumer) {
+            consumer.accept(request);
+            return this;
+        }
+
+        public Request apply() {
+            try {
+                connector = new NettyConnector(client, rw);
+                connector.apply(request);
+            } catch (ProcessingException expected) {
+            }
+            return this;
+        }
+    }
+}
diff --git a/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/CustomConnectionControllerTest.java b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/CustomConnectionControllerTest.java
new file mode 100644
index 0000000..abf23e5
--- /dev/null
+++ b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/CustomConnectionControllerTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.netty.connector;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientRequest;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+import java.net.URI;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class CustomConnectionControllerTest extends JerseyTest {
+    final AtomicBoolean hit = new AtomicBoolean(false);
+
+    @Path("/")
+    public static class CustomConnectionControllerTestResource {
+        @GET
+        public String get() {
+            return "ok";
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(CustomConnectionControllerTestResource.class);
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        NettyConnectorProvider provider = NettyConnectorProvider.config().connectionController(new NettyConnectionController() {
+            @Override
+            public String getConnectionGroup(ClientRequest clientRequest, URI uri, String hostName, int port) {
+                hit.set(true);
+                return super.getConnectionGroup(clientRequest, uri, hostName, port);
+            }
+        }).build();
+
+        config.connectorProvider(provider);
+    }
+
+    @Test
+    public void testCustomConnectionControllerIsInvoked() {
+        try (Response response = target().request().get()) {
+            Assertions.assertEquals(200, response.getStatus());
+        }
+        client().close();
+        Assertions.assertEquals(true, hit.get());
+
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java b/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java
index 267664d..559b7ad 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/ClientProperties.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -155,6 +155,15 @@
     public static final String BACKGROUND_SCHEDULER_THREADPOOL_SIZE = "jersey.config.client.backgroundScheduler.threadPoolSize";
 
     /**
+     * The connector configuration object available through connector provider configuration methods.
+     *
+     * <p>
+     *  The name of the configuration property is <tt>{@value}</tt>.
+     * </p>
+     */
+    public static final String CONNECTOR_CONFIGURATION = "jersey.config.client.ConnectorConfiguration";
+
+    /**
      * If {@link org.glassfish.jersey.client.filter.EncodingFilter} is
      * registered, this property indicates the value of Content-Encoding
      * property the filter should be adding.
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnectorProvider.java b/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnectorProvider.java
index dd96928..b8ec60b 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnectorProvider.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnectorProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -20,14 +20,12 @@
 import java.net.HttpURLConnection;
 import java.net.Proxy;
 import java.net.URL;
-import java.util.Map;
-import java.util.logging.Logger;
 
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.core.Configuration;
 
 import org.glassfish.jersey.client.internal.HttpUrlConnector;
-import org.glassfish.jersey.client.internal.LocalizationMessages;
+import org.glassfish.jersey.client.internal.HttpUrlConnectorConfiguration;
 import org.glassfish.jersey.client.spi.Connector;
 import org.glassfish.jersey.client.spi.ConnectorProvider;
 
@@ -110,26 +108,22 @@
      */
     public static final String SET_METHOD_WORKAROUND =
             "jersey.config.client.httpUrlConnection.setMethodWorkaround";
-    /**
-     * Default connection factory to be used.
-     */
-    private static final ConnectionFactory DEFAULT_CONNECTION_FACTORY = new DefaultConnectionFactory();
 
-    private static final Logger LOGGER = Logger.getLogger(HttpUrlConnectorProvider.class.getName());
-
-    private ConnectionFactory connectionFactory;
-    private int chunkSize;
-    private boolean useFixedLengthStreaming;
-    private boolean useSetMethodWorkaround;
+    protected final Config config;
 
     /**
      * Create new {@link java.net.HttpURLConnection}-based Jersey client connector provider.
      */
     public HttpUrlConnectorProvider() {
-        this.connectionFactory = DEFAULT_CONNECTION_FACTORY;
-        this.chunkSize = ClientProperties.DEFAULT_CHUNK_SIZE;
-        this.useFixedLengthStreaming = false;
-        this.useSetMethodWorkaround = false;
+        this.config = new Config();
+    }
+
+    private HttpUrlConnectorProvider(Config config) {
+        this.config = config;
+    }
+
+    public static Config config() {
+        return new Config();
     }
 
     /**
@@ -140,11 +134,7 @@
      * @throws java.lang.NullPointerException in case the supplied connectionFactory is {@code null}.
      */
     public HttpUrlConnectorProvider connectionFactory(final ConnectionFactory connectionFactory) {
-        if (connectionFactory == null) {
-            throw new NullPointerException(LocalizationMessages.NULL_INPUT_PARAMETER("connectionFactory"));
-        }
-
-        this.connectionFactory = connectionFactory;
+        config.connectionFactory(connectionFactory);
         return this;
     }
 
@@ -164,10 +154,7 @@
      * @throws java.lang.IllegalArgumentException in case the specified chunk size is negative.
      */
     public HttpUrlConnectorProvider chunkSize(final int chunkSize) {
-        if (chunkSize < 0) {
-            throw new IllegalArgumentException(LocalizationMessages.NEGATIVE_INPUT_PARAMETER("chunkSize"));
-        }
-        this.chunkSize = chunkSize;
+        config.chunkSize(chunkSize);
         return this;
     }
 
@@ -183,7 +170,7 @@
      * @return updated connector provider instance.
      */
     public HttpUrlConnectorProvider useFixedLengthStreaming() {
-        this.useFixedLengthStreaming = true;
+        config.useFixedLengthStreaming(true);
         return this;
     }
 
@@ -199,28 +186,18 @@
      * @return updated connector provider instance.
      */
     public HttpUrlConnectorProvider useSetMethodWorkaround() {
-        this.useSetMethodWorkaround = true;
+        config.useSetMethodWorkaround(true);
         return this;
     }
 
     @Override
-    public Connector getConnector(final Client client, final Configuration config) {
-        final Map<String, Object> properties = config.getProperties();
-
-        int computedChunkSize = ClientProperties.getValue(properties,
-                ClientProperties.CHUNKED_ENCODING_SIZE, chunkSize, Integer.class);
-        if (computedChunkSize < 0) {
-            LOGGER.warning(LocalizationMessages.NEGATIVE_CHUNK_SIZE(computedChunkSize, chunkSize));
-            computedChunkSize = chunkSize;
-        }
-
-        final boolean computedUseFixedLengthStreaming = ClientProperties.getValue(properties,
-                USE_FIXED_LENGTH_STREAMING, useFixedLengthStreaming, Boolean.class);
-        final boolean computedUseSetMethodWorkaround = ClientProperties.getValue(properties,
-                SET_METHOD_WORKAROUND, useSetMethodWorkaround, Boolean.class);
-
-        return createHttpUrlConnector(client, connectionFactory, computedChunkSize, computedUseFixedLengthStreaming,
-                                      computedUseSetMethodWorkaround);
+    public Connector getConnector(final Client client, final Configuration configuration) {
+        this.config.preInit(configuration);
+        return createHttpUrlConnector(client,
+                this.config.connectionFactory(),
+                this.config.chunkSize(),
+                this.config.fixLengthStreaming(),
+                this.config.setMethodWorkaround());
     }
 
     /**
@@ -230,7 +207,7 @@
      * @param connectionFactory   {@link javax.net.ssl.HttpsURLConnection} factory to be used when creating
      *                            connections.
      * @param chunkSize           chunk size to use when using HTTP chunked transfer coding.
-     * @param fixLengthStreaming  specify if the the {@link java.net.HttpURLConnection#setFixedLengthStreamingMode(int)
+     * @param fixLengthStreaming  specify if the {@link java.net.HttpURLConnection#setFixedLengthStreamingMode(int)
      *                            fixed-length streaming mode} on the underlying HTTP URL connection instances should
      *                            be used when sending requests.
      * @param setMethodWorkaround specify if the reflection workaround should be used to set HTTP URL connection method
@@ -240,12 +217,33 @@
     protected Connector createHttpUrlConnector(Client client, ConnectionFactory connectionFactory,
                                                int chunkSize, boolean fixLengthStreaming,
                                                boolean setMethodWorkaround) {
-        return new HttpUrlConnector(
-                client,
-                connectionFactory,
-                chunkSize,
-                fixLengthStreaming,
-                setMethodWorkaround);
+        return new HttpUrlConnector(client, client.getConfiguration(), config);
+    }
+
+    public static final class Config extends HttpUrlConnectorConfiguration<Config> {
+        public HttpUrlConnectorProvider build() {
+            return new HttpUrlConnectorProvider(this);
+        }
+
+        /* package */ ConnectionFactory connectionFactory() {
+            return connectionFactory.get();
+        }
+
+        /* package */ int chunkSize() {
+            return chunkSize.get();
+        }
+
+        /* package */ boolean fixLengthStreaming() {
+            return useFixedLengthStreaming.get();
+        }
+
+        /* package */ boolean setMethodWorkaround() {
+            return useSetMethodWorkaround.get();
+        }
+
+        /* package */ void preInit(Configuration configuration) {
+            super.preInit(configuration.getProperties());
+        }
     }
 
     /**
@@ -291,23 +289,6 @@
         }
     }
 
-    private static class DefaultConnectionFactory implements ConnectionFactory {
-
-        @Override
-        public HttpURLConnection getConnection(final URL url) throws IOException {
-            return connect(url, null);
-        }
-
-        @Override
-        public HttpURLConnection getConnection(URL url, Proxy proxy) throws IOException {
-            return connect(url, proxy);
-        }
-
-        private HttpURLConnection connect(URL url, Proxy proxy) throws IOException {
-            return (proxy == null) ? (HttpURLConnection) url.openConnection() : (HttpURLConnection) url.openConnection(proxy);
-        }
-    }
-
     @Override
     public boolean equals(final Object o) {
         if (this == o) {
@@ -318,22 +299,11 @@
         }
 
         final HttpUrlConnectorProvider that = (HttpUrlConnectorProvider) o;
-
-        if (chunkSize != that.chunkSize) {
-            return false;
-        }
-        if (useFixedLengthStreaming != that.useFixedLengthStreaming) {
-            return false;
-        }
-
-        return connectionFactory.equals(that.connectionFactory);
+        return config.equals(that.config);
     }
 
     @Override
     public int hashCode() {
-        int result = connectionFactory.hashCode();
-        result = 31 * result + chunkSize;
-        result = 31 * result + (useFixedLengthStreaming ? 1 : 0);
-        return result;
+        return config.hashCode();
     }
 }
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/innate/ClientProxy.java b/core-client/src/main/java/org/glassfish/jersey/client/innate/ClientProxy.java
index 68ab324..1d82b06 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/innate/ClientProxy.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/innate/ClientProxy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -16,8 +16,8 @@
 package org.glassfish.jersey.client.innate;
 
 import org.glassfish.jersey.client.ClientProperties;
-import org.glassfish.jersey.client.ClientRequest;
 import org.glassfish.jersey.client.internal.LocalizationMessages;
+import org.glassfish.jersey.internal.PropertiesResolver;
 
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.core.Configuration;
@@ -31,6 +31,7 @@
 import java.util.Arrays;
 import java.util.Base64;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -42,16 +43,20 @@
       // do not instantiate
     };
 
-    public static Optional<ClientProxy> proxyFromRequest(ClientRequest request) {
+    public static Optional<ClientProxy> proxyFromRequest(PropertiesResolver request) {
         return getProxy(request);
     }
 
-    public static Optional<ClientProxy> proxyFromProperties(URI requestUri) {
+    public static Optional<ClientProxy> proxyFromUri(URI requestUri) {
         return getSystemPropertiesProxy(requestUri);
     }
 
+    public static Optional<ClientProxy> proxyFromProperties(Map<String, Object> properties) {
+        return getProxy(properties);
+    }
+
     public static Optional<ClientProxy> proxyFromConfiguration(Configuration configuration) {
-        return getProxy(configuration);
+        return getProxy(configuration.getProperties());
     }
 
     public static ClientProxy proxy(Proxy proxy) {
@@ -103,7 +108,7 @@
         return userName;
     };
 
-    private static Optional<ClientProxy> getProxy(ClientRequest request) {
+    private static Optional<ClientProxy> getProxy(PropertiesResolver request) {
         Object proxyUri = request.resolveProperty(ClientProperties.PROXY_URI, Object.class);
         if (proxyUri != null) {
             ClientProxy proxy = toProxy(proxyUri);
@@ -118,13 +123,13 @@
         return Optional.empty();
     }
 
-    private static Optional<ClientProxy> getProxy(Configuration config) {
-        Object proxyUri = config.getProperties().get(ClientProperties.PROXY_URI);
+    private static Optional<ClientProxy> getProxy(Map<String, Object> properties) {
+        Object proxyUri = properties.get(ClientProperties.PROXY_URI);
         if (proxyUri != null) {
             ClientProxy proxy = toProxy(proxyUri);
             if (proxy != null) {
-                proxy.userName = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_USERNAME, String.class);
-                proxy.password = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_PASSWORD, String.class);
+                proxy.userName = ClientProperties.getValue(properties, ClientProperties.PROXY_USERNAME, String.class);
+                proxy.password = ClientProperties.getValue(properties, ClientProperties.PROXY_PASSWORD, String.class);
                 return Optional.of(proxy);
             } else {
                 return Optional.empty();
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/innate/ConnectorConfiguration.java b/core-client/src/main/java/org/glassfish/jersey/client/innate/ConnectorConfiguration.java
new file mode 100644
index 0000000..48e9244
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/innate/ConnectorConfiguration.java
@@ -0,0 +1,895 @@
+/*
+ * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.innate;
+
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientRequest;
+import org.glassfish.jersey.client.RequestEntityProcessing;
+import org.glassfish.jersey.client.innate.http.SSLParamConfigurator;
+import org.glassfish.jersey.internal.PropertiesResolver;
+
+import javax.net.ssl.SSLContext;
+import jakarta.ws.rs.RuntimeType;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Feature;
+import java.net.Proxy;
+import java.net.URI;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+/**
+ * Configuration object to use for configuring the client connectors and HTTP request processing.
+ * This configuration provides settings to be handled by the connectors, mainly declared by {@link ClientProperties}.
+ *
+ * @param <E> the connector configuration subtype.
+ */
+public class ConnectorConfiguration<E extends ConnectorConfiguration<E>> {
+    protected final NullableRef<Integer> connectTimeout = NullableRef.empty();
+    protected final NullableRef<Boolean> expect100Continue = NullableRef.empty();
+    protected final NullableRef<Long> expect100continueThreshold = NullableRef.empty();
+    protected final NullableRef<Boolean> followRedirects = NullableRef.empty();
+    protected final NullableRef<String> prefix = NullableRef.empty();
+    protected final NullableRef<Object> proxyUri = NullableRef.empty();
+    protected final NullableRef<String> proxyUserName = NullableRef.empty();
+    protected final NullableRef<String> proxyPassword = NullableRef.empty();
+    protected final NullableRef<Integer> readTimeout = NullableRef.empty();
+    protected final NullableRef<RequestEntityProcessing> requestEntityProcessing = NullableRef.empty();
+    protected final NullableRef<String> sniHostname = NullableRef.empty();
+    protected final NullableRef<Supplier<SSLContext>> sslContextSupplier = NullableRef.empty();
+    protected final NullableRef<Integer> threadPoolSize = NullableRef.empty();
+
+    /**
+     * Use factory methods provided by each connector supporting this configuration object and its subclass instead.
+     */
+    protected ConnectorConfiguration() {
+    }
+
+    /**
+     * Set the asynchronous thread-pool size. The property {@link ClientProperties#ASYNC_THREADPOOL_SIZE}
+     * has precedence over this setting.
+     *
+     * @param threadPoolSize the size of the asynchronous thread-pool.
+     * @return updated configuration.
+     */
+    public E asyncThreadPoolSize(int threadPoolSize) {
+        this.threadPoolSize.set(threadPoolSize);
+        return self();
+    }
+
+    /**
+     * Set connect timeout. The property {@link ClientProperties#CONNECT_TIMEOUT}
+     * has precedence over this setting.
+     *
+     * @param millis timeout in milliseconds.
+     * @return updated configuration.
+     */
+    public E connectTimeout(int millis) {
+        connectTimeout.set(millis);
+        return self();
+    }
+
+    /**
+     * Allows for HTTP Expect:100-Continue.
+     * The property {@link ClientProperties#EXPECT_100_CONTINUE} has precedence over this setting.
+     *
+     * @param enable allows for HTTP Expect:100-Continue or not.
+     * @return updated configuration.
+     */
+    public E expect100Continue(boolean enable) {
+        expect100Continue.set(enable);
+        return self();
+    }
+
+    /**
+     * Set the Expect:100-Continue content-length threshold size.
+     * The {@link ClientProperties#EXPECT_100_CONTINUE_THRESHOLD_SIZE} property has precedence over this setting.
+     *
+     * @param size the content-length threshold.
+     * @return updated configuration.
+     */
+    public E expect100ContinueThreshold(long size) {
+        expect100continueThreshold.set(size);
+        return self();
+    }
+
+    /**
+     * Set to follow redirects. The property {@link ClientProperties#FOLLOW_REDIRECTS} has precedence over this setting.
+     *
+     * @param follow to follow or not to follow.
+     * @return updated configuration.
+     */
+    public E followRedirects(boolean follow) {
+        followRedirects.set(follow);
+        return self();
+    }
+
+    /**
+     * <p>
+     * Set the prefix for the configuration properties used by Client/Request to configure and override the settings.
+     * For instance, if the prefix would be {@code com.example.MyProject.}, the property {@link #connectTimeout(int)}
+     * is overridden only by properties with key starting by the prefix,
+     * i.e. for {@link ClientProperties#CONNECT_TIMEOUT},
+     * the property key {@code com.example.MyProject.jersey.config.client.connectTimeout} would override the setting.
+     * </p>
+     * <p>
+     *     The prefix can be used to override the settings by the System property set specifically for the
+     *     prefixed connector. See {@link org.glassfish.jersey.CommonProperties#ALLOW_SYSTEM_PROPERTIES_PROVIDER}
+     *     for enabling System properties usage.
+     * </p>
+     * <p>
+     * The default configuration prefix is empty.
+     * </p>
+     *
+     * @param prefix the non-null prefix.
+     * @throws NullPointerException if the prefix is null.
+     * @return updated configuration.
+     */
+    public E prefix(String prefix) {
+        this.prefix.set(Objects.requireNonNull(prefix));
+        return self();
+    }
+
+    /**
+     * Set proxy password. The property {@link ClientProperties#PROXY_PASSWORD}
+     * has precedence over this setting.
+     *
+     * @param proxyPassword the proxy password.
+     * @return updated configuration.
+     */
+    public E proxyPassword(String proxyPassword) {
+        this.proxyPassword.set(proxyPassword);
+        return self();
+    }
+
+    /**
+     * Set proxy username. The property {@link ClientProperties#PROXY_USERNAME}
+     * has precedence over this setting.
+     *
+     * @param userName the proxy username.
+     * @return updated configuration.
+     */
+    public E proxyUserName(String userName) {
+        proxyUserName.set(userName);
+        return self();
+    }
+
+    /**
+     * Set proxy URI. The property {@link ClientProperties#PROXY_URI}
+     * has precedence over this setting.
+     *
+     * @param proxyUri the proxy URI.
+     * @return updated configuration.
+     */
+    public E proxyUri(String proxyUri) {
+        this.proxyUri.set(proxyUri);
+        return self();
+    }
+
+    /**
+     * Set proxy URI. The property {@link ClientProperties#PROXY_URI}
+     * has precedence over this setting.
+     *
+     * @param proxyUri the proxy URI.
+     * @return updated configuration.
+     */
+    public E proxyUri(URI proxyUri) {
+        this.proxyUri.set(proxyUri);
+        return self();
+    }
+
+    /**
+     * Set HTTP proxy. The property {@link ClientProperties#PROXY_URI}
+     * has precedence over this setting.
+     *
+     * @param proxy the HTTP proxy.
+     * @return updated configuration.
+     */
+    public E proxy(Proxy proxy) {
+        this.proxyUri.set(proxy);
+        return self();
+    }
+
+    /**
+     * Set read timeout. The property {@link ClientProperties#READ_TIMEOUT}
+     * has precedence over this setting.
+     *
+     * @param millis timeout in milliseconds.
+     * @return updated configuration.
+     */
+    public E readTimeout(int millis) {
+        readTimeout.set(millis);
+        return self();
+    }
+
+    /**
+     * Set the request entity processing type.
+     *
+     * @param requestEntityProcessing the request entity processing type.
+     * @return the updated configuration.
+     */
+    public E requestEntityProcessing(RequestEntityProcessing requestEntityProcessing) {
+        this.requestEntityProcessing.set(requestEntityProcessing);
+        return self();
+    }
+
+    public E sniHostName(String sniHostname) {
+        this.sniHostname.set(sniHostname);
+        return self();
+    }
+
+    /**
+     * Set the {@link SSLContext} supplier. The property {@link ClientProperties#SSL_CONTEXT_SUPPLIER} has precedence over
+     * this setting.
+     *
+     * @param sslContextSupplier the {@link SSLContext} supplier.
+     * @return the updated configuration.
+     */
+    public E sslContextSupplier(Supplier<SSLContext> sslContextSupplier) {
+        this.sslContextSupplier.set(sslContextSupplier);
+        return self();
+    }
+
+    /**
+     * Return type-cast self.
+     * @return self.
+     */
+    @SuppressWarnings("unchecked")
+    protected E self() {
+        return (E) this;
+    }
+
+    /**
+     * <p>
+     * A reference to a value. The reference can be empty, but unlike the {@code Optional}, once a value is set,
+     * it never can be empty again. The {@code null} value is treated as a non-empty value of null.
+     * </p><p>
+     * This {@code null}
+     * can be used to override some previous configuration value, to distinguish the intentional {@code null} override
+     * from an empty (non-set) configuration value.
+     * </p>
+     * @param <T> type of the value.
+     */
+    protected static class NullableRef<T> implements org.glassfish.jersey.internal.util.collection.Ref<T> {
+
+        private NullableRef() {
+            // use factory methods;
+        }
+
+        /**
+         * Return a new empty reference.
+         *
+         * @return an empty reference.
+         * @param <T> The type of the empty value.
+         */
+        public static <T> NullableRef<T> empty() {
+            return new NullableRef<>();
+        }
+
+        /**
+         * Return a reference of a given value.
+         *
+         * @param value the value this reference refers to.*
+         * @return a new reference to a given value.
+         * @param <T> type of the value.
+         */
+        public static <T> NullableRef<T> of(T value) {
+            NullableRef<T> ref = new NullableRef<>();
+            ref.set(value);
+            return ref;
+        }
+
+        private boolean empty = true;
+        private T ref = null;
+
+        @Override
+        public void set(T value) {
+            empty = false;
+            ref = value;
+        }
+
+        /**
+         * Set or replace the value if other value is set.
+         * @param other a reference to another value.
+         */
+        public void setNonEmpty(NullableRef<T> other) {
+            other.ifPresent(this::set);
+        }
+
+        @Override
+        public T get() {
+            return ref;
+        }
+
+        /**
+         * Run action if and only if the condition applies.
+         *
+         * @param predicate the condition to be met.
+         * @param action the action to run if condition is met.
+         */
+        public void iff(Predicate<T> predicate, Runnable action) {
+            if (predicate.test(ref)) {
+                action.run();
+            }
+        }
+
+        /**
+         * If it is empty, sets the {@code value} value. Keeps the original value, otherwise.
+         *
+         * @param value the value to be set if empty.
+         */
+        public void ifEmptySet(T value) {
+            if (empty) {
+                set(value);
+            }
+        }
+
+        /**
+         * If a value is present, performs the given action with the value,
+         * otherwise does nothing.
+         *
+         * @param action the action to be performed, if a value is present
+         * @throws NullPointerException if value is present and the given action is
+         *         {@code null}
+         */
+        public void ifPresent(Consumer<? super T> action) {
+            if (!empty) {
+                action.accept(ref);
+            }
+        }
+
+        /**
+         * If a value is present, performs the given action with the value,
+         * otherwise performs the given empty-based action.
+         *
+         * @param action the action to be performed, if a value is present
+         * @param emptyAction the empty-based action to be performed, if no value is
+         *        present
+         * @throws NullPointerException if a value is present and the given action
+         *         is {@code null}, or no value is present and the given empty-based
+         *         action is {@code null}.
+         */
+        public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
+            if (!empty) {
+                action.accept(ref);
+            } else {
+                emptyAction.run();
+            }
+        }
+
+        /**
+         * Return the value if present, the {@code other} otherwise.
+         *
+         * @param other the value if not present
+         * @return inner value if present or the other otherwise.
+         */
+        public T ifPresentOrElse(T other) {
+            return empty ? other : ref;
+        }
+
+        /**
+         * If a value is  not present, returns {@code true}, otherwise
+         * {@code false}.
+         *
+         * @return  {@code true} if a value is not present, otherwise {@code false}
+         */
+        public boolean isEmpty() {
+            return empty;
+        }
+
+        /**
+         * If a value is present, returns {@code true}, otherwise {@code false}.
+         *
+         * @return {@code true} if a value is present, otherwise {@code false}
+         */
+        public boolean isPresent() {
+            return !empty;
+        }
+
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(ref, empty);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+
+            if (!(o instanceof NullableRef)) {
+                return false;
+            }
+
+            NullableRef<?> that = (NullableRef<?>) o;
+            return Objects.equals(empty, that.empty) && Objects.equals(ref, that.ref);
+        }
+
+        @Override
+        public String toString() {
+            return empty ? "<empty>" : ref == null ? "<null>" : ref.toString();
+        }
+    }
+
+    protected interface Read<CC extends ConnectorConfiguration<CC> & Read<CC>>
+            extends SSLParamConfigurator.SSLParamConfiguratorConfiguration {
+
+        /**
+         * Set and replace the values of current configuration by values of other configuration
+         * if and only if the values of other configuration are set.
+         *
+         * @param other another configuration instance.
+         */
+        public default <X extends ConnectorConfiguration<?>> void setNonEmpty(X other) {
+            me().connectTimeout.setNonEmpty(other.connectTimeout);
+            me().expect100Continue.setNonEmpty(other.expect100Continue);
+            me().expect100continueThreshold.setNonEmpty(other.expect100continueThreshold);
+            me().followRedirects.setNonEmpty(other.followRedirects);
+            me().prefix.setNonEmpty(other.prefix);
+            me().proxyUri.setNonEmpty(other.proxyUri);
+            me().proxyUserName.setNonEmpty(other.proxyUserName);
+            me().proxyPassword.setNonEmpty(other.proxyPassword);
+            me().readTimeout.setNonEmpty(other.readTimeout);
+            me().requestEntityProcessing.setNonEmpty(other.requestEntityProcessing);
+            me().sniHostname.setNonEmpty(other.sniHostname);
+            me().sslContextSupplier.setNonEmpty(other.sslContextSupplier);
+            me().threadPoolSize.setNonEmpty(other.threadPoolSize);
+        }
+
+        /**
+         * Return the thread-pool size setting.
+         *
+         * @return the thread pool size setting.
+         */
+        public default Integer asyncThreadPoolSize() {
+            return me().threadPoolSize.get();
+        }
+
+        /**
+         * Update connect timeout value based on request properties settings.
+         *
+         * @param request the current HTTP client request.
+         * @return the updated configuration.
+         */
+        public default int connectTimeout(ClientRequest request) {
+            me().connectTimeout.set(
+                    request.resolveProperty(prefixed(ClientProperties.CONNECT_TIMEOUT), me().connectTimeout.get())
+            );
+            return me().connectTimeout.get();
+        }
+
+        /**
+         * Get the value of connect timeout setting.
+         *
+         * @return connect timeout value.
+         */
+        public default int connectTimeout() {
+            return me().connectTimeout.get();
+        }
+
+        /**
+         * Sets the default value. The default methods cannot be set on instances passed by the customers using
+         * {@link ClientProperties#CONNECTOR_CONFIGURATION} since they would override the values previously set
+         * by the connector configuration object.
+         * @return the initialized configuration object.
+         */
+        public default CC init() {
+            me().connectTimeout(0)
+                    .expect100ContinueThreshold(ClientProperties.DEFAULT_EXPECT_100_CONTINUE_THRESHOLD_SIZE)
+                    .followRedirects(Boolean.TRUE)
+                    .prefix("")
+                    .readTimeout(0);
+            return me();
+        }
+
+        /**
+         * Utility method to create a new instance of configuration to preserve the settings of previous configuration.
+         *
+         * @return a new instance of the configuration.
+         */
+        public default CC copy() {
+            CC config = instance();
+            config.init();
+            config.setNonEmpty(me());
+            return config;
+        }
+
+        public default CC copyFromClient(Configuration configuration) {
+            CC clientConfiguration = copy();
+            final Map<String, Object> properties = configuration.getProperties();
+            Object configProp = properties.get(clientConfiguration.prefixed(ClientProperties.CONNECTOR_CONFIGURATION));
+            if (configProp != null) {
+                ConnectorConfiguration<?> clientCfg = (ConnectorConfiguration<?>) configProp;
+                if (me().prefix.equals(clientCfg.prefix) || clientCfg.prefix.get() == null) {
+                    clientConfiguration.setNonEmpty(clientCfg);
+                }
+            } else {
+                configProp = properties.get(ClientProperties.CONNECTOR_CONFIGURATION);
+                if (configProp != null && me().prefix.equals(((ConnectorConfiguration<?>) configProp).prefix)) {
+                    clientConfiguration.setNonEmpty((ConnectorConfiguration<?>) configProp);
+                }
+            }
+            return clientConfiguration;
+        }
+
+        public default CC copyFromRequest(ClientRequest request) {
+            CC requestConfiguration = copy();
+            Object configProp = request.getProperty(prefixed(ClientProperties.CONNECTOR_CONFIGURATION));
+            if (configProp != null) {
+                ConnectorConfiguration<?> requestCfg = (ConnectorConfiguration<?>) configProp;
+                if (me().prefix.equals(requestCfg.prefix) || requestCfg.prefix.get() == null) {
+                    requestConfiguration.setNonEmpty(requestCfg);
+                }
+            } else {
+                configProp = request.getProperty(ClientProperties.CONNECTOR_CONFIGURATION);
+                if (configProp != null && me().prefix.equals(((ConnectorConfiguration<?>) configProp).prefix)) {
+                    requestConfiguration.setNonEmpty((ConnectorConfiguration<?>) configProp);
+                }
+            }
+            return requestConfiguration;
+        }
+
+        @Override
+        default String getSniHostNameProperty(Configuration configuration) {
+            Object property = configuration.getProperty(prefixed(ClientProperties.SNI_HOST_NAME));
+            if (property == null) {
+                property = configuration.getProperty(prefixed(ClientProperties.SNI_HOST_NAME.toLowerCase(Locale.ROOT)));
+            }
+            return property == null ? me().sniHostname.get() : (String) property;
+        }
+
+        /**
+         * Update the {@link #expect100Continue(boolean)} from the HTTP client request.
+         *
+         * @param request the HTTP client request.
+         * @return the Expect: 100-Continue support value.
+         */
+        public default Boolean expect100Continue(ClientRequest request) {
+            final Boolean expectContinueActivated =
+                    request.resolveProperty(prefixed(ClientProperties.EXPECT_100_CONTINUE), Boolean.class);
+            if (expectContinueActivated != null) {
+                me().expect100Continue.set(expectContinueActivated);
+            }
+            return me().expect100Continue.get();
+        }
+
+        /**
+         * Update the {@link #expect100ContinueThreshold(long)} from the HTTP client request.
+         *
+         * @param request the HTTP client request.
+         * @return the content length threshold size.
+         */
+        public default long expect100ContinueThreshold(ClientRequest request) {
+            me().expect100continueThreshold.set(
+                    request.resolveProperty(prefixed(ClientProperties.EXPECT_100_CONTINUE_THRESHOLD_SIZE),
+                            me().expect100continueThreshold.get())
+            );
+            return me().expect100continueThreshold.get();
+        }
+
+        /**
+         * Update the {@link #followRedirects(boolean)} setting from the HTTP client request. The default is {@code true}.
+         *
+         * @param request the HTTP client request.
+         * @return follow redirects setting.
+         */
+        public default boolean followRedirects(ClientRequest request) {
+            me().followRedirects.set(
+                    request.resolveProperty(prefixed(ClientProperties.FOLLOW_REDIRECTS), me().followRedirects.get())
+            );
+            return me().followRedirects.get();
+        }
+
+        /**
+         * Get the value of the follow redirects setting. The default is {@code true}.
+         *
+         * @return whether to follow redirects or not.
+         */
+        public default boolean followRedirects() {
+            return me().followRedirects.get();
+        }
+
+        public default Configuration prefixedConfiguration(Configuration configuration) {
+            return me().prefix.get().isEmpty() ? configuration : new PrefixedConfiguration(me().prefix.get(), configuration);
+        }
+
+        /**
+         * Create optional client proxy information based on the proxy information set in the configuration
+         * or the HTTP client request. The used settings are {@link #proxy(Proxy)},
+         * {@link #proxyUri(URI)}, {@link #proxyUri(String)}, {@link #proxyUserName(String)},
+         * and {@link #proxyPassword(String)}.
+         *
+         * @param request the HTTP client request,
+         * @param requestUri the HTTP request URI. It can differ from the URI used in the request, based on other
+         *                   information set by the HTTP client request.
+         * @return the optional client proxy.
+         */
+        public default Optional<ClientProxy> proxy(ClientRequest request, URI requestUri) {
+            Optional<ClientProxy> proxy = ClientProxy.proxyFromRequest(
+                    me().prefix.get().isEmpty()
+                        ? request
+                        : new PrefixedPropertiesResolver(me().prefix.get(), request)
+            );
+            if (!proxy.isPresent() && me().proxyUri.isPresent()) {
+                final Map<String, Object> properties = me().prefix.get().isEmpty()
+                        ? new HashMap<>()
+                        : new PrefixedMap<>(me().prefix.get(), new HashMap<>());
+                properties.put(me().prefix.get() + ClientProperties.PROXY_URI, me().proxyUri.get());
+                properties.put(me().prefix.get() + ClientProperties.PROXY_USERNAME, me().proxyUserName.get());
+                properties.put(me().prefix.get() + ClientProperties.PROXY_PASSWORD, me().proxyPassword.get());
+                request.getPropertyNames().forEach(k -> properties.put(k, request.getProperty(k)));
+                proxy = ClientProxy.proxyFromProperties(properties);
+            }
+            if (!proxy.isPresent()) {
+                proxy = ClientProxy.proxyFromUri(requestUri);
+            }
+            return proxy;
+        }
+
+        /**
+         * Update {@link #readTimeout(int) read timeout} based on the HTTP request properties.
+         *
+         * @param request the current HTTP client request.
+         * @return updated configuration.
+         */
+        public default CC readTimeout(ClientRequest request) {
+            me().readTimeout.set(request.resolveProperty(prefixed(ClientProperties.READ_TIMEOUT), me().readTimeout.get()));
+            return me();
+        }
+
+        /**
+         * Get the value of preset {@link #readTimeout(int)}.
+         *
+         * @return the read timeout milliseconds.
+         */
+        public default int readTimeout() {
+            return me().readTimeout.get();
+        }
+
+        /**
+         * Get the {@link RequestEntityProcessing} updated by the HTTP client request.
+         *
+         * @param request the HTTP client request.
+         * @return the RequestEntityProcessing type.
+         */
+        public default RequestEntityProcessing requestEntityProcessing(ClientRequest request) {
+            RequestEntityProcessing entityProcessing =
+                    request.resolveProperty(prefixed(ClientProperties.REQUEST_ENTITY_PROCESSING), RequestEntityProcessing.class);
+            if (entityProcessing == null) {
+                entityProcessing = me().requestEntityProcessing.get();
+            }
+            return entityProcessing;
+        }
+
+        @Override
+        default String resolveSniHostNameProperty(PropertiesResolver resolver) {
+            String property = resolver.resolveProperty(prefixed(ClientProperties.SNI_HOST_NAME), String.class);
+            if (property == null) {
+                property = resolver.resolveProperty(
+                        prefixed(ClientProperties.SNI_HOST_NAME.toLowerCase(Locale.ROOT)), String.class);
+            }
+            return property == null ? me().sniHostname.get() : property;
+        }
+
+        /**
+         * Get {@link SSLContext} either from the {@link ClientProperties#SSL_CONTEXT_SUPPLIER}, or from this configuration,
+         * or from the {@link Client#getSslContext()} in this order.
+         *
+         * @param client the client used to get the {@link SSLContext}.
+         * @param request the request used to get the {@link SSLContext}.
+         * @return the {@link SSLContext}.
+         */
+        public default SSLContext sslContext(Client client, ClientRequest request) {
+            @SuppressWarnings("unchecked")
+            Supplier<SSLContext> supplier =
+                    request.resolveProperty(prefixed(ClientProperties.SSL_CONTEXT_SUPPLIER), Supplier.class);
+            if (supplier == null) {
+                supplier = me().sslContextSupplier.get();
+            }
+            return supplier == null ? client.getSslContext() : supplier.get();
+        }
+
+        public default String prefixed(String propertyName) {
+            return me().prefix.get() + propertyName;
+        }
+
+        /**
+         * Return a new instance of configuration.
+         * @return a new instance of configuration.
+         */
+        public CC instance();
+
+        /**
+         * Return typed-cast self.
+         * @return self.
+         */
+        public CC me();
+    }
+
+
+    /**
+     * A properties map that works with prefixed properties.
+     *
+     * @param <V> Object type.
+     */
+    private static class PrefixedMap<V> implements Map<String, V> {
+        private final Map<String, V> inner;
+        private final String prefix;
+
+        private PrefixedMap(String prefix, Map<String, V> inner) {
+            this.inner = inner;
+            this.prefix = prefix;
+        }
+
+        @Override
+        public int size() {
+            return inner.size();
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return inner.isEmpty();
+        }
+
+        @Override
+        public boolean containsKey(Object key) {
+            return inner.containsKey(prefix + key);
+        }
+
+        @Override
+        public boolean containsValue(Object value) {
+            return inner.containsValue(value);
+        }
+
+        @Override
+        public V get(Object key) {
+            return inner.get(prefix + key);
+        }
+
+        @Override
+        public V put(String key, V value) {
+            return inner.put(key, value);
+        }
+
+        @Override
+        public V remove(Object key) {
+            return inner.remove(prefix + key);
+        }
+
+        @Override
+        public void putAll(Map<? extends String, ? extends V> m) {
+            inner.putAll(m);
+        }
+
+        @Override
+        public void clear() {
+            inner.clear();
+        }
+
+        @Override
+        public Set<String> keySet() {
+            return inner.keySet();
+        }
+
+        @Override
+        public Collection<V> values() {
+            return inner.values();
+        }
+
+        @Override
+        public Set<Entry<String, V>> entrySet() {
+            return inner.entrySet();
+        }
+    }
+
+    /**
+     * Properties resolver that resolves prefixed properties.
+     */
+    private static class PrefixedPropertiesResolver implements PropertiesResolver {
+        private final String prefix;
+        private final PropertiesResolver resolver;
+
+        private PrefixedPropertiesResolver(String prefix, PropertiesResolver resolver) {
+            this.prefix = prefix;
+            this.resolver = resolver;
+        }
+
+        @Override
+        public <T> T resolveProperty(String name, Class<T> type) {
+            return resolver.resolveProperty(prefix + name, type);
+        }
+
+        @Override
+        public <T> T resolveProperty(String name, T defaultValue) {
+            return resolver.resolveProperty(prefix + name, defaultValue);
+        }
+    }
+
+    protected static class PrefixedConfiguration implements Configuration {
+        private final String prefix;
+        private final Configuration inner;
+
+        private PrefixedConfiguration(String prefix, Configuration inner) {
+            this.prefix = prefix;
+            this.inner = inner;
+        }
+
+        @Override
+        public RuntimeType getRuntimeType() {
+            return inner.getRuntimeType();
+        }
+
+        @Override
+        public Map<String, Object> getProperties() {
+            return new PrefixedMap<>(prefix, inner.getProperties());
+        }
+
+        @Override
+        public Object getProperty(String name) {
+            return inner.getProperty(prefix + name);
+        }
+
+        @Override
+        public Collection<String> getPropertyNames() {
+            return inner.getPropertyNames();
+        }
+
+        @Override
+        public boolean isEnabled(Feature feature) {
+            return inner.isEnabled(feature);
+        }
+
+        @Override
+        public boolean isEnabled(Class<? extends Feature> featureClass) {
+            return inner.isEnabled(featureClass);
+        }
+
+        @Override
+        public boolean isRegistered(Object component) {
+            return inner.isRegistered(component);
+        }
+
+        @Override
+        public boolean isRegistered(Class<?> componentClass) {
+            return inner.isRegistered(componentClass);
+        }
+
+        @Override
+        public Map<Class<?>, Integer> getContracts(Class<?> componentClass) {
+            return inner.getContracts(componentClass);
+        }
+
+        @Override
+        public Set<Class<?>> getClasses() {
+            return inner.getClasses();
+        }
+
+        @Override
+        public Set<Object> getInstances() {
+            return inner.getInstances();
+        }
+    }
+}
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SSLParamConfigurator.java b/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SSLParamConfigurator.java
index 212e83d..93e1cb7 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SSLParamConfigurator.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/innate/http/SSLParamConfigurator.java
@@ -20,7 +20,6 @@
 import org.glassfish.jersey.client.ClientRequest;
 import org.glassfish.jersey.http.HttpHeaders;
 import org.glassfish.jersey.internal.PropertiesResolver;
-import org.glassfish.jersey.internal.guava.InetAddresses;
 
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLParameters;
@@ -52,6 +51,11 @@
         private String sniHostNameHeader = null;
         private String sniHostPrecedence = null;
         private boolean setAlways = false;
+        private final SSLParamConfiguratorConfiguration configConfiguration;
+
+        public Builder(SSLParamConfiguratorConfiguration configuration) {
+            this.configConfiguration = configuration;
+        }
 
 
         /**
@@ -61,7 +65,7 @@
          */
         public Builder request(ClientRequest clientRequest) {
             this.sniHostNameHeader = getSniHostNameHeader(clientRequest.getHeaders());
-            this.sniHostPrecedence = resolveSniHostNameProperty(clientRequest);
+            this.sniHostPrecedence = configConfiguration.resolveSniHostNameProperty(clientRequest);
             this.uri = clientRequest.getUri();
             return this;
         }
@@ -72,7 +76,7 @@
          * @return the builder instance
          */
         public Builder configuration(Configuration configuration) {
-            this.sniHostPrecedence = getSniHostNameProperty(configuration);
+            this.sniHostPrecedence = this.configConfiguration.getSniHostNameProperty(configuration);
             return this;
         }
 
@@ -141,7 +145,7 @@
          * @return the builder instance.
          */
         public Builder setSNIHostName(Configuration configuration) {
-            return setSNIHostName(getSniHostNameProperty(configuration));
+            return setSNIHostName(this.configConfiguration.getSniHostNameProperty(configuration));
         }
 
         /**
@@ -160,7 +164,7 @@
          * @return the builder instance.
          */
         public Builder setSNIHostName(PropertiesResolver resolver) {
-            return setSNIHostName(resolveSniHostNameProperty(resolver));
+            return setSNIHostName(configConfiguration.resolveSniHostNameProperty(resolver));
         }
 
         /**
@@ -180,22 +184,6 @@
             final String hostHeader = hostHeaders.get(0).toString();
             return hostHeader;
         }
-
-        private static String resolveSniHostNameProperty(PropertiesResolver resolver) {
-            String property = resolver.resolveProperty(ClientProperties.SNI_HOST_NAME, String.class);
-            if (property == null) {
-                property = resolver.resolveProperty(ClientProperties.SNI_HOST_NAME.toLowerCase(Locale.ROOT), String.class);
-            }
-            return property;
-        }
-
-        private static String getSniHostNameProperty(Configuration configuration) {
-            Object property = configuration.getProperty(ClientProperties.SNI_HOST_NAME);
-            if (property == null) {
-                property = configuration.getProperty(ClientProperties.SNI_HOST_NAME.toLowerCase(Locale.ROOT));
-            }
-            return (String) property;
-        }
     }
 
     private SSLParamConfigurator(SSLParamConfigurator.Builder builder) {
@@ -212,7 +200,14 @@
      * Create a new instance of TlsSupport class
      **/
     public static SSLParamConfigurator.Builder builder() {
-        return new SSLParamConfigurator.Builder();
+        return new SSLParamConfigurator.Builder(DEFAULT_CONFIGURATION);
+    }
+
+    /**
+     * Create a new instance of TlsSupport class
+     **/
+    public static SSLParamConfigurator.Builder builder(SSLParamConfiguratorConfiguration configuration) {
+        return new SSLParamConfigurator.Builder(configuration);
     }
 
     /**
@@ -290,4 +285,25 @@
         sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
         sslEngine.setSSLParameters(sslParameters);
     }
+
+    public static interface SSLParamConfiguratorConfiguration {
+        public default String getSniHostNameProperty(Configuration configuration) {
+            Object property = configuration.getProperty(ClientProperties.SNI_HOST_NAME);
+            if (property == null) {
+                property = configuration.getProperty(ClientProperties.SNI_HOST_NAME.toLowerCase(Locale.ROOT));
+            }
+            return (String) property;
+        }
+
+        public default String resolveSniHostNameProperty(PropertiesResolver resolver) {
+            String property = resolver.resolveProperty(ClientProperties.SNI_HOST_NAME, String.class);
+            if (property == null) {
+                property = resolver.resolveProperty(ClientProperties.SNI_HOST_NAME.toLowerCase(Locale.ROOT), String.class);
+            }
+            return property;
+        }
+    }
+
+    private static final SSLParamConfiguratorConfiguration DEFAULT_CONFIGURATION = new SSLParamConfiguratorConfiguration() {
+    };
 }
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java
index 630cb96..e1fd816 100644
--- a/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -52,6 +52,7 @@
 import javax.net.ssl.SSLSocketFactory;
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.Configuration;
 import jakarta.ws.rs.core.MultivaluedMap;
 import jakarta.ws.rs.core.Response;
 
@@ -81,7 +82,6 @@
 public class HttpUrlConnector implements Connector {
 
     private static final Logger LOGGER = Logger.getLogger(HttpUrlConnector.class.getName());
-    private static final String ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY = "sun.net.http.allowRestrictedHeaders";
     // Avoid multi-thread uses of HttpsURLConnection.getDefaultSSLSocketFactory() because it does not implement a
     // proper lazy-initialization. See https://github.com/jersey/jersey/issues/3293
     private static final LazyValue<SSLSocketFactory> DEFAULT_SSL_SOCKET_FACTORY =
@@ -110,11 +110,7 @@
         }
     }
 
-    private final HttpUrlConnectorProvider.ConnectionFactory connectionFactory;
-    private final int chunkSize;
-    private final boolean fixLengthStreaming;
-    private final boolean setMethodWorkaround;
-    private final boolean isRestrictedHeaderPropertySet;
+    private final HttpUrlConnectorConfiguration.ReadWrite clientConfig;
     private Value<SSLSocketFactory> sslSocketFactory;
 
     // SSLContext#getSocketFactory not idempotent
@@ -131,7 +127,7 @@
      * @param client              JAX-RS client instance for which the connector is being created.
      * @param connectionFactory   {@link javax.net.ssl.HttpsURLConnection} factory to be used when creating connections.
      * @param chunkSize           chunk size to use when using HTTP chunked transfer coding.
-     * @param fixLengthStreaming  specify if the the {@link java.net.HttpURLConnection#setFixedLengthStreamingMode(int)
+     * @param fixLengthStreaming  specify if the {@link java.net.HttpURLConnection#setFixedLengthStreamingMode(int)
      *                            fixed-length streaming mode} on the underlying HTTP URL connection instances should be
      *                            used when sending requests.
      * @param setMethodWorkaround specify if the reflection workaround should be used to set HTTP URL connection method
@@ -144,29 +140,23 @@
             final boolean fixLengthStreaming,
             final boolean setMethodWorkaround) {
 
-        this.connectionFactory = connectionFactory;
-        this.chunkSize = chunkSize;
-        this.fixLengthStreaming = fixLengthStreaming;
-        this.setMethodWorkaround = setMethodWorkaround;
+        this(client, client.getConfiguration(),
+                HttpUrlConnectorProvider.config()
+                    .connectionFactory(connectionFactory)
+                    .chunkSize(chunkSize)
+                    .useFixedLengthStreaming(fixLengthStreaming)
+                    .useSetMethodWorkaround(setMethodWorkaround)
+        );
+    }
 
+    public HttpUrlConnector(Client client, Configuration configuration, HttpUrlConnectorConfiguration<?> config) {
+        this.clientConfig = config.rw().fromClient(configuration);
         this.sslSocketFactory = Values.lazy(new Value<SSLSocketFactory>() {
             @Override
             public SSLSocketFactory get() {
                 return client.getSslContext().getSocketFactory();
             }
         });
-
-        // check if sun.net.http.allowRestrictedHeaders system property has been set and log the result
-        // the property is being cached in the HttpURLConnection, so this is only informative - there might
-        // already be some connection(s), that existed before the property was set/changed.
-        isRestrictedHeaderPropertySet = Boolean.valueOf(AccessController.doPrivileged(
-                PropertiesHelper.getSystemProperty(ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY, "false")
-        ));
-
-        LOGGER.config(isRestrictedHeaderPropertySet
-                        ? LocalizationMessages.RESTRICTED_HEADER_PROPERTY_SETTING_TRUE(ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY)
-                        : LocalizationMessages.RESTRICTED_HEADER_PROPERTY_SETTING_FALSE(ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY)
-        );
     }
 
     private static InputStream getInputStream(final HttpURLConnection uc, final ClientRequest clientRequest) throws IOException {
@@ -342,9 +332,15 @@
      * @param clientRequest the actual client request.
      * @param uc     http connection to be secured.
      */
-    private void secureConnection(
-            final ClientRequest clientRequest, final HttpURLConnection uc, final SSLParamConfigurator sniConfig) {
-        setSslContextFactory(clientRequest.getClient(), clientRequest);
+    private void secureConnection(final ClientRequest clientRequest,
+                                  final HttpURLConnection uc,
+                                  final SSLParamConfigurator sniConfig,
+                                  final HttpUrlConnectorConfiguration.ReadWrite config) {
+        if (config.isSslContextSupplier() || config.isPrefixed()) {
+            setSslContextFactory(clientRequest.getClient(), clientRequest, config.sslContext(clientRequest));
+        } else {
+            setSslContextFactory(clientRequest.getClient(), clientRequest);
+        }
         secureConnection(clientRequest.getClient(), uc); // keep this for compatibility
 
         if (sniConfig.isSNIRequired() && uc instanceof HttpsURLConnection) { // set SNI
@@ -355,9 +351,17 @@
         }
     }
 
+    @Deprecated
     protected void setSslContextFactory(Client client, ClientRequest request) {
-        final Supplier<SSLContext> supplier = request.resolveProperty(ClientProperties.SSL_CONTEXT_SUPPLIER, Supplier.class);
+        setSslContextFactory(client, request, request.resolveProperty(ClientProperties.SSL_CONTEXT_SUPPLIER, Supplier.class));
+    }
 
+    protected void setSslContextFactory(Client client, ClientRequest request,
+                                        HttpUrlConnectorConfiguration.ReadWrite requestConfig) {
+        setSslContextFactory(client, request, requestConfig.sslContext(request));
+    }
+
+    private void setSslContextFactory(Client client, ClientRequest request, Supplier<SSLContext> supplier) {
         if (supplier != null) {
             sslSocketFactory = Values.lazy(new Value<SSLSocketFactory>() { // lazy for double-check locking if multiple requests
                 @Override
@@ -375,9 +379,10 @@
     }
 
     private ClientResponse _apply(final ClientRequest request) throws IOException {
+        HttpUrlConnectorConfiguration.ReadWrite requestConfiguration = clientConfig.fromRequest(request);
+
         final HttpURLConnection uc;
-        final Optional<ClientProxy> proxy = ClientProxy.proxyFromRequest(request);
-        final SSLParamConfigurator sniConfig = SSLParamConfigurator.builder().request(request)
+        final SSLParamConfigurator sniConfig = SSLParamConfigurator.builder(requestConfiguration).request(request)
                 .setSNIHostName(request).build();
         final URI sniUri;
         if (sniConfig.isSNIRequired()) {
@@ -391,39 +396,45 @@
             DEFAULT_SSL_SOCKET_FACTORY.get();
         }
 
+        final Optional<ClientProxy> proxy = requestConfiguration.proxy(request, sniUri);
         proxy.ifPresent(clientProxy -> ClientProxy.setBasicAuthorizationHeader(request.getHeaders(), proxy.get()));
-        uc = this.connectionFactory.getConnection(sniUri.toURL(), proxy.isPresent() ? proxy.get().proxy() : null);
+        uc = ((Supplier<HttpUrlConnectorProvider.ConnectionFactory>) requestConfiguration.connectionFactory)
+                .get().getConnection(sniUri.toURL(), proxy.isPresent() ? proxy.get().proxy() : null);
         uc.setDoInput(true);
 
         final String httpMethod = request.getMethod();
-        if (request.resolveProperty(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, setMethodWorkaround)) {
+        if (requestConfiguration.isMethodWorkaround(request)) {
             setRequestMethodViaJreBugWorkaround(uc, httpMethod);
         } else {
             uc.setRequestMethod(httpMethod);
         }
 
-        uc.setInstanceFollowRedirects(request.resolveProperty(ClientProperties.FOLLOW_REDIRECTS, true));
+        uc.setInstanceFollowRedirects(requestConfiguration.followRedirects(request));
 
-        uc.setConnectTimeout(request.resolveProperty(ClientProperties.CONNECT_TIMEOUT, uc.getConnectTimeout()));
+        if (requestConfiguration.connectTimeout() == 0) {
+            requestConfiguration.connectTimeout(uc.getConnectTimeout());
+        }
+        uc.setConnectTimeout(requestConfiguration.connectTimeout(request));
 
-        uc.setReadTimeout(request.resolveProperty(ClientProperties.READ_TIMEOUT, uc.getReadTimeout()));
+        if (requestConfiguration.readTimeout() == 0) {
+            requestConfiguration.readTimeout(uc.getReadTimeout());
+        }
+        uc.setReadTimeout(requestConfiguration.readTimeout(request).readTimeout());
 
-        secureConnection(request, uc, sniConfig);
+        secureConnection(request, uc, sniConfig, requestConfiguration);
 
         final Object entity = request.getEntity();
         Exception storedException = null;
         try {
             if (entity != null) {
-                RequestEntityProcessing entityProcessing = request.resolveProperty(
-                        ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.class);
-
+                RequestEntityProcessing entityProcessing = requestConfiguration.requestEntityProcessing(request);
                 final long length = request.getLengthLong();
 
-                if (entityProcessing == null || entityProcessing != RequestEntityProcessing.BUFFERED) {
-                    if (fixLengthStreaming && length > 0) {
+                if (entityProcessing != RequestEntityProcessing.BUFFERED) {
+                    if (requestConfiguration.useFixedLengthStreaming.get() && length > 0) {
                         uc.setFixedLengthStreamingMode(length);
                     } else if (entityProcessing == RequestEntityProcessing.CHUNKED) {
-                        uc.setChunkedStreamingMode(chunkSize);
+                        uc.setChunkedStreamingMode(requestConfiguration.chunkSize.get());
                     }
                 }
                 uc.setDoOutput(true);
@@ -438,13 +449,13 @@
                 processExtensions(request, uc);
 
                 request.setStreamProvider(contentLength -> {
-                    setOutboundHeaders(request.getStringHeaders(), uc);
+                    setOutboundHeaders(request.getStringHeaders(), uc, requestConfiguration);
                     return uc.getOutputStream();
                 });
                 request.writeEntity();
 
             } else {
-                setOutboundHeaders(request.getStringHeaders(), uc);
+                setOutboundHeaders(request.getStringHeaders(), uc, requestConfiguration);
             }
         } catch (IOException ioe) {
             storedException = handleException(request, ioe, uc);
@@ -496,7 +507,9 @@
         return responseContext;
     }
 
-    private void setOutboundHeaders(MultivaluedMap<String, String> headers, HttpURLConnection uc) {
+    private void setOutboundHeaders(MultivaluedMap<String, String> headers,
+                                    HttpURLConnection uc,
+                                    HttpUrlConnectorConfiguration.ReadWrite requestConfiguration) {
         boolean restrictedSent = false;
         for (Map.Entry<String, List<String>> header : headers.entrySet()) {
             String headerName = header.getKey();
@@ -520,14 +533,15 @@
                 uc.setRequestProperty(headerName, headerValue);
             }
             // if (at least one) restricted header was added and the allowRestrictedHeaders
-            if (!isRestrictedHeaderPropertySet && !restrictedSent) {
+            if (!requestConfiguration.isRestrictedHeaderPropertySet.get() && !restrictedSent) {
                 if (isHeaderRestricted(headerName, headerValue)) {
                     restrictedSent = true;
                 }
             }
         }
         if (restrictedSent) {
-            LOGGER.warning(LocalizationMessages.RESTRICTED_HEADER_POSSIBLY_IGNORED(ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY));
+            LOGGER.warning(LocalizationMessages.RESTRICTED_HEADER_POSSIBLY_IGNORED(
+                    HttpUrlConnectorConfiguration.ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY));
         }
     }
 
@@ -635,7 +649,7 @@
 
     private static class SniSSLSocketFactory extends SSLSocketFactory {
         private final SSLSocketFactory socketFactory;
-        private ThreadLocal<SSLParamConfigurator> sniConfigs = new ThreadLocal<>();
+        private final ThreadLocal<SSLParamConfigurator> sniConfigs = new ThreadLocal<>();
 
         public void setSniConfig(SSLParamConfigurator sniConfigs) {
             this.sniConfigs.set(sniConfigs);
diff --git a/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnectorConfiguration.java b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnectorConfiguration.java
new file mode 100644
index 0000000..20c31f7
--- /dev/null
+++ b/core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnectorConfiguration.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client.internal;
+
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientRequest;
+import org.glassfish.jersey.client.HttpUrlConnectorProvider;
+import org.glassfish.jersey.client.innate.ConnectorConfiguration;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.internal.util.collection.Ref;
+
+import javax.net.ssl.SSLContext;
+import jakarta.ws.rs.core.Configuration;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.Proxy;
+import java.net.URL;
+import java.security.AccessController;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Supplier;
+import java.util.logging.Logger;
+
+public abstract class HttpUrlConnectorConfiguration<C extends HttpUrlConnectorConfiguration<C>>
+        extends ConnectorConfiguration<C> {
+    private static final Logger LOGGER = Logger.getLogger(HttpUrlConnectorConfiguration.class.getName());
+    /* package */ static final String ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY = "sun.net.http.allowRestrictedHeaders";
+    /**
+     * Default connection factory to be used.
+     */
+    protected static final HttpUrlConnectorProvider.ConnectionFactory DEFAULT_CONNECTION_FACTORY =
+            new DefaultConnectionFactory();
+
+    protected NullableRef<HttpUrlConnectorProvider.ConnectionFactory> connectionFactory = NullableRef.empty();
+    protected Ref<Integer> chunkSize = NullableRef.empty();
+    /* package */ Ref<Boolean> isRestrictedHeaderPropertySet = NullableRef.empty();
+    protected Ref<Boolean> useFixedLengthStreaming = NullableRef.empty();
+    protected Ref<Boolean> useSetMethodWorkaround = NullableRef.empty();
+
+    protected void preInit(Map<String, Object> properties) {
+        connectionFactory.ifEmptySet(DEFAULT_CONNECTION_FACTORY);
+        ((NullableRef<Integer>) chunkSize).ifEmptySet(ClientProperties.DEFAULT_CHUNK_SIZE);
+        ((NullableRef<Boolean>) useFixedLengthStreaming).ifEmptySet(Boolean.FALSE);
+        ((NullableRef<Boolean>) useSetMethodWorkaround).ifEmptySet(Boolean.FALSE);
+
+        int computedChunkSize = ClientProperties.getValue(properties,
+                _prefixed(ClientProperties.CHUNKED_ENCODING_SIZE), chunkSize.get(), Integer.class);
+        if (computedChunkSize < 0) {
+            LOGGER.warning(LocalizationMessages.NEGATIVE_CHUNK_SIZE(computedChunkSize, chunkSize.get()));
+        } else {
+            chunkSize.set(computedChunkSize);
+        }
+
+        useFixedLengthStreaming(ClientProperties.getValue(properties,
+                _prefixed(HttpUrlConnectorProvider.USE_FIXED_LENGTH_STREAMING),
+                useFixedLengthStreaming.get(), Boolean.class));
+        useSetMethodWorkaround(ClientProperties.getValue(properties,
+                _prefixed(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND),
+                useSetMethodWorkaround.get(), Boolean.class));
+    }
+
+    private String _prefixed(String property) {
+        return prefix.ifPresentOrElse("") + property;
+    }
+
+    /**
+     * Set a custom {@link java.net.HttpURLConnection} factory.
+     *
+     * @param connectionFactory custom HTTP URL connection factory. Must not be {@code null}.
+     * @return updated configuration.
+     * @throws java.lang.NullPointerException in case the supplied connectionFactory is {@code null}.
+     */
+    public C connectionFactory(final HttpUrlConnectorProvider.ConnectionFactory connectionFactory) {
+        if (connectionFactory == null) {
+            throw new NullPointerException(LocalizationMessages.NULL_INPUT_PARAMETER("connectionFactory"));
+        }
+
+        this.connectionFactory.set(connectionFactory);
+        return self();
+    }
+
+    /**
+     * Set chunk size for requests transferred using a
+     * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1">HTTP chunked transfer coding</a>.
+     *
+     * If no value is set, the default chunk size of 4096 bytes will be used.
+     * <p>
+     * Note that this programmatically set value can be overridden by
+     * setting the {@link org.glassfish.jersey.client.ClientProperties#CHUNKED_ENCODING_SIZE} property
+     * specified in the Jersey client instance configuration.
+     * </p>
+     *
+     * @param chunkSize chunked transfer coding chunk size to be used.
+     * @return updated configuration.
+     * @throws java.lang.IllegalArgumentException in case the specified chunk size is negative.
+     */
+    public C chunkSize(final int chunkSize) {
+        if (chunkSize < 0) {
+            throw new IllegalArgumentException(LocalizationMessages.NEGATIVE_INPUT_PARAMETER("chunkSize"));
+        }
+        this.chunkSize.set(chunkSize);
+        return self();
+    }
+
+    /**
+     * Instruct the provided connectors to use the {@link java.net.HttpURLConnection#setFixedLengthStreamingMode(int)
+     * fixed-length streaming mode} on the underlying HTTP URL connection instance when sending requests.
+     * See {@link HttpUrlConnectorProvider#USE_FIXED_LENGTH_STREAMING} property documentation for more details.
+     * <p>
+     * Note that this programmatically set value can be overridden by
+     * setting the {@code USE_FIXED_LENGTH_STREAMING} property specified in the Jersey client instance configuration.
+     * </p>
+     *
+     * @return updated configuration.
+     */
+    public C useFixedLengthStreaming(boolean use) {
+        this.useFixedLengthStreaming.set(use);
+        return self();
+    }
+
+    /**
+     * Instruct the provided connectors to use reflection when setting the
+     * HTTP method value. See {@link HttpUrlConnectorProvider#SET_METHOD_WORKAROUND} property documentation for more details.
+     * <p>
+     * Note that this programmatically set value can be overridden by
+     * setting the {@code SET_METHOD_WORKAROUND} property specified in the Jersey client instance configuration
+     * or in the request properties.
+     * </p>
+     *
+     * @return updated configuration.
+     */
+    public C useSetMethodWorkaround(boolean use) {
+        this.useSetMethodWorkaround.set(use);
+        return self();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        final HttpUrlConnectorConfiguration<?> that = (HttpUrlConnectorConfiguration<?>) o;
+
+        if (!chunkSize.equals(that.chunkSize)) {
+            return false;
+        }
+        if (!useFixedLengthStreaming.equals(that.useFixedLengthStreaming)) {
+            return false;
+        }
+        if (!useSetMethodWorkaround.equals(that.useSetMethodWorkaround)) {
+            return false;
+        }
+        if (!isRestrictedHeaderPropertySet.equals(that.isRestrictedHeaderPropertySet)) {
+            return false;
+        }
+
+        return connectionFactory.equals(that.connectionFactory);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(connectionFactory, chunkSize, useFixedLengthStreaming,
+                useSetMethodWorkaround, isRestrictedHeaderPropertySet);
+    }
+
+    /* package */ ReadWrite rw() {
+        final ReadWrite readWrite = this instanceof ReadWrite ? ((ReadWrite) this).instance() : new ReadWrite();
+        readWrite.setNonEmpty(this);
+        return readWrite;
+    }
+
+    protected static class ReadWrite
+        extends HttpUrlConnectorConfiguration<ReadWrite>
+        implements ConnectorConfiguration.Read<ReadWrite> {
+
+        @Override
+        public <X extends ConnectorConfiguration<?>> void setNonEmpty(X otherC) {
+            HttpUrlConnectorConfiguration<?> other = (HttpUrlConnectorConfiguration<?>) otherC;
+            Read.super.setNonEmpty(other);
+
+            this.connectionFactory.setNonEmpty(other.connectionFactory);
+            ((NullableRef<Integer>) this.chunkSize).setNonEmpty((NullableRef<Integer>) other.chunkSize);
+            ((NullableRef<Boolean>) this.isRestrictedHeaderPropertySet).setNonEmpty(
+                    (NullableRef<Boolean>) other.isRestrictedHeaderPropertySet);
+            ((NullableRef<Boolean>) this.useFixedLengthStreaming).setNonEmpty(
+                    (NullableRef<Boolean>) other.useFixedLengthStreaming);
+            ((NullableRef<Boolean>) this.useSetMethodWorkaround).setNonEmpty((NullableRef<Boolean>) other.useSetMethodWorkaround);
+        }
+
+        @Override
+        public ReadWrite init() {
+            ConnectorConfiguration.Read.super.init();
+            preInit(Collections.emptyMap());
+            isRestrictedHeaderPropertySet.set(Boolean.FALSE);
+            return self();
+        }
+
+        ReadWrite fromClient(Configuration configuration) {
+            ReadWrite clientConfiguration = copyFromClient(configuration);
+            clientConfiguration.preInit(configuration.getProperties());
+
+            // check if sun.net.http.allowRestrictedHeaders system property has been set and log the result
+            // the property is being cached in the HttpURLConnection, so this is only informative - there might
+            // already be some connection(s), that existed before the property was set/changed.
+            isRestrictedHeaderPropertySet.set(Boolean.valueOf(AccessController.doPrivileged(
+                    PropertiesHelper.getSystemProperty(ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY, "false")
+            )));
+
+            LOGGER.config(isRestrictedHeaderPropertySet.get()
+                    ? LocalizationMessages.RESTRICTED_HEADER_PROPERTY_SETTING_TRUE(ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY)
+                    : LocalizationMessages.RESTRICTED_HEADER_PROPERTY_SETTING_FALSE(ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY)
+            );
+
+            return clientConfiguration;
+        }
+
+        ReadWrite fromRequest(ClientRequest request) {
+            ReadWrite requestConfiguration = copyFromRequest(request);
+            requestConfiguration.chunkSize(
+                    request.resolveProperty(prefixed(ClientProperties.CHUNKED_ENCODING_SIZE),
+                                            requestConfiguration.chunkSize.get()));
+            requestConfiguration.useFixedLengthStreaming(
+                    request.resolveProperty(prefixed(HttpUrlConnectorProvider.USE_FIXED_LENGTH_STREAMING),
+                                            requestConfiguration.useFixedLengthStreaming.get()));
+            requestConfiguration.useSetMethodWorkaround(
+                    request.resolveProperty(prefixed(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND),
+                                            requestConfiguration.useSetMethodWorkaround.get()));
+
+            return requestConfiguration;
+        }
+
+        @Override
+        public ReadWrite instance() {
+            return new ReadWrite();
+        }
+
+        @Override
+        public ReadWrite me() {
+            return this;
+        }
+
+        public boolean isMethodWorkaround(ClientRequest request) {
+            return request.resolveProperty(
+                    prefixed(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND), useSetMethodWorkaround.get());
+        }
+
+        public boolean isPrefixed() {
+            return !prefix.get().isEmpty();
+        }
+
+        public boolean isSslContextSupplier() {
+            return sslContextSupplier.get() != null;
+        }
+
+        /**
+         * Get {@link SSLContext} either from the {@link ClientProperties#SSL_CONTEXT_SUPPLIER}, or from this configuration.
+         *
+         * @param request the request used to get the {@link SSLContext}.
+         * @return the {@link SSLContext} supplier.
+         */
+        public Supplier<SSLContext> sslContext(ClientRequest request) {
+            @SuppressWarnings("unchecked")
+            Supplier<SSLContext> supplier =
+                    request.resolveProperty(prefixed(ClientProperties.SSL_CONTEXT_SUPPLIER), Supplier.class);
+            if (supplier == null) {
+                supplier = self().sslContextSupplier.get();
+            }
+            return supplier;
+        }
+
+        @Override
+        public ReadWrite self() {
+            return this;
+        }
+    }
+
+    private static class DefaultConnectionFactory implements HttpUrlConnectorProvider.ConnectionFactory {
+
+        @Override
+        public HttpURLConnection getConnection(final URL url) throws IOException {
+            return connect(url, null);
+        }
+
+        @Override
+        public HttpURLConnection getConnection(URL url, Proxy proxy) throws IOException {
+            return connect(url, proxy);
+        }
+
+        private HttpURLConnection connect(URL url, Proxy proxy) throws IOException {
+            return (proxy == null) ? (HttpURLConnection) url.openConnection() : (HttpURLConnection) url.openConnection(proxy);
+        }
+    }
+}
diff --git a/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java b/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java
index ae487bf..9557c29 100644
--- a/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java
+++ b/core-client/src/test/java/org/glassfish/jersey/client/AbortTest.java
@@ -51,6 +51,7 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -222,6 +223,43 @@
         }
     }
 
+    @Test
+    public void testResponseContextCaseInsensitiveKeys() {
+        try (Response response = ClientBuilder.newClient()
+                .register(new ClientRequestFilter() {
+                    @Override
+                    public void filter(ClientRequestContext requestContext) throws IOException {
+                        requestContext.abortWith(Response.ok()
+                                .header("header1", "value")
+                                .header("header1", "value1 , value2")
+                                .header("header1", "Value3,white space ")
+                                .header("header2", "Value4;;Value5")
+                                .build());
+                    }
+                })
+                .register(new ClientResponseFilter() {
+                    @Override
+                    public void filter(ClientRequestContext requestContext, ClientResponseContext context) {
+                        Assertions.assertTrue(context.getHeaderString("header1").contains("value"));
+                        Assertions.assertTrue(context.getHeaderString("HEADER1").contains("value2"));
+                        //White space in value not trimmed
+                        Assertions.assertFalse(context.getHeaderString("header1").contains("whitespace"));
+                        //Multiple character separator
+                        Assertions.assertTrue(context.getHeaderString("header2").contains("Value5"));
+
+                        Assertions.assertTrue(context.getHeaders().containsKey("HEADer1"));
+                        Assertions.assertFalse(context.getHeaders().get("HEADer1").isEmpty());
+                        Assertions.assertFalse(context.getHeaders().remove("HeAdEr1").isEmpty());
+                        Assertions.assertFalse(context.getHeaders().containsKey("header1"));
+                    }
+                })
+                .target("http://localhost:8080")
+                .request()
+                .get()) {
+            Assertions.assertEquals(200, response.getStatus());
+        }
+    }
+
     private static class StringHeader extends AtomicReference<String> {
 
     }
diff --git a/core-client/src/test/java/org/glassfish/jersey/client/HttpUrlConnectorConfigurationTest.java b/core-client/src/test/java/org/glassfish/jersey/client/HttpUrlConnectorConfigurationTest.java
new file mode 100644
index 0000000..5e31e48
--- /dev/null
+++ b/core-client/src/test/java/org/glassfish/jersey/client/HttpUrlConnectorConfigurationTest.java
@@ -0,0 +1,793 @@
+/*
+ * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.client;
+
+import org.glassfish.jersey.client.innate.ClientProxy;
+import org.glassfish.jersey.client.innate.ConnectorConfiguration;
+import org.glassfish.jersey.client.internal.HttpUrlConnector;
+import org.glassfish.jersey.client.internal.HttpUrlConnectorConfiguration;
+import org.glassfish.jersey.http.HttpHeaders;
+import org.glassfish.jersey.internal.MapPropertiesDelegate;
+import org.glassfish.jersey.internal.util.JdkVersion;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import javax.net.ssl.SSLContext;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.core.MultivaluedMap;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
+import java.net.ProtocolException;
+import java.net.URI;
+import java.net.URL;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+public class HttpUrlConnectorConfigurationTest {
+
+    public static final String PREFIX = "test.";
+
+    @Test
+    public void testConnectTimeout() {
+        final AtomicInteger result = new AtomicInteger(0);
+        class RWConnect extends Conf.RW {
+            @Override
+            public int connectTimeout(ClientRequest request) {
+                result.set(super.connectTimeout(request));
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public RWConnect instance() {
+                return new RWConnect();
+            }
+
+        }
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000)).request().apply();
+        Assertions.assertEquals(1000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECT_TIMEOUT, 3000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
+                .request().apply();
+        Assertions.assertEquals(3000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECT_TIMEOUT, 3000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWConnect().connectTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(3000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWConnect().connectTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(4000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWConnect().connectTimeout(4000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECT_TIMEOUT, 5000))
+                .apply();
+        Assertions.assertEquals(5000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000).prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().connectTimeout(2000).prefix(PREFIX)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWConnect().connectTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(0);
+        new TestClient(new RWConnect()).rw(rw -> rw.connectTimeout(1000).prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWConnect().connectTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().connectTimeout(4000).prefix(PREFIX)))
+                .request(r -> r.setProperty(ClientProperties.CONNECT_TIMEOUT, 5000))
+                .apply();
+        Assertions.assertEquals(4000, result.get());
+    }
+
+    @Test
+    public void testFollowRedirects() {
+        final AtomicReference<Boolean> result = new AtomicReference<>();
+        class RWFollow extends Conf.RW {
+
+            @Override
+            public boolean followRedirects(ClientRequest request) {
+                result.set(super.followRedirects(request));
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public RWFollow instance() {
+                return new RWFollow();
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWFollow()).request().apply();
+        Assertions.assertEquals(((RWFollow) new RWFollow().copy()).followRedirects(), result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFollow().followRedirects(false)).request().apply();
+        Assertions.assertEquals(false, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFollow().prefix(PREFIX).followRedirects(false))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.FOLLOW_REDIRECTS, true))
+                .apply();
+        Assertions.assertEquals(true, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFollow().prefix(PREFIX).followRedirects(false))
+                .request(r -> r.setProperty(
+                        PREFIX + ClientProperties.CONNECTOR_CONFIGURATION, new RWFollow().followRedirects(true)))
+                .apply();
+        Assertions.assertEquals(true, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFollow())
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWFollow().followRedirects(false)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWFollow().followRedirects(true)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(true, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWFollow().prefix(PREFIX))
+                .client(c -> c.property(PREFIX + ClientProperties.FOLLOW_REDIRECTS, false))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWFollow().followRedirects(true)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(false, result.get());
+    }
+
+    @Test
+    public void testProxy() {
+        final AtomicReference<ClientProxy> result = new AtomicReference<>();
+        class RWProxy extends Conf.RW {
+
+            @Override
+            public Optional<ClientProxy> proxy(ClientRequest request, URI requestUri) {
+                Optional<ClientProxy> proxy = super.proxy(request, requestUri);
+                result.set(proxy.orElse(null));
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public RWProxy instance() {
+                return new RWProxy();
+            }
+        }
+        String proxyUri = "http://proxy.org:8080";
+        String userName = "USERNAME";
+        String password = "PASSWORD";
+
+        new TestClient(new RWProxy()).request().apply();
+        Assertions.assertNull(result.get());
+
+        result.set(null);
+        new TestClient(new RWProxy()).rw(rw -> rw.proxyUri(proxyUri).proxyUserName(userName).proxyPassword(password))
+                .request().apply();
+        Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
+        Assertions.assertEquals(userName, result.get().userName());
+        Assertions.assertEquals(password, result.get().password());
+
+        result.set(null);
+        new TestClient(new RWProxy()).rw(rw -> rw.prefix(PREFIX).proxyUri(proxyUri).proxyUserName("XXX").proxyPassword(password))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.PROXY_USERNAME, userName))
+                .request(r -> r.setProperty(ClientProperties.PROXY_PASSWORD, "XXX"))
+                .apply();
+        Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
+        Assertions.assertEquals(userName, result.get().userName());
+        Assertions.assertEquals(password, result.get().password());
+
+        result.set(null);
+        new TestClient(new RWProxy()).rw(rw -> rw.prefix(PREFIX).proxyUri(proxyUri).proxyUserName("XXX").proxyPassword(password))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().proxyUserName(userName).proxyPassword(null)))
+                .apply();
+        Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
+        Assertions.assertEquals(userName, result.get().userName());
+        Assertions.assertNull(result.get().password());
+
+        result.set(null);
+        new TestClient(new RWProxy().prefix(PREFIX)
+                .proxy(new java.net.Proxy(java.net.Proxy.Type.HTTP,
+                        new InetSocketAddress(proxyUri.split("g:")[0] + "g", Integer.parseInt(proxyUri.split("g:")[1])))))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().proxyUserName(userName).proxyPassword(password).prefix(PREFIX)))
+                .apply();
+        Assertions.assertEquals(proxyUri, result.get().uri().toASCIIString());
+        Assertions.assertEquals(userName, result.get().userName());
+        Assertions.assertEquals(password, result.get().password());
+    }
+
+    @Test
+    public void testReadTimeout() {
+        final AtomicInteger result = new AtomicInteger(0);
+        class RWRead extends Conf.RW {
+
+            @Override
+            public RWRead readTimeout(ClientRequest clientRequest) {
+                super.readTimeout(clientRequest);
+                result.set(readTimeout());
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public RWRead instance() {
+                return new RWRead();
+            }
+        }
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000)).request().apply();
+        Assertions.assertEquals(1000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
+                .client(c -> c.property(ClientProperties.READ_TIMEOUT, 3000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
+                .request().apply();
+        Assertions.assertEquals(3000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
+                .client(c -> c.property(ClientProperties.READ_TIMEOUT, 3000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().connectTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(3000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(4000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(4000)))
+                .request(r -> r.setProperty(ClientProperties.READ_TIMEOUT, 5000))
+                .apply();
+        Assertions.assertEquals(5000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000).prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().readTimeout(2000).prefix(PREFIX)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWRead().readTimeout(4000)))
+                .apply();
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(0);
+        new TestClient(new RWRead()).rw(rw -> rw.readTimeout(1000).prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION, new RWRead().readTimeout(2000)))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().readTimeout(4000).prefix(PREFIX)))
+                .request(r -> r.setProperty(ClientProperties.READ_TIMEOUT, 5000))
+                .apply();
+        Assertions.assertEquals(4000, result.get());
+    }
+
+    @Test
+    public void testRequestEntityProcessing() {
+        final AtomicReference<RequestEntityProcessing> result = new AtomicReference<>();
+        final AtomicReference<Conf.RW> config = new AtomicReference<>();
+        class RWRP extends Conf.RW {
+
+            @Override
+            public RequestEntityProcessing requestEntityProcessing(ClientRequest request) {
+                result.set(super.requestEntityProcessing(request));
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public RWRP instance() {
+                config.set(new RWRP());
+                return (RWRP) config.get();
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWRP().requestEntityProcessing(RequestEntityProcessing.CHUNKED))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(RequestEntityProcessing.CHUNKED, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWRP().prefix(PREFIX).requestEntityProcessing(RequestEntityProcessing.CHUNKED))
+                .request(r -> r.setEntity(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config()
+                                .requestEntityProcessing(RequestEntityProcessing.BUFFERED).prefix(PREFIX)))
+                .apply();
+        Assertions.assertEquals(RequestEntityProcessing.BUFFERED, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWRP().prefix(PREFIX).requestEntityProcessing(RequestEntityProcessing.CHUNKED))
+                .request(r -> r.setEntity(PREFIX))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.REQUEST_ENTITY_PROCESSING,
+                        RequestEntityProcessing.BUFFERED))
+                .apply();
+        Assertions.assertEquals(RequestEntityProcessing.BUFFERED, result.get());
+    }
+
+    @Test
+    public void testSslContext() {
+        final SSLContext testContext = new SSLContext(null, null, null){};
+        final AtomicReference<SSLContext> result = new AtomicReference<>();
+        final AtomicReference<Conf.RW> config = new AtomicReference<>();
+        class RWSsl extends Conf.RW {
+
+            @Override
+            public SSLContext sslContext(Client client, ClientRequest request) {
+                result.set(super.sslContext(client, request));
+                return result.get();
+            }
+
+            @Override
+            public boolean isSslContextSupplier() {
+                throw new IllegalStateException();
+            }
+
+            @Override
+            public RWSsl instance() {
+                RWSsl rw = new RWSsl();
+                config.set(rw);
+                return rw;
+            }
+        }
+
+        Request req;
+        req = new TestClient(new RWSsl().sslContextSupplier(() -> testContext)).request().apply();
+        config.get().sslContext(req.client, req.request);
+        Assertions.assertEquals(testContext, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSsl().prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.SSL_CONTEXT_SUPPLIER,
+                        (Supplier<SSLContext>) () -> testContext)).apply();
+        config.get().sslContext(req.client, req.request);
+        Assertions.assertEquals(testContext, result.get());
+
+        result.set(null);
+        req = new TestClient(new RWSsl().prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        new RWSsl().prefix(PREFIX).sslContextSupplier(() -> testContext))).apply();
+        config.get().sslContext(req.client, req.request);
+        Assertions.assertEquals(testContext, result.get());
+    }
+
+    @Test
+    public void testConnectionFactory() {
+        final AtomicReference<Boolean> result = new AtomicReference<>();
+        final HttpUrlConnectorProvider.ConnectionFactory connectionFactory = new HttpUrlConnectorProvider.ConnectionFactory() {
+            @Override
+            public HttpURLConnection getConnection(URL url) throws IOException {
+                result.set(true);
+                throw new IllegalStateException();
+            }
+        };
+
+        new TestClient(HttpUrlConnectorProvider.config().connectionFactory(connectionFactory)).request().apply();
+        Assertions.assertTrue(result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config().prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().connectionFactory(connectionFactory)))
+                .request().apply();
+        Assertions.assertNull(result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config().prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().connectionFactory(connectionFactory).prefix(PREFIX)))
+                .request().apply();
+        Assertions.assertTrue(result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config().prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().connectionFactory(connectionFactory).prefix(PREFIX)))
+                .apply();
+        Assertions.assertTrue(result.get());
+
+        result.set(null);
+        Client client = ClientBuilder.newClient();
+        try {
+            HttpUrlConnectorProvider.config().build()
+                    .connectionFactory(connectionFactory)
+                    .getConnector(client, client.getConfiguration()).apply(Request.createRequest(client));
+        } catch (IllegalStateException ise) {
+            // expected
+        }
+        Assertions.assertTrue(result.get());
+    }
+
+    @Test
+    public void testChunkSize() {
+        final AtomicReference<Integer> result = new AtomicReference<>();
+        final HttpUrlConnectorProvider.ConnectionFactory connectionFactory = new HttpUrlConnectorProvider.ConnectionFactory() {
+            @Override
+            public HttpURLConnection getConnection(URL url) throws IOException {
+                return new HttpURLConnection(url) {
+                    @Override
+                    public void disconnect() {
+
+                    }
+
+                    @Override
+                    public boolean usingProxy() {
+                        return false;
+                    }
+
+                    @Override
+                    public void connect() throws IOException {
+
+                    }
+
+                    @Override
+                    public void setChunkedStreamingMode(int chunklen) {
+                        result.set(chunklen);
+                        throw new IllegalStateException();
+                    }
+                };
+            }
+        };
+
+        new TestClient(HttpUrlConnectorProvider.config()
+                .requestEntityProcessing(RequestEntityProcessing.CHUNKED)
+                .connectionFactory(connectionFactory))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(ClientProperties.DEFAULT_CHUNK_SIZE, result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config()
+                .requestEntityProcessing(RequestEntityProcessing.CHUNKED)
+                .connectionFactory(connectionFactory)
+                .chunkSize(1000))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(1000, result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config()
+                .requestEntityProcessing(RequestEntityProcessing.CHUNKED)
+                .connectionFactory(connectionFactory)
+                .chunkSize(1000)
+                .prefix(PREFIX))
+                .client(c -> c.property(PREFIX + ClientProperties.CHUNKED_ENCODING_SIZE, 2000))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config()
+                .requestEntityProcessing(RequestEntityProcessing.CHUNKED)
+                .connectionFactory(connectionFactory)
+                .chunkSize(1000)
+                .prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + ClientProperties.CHUNKED_ENCODING_SIZE, 2000))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config()
+                .requestEntityProcessing(RequestEntityProcessing.CHUNKED)
+                .connectionFactory(connectionFactory)
+                .chunkSize(1000)
+                .prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().chunkSize(2000).prefix(PREFIX)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(2000, result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config()
+                .requestEntityProcessing(RequestEntityProcessing.CHUNKED)
+                .connectionFactory(connectionFactory)
+                .chunkSize(1000)
+                .prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().chunkSize(2000).prefix(PREFIX)))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(2000, result.get());
+    }
+
+    @Test
+    public void testUseFixedLengthStreaming() {
+        final AtomicReference<Integer> result = new AtomicReference<>();
+        final class FixedLengthStreamingUrlConnection extends HttpURLConnection {
+            private FixedLengthStreamingUrlConnection(URL u) {
+                super(u);
+            }
+
+            @Override
+            public void disconnect() {
+
+            }
+
+            @Override
+            public boolean usingProxy() {
+                return false;
+            }
+
+            @Override
+            public void connect() throws IOException {
+
+            }
+
+            @Override
+            public void setFixedLengthStreamingMode(long contentLength) {
+                super.setFixedLengthStreamingMode(contentLength);
+                result.set((int) contentLength);
+                throw new IllegalStateException();
+            }
+        }
+        final HttpUrlConnectorProvider.ConnectionFactory connectionFactory = new HttpUrlConnectorProvider.ConnectionFactory() {
+            @Override
+            public HttpURLConnection getConnection(URL url) throws IOException {
+                return new FixedLengthStreamingUrlConnection(url);
+            }
+        };
+
+        new TestClient(HttpUrlConnectorProvider.config()
+                .connectionFactory(connectionFactory))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.CONTENT_LENGTH, String.valueOf(PREFIX.length())))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertNull(result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config()
+                .connectionFactory(connectionFactory)
+                .useFixedLengthStreaming(true))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.CONTENT_LENGTH, String.valueOf(PREFIX.length())))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(PREFIX.length(), result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config()
+                .connectionFactory(connectionFactory)
+                .useFixedLengthStreaming(false)
+                .prefix(PREFIX))
+                .client(c -> c.property(PREFIX + HttpUrlConnectorProvider.USE_FIXED_LENGTH_STREAMING, true))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.CONTENT_LENGTH, String.valueOf(PREFIX.length())))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(PREFIX.length(), result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config()
+                .connectionFactory(connectionFactory)
+                .useFixedLengthStreaming(false)
+                .prefix(PREFIX))
+                .request(r -> r.setProperty(PREFIX + HttpUrlConnectorProvider.USE_FIXED_LENGTH_STREAMING, true))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.CONTENT_LENGTH, String.valueOf(PREFIX.length())))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(PREFIX.length(), result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config()
+                .connectionFactory(connectionFactory)
+                .useFixedLengthStreaming(false)
+                .prefix(PREFIX))
+                .client(c -> c.property(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().useFixedLengthStreaming(true).prefix(PREFIX)))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.CONTENT_LENGTH, String.valueOf(PREFIX.length())))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(PREFIX.length(), result.get());
+
+        result.set(null);
+        new TestClient(HttpUrlConnectorProvider.config()
+                .connectionFactory(connectionFactory)
+                .useFixedLengthStreaming(false)
+                .prefix(PREFIX))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().useFixedLengthStreaming(true).prefix(PREFIX)))
+                .request(r -> r.getRequestHeaders().add(HttpHeaders.CONTENT_LENGTH, String.valueOf(PREFIX.length())))
+                .request(r -> r.setEntity(PREFIX)).apply();
+        Assertions.assertEquals(PREFIX.length(), result.get());
+    }
+
+    @Test
+    public void testUseMethodWorkaround() {
+        JdkVersion version = JdkVersion.getJdkVersion();
+        if (!version.isReflectiveAccessToJdkSupported()) {
+            return;
+        }
+        final String method = "XYZ";
+        final AtomicReference<HttpURLConnection> result = new AtomicReference<>();
+        final HttpUrlConnectorProvider.ConnectionFactory connectionFactory = new HttpUrlConnectorProvider.ConnectionFactory() {
+            @Override
+            public HttpURLConnection getConnection(URL url) throws IOException {
+                return new HttpURLConnection(url) {
+                    @Override
+                    public void disconnect() {
+
+                    }
+
+                    @Override
+                    public boolean usingProxy() {
+                        return false;
+                    }
+
+                    @Override
+                    public void connect() throws IOException {
+
+                    }
+
+                    @Override
+                    public void setRequestMethod(String method) throws ProtocolException {
+                        result.set(this);
+                        super.setRequestMethod(method);
+                        throw new IllegalStateException();
+                    }
+                };
+            }
+        };
+
+        new TestClient(HttpUrlConnectorProvider.config()
+                .connectionFactory(connectionFactory))
+                .request(r -> r.setMethod(method))
+                .apply();
+        Assertions.assertNotEquals(method, result.get().getRequestMethod());
+
+        new TestClient(HttpUrlConnectorProvider.config()
+                .connectionFactory(connectionFactory)
+                .useSetMethodWorkaround(true))
+                .request(r -> r.setMethod(method))
+                .apply();
+        Assertions.assertEquals(method, result.get().getRequestMethod());
+
+        HttpUrlConnectorProvider.Config config = HttpUrlConnectorProvider.config();
+        config.build().useSetMethodWorkaround();
+        new TestClient(config
+                .connectionFactory(connectionFactory))
+                .request(r -> r.setMethod(method))
+                .apply();
+        Assertions.assertEquals(method, result.get().getRequestMethod());
+
+        new TestClient(HttpUrlConnectorProvider.config().prefix(PREFIX)
+                .connectionFactory(connectionFactory))
+                .request(r -> r.setMethod(method))
+                .request(r -> r.setProperty(ClientProperties.CONNECTOR_CONFIGURATION,
+                        HttpUrlConnectorProvider.config().useSetMethodWorkaround(true).prefix(PREFIX)))
+                .apply();
+        Assertions.assertEquals(method, result.get().getRequestMethod());
+
+        new TestClient(HttpUrlConnectorProvider.config().prefix(PREFIX)
+                .connectionFactory(connectionFactory))
+                .client(c -> c.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true))
+                .request(r -> r.setMethod(method))
+                .apply();
+        Assertions.assertNotEquals(method, result.get().getRequestMethod());
+
+        new TestClient(HttpUrlConnectorProvider.config().prefix(PREFIX)
+                .connectionFactory(connectionFactory))
+                .client(c -> c.property(PREFIX + HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true))
+                .request(r -> r.setMethod(method))
+                .apply();
+        Assertions.assertEquals(method, result.get().getRequestMethod());
+    }
+
+    private static class Conf extends HttpUrlConnectorConfiguration<Conf> {
+        private static class RW extends ReadWrite {
+            @Override
+            public <X extends ConnectorConfiguration<?>> void setNonEmpty(X otherC) {
+                super.setNonEmpty(otherC);
+            }
+
+            @Override
+            public RW prefix(String prefix) {
+                super.prefix(prefix);
+                return this;
+            }
+        }
+    }
+
+    private static class TestClient {
+        final Conf.RW rw;
+        final Client client;
+
+        private TestClient(ConnectorConfiguration<?> config) {
+            this.rw = config instanceof Conf.RW ? (Conf.RW) config : new Conf.RW() {
+                {
+                    setNonEmpty(config);
+                }
+            };
+            this.client = ClientBuilder.newClient(new ClientConfig());
+        }
+
+        public TestClient client(Consumer<Client> consumer) {
+            consumer.accept(client);
+            return this;
+        }
+
+        public TestClient rw(Consumer<HttpUrlConnectorConfiguration<?>> consumer) {
+            consumer.accept(rw);
+            return this;
+        }
+
+        public Request request() {
+            return new Request(client, rw);
+        }
+
+        public Request request(Consumer<ClientRequest> consumer) {
+            return request().request(consumer);
+        }
+    }
+
+    private static class Request {
+        final ClientRequest request;
+        final Client client;
+        final Conf.RW rw;
+
+        Request(Client client, Conf.RW rw) {
+            this.client = client;
+            this.rw = rw;
+            request = createRequest(client);
+        }
+
+        private static ClientRequest createRequest(Client client) {
+            ClientRequest request =  new ClientRequest(URI.create("http://localhost:8080"),
+                    (ClientConfig) client.getConfiguration(), new MapPropertiesDelegate()) {
+                @Override
+                public void writeEntity() throws IOException {
+                    throw new IllegalStateException();
+                }
+
+                @Override
+                public MultivaluedMap<String, String> getStringHeaders() {
+                    throw new IllegalStateException();
+                }
+            };
+            request.setMethod("POST");
+            return request;
+        }
+
+        public Request request(Consumer<ClientRequest> consumer) {
+            consumer.accept(request);
+            return this;
+        }
+
+        public Request apply() {
+            try {
+                HttpUrlConnector connector = new HttpUrlConnector(client, client.getConfiguration(), rw);
+                connector.apply(request);
+            } catch (ProcessingException | IllegalStateException expected) {
+            }
+            return this;
+        }
+    }
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
index 7b83560..8390bcf 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/inject/ParamConverters.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2025 Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
@@ -326,7 +326,8 @@
                         final List<ClassTypePair> ctps = ReflectionHelper.getTypeArgumentAndClass(genericType);
                         final ClassTypePair ctp = (ctps.size() == 1) ? ctps.get(0) : null;
                         final boolean empty = value.isEmpty();
-                        for (ParamConverterProvider provider : Providers.getProviders(manager, ParamConverterProvider.class)) {
+                        for (final ParamConverterProvider provider
+                                : Providers.getAllProviders(manager, ParamConverterProvider.class)) {
                             final ParamConverter<?> converter = provider.getConverter(ctp.rawClass(), ctp.type(), annotations);
                             if (converter != null) {
                                 if (empty) {
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/util/JdkVersion.java b/core-common/src/main/java/org/glassfish/jersey/internal/util/JdkVersion.java
index 9b8ec40..d7c478c 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/util/JdkVersion.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/util/JdkVersion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -119,6 +119,19 @@
     }
 
     /**
+     * <p>
+     *     Returns <tt>true</tt> if the reflective access to JDK classes is supported. It was disabled by JDK 16+.
+     * </p>
+     * <p>
+     *     This can be used to verify the property <tt>HttpUrlConnectorProvider#SET_METHOD_WORKAROUND</tt> still works,
+     *     for instance.
+     * </p>
+     */
+    public boolean isReflectiveAccessToJdkSupported() {
+        return getMajor() < 16;
+    }
+
+    /**
      * Returns <tt>true</tt> if {@code sun.misc.Unsafe} is present in the
      * current JDK version, or <tt>false</tt> otherwise.
      *
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Views.java b/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Views.java
index 75b1987..d1480d2 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Views.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/util/collection/Views.java
@@ -230,6 +230,76 @@
             final List<Object> old = originalMap.put(key, (List<Object>) (List<?>) value);
             return valuesTransformer.apply(old);
         }
+
+        @Override
+        public boolean containsKey(Object key) {
+            Iterator<Entry<String, List<String>>> i = entrySet().iterator();
+            if (key == null) {
+                while (i.hasNext()) {
+                    Entry<String, List<String>> e = i.next();
+                    if (e.getKey() == null) {
+                        return true;
+                    }
+                }
+            } else {
+                while (i.hasNext()) {
+                    Entry<String, List<String>> e = i.next();
+                    if (((String) key).equalsIgnoreCase(e.getKey())) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public List<String> get(Object key) {
+            Iterator<Entry<String, List<String>>> i = entrySet().iterator();
+            if (key == null) {
+                while (i.hasNext()) {
+                    Entry<String, List<String>> e = i.next();
+                    if (e.getKey() == null) {
+                        return e.getValue();
+                    }
+                }
+            } else {
+                while (i.hasNext()) {
+                    Entry<String, List<String>> e = i.next();
+                    if (((String) key).equalsIgnoreCase(e.getKey())) {
+                        return e.getValue();
+                    }
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public List<String> remove(Object key) {
+            Iterator<Entry<String, List<String>>> i = entrySet().iterator();
+            Entry<String, List<String>> correctEntry = null;
+            if (key == null) {
+                while (correctEntry == null && i.hasNext()) {
+                    Entry<String, List<String>> e = i.next();
+                    if (e.getKey() == null) {
+                        correctEntry = e;
+                    }
+                }
+            } else {
+                while (correctEntry == null && i.hasNext()) {
+                    Entry<String, List<String>> e = i.next();
+                    if (((String) key).equalsIgnoreCase(e.getKey())) {
+                        correctEntry = e;
+                    }
+                }
+            }
+
+            List<String> oldValue = null;
+            if (correctEntry != null) {
+                oldValue = correctEntry.getValue();
+                i.remove();
+            }
+            return oldValue;
+        }
     }
 
     /**
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java b/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java
index 04d820d..4e94366 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ServerRuntime.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -720,7 +720,7 @@
                             // output streams writes out bytes only on close (for example GZipOutputStream).
                             response.close();
                         } catch (final Exception e) {
-                            LOGGER.log(Level.SEVERE, LocalizationMessages.ERROR_CLOSING_COMMIT_OUTPUT_STREAM(), e);
+                            LOGGER.log(Level.FINER, LocalizationMessages.ERROR_CLOSING_COMMIT_OUTPUT_STREAM(), e);
                         }
                     }
                 }
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/model/ResourceMethodInvoker.java b/core-server/src/main/java/org/glassfish/jersey/server/model/ResourceMethodInvoker.java
index 7cf46ee..1a8f1b4 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/model/ResourceMethodInvoker.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/model/ResourceMethodInvoker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -21,7 +21,6 @@
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
@@ -280,13 +279,8 @@
                                 model.getPriority(ContainerResponseFilter.class)));
             }
         }
-
-        _readerInterceptors.addAll(
-                StreamSupport.stream(processingProviders.getGlobalReaderInterceptors().spliterator(), false)
-                             .collect(Collectors.toList()));
-        _writerInterceptors.addAll(
-                StreamSupport.stream(processingProviders.getGlobalWriterInterceptors().spliterator(), false)
-                             .collect(Collectors.toList()));
+        processingProviders.getGlobalReaderInterceptors().forEach(_readerInterceptors::add);
+        processingProviders.getGlobalWriterInterceptors().forEach(_writerInterceptors::add);
 
         if (resourceMethod != null) {
             addNameBoundFiltersAndInterceptors(
@@ -458,9 +452,7 @@
                 if (entityAnn.length == 0) {
                     response.setEntityAnnotations(methodAnnotations);
                 } else {
-                    final Annotation[] mergedAnn = Arrays.copyOf(methodAnnotations,
-                            methodAnnotations.length + entityAnn.length);
-                    System.arraycopy(entityAnn, 0, mergedAnn, methodAnnotations.length, entityAnn.length);
+                    final Annotation[] mergedAnn = mergeDistinctAnnotations(methodAnnotations, entityAnn);
                     response.setEntityAnnotations(mergedAnn);
                 }
             }
@@ -487,6 +479,22 @@
         return jaxrsResponse;
     }
 
+    private static Annotation[] mergeDistinctAnnotations(Annotation[] existing, Annotation[] newOnes) {
+        List<Annotation> merged = new ArrayList<>(existing.length + newOnes.length);
+        Collections.addAll(merged, existing);
+
+        newOnesLoop:
+        for (Annotation n : newOnes) {
+            for (Annotation ex : existing) {
+                if (ex == n) {
+                    continue newOnesLoop;
+                }
+            }
+            merged.add(n);
+        }
+        return merged.toArray(new Annotation[0]);
+    }
+
     private Type unwrapInvocableResponseType(ContainerRequest request, Type entityType) {
         if (isCompletionStageResponseType
                 && request.resolveProperty(ServerProperties.UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE, Boolean.TRUE)) {
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java b/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java
index 8413a07..4ee091b 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/internal/inject/ParamConverterInternalTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2025 Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2018 Payara Foundation and/or its affiliates.
  *
  * This program and the accompanying materials are made available under the
@@ -27,8 +27,11 @@
 import java.util.Date;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
+import jakarta.annotation.Priority;
+import jakarta.inject.Singleton;
 import jakarta.ws.rs.DefaultValue;
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.HeaderParam;
@@ -104,6 +107,15 @@
         assertEquals(404, responseContext.getStatus());
     }
 
+    @Test
+    public void testCustomEnumResource() throws ExecutionException, InterruptedException {
+        initiateWebApplication(BadEnumResource.class, EnumParamConverterProvider.class);
+        final ContainerResponse responseContext = getResponseContext(UriBuilder.fromPath("/")
+                .queryParam("d", "A").build().toString());
+        assertEquals(1, counter.get());
+        assertEquals(200, responseContext.getStatus());
+    }
+
     public static class URIStringReaderProvider implements ParamConverterProvider {
 
         @Override
@@ -188,6 +200,40 @@
         }
     }
 
+    static final AtomicInteger counter = new AtomicInteger(0);
+    @Singleton
+    @Priority(1)
+    public static class EnumParamConverterProvider implements ParamConverterProvider {
+
+        @Override
+        public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) {
+            if (Enum.class.isAssignableFrom(rawType)) {
+                return new ParamConverter<T>() {
+                    @Override
+                    public T fromString(final String value) {
+                        counter.addAndGet(1);
+                        if (value == null) {
+                            return null;
+                        }
+                        Class<? extends Enum> enumClass = null;
+                        try {
+                            enumClass = (Class<Enum>) Class.forName(genericType.getTypeName());
+                        } catch (ClassNotFoundException e) {
+                            throw new RuntimeException(e);
+                        }
+                        return (T) Enum.valueOf(enumClass, value.toUpperCase());
+                    }
+
+                    @Override
+                    public String toString(final T value) {
+                        return String.valueOf(value);
+                    }
+                };
+            }
+            return null;
+        }
+    }
+
     @Path("/")
     public static class ListOfStringResource {
 
diff --git a/examples/NOTICE.md b/examples/NOTICE.md
index 70c3d2b..0abdafc 100644
--- a/examples/NOTICE.md
+++ b/examples/NOTICE.md
@@ -71,7 +71,7 @@
 * Project: http://www.javassist.org/
 * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
 
-Jackson JAX-RS Providers Version 2.18.0
+Jackson JAX-RS Providers Version 2.19.1
 * License: Apache License, 2.0
 * Project: https://github.com/FasterXML/jackson-jaxrs-providers
 * Copyright: (c) 2009-2023 FasterXML, LLC. All rights reserved unless otherwise indicated.
diff --git a/examples/osgi-helloworld-webapp/functional-test/src/test/resources/felix.policy b/examples/osgi-helloworld-webapp/functional-test/src/test/resources/felix.policy
index d8348f9..51a40bb 100644
--- a/examples/osgi-helloworld-webapp/functional-test/src/test/resources/felix.policy
+++ b/examples/osgi-helloworld-webapp/functional-test/src/test/resources/felix.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2014, 2025 Oracle and/or its affiliates. All rights reserved.
 //
 // This program and the accompanying materials are made available under the
 // terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -33,6 +33,7 @@
 allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (org.osgi.framework.PackagePermission) } "packagePermissionToJerseyCommon";
 allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.lang.reflect.ReflectPermission "suppressAccessChecks") } "suppressAccessChecksToJerseyCommon";
 allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.net.SocketPermission "*" "connect,resolve") } "socketPermissionToJerseyCommon";
+allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.net.NetPermission "*" "getProxySelector") } "proxySelectorToClientProxy";
 allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.lang.RuntimePermission "accessDeclaredMembers") } "accessDeclaredMembersToJerseyCommon";
 allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.lang.RuntimePermission "accessClassInPackage.sun.misc") } "accessClassInPackageSunMisc";
 allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.lang.RuntimePermission "getClassLoader") } "getCLToJerseyCommon";
diff --git a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/base/ProviderBase.java b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/base/ProviderBase.java
index 350be25..d86fa8b 100644
--- a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/base/ProviderBase.java
+++ b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/base/ProviderBase.java
@@ -6,7 +6,10 @@
 import java.io.Reader;
 import java.io.Writer;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Type;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -18,9 +21,12 @@
 import jakarta.ws.rs.core.NoContentException;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.StreamingOutput;
+import jakarta.ws.rs.ext.ContextResolver;
 import jakarta.ws.rs.ext.MessageBodyReader;
 import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Providers;
 
+import com.fasterxml.jackson.core.PrettyPrinter;
 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.cfg.AnnotationBundleKey;
 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.cfg.Annotations;
 import org.glassfish.jersey.jackson.internal.jackson.jaxrs.cfg.EndpointConfigBase;
@@ -216,12 +222,13 @@
     protected ProviderBase() {
         this(null);
     }
+
     /**
      * @since 2.17
      */
     protected ProviderBase(MAPPER_CONFIG mconfig,
-            LookupCache<AnnotationBundleKey, EP_CONFIG> readerCache,
-            LookupCache<AnnotationBundleKey, EP_CONFIG> writerCache)
+                           LookupCache<AnnotationBundleKey, EP_CONFIG> readerCache,
+                           LookupCache<AnnotationBundleKey, EP_CONFIG> writerCache)
     {
         _mapperConfig = mconfig;
         _jaxRSFeatures = JAXRS_FEATURE_DEFAULTS;
@@ -612,7 +619,12 @@
         try {
             // Want indentation?
             if (writer.isEnabled(SerializationFeature.INDENT_OUTPUT)) {
-                g.useDefaultPrettyPrinter();
+                PrettyPrinter defaultPrettyPrinter = writer.getConfig().getDefaultPrettyPrinter();
+                if (defaultPrettyPrinter != null) {
+                    g.setPrettyPrinter(defaultPrettyPrinter);
+                } else {
+                    g.useDefaultPrettyPrinter();
+                }
             }
             JavaType rootType = null;
 
@@ -999,6 +1011,24 @@
     /**********************************************************
      */
 
+    // @since 2.19
+    protected <OM extends ObjectMapper> OM _locateMapperViaProvider(Class<?> type, MediaType mediaType,
+                                                                    Class<OM> mapperType, Providers providers) {
+        if (providers != null) {
+            ContextResolver<OM> resolver = providers.getContextResolver(mapperType, mediaType);
+            // Above should work as is, but due to this bug
+            //   [https://jersey.dev.java.net/issues/show_bug.cgi?id=288]
+            // in Jersey, it doesn't. But this works until resolution of the issue:
+            if (resolver == null) {
+                resolver = providers.getContextResolver(mapperType, null);
+            }
+            if (resolver != null) {
+                return resolver.getContext(type);
+            }
+        }
+        return null;
+    }
+
     protected static boolean _containedIn(Class<?> mainType, HashSet<ClassKey> set)
     {
         if (set != null) {
diff --git a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/JacksonJsonProvider.java b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/JacksonJsonProvider.java
index 13f9275..93a5192 100644
--- a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/JacksonJsonProvider.java
+++ b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/JacksonJsonProvider.java
@@ -19,6 +19,7 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectReader;
 import com.fasterxml.jackson.databind.ObjectWriter;
+import com.fasterxml.jackson.databind.json.JsonMapper;
 
 /**
  * Basic implementation of JAX-RS abstractions ({@link MessageBodyReader},
@@ -207,21 +208,12 @@
     @Override
     protected ObjectMapper _locateMapperViaProvider(Class<?> type, MediaType mediaType)
     {
-        if (_providers != null) {
-            ContextResolver<ObjectMapper> resolver = _providers.getContextResolver(ObjectMapper.class, mediaType);
-            /* Above should work as is, but due to this bug
-             *   [https://jersey.dev.java.net/issues/show_bug.cgi?id=288]
-             * in Jersey, it doesn't. But this works until resolution of
-             * the issue:
-             */
-            if (resolver == null) {
-                resolver = _providers.getContextResolver(ObjectMapper.class, null);
-            }
-            if (resolver != null) {
-                return resolver.getContext(type);
-            }
+        // 26-Nov-2024, tatu: [jakarta-rs#36] Look for JsonMapper primarily
+        ObjectMapper m =_locateMapperViaProvider(type, mediaType, JsonMapper.class, _providers);
+        if (m == null) {
+            m = _locateMapperViaProvider(type, mediaType, ObjectMapper.class, _providers);
         }
-        return null;
+        return m;
     }
 
     @Override
diff --git a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/JsonMapperConfigurator.java b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/JsonMapperConfigurator.java
index fd5d9aa..3325c5e 100644
--- a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/JsonMapperConfigurator.java
+++ b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/JsonMapperConfigurator.java
@@ -10,6 +10,7 @@
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
 import com.fasterxml.jackson.module.jakarta.xmlbind.JakartaXmlBindAnnotationIntrospector;
+import com.fasterxml.jackson.databind.json.JsonMapper;
 
 /**
  * Helper class used to encapsulate details of configuring an
@@ -49,7 +50,7 @@
             _lock.lock();
             try {
                 if (_defaultMapper == null) {
-                    _defaultMapper = new ObjectMapper();
+                    _defaultMapper = new JsonMapper();
                     _setAnnotations(_defaultMapper, _defaultAnnotationsToUse);
                 }
             } finally {
@@ -77,7 +78,7 @@
             _lock.lock();
             try {
                 if (_mapper == null) {
-                    _mapper = new ObjectMapper();
+                    _mapper = new JsonMapper();
                     _setAnnotations(_mapper, _defaultAnnotationsToUse);
                 }
             } finally {
@@ -120,9 +121,8 @@
             case JACKSON:
                 return new JacksonAnnotationIntrospector();
             case JAXB:
-                /* For this, need to use indirection just so that error occurs
-                 * when we get here, and not when this class is being loaded
-                 */
+                // For this, need to use indirection just so that error occurs
+                // when we get here, and not when this class is being loaded
                 try {
                     if (_jaxbIntrospectorClass == null) {
                         _jaxbIntrospectorClass = JakartaXmlBindAnnotationIntrospector.class;
diff --git a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/PackageVersion.java b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/PackageVersion.java
index 44c9073..a7c123c 100644
--- a/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/PackageVersion.java
+++ b/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/internal/jackson/jaxrs/json/PackageVersion.java
@@ -11,7 +11,7 @@
  */
 public final class PackageVersion implements Versioned {
     public final static Version VERSION = VersionUtil.parseVersion(
-        "2.18.0", "com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider");
+        "2.19.1", "com.fasterxml.jackson.jaxrs", "jackson-jaxrs-json-provider");
 
     @Override
     public Version version() {
diff --git a/media/json-jackson/src/main/resources/META-INF/NOTICE.markdown b/media/json-jackson/src/main/resources/META-INF/NOTICE.markdown
index d893c65..d9b20ee 100644
--- a/media/json-jackson/src/main/resources/META-INF/NOTICE.markdown
+++ b/media/json-jackson/src/main/resources/META-INF/NOTICE.markdown
@@ -31,7 +31,7 @@
 
 ## Third-party Content
 
-Jackson JAX-RS Providers version 2.18.0
+Jackson JAX-RS Providers version 2.19.1
 * License: Apache License, 2.0
 * Project: https://github.com/FasterXML/jackson-jaxrs-providers
 * Copyright: (c) 2009-2023 FasterXML, LLC. All rights reserved unless otherwise indicated.
diff --git a/pom.xml b/pom.xml
index f1fa3ef..ee38b9c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2244,7 +2244,7 @@
         <hk2.jvnet.osgi.version>org.jvnet.hk2.*;version="[2.5,4)"</hk2.jvnet.osgi.version>
         <httpclient.version>4.5.14</httpclient.version>
         <httpclient5.version>5.3.1</httpclient5.version>
-        <jackson.version>2.18.0</jackson.version>
+        <jackson.version>2.19.1</jackson.version>
         <javassist.version>3.30.2-GA</javassist.version>
         <jboss.logging.8.version>3.4.3.Final</jboss.logging.8.version>
         <jersey1.version>1.19.3</jersey1.version>
diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/Jersey5939Test.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/Jersey5939Test.java
new file mode 100644
index 0000000..78f1ef4
--- /dev/null
+++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/Jersey5939Test.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package org.glassfish.jersey.tests.api;
+
+import org.glassfish.jersey.server.ContainerResponse;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.jupiter.api.Test;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Check the reused response does not leak by additional Annotations (ContainerResponse#setEntityAnnottaions.
+ */
+public class Jersey5939Test extends JerseyTest {
+
+    private final List<ContainerResponse> capturedResponses = new ArrayList<>();
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(Restlet.class).register(new ContainerResponseFilter() {
+            @Override
+            public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
+                    throws IOException {
+                if (responseContext instanceof ContainerResponse) {
+                    capturedResponses.add((ContainerResponse) responseContext);
+                }
+            }
+        });
+    }
+
+    @Test
+    public void testIssue5939() {
+        for (int i = 0; i < 10; i++) {
+            Response response = target("foo/bar").request().get();
+            assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+            ContainerResponse containerResponse = capturedResponses.get(i);
+            Annotation[] annotations = containerResponse.getEntityAnnotations();
+            // [@javax.ws.rs.GET(), @javax.ws.rs.Path("/bar")]
+            assertEquals(2, annotations.length, "Found " + annotations.length + " annotations, in iteration " + i);
+        }
+    }
+
+    @Path("/foo")
+    public static class Restlet {
+
+        private static final Response RESPONSE_204 = Response.noContent().build();
+
+        @GET
+        @Path("/bar")
+        public Response fooBar() {
+            return RESPONSE_204;
+        }
+    }
+}
\ No newline at end of file
