CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-ktor--ktor-client-core-iosx64

Ktor HTTP client core library - asynchronous framework for creating HTTP clients in Kotlin multiplatform

Pending
Overview
Eval results
Files

form-handling.mddocs/

Form Handling

Support for URL-encoded forms and multipart form data with file uploads, providing type-safe form submission capabilities.

Capabilities

FormDataContent Class

URL-encoded form content for simple form submissions.

/**
 * URL-encoded form content implementation
 */
class FormDataContent(val formData: Parameters) : OutgoingContent.ByteArrayContent() {
    /** Form parameters */
    val formData: Parameters
    
    /** Content length in bytes */
    override val contentLength: Long
    
    /** Content type (application/x-www-form-urlencoded) */
    override val contentType: ContentType
    
    /**
     * Get form data as byte array
     */
    override fun bytes(): ByteArray
}

Usage Examples:

import io.ktor.client.request.forms.*
import io.ktor.http.*

// Create form data
val formData = FormDataContent(Parameters.build {
    append("username", "john_doe")
    append("password", "secret123")
    append("remember", "true")
})

// Send form data
val response = client.post("https://api.example.com/login") {
    setBody(formData)
}

MultiPartFormDataContent Class

Multipart form data content for complex forms with file uploads.

/**
 * Multipart form data content implementation
 */
class MultiPartFormDataContent(
    parts: List<PartData>,
    boundary: String,
    contentType: ContentType = ContentType.MultiPart.FormData.withParameter("boundary", boundary)
) : OutgoingContent.WriteChannelContent() {
    /** Multipart boundary string */
    val boundary: String
    
    /** Content type (multipart/form-data) */
    override val contentType: ContentType
    
    /** Content length if determinable */
    override val contentLength: Long?
    
    /**
     * Write multipart content to channel
     */
    override suspend fun writeTo(channel: ByteWriteChannel)
}

Form Submission Functions

Convenience functions for submitting forms with various content types.

/**
 * Submit URL-encoded form
 */
