From ccbe18567f731b00a25e2dff09b1615567f129ff Mon Sep 17 00:00:00 2001 From: John Niang Date: Fri, 7 Jun 2024 11:32:22 +0800 Subject: [PATCH] Fix the problem that theme assets could not be found after the first initialization (#6049) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind bug /area core /milestone 2.17.x #### What this PR does / why we need it: When initialized for the first time, the folder `${halo.work-dir}/themes` does not exist, resulting in the `themes` path being ignored when invoking `themeRootResource.createRelative(themeName + "/templates/assets/");`. It works very well after restarting. This PR fixes the problem by resolving theme resource directly rather than delegating to PathResourceResolver. #### Which issue(s) this PR fixes: Fixes #6048 #### Does this PR introduce a user-facing change? ```release-note 修复首次初始化后无法正常访问主题资源的问题 ``` --- .../theme/config/ThemeWebFluxConfigurer.java | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/application/src/main/java/run/halo/app/theme/config/ThemeWebFluxConfigurer.java b/application/src/main/java/run/halo/app/theme/config/ThemeWebFluxConfigurer.java index d6acc00f3..e066be10d 100644 --- a/application/src/main/java/run/halo/app/theme/config/ThemeWebFluxConfigurer.java +++ b/application/src/main/java/run/halo/app/theme/config/ThemeWebFluxConfigurer.java @@ -1,13 +1,11 @@ package run.halo.app.theme.config; -import java.io.IOException; -import java.net.MalformedURLException; import java.nio.file.Path; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.springframework.boot.autoconfigure.web.WebProperties; -import org.springframework.core.io.FileUrlResource; +import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.CacheControl; import org.springframework.stereotype.Component; @@ -16,11 +14,11 @@ import org.springframework.web.reactive.config.ResourceHandlerRegistry; import org.springframework.web.reactive.config.WebFluxConfigurer; import org.springframework.web.reactive.resource.AbstractResourceResolver; import org.springframework.web.reactive.resource.EncodedResourceResolver; -import org.springframework.web.reactive.resource.PathResourceResolver; import org.springframework.web.reactive.resource.ResourceResolverChain; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import run.halo.app.infra.ThemeRootGetter; +import run.halo.app.infra.utils.FileUtils; @Component public class ThemeWebFluxConfigurer implements WebFluxConfigurer { @@ -47,8 +45,7 @@ public class ThemeWebFluxConfigurer implements WebFluxConfigurer { .setUseLastModified(useLastModified) .resourceChain(true) .addResolver(new EncodedResourceResolver()) - .addResolver(new ThemePathResourceResolver(themeRootGetter.get())) - .addResolver(new PathResourceResolver()); + .addResolver(new ThemePathResourceResolver(themeRootGetter.get())); } /** @@ -59,14 +56,10 @@ public class ThemeWebFluxConfigurer implements WebFluxConfigurer { */ private static class ThemePathResourceResolver extends AbstractResourceResolver { - private final Resource themeRootResource; + private final Path themeRoot; private ThemePathResourceResolver(Path themeRoot) { - try { - this.themeRootResource = new FileUrlResource(themeRoot.toUri().toURL()); - } catch (MalformedURLException e) { - throw new RuntimeException("Failed to resolve " + themeRoot + " to URL.", e); - } + this.themeRoot = themeRoot; } @Override @@ -84,19 +77,17 @@ public class ThemeWebFluxConfigurer implements WebFluxConfigurer { return Mono.empty(); } - try { - var location = themeRootResource.createRelative(themeName + "/templates/assets/"); - return chain.resolveResource(exchange, resourcePaths, List.of(location)); - } catch (IOException e) { - return Mono.empty(); - } + var assetsPath = themeRoot.resolve(themeName + "/templates/assets/" + resourcePaths); + FileUtils.checkDirectoryTraversal(themeRoot, assetsPath); + var location = new FileSystemResource(assetsPath); + return Mono.just(location); } @Override protected Mono resolveUrlPathInternal(String resourceUrlPath, - List locations, - ResourceResolverChain chain) { - return chain.resolveUrlPath(resourceUrlPath, locations); + List locations, ResourceResolverChain chain) { + throw new UnsupportedOperationException(); } + } }