Ktor utilities library for JVM platform containing common utility functions, cryptographic operations, date handling, logging utilities, pipeline functionality, I/O adapters, encoding/decoding utilities, network address handling, and various platform-specific implementations for the Ktor framework.
—
String handling utilities including case-insensitive operations, HTML processing, and multi-value string collections. Provides a comprehensive system for managing collections of string values with support for case-insensitive operations.
Core interface for associating string names with lists of string values, commonly used for headers, parameters, and form data.
/**
* Data structure for associating a String with a List of Strings
*/
interface StringValues {
/** Specifies if map has case-sensitive or case-insensitive names */
val caseInsensitiveName: Boolean
/** Gets first value associated with name, or null if not present */
operator fun get(name: String): String?
/** Gets all values associated with name, or null if not present */
fun getAll(name: String): List<String>?
/** Gets all names from the map */
fun names(): Set<String>
/** Gets all entries from the map */
fun entries(): Set<Map.Entry<String, List<String>>>
/** Checks if the given name exists in the map */
operator fun contains(name: String): Boolean
/** Checks if the given name and value pair exists */
fun contains(name: String, value: String): Boolean
/** Iterates over all entries calling body for each pair */
fun forEach(body: (String, List<String>) -> Unit)
/** Checks if this map is empty */
fun isEmpty(): Boolean
}Usage Examples:
import io.ktor.util.*
// Create StringValues with case-insensitive names
val headers = StringValues.build(caseInsensitiveName = true) {
append("Content-Type", "application/json")
append("Accept", "application/json")
append("Accept", "text/html")
}
// Access values
println(headers["content-type"]) // "application/json" (case-insensitive)
println(headers.getAll("Accept")) // ["application/json", "text/html"]
// Check existence
if ("Content-Type" in headers) {
println("Content-Type header is present")
}
// Iterate over entries
headers.forEach { name, values ->
println("$name: ${values.joinToString(", ")}")
}Builder interface for constructing StringValues instances with mutable operations.
/**
* Builder interface for constructing StringValues
*/
interface StringValuesBuilder {
val caseInsensitiveName: Boolean
/** Gets all values associated with name */
fun getAll(name: String): List<String>?
/** Checks if name exists */
operator fun contains(name: String): Boolean
/** Checks if name and value pair exists */
fun contains(name: String, value: String): Boolean
/** Gets all names */
fun names(): Set<String>
/** Checks if builder is empty */
fun isEmpty(): Boolean
/** Gets all entries */
fun entries(): Set<Map.Entry<String, List<String>>>
/** Sets single value for name (replaces existing) */
operator fun set(name: String, value: String)
/** Gets first value for name */
operator fun get(name: String): String?
/** Appends value to name */
fun append(name: String, value: String)
/** Appends all values from another StringValues */
fun appendAll(stringValues: StringValues)
/** Appends all values for name from iterable */
fun appendAll(name: String, values: Iterable<String>)
/** Appends missing values from another StringValues */
fun appendMissing(stringValues: StringValues)
/** Appends missing values for name from iterable */
fun appendMissing(name: String, values: Iterable<String>)
/** Removes all values for name */
fun remove(name: String)
/** Removes keys with no entries */
fun removeKeysWithNoEntries()
/** Removes specific name-value pair */
fun remove(name: String, value: String): Boolean
/** Clears all entries */
fun clear()
/** Builds final StringValues instance */
fun build(): StringValues
}Usage Examples:
import io.ktor.util.*
// Build StringValues step by step
val builder = StringValuesBuilderImpl(caseInsensitiveName = true)
// Add values
builder.append("header1", "value1")
builder.append("header1", "value2")
builder["header2"] = "single-value"
// Modify values
builder.remove("header1", "value1") // Remove specific value
builder.appendAll("header3", listOf("a", "b", "c"))
// Build final result
val result = builder.build()Convenient functions for creating StringValues instances.
/**
* Build StringValues from vararg pairs
*/
fun valuesOf(
vararg pairs: Pair<String, List<String>>,
caseInsensitiveKey: Boolean = false
): StringValues
/**
* Build StringValues from single name-value pair
*/
fun valuesOf(name: String, value: String, caseInsensitiveKey: Boolean = false): StringValues
/**
* Build StringValues from single name with multiple values
*/
fun valuesOf(name: String, values: List<String>, caseInsensitiveKey: Boolean = false): StringValues
/**
* Build empty StringValues
*/
fun valuesOf(): StringValues
/**
* Build StringValues from map
*/
fun valuesOf(map: Map<String, Iterable<String>>, caseInsensitiveKey: Boolean = false): StringValuesUsage Examples:
import io.ktor.util.*
// Create from pairs
val headers1 = valuesOf(
"Content-Type" to listOf("application/json"),
"Accept" to listOf("application/json", "text/html"),
caseInsensitiveKey = true
)
// Create from single value
val headers2 = valuesOf("Content-Type", "application/json")
// Create from multiple values
val headers3 = valuesOf("Accept", listOf("json", "html"))
// Create empty
val empty = valuesOf()
// Create from map
val map = mapOf(
"Content-Type" to listOf("application/json"),
"Accept" to listOf("application/json", "text/html")
)
val headers4 = valuesOf(map, caseInsensitiveKey = true)Utility functions for working with StringValues instances.
/**
* Copy values to a new independent map
*/
fun StringValues.toMap(): Map<String, List<String>>
/**
* Copy values to a list of name-value pairs
*/
fun StringValues.flattenEntries(): List<Pair<String, String>>
/**
* Invoke block function for every name-value pair
*/
fun StringValues.flattenForEach(block: (String, String) -> Unit)
/**
* Create filtered StringValues by predicate
*/
fun StringValues.filter(
keepEmpty: Boolean = false,
predicate: (String, String) -> Boolean
): StringValuesUsage Examples:
import io.ktor.util.*
val headers = valuesOf(
"Accept" to listOf("application/json", "text/html"),
"Content-Type" to listOf("application/json")
)
// Convert to map
val map = headers.toMap()
// Flatten to pairs
val pairs = headers.flattenEntries()
// Result: [("Accept", "application/json"), ("Accept", "text/html"), ("Content-Type", "application/json")]
// Process each name-value pair
headers.flattenForEach { name, value ->
println("$name: $value")
}
// Filter values
val jsonOnly = headers.filter { name, value ->
value.contains("json")
}Additional utility functions for building StringValues.
/**
* Append values from source filtering by predicate
*/
fun StringValuesBuilder.appendFiltered(
source: StringValues,
keepEmpty: Boolean = false,
predicate: (String, String) -> Boolean
)
/**
* Append all values from another builder
*/
fun StringValuesBuilder.appendAll(builder: StringValuesBuilder): StringValuesBuilder
/**
* Append name-value pair if name is absent
*/
fun StringValuesBuilder.appendIfNameAbsent(name: String, value: String): StringValuesBuilder
/**
* Append name-value pair if both name and value are absent
*/
fun StringValuesBuilder.appendIfNameAndValueAbsent(name: String, value: String): StringValuesBuilder
/**
* Append multiple key-value pairs
*/
fun StringValuesBuilder.appendAll(vararg values: Pair<String, String>): StringValuesBuilder
/**
* Append multiple key-value pairs where values are Iterable
*/
fun StringValuesBuilder.appendAll(vararg values: Pair<String, Iterable<String>>): StringValuesBuilder
/**
* Append from map where values are Iterable
*/
fun StringValuesBuilder.appendAll(values: Map<String, Iterable<String>>): StringValuesBuilder
/**
* Append from map with single string values
*/
fun StringValuesBuilder.appendAll(values: Map<String, String>): StringValuesBuilderUsage Examples:
import io.ktor.util.*
val builder = StringValuesBuilderImpl()
// Append conditionally
builder.appendIfNameAbsent("Content-Type", "application/json")
builder.appendIfNameAndValueAbsent("Accept", "text/html")
// Append multiple pairs
builder.appendAll(
"header1" to "value1",
"header2" to "value2"
)
// Append from map
val additionalHeaders = mapOf(
"Cache-Control" to "no-cache",
"User-Agent" to "Ktor Client"
)
builder.appendAll(additionalHeaders)Additional text processing functions for HTML and case conversion.
/**
* Escape HTML special characters in string
*/
fun String.escapeHTML(): String
/**
* Convert to lowercase preserving ASCII rules
*/
fun String.toLowerCasePreservingASCIIRules(): StringUsage Examples:
import io.ktor.util.*
// HTML escaping
val html = "<script>alert('xss')</script>"
val escaped = html.escapeHTML()
println(escaped) // "<script>alert('xss')</script>"
// Case conversion
val mixed = "Content-TYPE"
val lower = mixed.toLowerCasePreservingASCIIRules()
println(lower) // "content-type"/**
* Default implementation of StringValues
*/
open class StringValuesImpl(
override val caseInsensitiveName: Boolean = false,
values: Map<String, List<String>> = emptyMap()
) : StringValues
/**
* Optimized StringValues for single name-value mapping
*/
open class StringValuesSingleImpl(
override val caseInsensitiveName: Boolean,
val name: String,
val values: List<String>
) : StringValues
/**
* Default builder implementation
*/
open class StringValuesBuilderImpl(
override val caseInsensitiveName: Boolean = false,
size: Int = 8
) : StringValuesBuilderInstall with Tessl CLI
npx tessl i tessl/maven-io-ktor--ktor-utils-jvm