fix: thumbnail generation for URI string containing spaces (#6698)

#### What type of PR is this?
/kind improvement
/area core
/milestone 2.20.x

#### What this PR does / why we need it:
修复文章封面图链接包含空格时主题端会因为生成缩略图错误而无法访问的问题

这是由于 URI string 中包含空格无法创建 URI 对象,目前将忽略这种非法参数,如果生成失败则直接返回原始 URI string

#### Which issue(s) this PR fixes:
Fixes #6690

#### Does this PR introduce a user-facing change?
```release-note
修复文章封面图链接包含空格时主题端会因为生成缩略图错误而无法访问的问题
```
pull/6703/head^2
guqing 2024-09-28 18:41:42 +08:00 committed by GitHub
parent 3fe1afb952
commit a1fcd51714
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 63 additions and 1 deletions

View File

@ -2,12 +2,14 @@ package run.halo.app.theme.finders.impl;
import java.net.URI;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
import run.halo.app.core.attachment.ThumbnailService;
import run.halo.app.core.attachment.ThumbnailSize;
import run.halo.app.theme.finders.Finder;
import run.halo.app.theme.finders.ThumbnailFinder;
@Slf4j
@Finder("thumbnail")
@RequiredArgsConstructor
public class ThumbnailFinderImpl implements ThumbnailFinder {
@ -15,8 +17,14 @@ public class ThumbnailFinderImpl implements ThumbnailFinder {
@Override
public Mono<String> gen(String uriStr, String size) {
return thumbnailService.generate(URI.create(uriStr), ThumbnailSize.fromName(size))
return Mono.fromSupplier(() -> URI.create(uriStr))
.flatMap(uri -> thumbnailService.generate(uri, ThumbnailSize.fromName(size)))
.map(URI::toString)
.onErrorResume(Throwable.class, e -> {
log.debug("Failed to generate thumbnail for [{}], error: [{}]", uriStr,
e.getMessage());
return Mono.just(uriStr);
})
.defaultIfEmpty(uriStr);
}
}

View File

@ -0,0 +1,54 @@
package run.halo.app.theme.finders.impl;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.net.URI;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import run.halo.app.core.attachment.ThumbnailService;
/**
* Tests for {@link ThumbnailFinderImpl}.
*
* @author guqing
* @since 2.20.0
*/
@ExtendWith(MockitoExtension.class)
class ThumbnailFinderImplTest {
@Mock
ThumbnailService thumbnailService;
@InjectMocks
ThumbnailFinderImpl thumbnailFinder;
@Test
void shouldNotGenWhenUriIsInvalid() {
thumbnailFinder.gen("invalid uri", "l")
.as(StepVerifier::create)
.expectNext("invalid uri")
.verifyComplete();
verify(thumbnailService, times(0)).generate(any(), any());
}
@Test
void shouldGenWhenUriIsValid() {
when(thumbnailService.generate(any(), any()))
.thenReturn(Mono.just(URI.create("/test-thumb.jpg")));
thumbnailFinder.gen("/test.jpg", "l")
.as(StepVerifier::create)
.expectNext("/test-thumb.jpg")
.verifyComplete();
verify(thumbnailService).generate(any(), any());
}
}