mirror of https://github.com/usbharu/Hideout.git
Merge pull request #248 from usbharu/feature/remote-media-file-size-limit
feat: リモートのメディアのファイルサイズ制限ができるように
This commit is contained in:
commit
3e649ca13d
|
@ -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
|
||||||
|
)
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package dev.usbharu.hideout.core.service.media
|
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 dev.usbharu.hideout.core.service.resource.KtorResourceResolveService
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
@ -8,7 +10,10 @@ import java.nio.file.Path
|
||||||
import kotlin.io.path.outputStream
|
import kotlin.io.path.outputStream
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class RemoteMediaDownloadServiceImpl(private val resourceResolveService: KtorResourceResolveService) :
|
class RemoteMediaDownloadServiceImpl(
|
||||||
|
private val resourceResolveService: KtorResourceResolveService,
|
||||||
|
private val mediaConfig: MediaConfig
|
||||||
|
) :
|
||||||
RemoteMediaDownloadService {
|
RemoteMediaDownloadService {
|
||||||
override suspend fun download(url: String): Path {
|
override suspend fun download(url: String): Path {
|
||||||
logger.info("START Download remote file. url: {}", url)
|
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)
|
logger.info("SUCCESS Download remote file. url: {}", url)
|
||||||
return createTempFile
|
return createTempFile
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,22 @@
|
||||||
package dev.usbharu.hideout.core.service.resource
|
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.*
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
|
import io.ktor.http.*
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
@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 {
|
ResourceResolveService {
|
||||||
|
|
||||||
|
var sizeLimit = mediaConfig.remoteMediaFileSizeLimit
|
||||||
|
|
||||||
override suspend fun resolve(url: String): ResolveResponse {
|
override suspend fun resolve(url: String): ResolveResponse {
|
||||||
cacheManager.putCache(getCacheKey(url)) {
|
cacheManager.putCache(getCacheKey(url)) {
|
||||||
runResolve(url)
|
runResolve(url)
|
||||||
|
@ -16,7 +26,10 @@ open class KtorResourceResolveService(private val httpClient: HttpClient, privat
|
||||||
|
|
||||||
protected suspend fun runResolve(url: String): ResolveResponse {
|
protected suspend fun runResolve(url: String): ResolveResponse {
|
||||||
val httpResponse = httpClient.get(url)
|
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)
|
return KtorResolveResponse(httpResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue