Skip to content

Commit

Permalink
KTOR-7596 Make multipart Content-Type check case-insensitive
Browse files Browse the repository at this point in the history
  • Loading branch information
osipxd committed Oct 18, 2024
1 parent 0bbdf4f commit 9a99746
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
6 changes: 2 additions & 4 deletions ktor-http/ktor-http-cio/jvm/src/io/ktor/http/cio/Multipart.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.http.cio
Expand All @@ -11,7 +11,6 @@ import io.ktor.utils.io.core.*
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
import kotlinx.io.*
import kotlinx.io.IOException
import kotlinx.io.bytestring.*
import java.io.EOFException
import java.nio.*
Expand Down Expand Up @@ -148,14 +147,13 @@ public fun CoroutineScope.parseMultipart(
/**
* Starts a multipart parser coroutine producing multipart events
*/
@Suppress("DEPRECATION_ERROR")
public fun CoroutineScope.parseMultipart(
input: ByteReadChannel,
contentType: CharSequence,
contentLength: Long?,
maxPartSize: Long = Long.MAX_VALUE,
): ReceiveChannel<MultipartEvent> {
if (!contentType.startsWith("multipart/")) {
if (!contentType.startsWith("multipart/", ignoreCase = true)) {
throw IOException("Failed to parse multipart: Content-Type should be multipart/* but it is $contentType")
}
val boundaryByteBuffer = parseBoundaryInternal(contentType)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
* Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.tests.http.cio

import io.ktor.http.cio.*
import io.ktor.utils.io.*
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*
import kotlinx.coroutines.test.*
import kotlinx.io.*
import kotlin.test.*

@OptIn(DelicateCoroutinesApi::class)
Expand Down Expand Up @@ -335,6 +337,17 @@ class MultipartTest {
}
}

@Test
fun testParseContentType() = runTest {
fun testContentType(contentType: String) {
parseMultipart(ByteReadChannel.Empty, "$contentType; boundary=A", 0L)
}

testContentType("multipart/mixed")
testContentType("Multipart/mixed")
assertFailsWith<IOException> { testContentType("multi-part/mixed") }
}

@OptIn(DelicateCoroutinesApi::class)
@Test
fun testEmptyPayload() = runBlocking {
Expand Down

0 comments on commit 9a99746

Please sign in to comment.