This is an automated email from the ASF dual-hosted git repository.
jmclean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new fca9e35401 Fixed UI routes ending in WebUIFilter (#9135)
fca9e35401 is described below
commit fca9e354016f9187a2d78513387bce9c00dd5904
Author: Joel <[email protected]>
AuthorDate: Tue Nov 18 22:22:35 2025 -0600
Fixed UI routes ending in WebUIFilter (#9135)
### What changes were proposed in this pull request?
This pull request fixes the routing logic in WebUIFilter to correctly
resolve UI paths that either:
1. End with a trailing slash
2. Omit a file extension
The filter now:
- Forwards directory paths to index.html
````/ui/section/ → /ui/section/index.html````
- Forwards extension-less UI paths to .html
````/ui/dashboard → /ui/dashboard.html````
This ensures that static HTML pages are correctly served by the Web UI.
### Why are the changes needed?
The previous implementation incorrectly handled directory-style UI
routes.
A request such as:
````
/ui/section/
````
was forwarded to:
````
/ui/section/.html
````
instead of:
````
/ui/section/index.html
````
This caused the UI to render incorrectly and broke navigation on static
exports.
The PR fixes this bug by adding explicit handling for trailing-slash
directory routes.
Fix: #9123
### Does this PR introduce _any_ user-facing change?
Yes.
Requests to UI directories now correctly resolve to index.html pages
instead of returning an invalid .html path.
---
.../gravitino/server/web/ui/WebUIFilter.java | 7 +++
.../gravitino/server/web/ui/WebUIFilterTest.java | 53 ++++++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git
a/server/src/main/java/org/apache/gravitino/server/web/ui/WebUIFilter.java
b/server/src/main/java/org/apache/gravitino/server/web/ui/WebUIFilter.java
index d1722bff4a..9a87fcccdd 100644
--- a/server/src/main/java/org/apache/gravitino/server/web/ui/WebUIFilter.java
+++ b/server/src/main/java/org/apache/gravitino/server/web/ui/WebUIFilter.java
@@ -33,15 +33,22 @@ public class WebUIFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
+
HttpServletRequest httpRequest = (HttpServletRequest) request;
String path = httpRequest.getRequestURI();
String lastPathSegment = path.substring(path.lastIndexOf("/") + 1);
+
if (path.equals("/") || path.equals("/ui") || path.equals("/ui/")) {
// Redirect to the index page.
httpRequest.getRequestDispatcher("/ui/index.html").forward(request,
response);
+
+ } else if (path.startsWith("/ui/") && path.endsWith("/")) {
+ httpRequest.getRequestDispatcher(path + "index.html").forward(request,
response);
+
} else if (path.startsWith("/ui/") && !lastPathSegment.contains(".")) {
// Redirect to the static HTML file.
httpRequest.getRequestDispatcher(path + ".html").forward(request,
response);
+
} else {
// Continue processing the rest of the filter chain.
chain.doFilter(request, response);
diff --git
a/server/src/test/java/org/apache/gravitino/server/web/ui/WebUIFilterTest.java
b/server/src/test/java/org/apache/gravitino/server/web/ui/WebUIFilterTest.java
new file mode 100644
index 0000000000..6051023613
--- /dev/null
+++
b/server/src/test/java/org/apache/gravitino/server/web/ui/WebUIFilterTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.gravitino.server.web.ui;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import javax.servlet.FilterChain;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import org.junit.jupiter.api.Test;
+
+public class WebUIFilterTest {
+ @Test
+ public void testNestedDirectoryRequestForwardsToIndexHtml() throws
ServletException, IOException {
+ WebUIFilter filter = new WebUIFilter();
+ HttpServletRequest request = mock(HttpServletRequest.class);
+ ServletResponse response = mock(ServletResponse.class);
+ FilterChain chain = mock(FilterChain.class);
+ RequestDispatcher dispatcher = mock(RequestDispatcher.class);
+
+ when(request.getRequestURI()).thenReturn("/ui/section/subsection/");
+
when(request.getRequestDispatcher("/ui/section/subsection/index.html")).thenReturn(dispatcher);
+
+ filter.doFilter(request, response, chain);
+
+ verify(dispatcher).forward(request, response);
+ verify(chain, never()).doFilter(any(), any());
+ }
+}