JVM-specific HTTP utilities and extensions for the Ktor framework providing URL utilities, file content type detection, HTTP message properties, and content handling for JVM platforms
—
HTTP authentication header parsing and generation supporting Basic, Bearer, Digest, and custom authentication schemes with parameter handling and encoding options.
Abstract base class for HTTP authentication headers with rendering support.
/**
* Base class for HTTP authentication headers
*/
abstract class HttpAuthHeader {
/**
* Authentication scheme name (e.g., "Basic", "Bearer")
*/
val authScheme: String
/**
* Render header value with default encoding
*/
abstract fun render(): String
/**
* Render header value with specified encoding
* @param encoding header value encoding strategy
*/
abstract fun render(encoding: HeaderValueEncoding): String
companion object {
/**
* Create Basic authentication challenge
* @param realm authentication realm
* @param charset character set for encoding
*/
fun basicAuthChallenge(
realm: String,
charset: Charset = Charsets.UTF_8
): Parameterized
/**
* Create Bearer authentication challenge
* @param realm optional realm
* @param scope optional scope
*/
fun bearerAuthChallenge(
realm: String? = null,
scope: String? = null
): HttpAuthHeader
/**
* Create Digest authentication challenge
* @param realm authentication realm
* @param nonce server nonce value
* @param domain list of protected URIs
* @param opaque opaque value
* @param stale whether credentials are stale
* @param algorithm digest algorithm
*/
fun digestAuthChallenge(
realm: String,
nonce: String,
domain: List<String> = emptyList(),
opaque: String? = null,
stale: Boolean? = null,
algorithm: String? = null
): Parameterized
}
}Simple authentication header with single blob value.
/**
* Simple authentication header with blob value
*/
class HttpAuthHeader.Single(
authScheme: String,
val blob: String
) : HttpAuthHeader {
override fun render(): String
override fun render(encoding: HeaderValueEncoding): String
}Authentication header with parameters for complex schemes like Digest.
/**
* Authentication header with parameters
*/
class HttpAuthHeader.Parameterized(
authScheme: String,
val parameters: List<HeaderValueParam>,
val encoding: HeaderValueEncoding = HeaderValueEncoding.QUOTED_WHEN_REQUIRED
) : HttpAuthHeader {
/**
* Constructor from parameter map
*/
constructor(
authScheme: String,
parameters: Map<String, String>,
encoding: HeaderValueEncoding = HeaderValueEncoding.QUOTED_WHEN_REQUIRED
)
/**
* Get parameter value by name
* @param name parameter name
* @return parameter value or null
*/
fun parameter(name: String): String?
/**
* Add parameter to header
* @param name parameter name
* @param value parameter value
* @return new Parameterized header with added parameter
*/
fun withParameter(name: String, value: String): Parameterized
/**
* Replace parameter in header
* @param name parameter name
* @param value new parameter value
* @return new Parameterized header with replaced parameter
*/
fun withReplacedParameter(name: String, value: String): Parameterized
override fun render(): String
override fun render(encoding: HeaderValueEncoding): String
}Constants for standard authentication schemes.
/**
* Standard authentication scheme names
*/
object AuthScheme {
const val Basic: String = "Basic"
const val Bearer: String = "Bearer"
const val Digest: String = "Digest"
const val OAuth: String = "OAuth"
const val Negotiate: String = "Negotiate"
}Constants for standard authentication parameters.
/**
* Standard authentication header parameters
*/
object HttpAuthHeader.Parameters {
const val Realm: String = "realm"
const val Charset: String = "charset"
// OAuth parameters
const val OAuthCallback: String = "oauth_callback"
const val OAuthCallbackConfirmed: String = "oauth_callback_confirmed"
const val OAuthConsumerKey: String = "oauth_consumer_key"
const val OAuthNonce: String = "oauth_nonce"
const val OAuthSignature: String = "oauth_signature"
const val OAuthSignatureMethod: String = "oauth_signature_method"
const val OAuthTimestamp: String = "oauth_timestamp"
const val OAuthToken: String = "oauth_token"
const val OAuthTokenSecret: String = "oauth_token_secret"
const val OAuthVerifier: String = "oauth_verifier"
const val OAuthVersion: String = "oauth_version"
}Encoding strategies for authentication header values.
/**
* Header value encoding strategies
*/
enum class HeaderValueEncoding {
/**
* Quote values only when required by RFC
*/
QUOTED_WHEN_REQUIRED,
/**
* Always quote values
*/
QUOTED_ALWAYS,
/**
* URI encode values
*/
URI_ENCODE
}Functions for parsing Authorization and WWW-Authenticate headers.
/**
* Parse Authorization header value
* @param headerValue header value string
* @return HttpAuthHeader instance or null if invalid
*/
fun parseAuthorizationHeader(headerValue: String): HttpAuthHeader?
/**
* Parse multiple authorization headers
* @param headerValue header value string
* @return List of HttpAuthHeader instances
*/
fun parseAuthorizationHeaders(headerValue: String): List<HttpAuthHeader>Usage Examples:
import io.ktor.http.auth.*
import io.ktor.http.*
import java.util.*
// Create Basic authentication challenge
val basicChallenge = HttpAuthHeader.basicAuthChallenge(
realm = "Secure Area",
charset = Charsets.UTF_8
)
println(basicChallenge.render()) // Basic realm="Secure Area"
// Create Bearer authentication challenge
val bearerChallenge = HttpAuthHeader.bearerAuthChallenge(
realm = "api",
scope = "read write"
)
println(bearerChallenge.render()) // Bearer realm="api" scope="read write"
// Create Digest authentication challenge
val digestChallenge = HttpAuthHeader.digestAuthChallenge(
realm = "Protected Area",
nonce = UUID.randomUUID().toString(),
domain = listOf("/api", "/secure"),
opaque = "opaque-value",
stale = false,
algorithm = "MD5"
)
// Create custom parameterized header
val customAuth = HttpAuthHeader.Parameterized(
authScheme = "Custom",
parameters = mapOf(
"token" to "abc123",
"expires" to "3600"
),
encoding = HeaderValueEncoding.QUOTED_ALWAYS
)
// Add parameters to existing header
val updatedAuth = digestChallenge.withParameter("qop", "auth")
val replacedAuth = updatedAuth.withReplacedParameter("nonce", "new-nonce")
// Access parameters
val realm = digestChallenge.parameter("realm") // "Protected Area"
val nonce = digestChallenge.parameter("nonce")
// Create simple auth header
val apiKeyAuth = HttpAuthHeader.Single(
authScheme = "ApiKey",
blob = "key-12345"
)
// Parse authorization headers
val authHeaderValue = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
val parsedAuth = parseAuthorizationHeader(authHeaderValue)
when (parsedAuth) {
is HttpAuthHeader.Single -> {
println("Scheme: ${parsedAuth.authScheme}")
println("Token: ${parsedAuth.blob}")
}
is HttpAuthHeader.Parameterized -> {
println("Scheme: ${parsedAuth.authScheme}")
parsedAuth.parameters.forEach { param ->
println("${param.name}: ${param.value}")
}
}
}
// Parse multiple auth headers
val multiAuthValue = "Basic dXNlcjpwYXNz, Bearer token123"
val parsedHeaders = parseAuthorizationHeaders(multiAuthValue)
// Render with different encodings
val header = HttpAuthHeader.Parameterized(
authScheme = "Test",
parameters = mapOf("value" to "needs quoting")
)
println(header.render(HeaderValueEncoding.QUOTED_WHEN_REQUIRED))
println(header.render(HeaderValueEncoding.QUOTED_ALWAYS))
println(header.render(HeaderValueEncoding.URI_ENCODE))
// Use in HTTP headers
val headers = headers {
append(HttpHeaders.Authorization, parsedAuth.render())
append(HttpHeaders.WWWAuthenticate, basicChallenge.render())
}
// Common authentication patterns
fun createBasicAuth(username: String, password: String): HttpAuthHeader.Single {
val credentials = "$username:$password"
val encoded = Base64.getEncoder().encodeToString(credentials.toByteArray())
return HttpAuthHeader.Single(AuthScheme.Basic, encoded)
}
fun createBearerAuth(token: String): HttpAuthHeader.Single {
return HttpAuthHeader.Single(AuthScheme.Bearer, token)
}
// Usage
val basicAuth = createBasicAuth("user", "password")
val bearerAuth = createBearerAuth("jwt-token-here")All types are defined above in their respective capability sections.
Install with Tessl CLI
npx tessl i tessl/maven-io-ktor--ktor-http-jvm