diff --git a/build.gradle.kts b/build.gradle.kts index 2eb8b47..f4e4f99 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ plugins { - kotlin("jvm") version "2.3.20" - kotlin("plugin.serialization") version "2.3.20" - id("io.ktor.plugin") version "3.4.2" + kotlin("jvm") version "2.3.21" + kotlin("plugin.serialization") version "2.3.21" + id("io.ktor.plugin") version "3.4.3" id("jacoco") } @@ -29,25 +29,25 @@ dependencies { implementation("io.ktor:ktor-server-call-logging-jvm") implementation("io.ktor:ktor-server-rate-limit-jvm") implementation("ch.qos.logback:logback-classic:1.5.32") - implementation("com.github.InfinityLoop1308.PipePipeExtractor:extractor:274ba4ddf31a7d39679f44be2db9cbdfc7986b20") - implementation("com.squareup.okhttp3:okhttp:4.12.0") - implementation("io.lettuce:lettuce-core:6.8.2.RELEASE") + implementation("com.github.InfinityLoop1308.PipePipeExtractor:extractor:810a08db8efc8bf218e92019c09a83229c6abd1b") + implementation("com.squareup.okhttp3:okhttp:5.3.2") + implementation("io.lettuce:lettuce-core:7.5.1.RELEASE") implementation("org.jetbrains.exposed:exposed-core:1.2.0") implementation("org.jetbrains.exposed:exposed-jdbc:1.2.0") - implementation("com.zaxxer:HikariCP:6.3.3") - implementation("org.postgresql:postgresql:42.7.10") + implementation("com.zaxxer:HikariCP:7.0.2") + implementation("org.postgresql:postgresql:42.7.11") implementation("org.xerial:sqlite-jdbc:3.53.0.0") implementation("com.password4j:password4j:1.8.4") - implementation("com.auth0:java-jwt:4.5.1") - testImplementation("org.junit.jupiter:junit-jupiter:5.14.3") + implementation("com.auth0:java-jwt:4.5.2") + testImplementation("org.junit.jupiter:junit-jupiter:6.0.3") testRuntimeOnly("org.junit.platform:junit-platform-launcher") testImplementation("io.mockk:mockk:1.14.9") testImplementation("io.ktor:ktor-server-test-host-jvm") testImplementation("io.ktor:ktor-server-content-negotiation-jvm") testImplementation("io.ktor:ktor-serialization-kotlinx-json-jvm") - testImplementation("org.testcontainers:testcontainers:1.21.4") - testImplementation("org.testcontainers:postgresql:1.21.4") - testImplementation("org.testcontainers:junit-jupiter:1.21.4") + testImplementation("org.testcontainers:testcontainers:2.0.5") + testImplementation("org.testcontainers:testcontainers-postgresql:2.0.5") + testImplementation("org.testcontainers:testcontainers-junit-jupiter:2.0.5") } tasks.test { diff --git a/src/main/kotlin/dev/typetype/server/downloader/OkHttpDownloader.kt b/src/main/kotlin/dev/typetype/server/downloader/OkHttpDownloader.kt index d31a611..0e19673 100644 --- a/src/main/kotlin/dev/typetype/server/downloader/OkHttpDownloader.kt +++ b/src/main/kotlin/dev/typetype/server/downloader/OkHttpDownloader.kt @@ -31,8 +31,8 @@ class OkHttpDownloader private constructor(private val client: OkHttpClient) : D throw ReCaptchaException("reCaptcha required", request.url()) } - val responseBodyBytes = httpResponse.body?.bytes() - val responseBody = responseBodyBytes?.toString(Charsets.UTF_8) ?: "" + val responseBodyBytes = httpResponse.body.bytes() + val responseBody = responseBodyBytes.toString(Charsets.UTF_8) return Response( httpResponse.code, httpResponse.message, @@ -50,8 +50,8 @@ class OkHttpDownloader private constructor(private val client: OkHttpClient) : D call.enqueue(object : Callback { override fun onResponse(call: Call, response: okhttp3.Response) { - val responseBodyBytes = response.body?.bytes() - val responseBody = responseBodyBytes?.toString(Charsets.UTF_8) ?: "" + val responseBodyBytes = response.body.bytes() + val responseBody = responseBodyBytes.toString(Charsets.UTF_8) val extractorResponse = Response( response.code, response.message, diff --git a/src/main/kotlin/dev/typetype/server/routes/DownloaderGatewaySseProxy.kt b/src/main/kotlin/dev/typetype/server/routes/DownloaderGatewaySseProxy.kt index dada4e3..a0acae8 100644 --- a/src/main/kotlin/dev/typetype/server/routes/DownloaderGatewaySseProxy.kt +++ b/src/main/kotlin/dev/typetype/server/routes/DownloaderGatewaySseProxy.kt @@ -37,7 +37,7 @@ suspend fun forwardDownloaderSseRequest( ?.let { runCatching { ContentType.parse(it) }.getOrNull() } ?: ContentType.Text.EventStream - response.body?.byteStream()?.use { input -> + response.body.byteStream().use { input -> call.respondOutputStream(contentType = contentType, status = status) { val buffer = ByteArray(DEFAULT_BUFFER_SIZE) while (true) { @@ -47,6 +47,6 @@ suspend fun forwardDownloaderSseRequest( flush() } } - } ?: call.respond(HttpStatusCode.fromValue(response.code)) + } } } diff --git a/src/main/kotlin/dev/typetype/server/services/DownloaderGatewayService.kt b/src/main/kotlin/dev/typetype/server/services/DownloaderGatewayService.kt index 12760d0..8018248 100644 --- a/src/main/kotlin/dev/typetype/server/services/DownloaderGatewayService.kt +++ b/src/main/kotlin/dev/typetype/server/services/DownloaderGatewayService.kt @@ -24,7 +24,7 @@ class DownloaderGatewayService( status = response.code, contentType = response.header("Content-Type"), headers = responseHeaders, - body = response.body?.bytes() ?: ByteArray(0), + body = response.body.bytes(), ) } } @@ -51,7 +51,7 @@ class DownloaderGatewayService( status = response.code, contentType = response.header("Content-Type"), headers = responseHeaders, - body = response.body?.bytes() ?: ByteArray(0), + body = response.body.bytes(), ) } } diff --git a/src/main/kotlin/dev/typetype/server/services/HlsManifestService.kt b/src/main/kotlin/dev/typetype/server/services/HlsManifestService.kt index a6c28ca..98db4a5 100644 --- a/src/main/kotlin/dev/typetype/server/services/HlsManifestService.kt +++ b/src/main/kotlin/dev/typetype/server/services/HlsManifestService.kt @@ -76,7 +76,7 @@ class HlsManifestService( response.close() ExtractionResult.Failure("Upstream returned ${response.code}") } else { - val text = body?.string() ?: "" + val text = body.string() response.close() ExtractionResult.Success(rewriteYouTubeHlsManifest(text)) } diff --git a/src/main/kotlin/dev/typetype/server/services/NicoNicoTrendingService.kt b/src/main/kotlin/dev/typetype/server/services/NicoNicoTrendingService.kt index 929ad89..0c074a1 100644 --- a/src/main/kotlin/dev/typetype/server/services/NicoNicoTrendingService.kt +++ b/src/main/kotlin/dev/typetype/server/services/NicoNicoTrendingService.kt @@ -36,7 +36,7 @@ class NicoNicoTrendingService(private val httpClient: OkHttpClient) { .url(TRENDING_URL) .header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36") .build() - val body = httpClient.newCall(request).execute().use { it.body?.string() ?: "" } + val body = httpClient.newCall(request).execute().use { it.body.string() } val rawMeta = META_REGEX.find(body)?.groupValues?.get(1) ?: return@runCatching emptyList() val unescaped = htmlUnescape(rawMeta) diff --git a/src/main/kotlin/dev/typetype/server/services/NicoVideoProxyService.kt b/src/main/kotlin/dev/typetype/server/services/NicoVideoProxyService.kt index d4212cd..f06a39c 100644 --- a/src/main/kotlin/dev/typetype/server/services/NicoVideoProxyService.kt +++ b/src/main/kotlin/dev/typetype/server/services/NicoVideoProxyService.kt @@ -68,7 +68,7 @@ class NicoVideoProxyService { response.close() ExtractionResult.Failure("Upstream returned ${response.code}") } else { - val text = body?.string() ?: "" + val text = body.string() response.close() val rewritten = rewriteNicoManifest(text, manifestUrl, resolvedBid) ExtractionResult.Success(ProxyResponse( @@ -109,7 +109,7 @@ class NicoVideoProxyService { contentLength = response.header("Content-Length")?.toLongOrNull(), contentRange = response.header("Content-Range"), acceptRanges = response.header("Accept-Ranges"), - stream = body?.byteStream() ?: java.io.InputStream.nullInputStream(), + stream = body.byteStream(), close = response::close, )) } diff --git a/src/main/kotlin/dev/typetype/server/services/OkHttpProxyService.kt b/src/main/kotlin/dev/typetype/server/services/OkHttpProxyService.kt index 2fe56b3..a4b8f79 100644 --- a/src/main/kotlin/dev/typetype/server/services/OkHttpProxyService.kt +++ b/src/main/kotlin/dev/typetype/server/services/OkHttpProxyService.kt @@ -7,7 +7,6 @@ import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import okhttp3.Request import java.io.ByteArrayInputStream -import java.io.InputStream import java.net.URLEncoder import java.nio.charset.StandardCharsets @@ -48,7 +47,7 @@ class OkHttpProxyService(private val client: OkHttpClient) : ProxyService { val acceptRanges = response.header("Accept-Ranges") val contentLength = response.header("Content-Length")?.toLongOrNull() if (isHls(contentType)) { - val rewritten = rewriteHlsManifest(body?.string() ?: "") + val rewritten = rewriteHlsManifest(body.string()) response.close() ExtractionResult.Success(ProxyResponse( status = statusCode, @@ -66,7 +65,7 @@ class OkHttpProxyService(private val client: OkHttpClient) : ProxyService { contentLength = contentLength, contentRange = contentRange, acceptRanges = acceptRanges, - stream = body?.byteStream() ?: InputStream.nullInputStream(), + stream = body.byteStream(), close = response::close, )) } diff --git a/src/main/kotlin/dev/typetype/server/services/OpenMojiProxyService.kt b/src/main/kotlin/dev/typetype/server/services/OpenMojiProxyService.kt index 9cfcd11..6c191b0 100644 --- a/src/main/kotlin/dev/typetype/server/services/OpenMojiProxyService.kt +++ b/src/main/kotlin/dev/typetype/server/services/OpenMojiProxyService.kt @@ -56,7 +56,7 @@ class OpenMojiProxyService(private val cache: CacheService) { client.newCall(request).execute().use { response -> if (response.code == 404) return@use FetchResult.NotFound if (!response.isSuccessful) return@use FetchResult.Failed - val bytes = response.body?.bytes() ?: return@use FetchResult.Failed + val bytes = response.body.bytes() FetchResult.Success(bytes) } }.getOrElse { FetchResult.Failed } diff --git a/src/main/kotlin/dev/typetype/server/services/YouTubeSubtitleService.kt b/src/main/kotlin/dev/typetype/server/services/YouTubeSubtitleService.kt index 5671573..ed606f1 100644 --- a/src/main/kotlin/dev/typetype/server/services/YouTubeSubtitleService.kt +++ b/src/main/kotlin/dev/typetype/server/services/YouTubeSubtitleService.kt @@ -17,9 +17,7 @@ internal class YouTubeSubtitleService(private val httpClient: OkHttpClient, priv .url("$baseUrl/subtitles?videoId=$videoId") .build() ).execute() - CacheJson.decodeFromString>( - response.body?.string() ?: return@runCatching emptyList() - ) + response.use { CacheJson.decodeFromString>(it.body.string()) } }.getOrElse { emptyList() } } } diff --git a/src/test/kotlin/dev/typetype/server/TestDatabase.kt b/src/test/kotlin/dev/typetype/server/TestDatabase.kt index 224c0f4..8ceab87 100644 --- a/src/test/kotlin/dev/typetype/server/TestDatabase.kt +++ b/src/test/kotlin/dev/typetype/server/TestDatabase.kt @@ -30,7 +30,7 @@ import dev.typetype.server.db.tables.WatchLaterTable import org.jetbrains.exposed.v1.jdbc.deleteAll import org.jetbrains.exposed.v1.jdbc.transactions.transaction import org.testcontainers.containers.ContainerLaunchException -import org.testcontainers.containers.PostgreSQLContainer +import org.testcontainers.postgresql.PostgreSQLContainer import java.sql.DriverManager import java.util.UUID @@ -43,7 +43,7 @@ object TestDatabase { private val schemaName: String = "tt_test_${UUID.randomUUID().toString().replace("-", "")}".lowercase() - private val container: PostgreSQLContainer<*> by lazy { + private val container: PostgreSQLContainer by lazy { PostgreSQLContainer("postgres:16-alpine").apply { start() } }