Прокси в Kotlin
Kotlin работает на JVM и имеет полный доступ к Java API для работы с прокси. Кроме того, популярные Kotlin-библиотеки (OkHttp, Ktor) предоставляют собственные удобные API для настройки прокси.
OkHttp (рекомендуемый)
OkHttp — самый популярный HTTP-клиент для Kotlin/Android.
HTTP прокси
import okhttp3.OkHttpClient
import okhttp3.Request
import java.net.InetSocketAddress
import java.net.Proxy
val proxy = Proxy(
Proxy.Type.HTTP,
InetSocketAddress("proxy_ip", 8080)
)
val client = OkHttpClient.Builder()
.proxy(proxy)
.build()
val request = Request.Builder()
.url("https://httpbin.org/ip")
.build()
client.newCall(request).execute().use { response ->
println(response.body?.string())
}
SOCKS5 прокси
val proxy = Proxy(
Proxy.Type.SOCKS,
InetSocketAddress("proxy_ip", 1080)
)
val client = OkHttpClient.Builder()
.proxy(proxy)
.build()
Аутентификация
import okhttp3.Authenticator
import okhttp3.Credentials
import okhttp3.Route
val proxyAuthenticator = Authenticator { _: Route?, response: okhttp3.Response ->
val credential = Credentials.basic("username", "password")
response.request.newBuilder()
.header("Proxy-Authorization", credential)
.build()
}
val client = OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator(proxyAuthenticator)
.build()
Ktor Client
Ktor — асинхронный фреймворк от JetBrains, нативный для Kotlin.
HTTP прокси
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import java.net.InetSocketAddress
import java.net.Proxy
val client = HttpClient(OkHttp) {
engine {
proxy = Proxy(
Proxy.Type.HTTP,
InetSocketAddress("proxy_ip", 8080)
)
}
}
suspend fun main() {
val response: HttpResponse = client.get("https://httpbin.org/ip")
println(response.bodyAsText())
client.close()
}
С CIO-движком
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
val client = HttpClient(CIO) {
engine {
proxy = io.ktor.client.engine.ProxyBuilder.http("http://proxy_ip:8080")
}
}
SOCKS через Ktor
val client = HttpClient(OkHttp) {
engine {
proxy = Proxy(
Proxy.Type.SOCKS,
InetSocketAddress("proxy_ip", 1080)
)
}
}
Java Proxy API
Стандартный Java API работает в Kotlin:
import java.net.HttpURLConnection
import java.net.InetSocketAddress
import java.net.Proxy
import java.net.URL
val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("proxy_ip", 8080))
val url = URL("https://httpbin.org/ip")
val connection = url.openConnection(proxy) as HttpURLConnection
// Аутентификация
val encoded = java.util.Base64.getEncoder()
.encodeToString("user:pass".toByteArray())
connection.setRequestProperty("Proxy-Authorization", "Basic $encoded")
connection.inputStream.bufferedReader().use { reader ->
println(reader.readText())
}
Ротация прокси
import okhttp3.OkHttpClient
import okhttp3.Request
import java.net.InetSocketAddress
import java.net.Proxy
data class ProxyConfig(val host: String, val port: Int, val user: String, val pass: String)
val proxies = listOf(
ProxyConfig("proxy1", 8080, "user", "pass"),
ProxyConfig("proxy2", 8080, "user", "pass"),
ProxyConfig("proxy3", 8080, "user", "pass"),
)
fun getClient(proxyConfig: ProxyConfig): OkHttpClient {
val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress(proxyConfig.host, proxyConfig.port))
return OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator { _, response ->
val credential = okhttp3.Credentials.basic(proxyConfig.user, proxyConfig.pass)
response.request.newBuilder()
.header("Proxy-Authorization", credential)
.build()
}
.build()
}
fun fetchWithRotation(url: String): String? {
val proxy = proxies.random()
val client = getClient(proxy)
val request = Request.Builder().url(url).build()
return try {
client.newCall(request).execute().use { it.body?.string() }
} catch (e: Exception) {
println("Failed with ${proxy.host}: ${e.message}")
null
}
}
Android-специфичные моменты
Системные прокси Android
На Android можно использовать системные прокси:
val proxyHost = System.getProperty("http.proxyHost")
val proxyPort = System.getProperty("http.proxyPort")?.toIntOrNull()
NetworkSecurityConfig
Для работы с прокси на Android 7+ нужно настроить network_security_config.xml для разрешения cleartext traffic (если прокси HTTP).
Retrofit + прокси
val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress("proxy_ip", 8080))
val okHttpClient = OkHttpClient.Builder().proxy(proxy).build()
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
Таймауты и настройки
import java.util.concurrent.TimeUnit
val client = OkHttpClient.Builder()
.proxy(proxy)
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build()
Заключение
Kotlin предлагает несколько способов работы с прокси: OkHttp для простоты и производительности, Ktor для асинхронного корутинного подхода, и стандартный Java API для совместимости. Для Android-разработки OkHttp + Retrofit — стандарт индустрии. Все варианты поддерживают HTTP и SOCKS5 прокси с аутентификацией.