Merge pull request #248 from usbharu/feature/remote-media-file-size-limit

feat: リモートのメディアのファイルサイズ制限ができるように
This commit is contained in:
usbharu 2024-01-25 15:06:56 +09:00 committed by GitHub
commit 3e649ca13d
5 changed files with 110 additions and 3 deletions

View File

@ -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
)

View File

@ -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
}
}

View File

@ -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,13 @@ 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
}

View File

@ -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)
}

View File

@ -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<RemoteMediaFileSizeException> {
ktorResourceResolveService.resolve("https://example.com/over-size-limit")
}
}
}