suspend fun HttpClient.submitForm(
    formParameters: Parameters,
    encodeInQuery: Boolean = false,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

/**
 * Submit URL-encoded form with URL
 */
suspend fun HttpClient.submitForm(
    url: String,
    formParameters: Parameters,
    encodeInQuery: Boolean = false,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

/**
 * Submit multipart form with binary data
 */
suspend fun HttpClient.submitFormWithBinaryData(
    formData: List<PartData>,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

/**
 * Submit multipart form with binary data and URL
 */
suspend fun HttpClient.submitFormWithBinaryData(
    url: String,
    formData: List<PartData>,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

Usage Examples:

// Simple form submission
val loginParams = Parameters.build {
    append("username", "alice")
    append("password", "secret")
}

val loginResponse = client.submitForm(
    url = "https://api.example.com/login",
    formParameters = loginParams
) {
    headers["User-Agent"] = "MyApp/1.0"
}

// Form data in query string
val searchResponse = client.submitForm(
    url = "https://api.example.com/search",
    formParameters = Parameters.build {
        append("q", "kotlin")
        append("limit", "10")
    },
    encodeInQuery = true // Use GET with query parameters
)

// Multipart form with file upload
val uploadData = listOf(
    PartData.FormItem("title", "My Document"),
    PartData.FormItem("description", "Important document"),
    PartData.FileItem(
        provider = { ByteReadChannel(fileBytes) },
        dispose = {},
        partHeaders = headersOf(
            HttpHeaders.ContentDisposition,
            "form-data; name=\"file\"; filename=\"document.pdf\""
        )
    )
)

val uploadResponse = client.submitFormWithBinaryData(
    url = "https://api.example.com/upload",
    formData = uploadData
) {
    headers["Authorization"] = "Bearer $token"
}

Prepared Form Functions

Functions for creating reusable prepared form requests.

/**
 * Prepare URL-encoded form submission
 */
suspend fun HttpClient.prepareForm(
    formParameters: Parameters,
    encodeInQuery: Boolean = false,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpStatement

/**
 * Prepare URL-encoded form submission with URL
 */
suspend fun HttpClient.prepareForm(
    url: String,
    formParameters: Parameters,
    encodeInQuery: Boolean = false,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpStatement

/**
 * Prepare multipart form submission
 */
suspend fun HttpClient.prepareFormWithBinaryData(
    formData: List<PartData>,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpStatement

/**
 * Prepare multipart form submission with URL
 */
suspend fun HttpClient.prepareFormWithBinaryData(
    url: String,
    formData: List<PartData>,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpStatement

Usage Examples:

// Prepare reusable form
val loginForm = client.prepareForm(
    url = "https://api.example.com/login",
    formParameters = Parameters.build {
        append("username", "placeholder")
        append("password", "placeholder")
    }
)

// Use prepared form multiple times
val response1 = loginForm.execute { response ->
    // Custom response handling
    response.bodyAsText()
}

val response2 = loginForm.execute()

PartData Classes

Classes representing different types of form parts in multipart forms.

/**
 * Base class for multipart form parts
 */
sealed class PartData {
    abstract val headers: Headers
    abstract val name: String?
    
    /**
     * Simple form field
     */
    data class FormItem(
        override val name: String,
        val value: String,
        override val headers: Headers = Headers.Empty
    ) : PartData()
    
    /**
     * Binary file part
     */
    data class BinaryItem(
        override val name: String?,
        val contentType: ContentType?,
        override val headers: Headers = Headers.Empty,
        val provider: () -> ByteReadChannel
    ) : PartData()
    
    /**
     * File upload part
     */
    data class FileItem(
        override val name: String?,
        val originalFileName: String?,
        override val headers: Headers = Headers.Empty,
        val provider: () -> ByteReadChannel,
        val dispose: () -> Unit = {}
    ) : PartData()
    
    /**
     * Binary channel part
     */
    data class BinaryChannelItem(
        override val name: String?,
        val contentType: ContentType?,
        override val headers: Headers = Headers.Empty,
        val provider: () -> ByteReadChannel
    ) : PartData()
}

Usage Examples:

import io.ktor.http.content.*
import io.ktor.utils.io.*
import java.io.File

// Create different types of form parts
val formParts = listOf(
    // Simple text field
    PartData.FormItem("username", "alice"),
    
    // File upload from File object (JVM)
    PartData.FileItem(
        provider = { file.readChannel() },
        dispose = {},
        partHeaders = headersOf(
            HttpHeaders.ContentDisposition,
            "form-data; name=\"avatar\"; filename=\"avatar.jpg\""
        )
    ),
    
    // Binary data
    PartData.BinaryItem(
        name = "data",
        contentType = ContentType.Application.OctetStream,
        provider = { ByteReadChannel(binaryData) }
    ),
    
    // Binary channel
    PartData.BinaryChannelItem(
        name = "stream",
        contentType = ContentType.Text.Plain,
        provider = { dataChannel }
    )
)

// Submit multipart form
val response = client.submitFormWithBinaryData(
    url = "https://api.example.com/upload",
    formData = formParts
)

Form Building DSL

DSL for building form data with type safety.

/**
 * Build form parameters using DSL
 */
fun formParameters(block: ParametersBuilder.() -> Unit): Parameters =
    ParametersBuilder().apply(block).build()

/**
 * Build multipart form data using DSL
 */
fun multiPartFormData(block: MultiPartFormDataContent.Builder.() -> Unit): MultiPartFormDataContent

Usage Examples:

// Form parameters DSL
val params = formParameters {
    append("name", "John Doe")
    append("email", "john@example.com")
    append("subscribe", "true")
    appendAll("interests", listOf("kotlin", "web", "mobile"))
}

val response = client.submitForm(
    url = "https://api.example.com/register",
    formParameters = params
)

// Multipart form DSL
val multipart = multiPartFormData {
    // Add text fields
    append("title", "My Upload")
    append("description", "File description")
    
    // Add file
    append("file", fileBytes, Headers.build {
        append(HttpHeaders.ContentDisposition, "filename=document.pdf")
        append(HttpHeaders.ContentType, "application/pdf")
    })
}

val uploadResponse = client.post("https://api.example.com/upload") {
    setBody(multipart)
}

Install with Tessl CLI

npx tessl i tessl/maven-io-ktor--ktor-client-core-iosx64

docs

client-configuration.md

cookie-management.md

engine-configuration.md

form-handling.md

http-caching.md

index.md

plugin-system.md

request-building.md

response-handling.md

websocket-support.md

tile.json