This is an automated email from the ASF dual-hosted git repository.
janhoy pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_9x by this push:
new 4cfbe6d3ff3 SOLR-18282 Improve ZookeeperInfoHandler path normalization
(branch_9x)
4cfbe6d3ff3 is described below
commit 4cfbe6d3ff33ace95f8a05a2fe67b19c93c4d2e9
Author: Jan Høydahl <[email protected]>
AuthorDate: Sun Jun 28 01:51:41 2026 +0200
SOLR-18282 Improve ZookeeperInfoHandler path normalization (branch_9x)
---
.../solr/handler/admin/ZookeeperInfoHandler.java | 37 ++++-------
.../handler/admin/ZookeeperInfoHandlerTest.java | 72 ++++++++++++++++++++++
2 files changed, 85 insertions(+), 24 deletions(-)
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java
b/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java
index ed46a25f20f..3b09a3420c9 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/ZookeeperInfoHandler.java
@@ -16,6 +16,7 @@
*/
package org.apache.solr.handler.admin;
+import static
org.apache.solr.common.cloud.ZkStateReader.SOLR_SECURITY_CONF_PATH;
import static org.apache.solr.common.params.CommonParams.OMIT_HEADER;
import static org.apache.solr.common.params.CommonParams.PATH;
import static org.apache.solr.common.params.CommonParams.WT;
@@ -82,6 +83,7 @@ import org.slf4j.LoggerFactory;
*/
public final class ZookeeperInfoHandler extends RequestHandlerBase {
private static final String PARAM_DETAIL = "detail";
+ private static final String PARAM_DUMP = "dump";
private final CoreContainer cores;
private static final Logger log =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -108,8 +110,8 @@ public final class ZookeeperInfoHandler extends
RequestHandlerBase {
public Name getPermissionName(AuthorizationContext request) {
var params = request.getParams();
String path = normalizePath(params.get(PATH, ""));
- String detail = params.get(PARAM_DETAIL, "false");
- if ("/security.json".equalsIgnoreCase(path) &&
"true".equalsIgnoreCase(detail)) {
+ if (path.equals(SOLR_SECURITY_CONF_PATH)
+ || (params.getBool(PARAM_DUMP, false) && "/".equals(path))) {
return Name.SECURITY_READ_PERM;
} else {
return Name.ZK_READ_PERM;
@@ -374,17 +376,14 @@ public final class ZookeeperInfoHandler extends
RequestHandlerBase {
}
}
- String path = params.get(PATH);
+ String path = normalizePath(params.get(PATH));
if (params.get("addr") != null) {
throw new SolrException(ErrorCode.BAD_REQUEST, "Illegal parameter
\"addr\"");
}
- String detailS = params.get(PARAM_DETAIL);
- boolean detail = detailS != null && detailS.equals("true");
-
- String dumpS = params.get("dump");
- boolean dump = dumpS != null && dumpS.equals("true");
+ boolean detail = params.getBool(PARAM_DETAIL, false);
+ boolean dump = params.getBool(PARAM_DUMP, false);
int start = params.getInt("start", 0); // Note start ignored if rows not
specified
int rows = params.getInt("rows", -1);
@@ -428,8 +427,12 @@ public final class ZookeeperInfoHandler extends
RequestHandlerBase {
}
@SuppressForbidden(reason = "JDK String class doesn't offer a stripEnd
equivalent")
- private String normalizePath(String path) {
- return StringUtils.stripEnd(path, "/");
+ String normalizePath(String path) {
+ if (path == null) {
+ return "/";
+ }
+ String normalized = StringUtils.stripEnd(path.trim(), "/");
+ return normalized.isEmpty() ? "/" : normalized;
}
//
--------------------------------------------------------------------------------------
@@ -474,20 +477,6 @@ public final class ZookeeperInfoHandler extends
RequestHandlerBase {
return;
}
- // normalize path
- if (path == null) {
- path = "/";
- } else {
- path = path.trim();
- if (path.length() == 0) {
- path = "/";
- }
- }
-
- if (path.endsWith("/") && path.length() > 1) {
- path = path.substring(0, path.length() - 1);
- }
-
int idx = path.lastIndexOf('/');
String parent = idx >= 0 ? path.substring(0, idx) : path;
if (parent.length() == 0) {
diff --git
a/solr/core/src/test/org/apache/solr/handler/admin/ZookeeperInfoHandlerTest.java
b/solr/core/src/test/org/apache/solr/handler/admin/ZookeeperInfoHandlerTest.java
new file mode 100644
index 00000000000..5d82405372f
--- /dev/null
+++
b/solr/core/src/test/org/apache/solr/handler/admin/ZookeeperInfoHandlerTest.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.handler.admin;
+
+import java.io.IOException;
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.impl.JsonMapResponseParser;
+import org.apache.solr.client.solrj.request.GenericSolrRequest;
+import org.apache.solr.cloud.SolrCloudTestCase;
+import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.NamedList;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/** Basic tests for {@link ZookeeperInfoHandler} */
+public class ZookeeperInfoHandlerTest extends SolrCloudTestCase {
+
+ @BeforeClass
+ public static void setupCluster() throws Exception {
+ configureCluster(1).addConfig("conf",
configset("cloud-minimal")).configure();
+ }
+
+ @Test
+ public void testZkInfoHandlerDetailView() throws SolrServerException,
IOException {
+ SolrClient client = cluster.getSolrClient();
+
+ ModifiableSolrParams params = new ModifiableSolrParams();
+ params.set(CommonParams.PATH, "/");
+ params.set("detail", "true");
+ GenericSolrRequest req =
+ new GenericSolrRequest(SolrRequest.METHOD.GET, "/admin/zookeeper",
params);
+ req.setResponseParser(new JsonMapResponseParser());
+
+ NamedList<Object> response = client.request(req);
+ assertNotNull("Response should not be null", response);
+
+ // ZK handler should return 'znode' for detail requests
+ assertNotNull(response.get("znode"));
+ }
+
+ @Test
+ public void testNormalizePath() {
+ ZookeeperInfoHandler handler =
+ new
ZookeeperInfoHandler(cluster.getJettySolrRunner(0).getCoreContainer());
+
+ assertEquals("/foo", handler.normalizePath(" /foo"));
+ assertEquals("/foo", handler.normalizePath("/foo "));
+ assertEquals("/foo", handler.normalizePath("/foo/"));
+ assertEquals("/foo", handler.normalizePath("/foo//"));
+ assertEquals("/", handler.normalizePath(null));
+ assertEquals("/", handler.normalizePath(""));
+ assertEquals("/", handler.normalizePath(" "));
+ assertEquals("/", handler.normalizePath("/"));
+ }
+}