diff --git a/ktor-http/common/src/io/ktor/http/FileContentType.kt b/ktor-http/common/src/io/ktor/http/FileContentType.kt index 4241f843105..9bb1327ed22 100644 --- a/ktor-http/common/src/io/ktor/http/FileContentType.kt +++ b/ktor-http/common/src/io/ktor/http/FileContentType.kt @@ -65,18 +65,34 @@ private val extensionsByContentType: Map> by lazy { internal fun List.selectDefault(): ContentType { val contentType = firstOrNull() ?: ContentType.Application.OctetStream return when { - contentType.match(ContentType.Text.Any) && contentType.charset() == null -> contentType.withCharset( - Charsets.UTF_8 - ) + contentType.match(ContentType.Text.Any) -> contentType.withCharsetUTF8IfNeeded() + contentType.match(ContentType.Image.SVG) -> contentType.withCharsetUTF8IfNeeded() + contentType.matchApplicationTypeWithCharset() -> contentType.withCharsetUTF8IfNeeded() + else -> contentType + } +} - contentType.match(ContentType.Image.SVG) && contentType.charset() == null -> contentType.withCharset( - Charsets.UTF_8 - ) +private fun ContentType.matchApplicationTypeWithCharset(): Boolean { + if (!match(ContentType.Application.Any)) return false - else -> contentType + return when { + match(ContentType.Application.Atom) || + match(ContentType.Application.JavaScript) || + match(ContentType.Application.Rss) || + match(ContentType.Application.Xml) || + match(ContentType.Application.Xml_Dtd) + -> true + + else -> false } } +private fun ContentType.withCharsetUTF8IfNeeded(): ContentType { + if (charset() != null) return this + + return withCharset(Charsets.UTF_8) +} + internal fun Sequence>.groupByPairs() = groupBy { it.first } .mapValues { e -> e.value.map { it.second } } diff --git a/ktor-server/ktor-server-tests/jvm/test-resources/public/types/file.xml b/ktor-server/ktor-server-tests/jvm/test-resources/public/types/file.xml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ktor-server/ktor-server-tests/jvm/test/io/ktor/server/plugins/StaticContentTest.kt b/ktor-server/ktor-server-tests/jvm/test/io/ktor/server/plugins/StaticContentTest.kt index 8b5dd33349a..74c229881de 100644 --- a/ktor-server/ktor-server-tests/jvm/test/io/ktor/server/plugins/StaticContentTest.kt +++ b/ktor-server/ktor-server-tests/jvm/test/io/ktor/server/plugins/StaticContentTest.kt @@ -1260,7 +1260,8 @@ class StaticContentTest { val extensions = mapOf( "js" to ContentType.Text.JavaScript, "css" to ContentType.Text.CSS, - "svg" to ContentType.Image.SVG + "svg" to ContentType.Image.SVG, + "xml" to ContentType.Application.Xml, ) routing {