Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support oneshot forms #8160

Merged
merged 3 commits into from
Dec 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions okhttp/api/okhttp.api
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,7 @@ public final class okhttp3/MultipartBody : okhttp3/RequestBody {
public final fun boundary ()Ljava/lang/String;
public fun contentLength ()J
public fun contentType ()Lokhttp3/MediaType;
public fun isOneShot ()Z
public final fun part (I)Lokhttp3/MultipartBody$Part;
public final fun parts ()Ljava/util/List;
public final fun size ()I
Expand Down
4 changes: 4 additions & 0 deletions okhttp/src/main/kotlin/okhttp3/MultipartBody.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ class MultipartBody internal constructor(

fun part(index: Int): Part = parts[index]

override fun isOneShot(): Boolean {
return parts.any { it.body.isOneShot() }
}

/** A combination of [type] and [boundaryByteString]. */
override fun contentType(): MediaType = contentType

Expand Down
63 changes: 63 additions & 0 deletions okhttp/src/test/java/okhttp3/MultipartBodyTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody
import okio.Buffer
import okio.BufferedSink
import okio.ByteString.Companion.encodeUtf8
import okio.utf8Size
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.fail
import org.junit.jupiter.api.Test
Expand Down Expand Up @@ -298,4 +300,65 @@ class MultipartBodyTest {
body.writeTo(buffer)
assertThat(buffer.readUtf8()).isEqualTo(expected)
}

@Test
fun writeTwice() {
val expected = """
|--123
|
|Hello, World!
|--123--
|
""".trimMargin().replace("\n", "\r\n")
val body = MultipartBody.Builder("123")
.addPart("Hello, World!".toRequestBody(null))
.build()

assertThat(body.isOneShot()).isEqualTo(false)

val buffer = Buffer()
body.writeTo(buffer)
assertThat(body.contentLength()).isEqualTo(buffer.size)
assertThat(buffer.readUtf8()).isEqualTo(expected)

val buffer2 = Buffer()
body.writeTo(buffer2)
assertThat(body.contentLength()).isEqualTo(buffer2.size)
assertThat(buffer2.readUtf8()).isEqualTo(expected)
}

@Test
fun writeTwiceWithOneShot() {
val expected = """
|--123
|
|Hello, World!
|--123--
|
""".trimMargin().replace("\n", "\r\n")
val body = MultipartBody.Builder("123")
.addPart("Hello, World!".toOneShotRequestBody())
.build()

assertThat(body.isOneShot()).isEqualTo(true)

val buffer = Buffer()
body.writeTo(buffer)
assertThat(body.contentLength()).isEqualTo(buffer.size)
assertThat(buffer.readUtf8()).isEqualTo(expected)
}

fun String.toOneShotRequestBody(): RequestBody {
return object : RequestBody() {
override fun contentType() = null

override fun isOneShot(): Boolean = true

override fun contentLength() = [email protected]()

override fun writeTo(sink: BufferedSink) {
sink.writeUtf8(this@toOneShotRequestBody)
}
}
}
}