Multiplatform asynchronous HTTP client core library for JVM that provides request/response handling, plugin architecture, and extensible HTTP communication capabilities.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
HTTP engine abstraction and configuration for different backend implementations like Apache HttpClient, OkHttp, and CIO. The engine system provides a pluggable architecture that allows switching between different HTTP implementations while maintaining a consistent API.
Base interface for all HTTP client engines providing the core execution and lifecycle management.
/**
* Base interface for HTTP client engines
*/
interface HttpClientEngine : CoroutineScope, Closeable {
/** Coroutine dispatcher for I/O operations */
val dispatcher: CoroutineDispatcher
/** Engine configuration */
val config: HttpClientEngineConfig
/** Set of capabilities supported by this engine */
val supportedCapabilities: Set<HttpClientEngineCapability<*>>
/** Coroutine context for the engine */
override val coroutineContext: CoroutineContext
/**
* Execute an HTTP request and return response data
*/
suspend fun execute(data: HttpRequestData): HttpResponseData
/**
* Install this engine into the specified client
*/
fun install(client: HttpClient)
/**
* Close the engine and release resources
*/
override fun close()
}Factory interface for creating engine instances with configuration.
/**
* Factory for creating HTTP client engines
*/
interface HttpClientEngineFactory<out T : HttpClientEngineConfig> {
/**
* Create an engine instance with the given configuration
*/
fun create(block: T.() -> Unit = {}): HttpClientEngine
}Base configuration class for all HTTP engines with common settings.
/**
* Base configuration for HTTP client engines
*/
abstract class HttpClientEngineConfig {
/** Custom coroutine dispatcher for I/O operations */
var dispatcher: CoroutineDispatcher? = null
/** Enable HTTP pipelining (where supported) */
var pipelining: Boolean = false
/** Proxy configuration */
var proxy: ProxyConfig? = null
/** Number of threads in the engine thread pool */
var threadsCount: Int = 4
}System for declaring and checking engine capabilities.
/**
* Represents a capability that an engine may support
*/
class HttpClientEngineCapability<T>(name: String) {
companion object {
/**
* Create a new capability with the given name
*/
fun <T> create(name: String): HttpClientEngineCapability<T>
}
}
/**
* Common engine capabilities
*/
object EngineCapabilities {
/** WebSocket support capability */
val WebSocketCapability: HttpClientEngineCapability<Unit>
/** HTTP/2 support capability */
val HTTP2Capability: HttpClientEngineCapability<Unit>
/** Server-Sent Events support capability */
val SSECapability: HttpClientEngineCapability<Unit>
}Proxy support for routing requests through intermediary servers.
/**
* Base proxy configuration
*/
abstract class ProxyConfig {
/** Proxy server URL */
abstract val url: Url
}
/**
* HTTP proxy configuration
*/
class ProxyBuilder {
companion object {
/**
* Create HTTP proxy configuration
*/
fun http(url: String): ProxyConfig
/**
* Create SOCKS proxy configuration
*/
fun socks(host: String, port: Int): ProxyConfig
}
}JVM-specific proxy configuration with authentication support.
/**
* JVM HTTP proxy configuration with authentication
*/
class HttpProxyConfig(
override val url: Url
) : ProxyConfig() {
/** Proxy authentication credentials */
var credentials: ProxyCredentials? = null
}
/**
* JVM SOCKS proxy configuration
*/
class SocksProxyConfig(
override val url: Url
) : ProxyConfig() {
/** SOCKS version (4 or 5) */
var version: Int = 5
/** SOCKS authentication credentials */
var credentials: ProxyCredentials? = null
}
/**
* Proxy authentication credentials
*/
data class ProxyCredentials(
val username: String,
val password: String
)ServiceLoader mechanism for automatic engine discovery on JVM platform.
/**
* ServiceLoader container for engine discovery
*/
interface HttpClientEngineContainer {
/** Engine factory instance */
val factory: HttpClientEngineFactory<*>
}
/**
* Load available engines using ServiceLoader
*/
fun loadEngines(): List<HttpClientEngineFactory<*>>
/**
* Get default engine factory
*/
fun getDefaultEngine(): HttpClientEngineFactory<*>Connection pooling and lifecycle management configuration.
/**
* Connection pool configuration base class
*/
abstract class ConnectionPoolConfig {
/** Maximum number of connections per route */
var maxConnectionsPerRoute: Int = 5
/** Maximum total number of connections */
var maxConnectionsTotal: Int = 20
/** Connection keep-alive time in milliseconds */
var keepAliveTime: Long = 60_000
/** Connection idle timeout in milliseconds */
var connectionIdleTimeout: Long = 30_000
}Configuration classes for different engine implementations.
/**
* Apache HttpClient engine configuration
*/
class ApacheEngineConfig : HttpClientEngineConfig() {
/** Socket timeout in milliseconds */
var socketTimeout: Int = 0
/** Connection timeout in milliseconds */
var connectTimeout: Int = 0
/** Connection request timeout in milliseconds */
var connectionRequestTimeout: Int = 0
/** Custom SSL context */
var sslContext: SSLContext? = null
/** Follow redirects automatically */
var followRedirects: Boolean = true
/** Custom connection manager */
var customizeClient: (HttpClientBuilder) -> Unit = {}
/** Custom request configuration */
var customizeRequest: (RequestConfig.Builder) -> Unit = {}
}
/**
* OkHttp engine configuration
*/
class OkHttpConfig : HttpClientEngineConfig() {
/** Connection timeout in milliseconds */
var connectTimeout: Duration = Duration.ofSeconds(10)
/** Read timeout in milliseconds */
var readTimeout: Duration = Duration.ofSeconds(10)
/** Write timeout in milliseconds */
var writeTimeout: Duration = Duration.ofSeconds(10)
/** Follow redirects automatically */
var followRedirects: Boolean = true
/** Follow SSL redirects automatically */
var followSslRedirects: Boolean = true
/** Custom OkHttpClient configuration */
var config: OkHttpClient.Builder.() -> Unit = {}
/** Add network interceptor */
fun addNetworkInterceptor(interceptor: Interceptor)
/** Add application interceptor */
fun addInterceptor(interceptor: Interceptor)
}
/**
* CIO (Coroutine I/O) engine configuration
*/
class CIOEngineConfig : HttpClientEngineConfig() {
/** Maximum number of connections */
var maxConnectionsCount: Int = 1000
/** Endpoint configuration */
var endpoint: EndpointConfig = EndpointConfig()
/** HTTPS configuration */
var https: HttpsConfig = HttpsConfig()
/** Request timeout in milliseconds */
var requestTimeout: Long = 15_000
}
/**
* Java HTTP client engine configuration (Java 11+)
*/
class JavaHttpEngineConfig : HttpClientEngineConfig() {
/** HTTP version preference */
var version: HttpClient.Version = HttpClient.Version.HTTP_2
/** Follow redirects policy */
var followRedirects: HttpClient.Redirect = HttpClient.Redirect.NORMAL
/** Connection timeout */
var connectTimeout: Duration = Duration.ofSeconds(10)
/** Custom Java HttpClient configuration */
var config: HttpClient.Builder.() -> Unit = {}
}Usage Examples:
import io.ktor.client.*
import io.ktor.client.engine.apache.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.engine.cio.*
import io.ktor.client.engine.java.*
import io.ktor.client.request.*
// Apache HttpClient engine
val apacheClient = HttpClient(Apache) {
engine {
socketTimeout = 30_000
connectTimeout = 10_000
connectionRequestTimeout = 5_000
followRedirects = false
// Custom SSL configuration
sslContext = SSLContext.getDefault()
// Proxy configuration
proxy = ProxyBuilder.http("http://proxy.company.com:8080")
// Custom client configuration
customizeClient { builder ->
builder.setMaxConnPerRoute(10)
builder.setMaxConnTotal(50)
}
// Custom request configuration
customizeRequest { requestConfig ->
requestConfig.setSocketTimeout(25_000)
}
}
}
// OkHttp engine
val okHttpClient = HttpClient(OkHttp) {
engine {
connectTimeout = Duration.ofSeconds(15)
readTimeout = Duration.ofSeconds(30)
writeTimeout = Duration.ofSeconds(30)
followRedirects = true
followSslRedirects = true
// Proxy configuration
proxy = ProxyBuilder.socks("socks.proxy.com", 1080)
// Custom OkHttp configuration
config {
retryOnConnectionFailure(true)
connectionPool(ConnectionPool(10, 5, TimeUnit.MINUTES))
// Add interceptors
addInterceptor { chain ->
val request = chain.request().newBuilder()
.addHeader("User-Agent", "MyApp/1.0")
.build()
chain.proceed(request)
}
}
// Add network interceptor
addNetworkInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
}
}
// CIO engine (Kotlin native coroutine-based)
val cioClient = HttpClient(CIO) {
engine {
maxConnectionsCount = 500
requestTimeout = 20_000
endpoint {
maxConnectionsPerRoute = 8
keepAliveTime = 120_000
connectionIdleTimeout = 60_000
}
https {
serverName = "api.example.com"
cipherSuites = CIOCipherSuites.SupportedSuites
trustManager = X509TrustManager { /* custom trust manager */ }
}
}
}
// Java HTTP Client engine (Java 11+)
val javaClient = HttpClient(Java) {
engine {
version = HttpClient.Version.HTTP_2
followRedirects = HttpClient.Redirect.NORMAL
connectTimeout = Duration.ofSeconds(20)
config {
executor(Executors.newCachedThreadPool())
cookieHandler(CookieManager())
authenticator(Authenticator.getDefault())
}
}
}
// Check engine capabilities
if (apacheClient.isSupported(EngineCapabilities.HTTP2Capability)) {
println("Apache engine supports HTTP/2")
}
if (cioClient.isSupported(EngineCapabilities.WebSocketCapability)) {
println("CIO engine supports WebSockets")
}
// Engine with custom capability
val customCapability = HttpClientEngineCapability.create<String>("CustomFeature")
// Access engine configuration
val engineConfig = apacheClient.engineConfig as ApacheEngineConfig
println("Socket timeout: ${engineConfig.socketTimeout}ms")
// Using engine factory directly
val engineFactory = Apache
val customEngine = engineFactory.create {
socketTimeout = 45_000
proxy = ProxyBuilder.http("http://custom.proxy:3128")
}
val factoryClient = HttpClient(customEngine) {
expectSuccess = false
}
// Close clients
apacheClient.close()
okHttpClient.close()
cioClient.close()
javaClient.close()
factoryClient.close()
// For proper shutdown with custom engine
customEngine.close()Secure connection configuration for HTTPS requests.
/**
* HTTPS configuration for CIO engine
*/
class HttpsConfig {
/** Server name for SNI */
var serverName: String? = null
/** Supported cipher suites */
var cipherSuites: List<CipherSuite> = CIOCipherSuites.SupportedSuites
/** Custom trust manager */
var trustManager: X509TrustManager? = null
/** Custom SSL context */
var sslContext: SSLContext? = null
/** Certificate verification */
var certificateVerifier: CertificateVerifier? = null
}
/**
* Certificate verifier interface
*/
interface CertificateVerifier {
fun verify(hostname: String, session: SSLSession): Boolean
}Endpoint-specific configuration for connection management.
/**
* Endpoint configuration for CIO engine
*/
class EndpointConfig {
/** Maximum connections per route */
var maxConnectionsPerRoute: Int = 100
/** Keep-alive time in milliseconds */
var keepAliveTime: Long = 5000
/** Connection pipeline size */
var pipelineMaxSize: Int = 20
/** Connection idle timeout */
var connectionIdleTimeout: Long = 2000
/** Connect timeout per attempt */
var connectTimeout: Long = 5000
/** Connect retry attempts */
var connectAttempts: Int = 5
}