Skip to content

Commit 2d65818

Browse files
committed
imp: webjar priority of local file
1 parent 95c3e64 commit 2d65818

File tree

2 files changed

+71
-31
lines changed

2 files changed

+71
-31
lines changed

bootstrap-plugin/src/main/java/org/ligoj/bootstrap/resource/system/plugin/WebjarsServlet.java

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,20 @@
33
*/
44
package org.ligoj.bootstrap.resource.system.plugin;
55

6-
import java.io.IOException;
7-
import java.io.InputStream;
8-
import java.net.URL;
9-
import java.nio.file.Paths;
10-
import java.util.HashMap;
11-
import java.util.Map;
12-
136
import jakarta.activation.FileTypeMap;
147
import jakarta.servlet.http.HttpServlet;
158
import jakarta.servlet.http.HttpServletRequest;
169
import jakarta.servlet.http.HttpServletResponse;
17-
10+
import lombok.extern.slf4j.Slf4j;
1811
import org.apache.commons.io.FilenameUtils;
1912

20-
import lombok.extern.slf4j.Slf4j;
13+
import java.io.IOException;
14+
import java.io.InputStream;
15+
import java.net.URL;
16+
import java.nio.file.Paths;
17+
import java.util.Enumeration;
18+
import java.util.HashMap;
19+
import java.util.Map;
2120

2221
/**
2322
* <p>
@@ -54,12 +53,20 @@ public WebjarsServlet() {
5453
mimeTypes.put("otf", "application/x-font-opentype");
5554
}
5655

56+
protected boolean hasMorePriority(URL url) {
57+
return url.toString().startsWith("file:");
58+
}
59+
60+
protected Enumeration<URL> getResources(String webjarsResourceURI) throws IOException {
61+
return Thread.currentThread().getContextClassLoader().getResources(webjarsResourceURI);
62+
}
63+
5764
@Override
5865
protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
5966
throws IOException {
6067
final var webjarsResourceURI = "META-INF/resources"
6168
+ request.getRequestURI().replaceFirst(request.getContextPath(), "");
62-
log.debug("Webjars resource requested: {}", webjarsResourceURI);
69+
log.debug("Webjars requested resource: {}", webjarsResourceURI);
6370

6471
if (isDirectoryRequest(webjarsResourceURI)) {
6572
// Directory listing is forbidden, but act as a 404 for security purpose.
@@ -68,11 +75,19 @@ protected void doGet(final HttpServletRequest request, final HttpServletResponse
6875
}
6976

7077
// Regular file, use the last resource instead of the first found
71-
final var resources = Thread.currentThread().getContextClassLoader().getResources(webjarsResourceURI);
78+
final var resources = getResources(webjarsResourceURI);
7279
URL webjarsResourceURL = null;
7380
if (resources.hasMoreElements()) {
7481
webjarsResourceURL = resources.nextElement();
7582
}
83+
if (resources.hasMoreElements()) {
84+
var webjarsResourceFileUrl = resources.nextElement();
85+
if (hasMorePriority(webjarsResourceFileUrl)) {
86+
// Highest priority for local files
87+
webjarsResourceURL = webjarsResourceFileUrl;
88+
}
89+
}
90+
7691
if (webjarsResourceURL == null) {
7792
// File not found --> 404
7893
response.sendError(HttpServletResponse.SC_NOT_FOUND);

bootstrap-plugin/src/test/java/org/ligoj/bootstrap/resource/system/plugin/WebjarsServletTest.java

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,11 @@
33
*/
44
package org.ligoj.bootstrap.resource.system.plugin;
55

6-
import java.io.ByteArrayInputStream;
7-
import java.io.ByteArrayOutputStream;
8-
import java.io.InputStream;
9-
import java.net.URL;
10-
import java.nio.charset.StandardCharsets;
11-
import java.util.ArrayList;
12-
import java.util.Collections;
13-
146
import jakarta.servlet.ServletConfig;
157
import jakarta.servlet.ServletContext;
168
import jakarta.servlet.ServletException;
179
import jakarta.servlet.http.HttpServletRequest;
1810
import jakarta.servlet.http.HttpServletResponse;
19-
2011
import org.junit.jupiter.api.AfterEach;
2112
import org.junit.jupiter.api.Assertions;
2213
import org.junit.jupiter.api.BeforeEach;
@@ -26,6 +17,17 @@
2617
import org.mockito.Mockito;
2718
import org.springframework.mock.web.DelegatingServletOutputStream;
2819

