This is an automated email from the ASF dual-hosted git repository.

jdyer pushed a commit to branch feature/SOLR-17771
in repository https://gitbox.apache.org/repos/asf/solr.git

commit 4f3157720fff82c8f981f4a138ffdc28720d59da
Author: jdyer1 <[email protected]>
AuthorDate: Tue Oct 14 14:32:26 2025 -0500

    Enhance JDK client to track if it has issued a HEAD request by unique base 
URI
---
 .../solr/client/solrj/impl/HttpJdkSolrClient.java  | 28 ++++++++++++----------
 .../client/solrj/impl/HttpJdkSolrClientTest.java   | 18 ++++++++++----
 2 files changed, 29 insertions(+), 17 deletions(-)

diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java
index 15e686d5773..54ca3b8b8b7 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpJdkSolrClient.java
@@ -34,11 +34,13 @@ import java.net.http.HttpTimeoutException;
 import java.time.Duration;
 import java.time.temporal.ChronoUnit;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -379,17 +381,6 @@ public class HttpJdkSolrClient extends HttpSolrClientBase {
     if (forceHttp11 || url == null || 
url.toLowerCase(Locale.ROOT).startsWith("https://";)) {
       return true;
     }
-    return maybeTryHeadRequestSync(url);
-  }
-
-  protected volatile boolean headRequested; // must be threadsafe
-  private boolean headSucceeded; // must be threadsafe
-
-  private synchronized boolean maybeTryHeadRequestSync(String url) {
-    if (headRequested) {
-      return headSucceeded;
-    }
-
     URI uriNoQueryParams;
     try {
       uriNoQueryParams = new URI(url);
@@ -397,6 +388,17 @@ public class HttpJdkSolrClient extends HttpSolrClientBase {
       // If the url is invalid, let a subsequent request try again.
       return false;
     }
+    return maybeTryHeadRequestSync(uriNoQueryParams);
+  }
+
+  protected Map<URI, Boolean> headSucceededByBaseUri = new HashMap<>();  // 
use only in synchronized method
+
+  private synchronized boolean maybeTryHeadRequestSync(URI uriNoQueryParams) {
+    Boolean headSucceeded = headSucceededByBaseUri.get(uriNoQueryParams);
+    if (headSucceeded !=null) {
+      return headSucceeded;
+    }
+
     HttpRequest.Builder headReqB =
         HttpRequest.newBuilder(uriNoQueryParams)
             .method("HEAD", HttpRequest.BodyPublishers.noBody())
@@ -406,7 +408,7 @@ public class HttpJdkSolrClient extends HttpSolrClientBase {
       httpClient.send(headReqB.build(), 
HttpResponse.BodyHandlers.discarding());
       headSucceeded = true;
     } catch (IOException ioe) {
-      log.warn("Could not issue HEAD request to {} ", url, ioe);
+      log.warn("Could not issue HEAD request to {} ", uriNoQueryParams, ioe);
       headSucceeded = false;
     } catch (InterruptedException ie) {
       Thread.currentThread().interrupt();
@@ -414,7 +416,7 @@ public class HttpJdkSolrClient extends HttpSolrClientBase {
     } finally {
 
       // The HEAD request is tried only once.  All future requests will skip 
this check.
-      headRequested = true;
+      headSucceededByBaseUri.put(uriNoQueryParams, headSucceeded);
 
       if (!headSucceeded) {
         log.info("All unencrypted POST requests with a chunked body will use 
http/1.1");
diff --git 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpJdkSolrClientTest.java
 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpJdkSolrClientTest.java
index e6a47680bc8..9bd418e7e6c 100644
--- 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpJdkSolrClientTest.java
+++ 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/HttpJdkSolrClientTest.java
@@ -20,6 +20,8 @@ package org.apache.solr.client.solrj.impl;
 import java.io.IOException;
 import java.net.CookieHandler;
 import java.net.CookieManager;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.http.HttpClient;
 import java.util.Arrays;
 import java.util.Collections;
@@ -328,9 +330,9 @@ public class HttpJdkSolrClientTest extends 
HttpSolrClientTestBase {
       testUpdate(client, HttpSolrClientTestBase.WT.XML, "application/xml; 
charset=UTF-8", value);
       if (http11) {
         assertEquals(HttpClient.Version.HTTP_1_1, client.httpClient.version());
-        assertFalse(
+        assertNull(
             "The HEAD request should not be performed if already forcing 
Http/1.1.",
-            client.headRequested);
+            client.headSucceededByBaseUri.get(baseUri()));
       } else {
         assertEquals(HttpClient.Version.HTTP_2, client.httpClient.version());
       }
@@ -504,7 +506,7 @@ public class HttpJdkSolrClientTest extends 
HttpSolrClientTestBase {
       assertTrue(client.maybeTryHeadRequest(url));
 
       // if https, the client won't attempt a HEAD request
-      if (client.headRequested) {
+      if (!client.headSucceededByBaseUri.isEmpty()) {
         assertEquals("head", DebugServlet.lastMethod);
         assertTrue(DebugServlet.headers.containsKey("content-type"));
       }
@@ -524,7 +526,15 @@ public class HttpJdkSolrClientTest extends 
HttpSolrClientTestBase {
 
   private void assertNoHeadRequestWithSsl(HttpJdkSolrClient client) {
     if (isSSLMode()) {
-      assertFalse("The HEAD request should not be performed if using SSL.", 
client.headRequested);
+      assertNull("The HEAD request should not be performed if using SSL.", 
client.headSucceededByBaseUri.get(baseUri()));
+    }
+  }
+
+  private URI baseUri() {
+    try {
+      return new URI(getBaseUrl());
+    } catch(URISyntaxException e) {
+      throw new RuntimeException(e);
     }
   }
 

Reply via email to