From 5db462d9d8042f49bed0db5438a505e146d9707b Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:20:27 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E3=83=AA=E3=83=A2=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=81=AE=E3=83=A1=E3=83=87=E3=82=A3=E3=82=A2=E3=81=AE?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=B5=E3=82=A4=E3=82=BA?= =?UTF-8?q?=E5=88=B6=E9=99=90=E3=81=8C=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hideout/application/config/MediaConfig.kt | 8 +++++++ .../media/RemoteMediaFileSizeException.kt | 21 +++++++++++++++++++ .../media/RemoteMediaDownloadServiceImpl.kt | 12 ++++++++++- .../resource/KtorResourceResolveService.kt | 17 +++++++++++++-- 4 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/application/config/MediaConfig.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/RemoteMediaFileSizeException.kt diff --git a/src/main/kotlin/dev/usbharu/hideout/application/config/MediaConfig.kt b/src/main/kotlin/dev/usbharu/hideout/application/config/MediaConfig.kt new file mode 100644 index 00000000..cf34e6ca --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/application/config/MediaConfig.kt @@ -0,0 +1,8 @@ +package dev.usbharu.hideout.application.config + +import org.springframework.boot.context.properties.ConfigurationProperties + +@ConfigurationProperties("hideout.media") +data class MediaConfig( + val remoteMediaFileSizeLimit: Long = 3000000L +) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/RemoteMediaFileSizeException.kt b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/RemoteMediaFileSizeException.kt new file mode 100644 index 00000000..16c50cd8 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/core/domain/exception/media/RemoteMediaFileSizeException.kt @@ -0,0 +1,21 @@ +package dev.usbharu.hideout.core.domain.exception.media + +import java.io.Serial + +class RemoteMediaFileSizeException : MediaFileSizeException { + constructor() : super() + constructor(message: String?) : super(message) + constructor(message: String?, cause: Throwable?) : super(message, cause) + constructor(cause: Throwable?) : super(cause) + constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super( + message, + cause, + enableSuppression, + writableStackTrace + ) + + companion object { + @Serial + private const val serialVersionUID: Long = 9188247721397839435L + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt index bd1014f8..e9e96645 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt @@ -1,5 +1,7 @@ package dev.usbharu.hideout.core.service.media +import dev.usbharu.hideout.application.config.MediaConfig +import dev.usbharu.hideout.core.domain.exception.media.RemoteMediaFileSizeException import dev.usbharu.hideout.core.service.resource.KtorResourceResolveService import org.slf4j.LoggerFactory import org.springframework.stereotype.Service @@ -8,7 +10,10 @@ import java.nio.file.Path import kotlin.io.path.outputStream @Service -class RemoteMediaDownloadServiceImpl(private val resourceResolveService: KtorResourceResolveService) : +class RemoteMediaDownloadServiceImpl( + private val resourceResolveService: KtorResourceResolveService, + private val mediaConfig: MediaConfig +) : RemoteMediaDownloadService { override suspend fun download(url: String): Path { logger.info("START Download remote file. url: {}", url) @@ -23,6 +28,11 @@ class RemoteMediaDownloadServiceImpl(private val resourceResolveService: KtorRes } } + val contentLength = createTempFile.toFile().length() + if (contentLength >= mediaConfig.remoteMediaFileSizeLimit) { + throw RemoteMediaFileSizeException("File size is too large. $contentLength >= ${mediaConfig.remoteMediaFileSizeLimit}") + } + logger.info("SUCCESS Download remote file. url: {}", url) return createTempFile } diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveService.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveService.kt index 4cd99bc8..06f04d7e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveService.kt @@ -1,12 +1,22 @@ package dev.usbharu.hideout.core.service.resource +import dev.usbharu.hideout.application.config.MediaConfig +import dev.usbharu.hideout.core.domain.exception.media.RemoteMediaFileSizeException import io.ktor.client.* import io.ktor.client.request.* +import io.ktor.http.* import org.springframework.stereotype.Service @Service -open class KtorResourceResolveService(private val httpClient: HttpClient, private val cacheManager: CacheManager) : +open class KtorResourceResolveService( + private val httpClient: HttpClient, + private val cacheManager: CacheManager, + private val mediaConfig: MediaConfig +) : ResourceResolveService { + + var sizeLimit = mediaConfig.remoteMediaFileSizeLimit + override suspend fun resolve(url: String): ResolveResponse { cacheManager.putCache(getCacheKey(url)) { runResolve(url) @@ -16,7 +26,10 @@ open class KtorResourceResolveService(private val httpClient: HttpClient, privat protected suspend fun runResolve(url: String): ResolveResponse { val httpResponse = httpClient.get(url) - + val contentLength = httpResponse.contentLength() + if ((contentLength ?: sizeLimit) >= sizeLimit) { + throw RemoteMediaFileSizeException("File size is too large. $contentLength >= $sizeLimit") + } return KtorResolveResponse(httpResponse) } From c5aee7b35db121a071dbc88d149aae843a7f05a6 Mon Sep 17 00:00:00 2001 From: usbharu Date: Thu, 25 Jan 2024 13:47:52 +0900 Subject: [PATCH 2/3] Update src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../core/service/media/RemoteMediaDownloadServiceImpl.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt index e9e96645..8c488181 100644 --- a/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/core/service/media/RemoteMediaDownloadServiceImpl.kt @@ -30,7 +30,9 @@ class RemoteMediaDownloadServiceImpl( val contentLength = createTempFile.toFile().length() if (contentLength >= mediaConfig.remoteMediaFileSizeLimit) { - throw RemoteMediaFileSizeException("File size is too large. $contentLength >= ${mediaConfig.remoteMediaFileSizeLimit}") + throw RemoteMediaFileSizeException( + "File size is too large. $contentLength >= ${mediaConfig.remoteMediaFileSizeLimit}" + ) } logger.info("SUCCESS Download remote file. url: {}", url) From 8b9fe2d7bee5f5396a6b12dd9d40cb01dc75c9c9 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 25 Jan 2024 15:03:04 +0900 Subject: [PATCH 3/3] =?UTF-8?q?test:=20=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=82=B5=E3=82=A4=E3=82=BA=E5=88=B6=E9=99=90=E3=82=92?= =?UTF-8?q?=E8=B6=85=E3=81=88=E3=81=9F=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E3=81=AE=E3=81=A8=E3=81=8D=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E3=81=AE=E3=83=80=E3=82=A6=E3=83=B3=E3=83=AD=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=81=AB=E5=A4=B1=E6=95=97=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../KtorResourceResolveServiceTest.kt | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/test/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveServiceTest.kt diff --git a/src/test/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveServiceTest.kt b/src/test/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveServiceTest.kt new file mode 100644 index 00000000..7f59eeab --- /dev/null +++ b/src/test/kotlin/dev/usbharu/hideout/core/service/resource/KtorResourceResolveServiceTest.kt @@ -0,0 +1,53 @@ +package dev.usbharu.hideout.core.service.resource + +import dev.usbharu.hideout.application.config.MediaConfig +import dev.usbharu.hideout.core.domain.exception.media.RemoteMediaFileSizeException +import io.ktor.client.* +import io.ktor.client.engine.mock.* +import io.ktor.http.* +import io.ktor.http.HttpHeaders.ContentLength +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.InjectMocks +import org.mockito.Spy +import org.mockito.junit.jupiter.MockitoExtension + +@ExtendWith(MockitoExtension::class) +class KtorResourceResolveServiceTest { + + @Spy + private val httpClient: HttpClient = HttpClient(MockEngine { + when (it.url.encodedPath) { + "/over-size-limit" -> { + respond(ByteArray(1000), HttpStatusCode.OK, Headers.build { + append(ContentLength, "1000") + }) + } + + else -> { + respond("Not Found", HttpStatusCode.NotFound) + } + } + }) { + expectSuccess = true + } + + @Spy + private val cacheManager: CacheManager = InMemoryCacheManager() + + @Spy + private val mediaConfig: MediaConfig = MediaConfig() + + @InjectMocks + private lateinit var ktorResourceResolveService: KtorResourceResolveService + + @Test + fun ファイルサイズ制限を超えたときRemoteMediaFileSizeExceptionが発生する() = runTest { + ktorResourceResolveService.sizeLimit = 100L + assertThrows { + ktorResourceResolveService.resolve("https://example.com/over-size-limit") + } + } +}