Skip to content

Commit

Permalink
Configured caching headers (#179)
Browse files Browse the repository at this point in the history
Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>
  • Loading branch information
ArnyminerZ authored Oct 22, 2024
1 parent fd38cd0 commit c571999
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ repositories {

dependencies {
// Ktor dependencies
implementation(libs.ktor.server.cachingHeaders)
implementation(libs.ktor.server.conditionalHeaders)
implementation(libs.ktor.server.contentNegotiation)
implementation(libs.ktor.server.core)
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ ktor-client-contentNegotiation = { module = "io.ktor:ktor-client-content-negotia
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-serializationJson = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-server-cachingHeaders = { module = "io.ktor:ktor-server-caching-headers", version.ref = "ktor" }
ktor-server-conditionalHeaders = { module = "io.ktor:ktor-server-conditional-headers", version.ref = "ktor" }
ktor-server-contentNegotiation = { module = "io.ktor:ktor-server-content-negotiation", version.ref = "ktor" }
ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }
Expand Down
57 changes: 57 additions & 0 deletions src/main/kotlin/server/plugins/CachingHeaders.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package server.plugins

import io.ktor.http.CacheControl
import io.ktor.http.HttpHeaders
import io.ktor.http.content.CachingOptions
import io.ktor.server.http.content.CachingOptions
import io.ktor.server.plugins.cachingheaders.CachingHeadersConfig
import java.time.ZonedDateTime
import server.response.FileSource
import server.response.FileUUID
import server.response.ResourceId
import server.response.ResourceType

/**
* Configures the maximum age in seconds that file requests should be cached for.
*
* Default: `24 hours`
*/
private const val FILE_MAX_AGE = 24 * 60 * 60

/**
* Configures the maximum age in seconds that data requests should be cached for.
*
* Default: `10 minutes`
*/
private const val DATA_MAX_AGE = 10 * 60

/**
* Generates [CachingOptions] for caching file requests.
*
* @param maxAge The maximum age in seconds that file requests should be cached for.
*/
private fun cachingOptions(maxAge: Int): CachingOptions {
return CachingOptions(
cacheControl = CacheControl.MaxAge(maxAge),
expires = ZonedDateTime.now().plusSeconds(maxAge.toLong())
)
}

fun CachingHeadersConfig.configure() {
options { call, outgoingContent ->
val headers = call.response.headers

val fileUUID = headers[HttpHeaders.FileUUID]
val fileSource = headers[HttpHeaders.FileSource]
val resourceType = headers[HttpHeaders.ResourceType]
val resourceId = headers[HttpHeaders.ResourceId]?.toIntOrNull()

if (fileUUID != null && fileSource != null) {
return@options cachingOptions(FILE_MAX_AGE)
} else if (resourceType != null && resourceId != null) {
return@options cachingOptions(DATA_MAX_AGE)
}

null
}
}
2 changes: 2 additions & 0 deletions src/main/kotlin/server/plugins/Plugins.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import database.serialization.Json
import io.ktor.serialization.kotlinx.json.json
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.plugins.cachingheaders.CachingHeaders
import io.ktor.server.plugins.conditionalheaders.ConditionalHeaders
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
import io.ktor.server.plugins.statuspages.StatusPages
Expand All @@ -17,6 +18,7 @@ import io.ktor.server.plugins.statuspages.StatusPages
* @receiver The application on which this method is called.
*/
fun Application.installPlugins() {
install(CachingHeaders) { configure() }
install(ConditionalHeaders) { configure() }
install(ContentNegotiation) { json(Json) }
install(StatusPages) { configureStatusPages() }
Expand Down

0 comments on commit c571999

Please sign in to comment.