Skip to content

Commit 355e990

Browse files
authored
KTOR-3757 Allow specifying custom CacheControl directives (#3318)
1 parent 20099e0 commit 355e990

File tree

4 files changed

+31
-5
lines changed

4 files changed

+31
-5
lines changed

ktor-http/api/ktor-http.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public final class io/ktor/http/BadContentTypeFormatException : java/lang/Except
77
}
88

99
public abstract class io/ktor/http/CacheControl {
10-
public synthetic fun <init> (Lio/ktor/http/CacheControl$Visibility;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
10+
public fun <init> (Lio/ktor/http/CacheControl$Visibility;)V
1111
public final fun getVisibility ()Lio/ktor/http/CacheControl$Visibility;
1212
}
1313

ktor-http/common/src/io/ktor/http/CacheControl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ package io.ktor.http
99
*
1010
* @param visibility specifies an optional visibility such as private or public
1111
*/
12-
public sealed class CacheControl(public val visibility: Visibility?) {
12+
public abstract class CacheControl(public val visibility: Visibility?) {
1313

1414
/**
1515
* Controls caching by proxies

ktor-server/ktor-server-plugins/ktor-server-caching-headers/jvmAndNix/src/io/ktor/server/plugins/cachingheaders/CacheControlMerge.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import io.ktor.http.*
1212
* Currently, visibility is pinned to the expiration directive,
1313
* then to the first no-cache,
1414
* then to the no-store directive.
15-
* The RFC doesn't state, where a visibility modifier should be so we can place it at any place
16-
* so there is nothing behind the rule beyond, therefore could be changed.
15+
* The RFC doesn't state where a visibility modifier should be, so we can place it at any place
16+
* so there is nothing behind the rule beyond, therefore, could be changed.
1717
*
1818
* Only one visibility specifier is kept.
1919
*
@@ -26,7 +26,7 @@ import io.ktor.http.*
2626
*
2727
* Revalidation directives are collected as well.
2828
* Currently, revalidation directives are tied to max age by-design.
29-
* This is not fair according to RFC so will be changed in the future.
29+
* This is not fair, according to RFC, so it will be changed in the future.
3030
*/
3131
internal fun List<CacheControl>.mergeCacheControlDirectives(): List<CacheControl> {
3232
if (size < 2) return this
@@ -50,6 +50,12 @@ internal fun List<CacheControl>.mergeCacheControlDirectives(): List<CacheControl
5050
noCacheDirective?.let { add(CacheControl.NoCache(null)) }
5151
noStoreDirective?.let { add(CacheControl.NoStore(null)) }
5252

53+
this@mergeCacheControlDirectives
54+
.filter {
55+
it !is CacheControl.NoCache && it !is CacheControl.NoStore && it !is CacheControl.MaxAge
56+
}
57+
.let { addAll(it) }
58+
5359
if (maxAgeDirectives.isNotEmpty()) {
5460
add(
5561
CacheControl.MaxAge(

ktor-server/ktor-server-tests/jvmAndNix/test/io/ktor/tests/server/plugins/CachingHeadersTest.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,26 @@ class CachingHeadersTest {
6262
}
6363
)
6464

65+
object Immutable: CacheControl(null) {
66+
override fun toString(): String = "immutable"
67+
}
68+
69+
@Test
70+
fun testCustomCacheControl(): Unit = test(
71+
configure = {
72+
install(CachingHeaders) {
73+
options { _, _ -> CachingOptions(CacheControl.NoStore(CacheControl.Visibility.Private)) }
74+
options { _, _ -> CachingOptions(Immutable) }
75+
}
76+
},
77+
test = { response ->
78+
assertEquals(
79+
"no-cache, private, no-store, immutable",
80+
response.headers[HttpHeaders.CacheControl]
81+
)
82+
}
83+
)
84+
6585
@Test
6686
fun testSetInCall() = testApplication {
6787
install(CachingHeaders)

0 commit comments

Comments
 (0)