Skip to content

Commit

Permalink
KTOR-7934 Remove Content-Length for browser
Browse files Browse the repository at this point in the history
  • Loading branch information
bjhham committed Jan 23, 2025
1 parent 4fd2282 commit fb4e99b
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ private val DecompressionListAttribute: AttributeKey<MutableList<String>> = Attr
* (like js and Curl) to make sure all the plugins and checks work with the correct content length and encoding.
*/
@InternalAPI
public fun HeadersBuilder.dropCompressionHeaders(method: HttpMethod, attributes: Attributes) {
public fun HeadersBuilder.dropCompressionHeaders(
method: HttpMethod,
attributes: Attributes,
alwaysRemove: Boolean = false,
) {
if (method == HttpMethod.Head || method == HttpMethod.Options) return
val header = get(HttpHeaders.ContentEncoding) ?: return
attributes.computeIfAbsent(DecompressionListAttribute) { mutableListOf<String>() }.add(header)
when(val header = get(HttpHeaders.ContentEncoding)) {
null -> if (!alwaysRemove) return
else -> attributes.computeIfAbsent(DecompressionListAttribute) { mutableListOf<String>() }.add(header)
}
remove(HttpHeaders.ContentEncoding)
remove(HttpHeaders.ContentLength)
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,13 @@ internal fun org.w3c.fetch.Headers.mapToKtor(method: HttpMethod, attributes: Att
append(key, value)
}

dropCompressionHeaders(method, attributes)
// Content-Encoding is hidden for cross-origin calls,
// so browser requests should always ignore Content-Length
dropCompressionHeaders(
method,
attributes,
alwaysRemove = PlatformUtils.IS_BROWSER
)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ abstract class ClientLoader(private val timeout: Duration = 1.minutes) {
return EngineSelectionRule { pattern.matches(it) }
}

/** Includes the set of [engines] for the test */
fun only(vararg engines: String): EngineSelectionRule {
val includePatterns = engines.map(EnginePattern::parse)
return EngineSelectionRule { engineName -> includePatterns.any { it.matches(engineName) } }
}

/** Excludes the specified [engines] from test execution. */
fun except(vararg engines: String): EngineSelectionRule = except(engines.asList())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ContentEncodingIntegrationTest : ClientLoader() {

// GZipEncoder is implemented only on JVM.
@Test
fun testGzipWithContentLengthWithoutPlugin() = clientTests(only("jvm:*")) {
fun testGzipWithContentLengthWithoutPlugin() = clientTests(only("jvm:*", "web:Js")) {
test { client ->
val response = client.get("$TEST_URL/gzip-with-content-length")
val content = if (response.headers[HttpHeaders.ContentEncoding] == "gzip") {
Expand All @@ -43,4 +43,5 @@ class ContentEncodingIntegrationTest : ClientLoader() {
assertEquals("32", response.headers[HttpHeaders.ContentLength])
}
}

}

0 comments on commit fb4e99b

Please sign in to comment.