From 398a8189352e42c034685e582f215bdc93fa8f33 Mon Sep 17 00:00:00 2001 From: John Niang Date: Tue, 30 Sep 2025 15:31:23 +0800 Subject: [PATCH] Refactor thumbnail URI handling to support width parameter and improve error messaging --- .../endpoint/theme/ThumbnailEndpoint.java | 63 +++---------------- .../app/theme/finders/ThumbnailFinder.java | 1 + .../finders/impl/ThumbnailFinderImpl.java | 3 +- 3 files changed, 11 insertions(+), 56 deletions(-) diff --git a/application/src/main/java/run/halo/app/core/endpoint/theme/ThumbnailEndpoint.java b/application/src/main/java/run/halo/app/core/endpoint/theme/ThumbnailEndpoint.java index 16e4cadd6..104ec1d2d 100644 --- a/application/src/main/java/run/halo/app/core/endpoint/theme/ThumbnailEndpoint.java +++ b/application/src/main/java/run/halo/app/core/endpoint/theme/ThumbnailEndpoint.java @@ -1,20 +1,16 @@ package run.halo.app.core.endpoint.theme; -import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder; import static org.springdoc.core.fn.builders.parameter.Builder.parameterBuilder; import io.swagger.v3.oas.annotations.enums.ParameterIn; -import io.swagger.v3.oas.annotations.media.Schema; import java.net.URI; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; -import org.springdoc.core.fn.builders.operation.Builder; import org.springdoc.webflux.core.fn.SpringdocRouteBuilder; import org.springframework.core.io.Resource; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; -import org.springframework.util.MultiValueMap; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; @@ -66,10 +62,6 @@ public class ThumbnailEndpoint implements CustomEndpoint { .build(); } - public ThumbnailService getThumbnailService() { - return thumbnailService; - } - private Mono getThumbnailByUri(ServerRequest request) { var uri = request.queryParam("uri") .filter(StringUtils::isNotBlank) @@ -81,11 +73,15 @@ public class ThumbnailEndpoint implements CustomEndpoint { } var size = request.queryParam("size") .filter(StringUtils::isNotBlank) - .flatMap(ThumbnailSize::optionalValueOf); - if (size.isEmpty()) { - return Mono.error( - new ServerWebInputException("Required parameter 'size' is missing or invalid") + .flatMap(ThumbnailSize::optionalValueOf) + .or(() -> request.queryParam("width") + .filter(StringUtils::isNotBlank) + .map(ThumbnailSize::fromWidth) ); + if (size.isEmpty()) { + return Mono.error(new ServerWebInputException( + "Required parameter 'size' or 'width' is missing or invalid" + )); } return thumbnailService.get(uri.get(), size.get()) .defaultIfEmpty(uri.get()) @@ -95,49 +91,6 @@ public class ThumbnailEndpoint implements CustomEndpoint { ); } - static class ThumbnailQuery { - private final MultiValueMap params; - - public ThumbnailQuery(MultiValueMap params) { - this.params = params; - } - - @Schema(requiredMode = REQUIRED) - public URI getUri() { - var uriStr = params.getFirst("uri"); - if (StringUtils.isBlank(uriStr)) { - throw new ServerWebInputException("Required parameter 'uri' is missing"); - } - try { - return URI.create(uriStr); - } catch (IllegalArgumentException e) { - throw new ServerWebInputException("Invalid URI: " + uriStr); - } - } - - @Schema(requiredMode = REQUIRED) - public ThumbnailSize getSize() { - var size = params.getFirst("size"); - if (StringUtils.isBlank(size)) { - throw new ServerWebInputException("Required parameter 'size' is missing"); - } - return ThumbnailSize.fromName(size); - } - - public static void buildParameters(Builder builder) { - builder.parameter(parameterBuilder() - .in(ParameterIn.QUERY) - .name("uri") - .description("The URI of the image") - .required(true)) - .parameter(parameterBuilder() - .in(ParameterIn.QUERY) - .name("size") - .description("The size of the thumbnail,available values are s,m,l,xl") - .required(true)); - } - } - @Override public GroupVersion groupVersion() { return new GroupVersion("api.storage.halo.run", "v1alpha1"); diff --git a/application/src/main/java/run/halo/app/theme/finders/ThumbnailFinder.java b/application/src/main/java/run/halo/app/theme/finders/ThumbnailFinder.java index 53f67a29a..56f448be7 100644 --- a/application/src/main/java/run/halo/app/theme/finders/ThumbnailFinder.java +++ b/application/src/main/java/run/halo/app/theme/finders/ThumbnailFinder.java @@ -13,6 +13,7 @@ public interface ThumbnailFinder { /** * Generate thumbnail uri from given image uri and size. * + * @param uri URI of the original image, must be encoded * @param size the size of thumbnail to generate * @return the generated thumbnail url */ diff --git a/application/src/main/java/run/halo/app/theme/finders/impl/ThumbnailFinderImpl.java b/application/src/main/java/run/halo/app/theme/finders/impl/ThumbnailFinderImpl.java index 552f3ccc4..dd91e5aba 100644 --- a/application/src/main/java/run/halo/app/theme/finders/impl/ThumbnailFinderImpl.java +++ b/application/src/main/java/run/halo/app/theme/finders/impl/ThumbnailFinderImpl.java @@ -21,7 +21,8 @@ public class ThumbnailFinderImpl implements ThumbnailFinder { return Mono.fromCallable(() -> URI.create(uriStr)) .flatMap(uri -> thumbnailService.get(uri, ThumbnailSize.fromName(size))) .map(URI::toASCIIString) - .onErrorReturn(IllegalArgumentException.class, uriStr); + .onErrorComplete(IllegalArgumentException.class) + .defaultIfEmpty(uriStr); } }