20+
import java.io.ByteArrayInputStream;
21+
import java.io.ByteArrayOutputStream;
22+
import java.io.IOException;
23+
import java.io.InputStream;
24+
import java.net.URL;
25+
import java.nio.charset.StandardCharsets;
26+
import java.util.ArrayList;
27+
import java.util.Collections;
28+
import java.util.Enumeration;
29+
import java.util.List;
30+
2931
/**
3032
* Test class of {@link WebjarsServlet}
3133
*/
@@ -68,24 +70,21 @@ void fileNotFound() throws Exception {
6870

6971
@Test
7072
void downloadFile() throws Exception {
73+
final var webjarResource = "META-INF/resources/webjars/image.png";
7174
final var request = defaultRequest();
7275
final var response = Mockito.mock(HttpServletResponse.class);
7376

74-
final var classLoader = Mockito.mock(ClassLoader.class);
7577
final var baos = new ByteArrayOutputStream();
7678
final var out = new DelegatingServletOutputStream(baos);
7779
Mockito.when(response.getOutputStream()).thenReturn(out);
78-
final var urlsAsList = new ArrayList<URL>();
79-
final var url = Thread.currentThread().getContextClassLoader()
80-
.getResource("META-INF/resources/webjars/image.png");
81-
urlsAsList.add(url);
82-
urlsAsList.add(url);
83-
final var urls = Collections.enumeration(urlsAsList);
84-
Mockito.when(classLoader.getResources("META-INF/resources/webjars/image.png")).thenReturn(urls);
85-
Thread.currentThread().setContextClassLoader(classLoader);
86-
getServlet("false").doGet(request, response);
80+
final var urls = new ArrayList<URL>();
81+
final var url = Thread.currentThread().getContextClassLoader().getResource(webjarResource);
82+
urls.add(url);
83+
urls.add(url);
84+
getServlet("false", true, urls).doGet(request, response);
8785
Assertions.assertEquals("image-content", baos.toString(StandardCharsets.UTF_8));
8886
Mockito.verify(response).setContentType("image/x-png");
87+
getServlet("false", false, urls).doGet(request, response);
8988
Mockito.verify(response, Mockito.never()).setStatus(ArgumentMatchers.anyInt());
9089
Mockito.verify(response, Mockito.never()).sendError(ArgumentMatchers.anyInt());
9190
}
@@ -138,7 +137,12 @@ private HttpServletRequest defaultRequest(final String file) {
138137
}
139138

140139
private WebjarsServlet getServlet(final String disableCache) throws ServletException {
141-
final var servlet = new WebjarsServlet();
140+
return getServlet(disableCache, true, null);
141+
}
142+
143+
144+
private WebjarsServlet getServlet(final String disableCache, boolean fileHasMorePriority, List<URL> urls) throws ServletException {
145+
final var servlet = new MyWebjarsServlet(fileHasMorePriority, urls);
142146
final var servletConfig = Mockito.mock(ServletConfig.class);
143147
final var servletContext = Mockito.mock(ServletContext.class);
144148
Mockito.when(servletConfig.getInitParameter("disableCache")).thenReturn(disableCache);
@@ -147,4 +151,25 @@ private WebjarsServlet getServlet(final String disableCache) throws ServletExcep
147151
servlet.init(servletConfig);
148152
return servlet;
149153
}
154+
155+
private static class MyWebjarsServlet extends WebjarsServlet {
156+
157+
private final boolean fileHasMorePriority;
158+
private final List<URL> urls;
159+
160+
public MyWebjarsServlet(boolean fileHasMorePriority, List<URL> urls) {
161+
this.fileHasMorePriority = fileHasMorePriority;
162+
this.urls = urls;
163+
}
164+
165+
@Override
166+
protected boolean hasMorePriority(URL url) {
167+
return fileHasMorePriority && super.hasMorePriority(url);
168+
}
169+
170+
@Override
171+
protected Enumeration<URL> getResources(String webjarsResourceURI) throws IOException {
172+
return urls == null ? super.getResources(webjarsResourceURI) : Collections.enumeration(urls);
173+
}
174+
}
150175
}

0 commit comments

Comments
 (0)