Kotlin proxy entegrasyonu, modern Android ve backend geliştiriciler için kritik bir beceridir. İster SERP takibi, ister e-ticaret fiyat monitoringi, ister sosyal medya araştırması yapıyor olun — doğru proxy konfigürasyonu olmadan istekleriniz IP bloklarına takılır, CAPTCHA duvarlarıyla karşılaşır ve ölçeklenemez. Bu rehberde Ktor client proxy ve OkHttp proxy authentication konularını gerçek kod örnekleriyle ele alacağız.
Kotlin Proxy Nedir ve Neden Gereklidir?
Bir Kotlin proxy kurulumu, HTTP istemcinizin tüm trafiğini bir ara sunucu üzerinden yönlendirir. Hedef sunucu sizin gerçek IP'nizi değil, proxy'nin IP'sini görür. Bu, Kotlin web scraping projelerinde IP tabanlı rate limit'leri aşmak, coğrafi kısıtlamaları atlamak ve kimliğinizi korumak için temel bir tekniktir.
Sorun şu: Datacenter IP'leri (AWS, DigitalOcean, Google Cloud gibi ASN'ler) çoğu modern platform tarafından kolayca tespit edilir ve bloklanır. Sosyal medya uygulamaları, e-ticaret siteleri ve arama motorları, datacenter ASN'lerini gerçek kullanıcı trafiğinden ayırt etmek için gelişmiş anti-bot sistemleri kullanır. Residential proxy'ler, gerçek ISP'lere ait IP'leri kullanarak bu tespiti zorlaştırır.
ProxyHat, residential, mobile ve datacenter proxy tiplerini tek bir gateway üzerinden sunar. Tüm örneklerde gate.proxyhat.com:8080 (HTTP) ve gate.proxyhat.com:1080 (SOCKS5) kullanacağız. Daha fazla bilgi için ProxyHat fiyatlandırma sayfasını inceleyebilirsiniz.
Proje Kurulumu: Ktor 3 ve OkHttp Bağımlılıkları
Kotlin'de proxy kullanımı için iki ana yaklaşım vardır: Ktor Client (Kotlin-native, coroutine dostu) ve OkHttp (JVM ekosisteminin en olgun HTTP istemcisi). İkisini yan yana kullanacağız.
Gradle Bağımlılıkları
build.gradle.kts dosyanıza şu bağımlılıkları ekleyin:
// Ktor 3.x — CIO engine (Kotlin-native, coroutine dostu)
implementation("io.ktor:ktor-client-core:3.0.3")
implementation("io.ktor:ktor-client-cio:3.0.3")
implementation("io.ktor:ktor-client-auth:3.0.3")
implementation("io.ktor:ktor-client-content-negotiation:3.0.3")
implementation("io.ktor:ktor-serialization-kotlinx-json:3.0.3")
// OkHttp — JVM ekosistemi
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
OkHttp engine'i Ktor ile de kullanabilirsiniz — bu, OkHttp'in olgun proxy altyapısından yararlanmanızı sağlar:
implementation("io.ktor:ktor-client-okhttp:3.0.3")
Temel Proxy Yönlendirme: gate.proxyhat.com:8080
ProxyHat'in HTTP proxy gateway'ine bağlanmak için iki şey gerekir: proxy adresi ve Basic authentication. Proxy auth, HTTP istemcisinden bağımsız bir protokol adımıdır — Proxy-Authorization header'ı proxy'ye gönderilir, hedef sunucuya değil.
Yöntem 1: Ktor Client ile Proxy (CIO Engine)
Ktor'da proxy konfigürasyonu engine'e özeldir. CIO engine, proxyConfig parametresi ile HTTP proxy destekler. Proxy authentication ise defaultRequest bloğunda Proxy-Authorization header olarak eklenmelidir:
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import io.ktor.http.*
import java.util.Base64
fun createKtorClientWithProxy(): HttpClient {
val proxyUser = "user-country-DE-city-berlin"
val proxyPass = "SIFRENIZ"
val authHeader = "Basic " + Base64.getEncoder()
.encodeToString("$proxyUser:$proxyPass".toByteArray())
return HttpClient(CIO) {
engine {
proxyConfig = ProxyConfig(
url = "http://gate.proxyhat.com:8080",
type = ProxyType.HTTP
)
}
defaultRequest {
header("Proxy-Authorization", authHeader)
}
}
}
suspend fun main() {
val client = createKtorClientWithProxy()
val response = client.get("https://httpbin.org/ip")
println("IP: ${response.bodyAsText()}")
client.close()
}
Dikkat: user-country-DE-city-berlin formatı, ProxyHat'in geo-targeting söz dizimidir. -session-abc123 ekleyerek sticky session oluşturabilirsiniz. Detaylı bilgi için ProxyHat lokasyonlar sayfasını ziyaret edin.
Yöntem 2: OkHttp ile Proxy (Raw Java.net.Proxy)
OkHttp, proxy konfigürasyonu için java.net.Proxy sınıfını kullanır. Authentication ise Authenticator arayüzü ile sağlanır:
import okhttp3.*
import java.net.InetSocketAddress
import java.net.Proxy
import java.util.Base64
fun createOkHttpClientWithProxy(): OkHttpClient {
val proxy = Proxy(
Proxy.Type.HTTP,
InetSocketAddress("gate.proxyhat.com", 8080)
)
val proxyAuthenticator = Authenticator { _, response ->
val credential = Credentials.basic(
"user-country-DE-city-berlin",
"SIFRENIZ"
)
response.request.newBuilder()
.header("Proxy-Authorization", credential)
.build()
}
return OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator(proxyAuthenticator)
.connectTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
.readTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
.build()
}
fun main() {
val client = createOkHttpClientWithProxy()
val request = Request.Builder()
.url("https://httpbin.org/ip")
.build()
client.newCall(request).execute().use { response ->
println("Status: ${response.code}")
println("Body: ${response.body?.string()}")
}
}
Geo-Targeting ve Sticky Session Encoding
ProxyHat, geo-targeting ve sticky session bilgilerini kullanıcı adına gömer. Bu, URL'de ek parametre gerektirmeden proxy davranışını kontrol etmenizi sağlar:
| Username Format | Açıklama | Kullanım |
|---|---|---|
user-country-US | ABD IP'si | Ülke bazlı scraping |
user-country-DE-city-berlin | Berlin IP'si | Şehir bazlı içerik |
user-country-DE-session-abc123 | Sticky session | Oturum gerektiren siteler |
user-country-US-session-xyz789 | ABD + sticky | Sosyal medya oturumları |
Sticky session, aynı IP'yi belirli bir süre boyunca korur — bu, oturum açma gerektiren sitelerde (e-ticaret sepetleri, sosyal medya hesapları) kritiktir. MDN Proxy-Authorization dokümantasyonu, bu header'ın nasıl çalıştığını detaylandırır.
SOCKS5 Proxy: Port 1080 ve System Properties
SOCKS5, HTTP proxy'den farklı olarak TCP katmanında çalışır ve tüm trafiği şeffaf şekilde yönlendirir. JVM'de SOCKS5 proxy için java.net.socks.username ve java.net.socks.password sistem özellikleri kullanılır:
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
fun setupSocks5SystemProperties() {
// SOCKS5 authentication JVM seviyesinde ayarlanır
System.setProperty("socksProxyHost", "gate.proxyhat.com")
System.setProperty("socksProxyPort", "1080")
System.setProperty("java.net.socks.username", "user-country-US-session-abc123")
System.setProperty("java.net.socks.password", "SIFRENIZ")
}
suspend fun main() {
setupSocks5SystemProperties()
// CIO engine, JVM SOCKS ayarlarını otomatik devralır
val client = HttpClient(CIO) {
engine {
// SOCKS5 için system properties kullanılır
// CIO bu ayarları otomatik algılar
}
}
val response = client.get("https://httpbin.org/ip")
println("SOCKS5 üzerinden IP: ${response.bodyAsText()}")
client.close()
}
OkHttp ile SOCKS5 kullanımı ise Proxy.Type.SOCKS ile yapılır:
import okhttp3.*
import java.net.InetSocketAddress
import java.net.Proxy
fun createOkHttpSocks5Client(): OkHttpClient {
val proxy = Proxy(
Proxy.Type.SOCKS,
InetSocketAddress("gate.proxyhat.com", 1080)
)
// SOCKS5 auth için Authenticator yeterli değildir;
// java.net.Authenticator kullanılır
java.net.Authenticator.setDefault(object : java.net.Authenticator() {
override fun getPasswordAuthentication(): java.net.PasswordAuthentication {
return java.net.PasswordAuthentication(
"user-country-US-session-abc123",
"SIFRENIZ".toCharArray()
)
}
})
return OkHttpClient.Builder()
.proxy(proxy)
.connectTimeout(15, java.util.concurrent.TimeUnit.SECONDS)
.build()
}
SOCKS5, WebSocket ve gRPC gibi HTTP dışı protokoller için de uygundur. ProxyHat SDK'sı da aynı pattern'i kullanır — ProxyHat dokümantasyonunu inceleyebilirsiniz.
Residential Proxy'ler: Neden Datacenter IP'leri Yetersiz Kalır?
Modern platformlar — Instagram, Amazon, Ticketmaster, Shopify siteleri — datacenter IP'lerini ASN veritabanlarıyla eşleştirir. ASN (Autonomous System Number) kontrolü ile bir IP'nin AWS, Google Cloud veya DigitalOcean'a ait olduğunu saniyeler içinde tespit edebilirler. Bu IP'ler genellikle 403 veya 429 yanıtı alır.
Residential proxy'ler, gerçek ISP'lere (Deutsche Telekom, Comcast, Vodafone) ait IP'leri kullandığı için bu tespiti atlatır. ProxyHat'in residential havuzu, 190+ ülkede milyonlarca IP barındırır. Web scraping use case sayfamızda bu konuyu detaylı işledik.
Coroutine ile Concurrent Fan-Out Örneği
Aşağıdaki örnek, Kotlin coroutines kullanarak paralel istekler gönderir ve Semaphore ile eşzamanlılık sınırını kontrol eder:
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import io.ktor.http.*
import kotlinx.coroutines.*
import java.util.Base64
data class ScrapeResult(val url: String, val status: Int, val body: String)
suspend fun fanOutScrape(urls: List<String>): List<ScrapeResult> = coroutineScope {
val semaphore = Semaphore(10) // Aynı anda maksimum 10 istek
val proxyUser = "user-country-DE-city-berlin"
val proxyPass = "SIFRENIZ"
val authHeader = "Basic " + Base64.getEncoder()
.encodeToString("$proxyUser:$proxyPass".toByteArray())
val client = HttpClient(CIO) {
engine {
proxyConfig = ProxyConfig(
url = "http://gate.proxyhat.com:8080",
type = ProxyType.HTTP
)
}
defaultRequest {
header("Proxy-Authorization", authHeader)
}
}
val results = urls.map { url ->
async(Dispatchers.IO) {
semaphore.withPermit {
try {
val response = client.get(url)
ScrapeResult(url, response.status.value, response.bodyAsText())
} catch (e: Exception) {
ScrapeResult(url, 0, e.message ?: "Error")
}
}
}
}.awaitAll()
client.close()
results
}
suspend fun main() {
val urls = listOf(
"https://httpbin.org/ip",
"https://httpbin.org/headers",
"https://httpbin.org/user-agent",
"https://httpbin.org/status/200",
"https://httpbin.org/status/404"
)
val results = fanOutScrape(urls)
results.forEach { r ->
println("${r.url} -> ${r.status}")
}
}
Bu örnekte Semaphore(10) ile aynı anda en fazla 10 istek gönderilir. Hedef sunucunun rate limit'ini aşmadan ölçeklenmenizi sağlar. 50 URL için bu yaklaşım 5 batch halinde çalışır ve ortalama 2-3 saniyede tamamlanır.
Production Hardening: 407 Challenge, Retry, Timeout ve TLS
Production'da proxy bağlantıları kırılgandır. Proxy sunucusu 407 Proxy Authentication Required yanıtı gönderebilir, bağlantı zaman aşımına uğrayabilir veya TLS el sıkışması başarısız olabilir.
OkHttp Authenticator ile 407 Yönetimi
OkHttp'in Authenticator arayüzü, 407 yanıtı alındığında otomatik olarak credential ekler ve isteği yeniden gönderir:
import okhttp3.*
import java.net.InetSocketAddress
import java.net.Proxy
fun createProductionOkHttpClient(): OkHttpClient {
val proxy = Proxy(
Proxy.Type.HTTP,
InetSocketAddress("gate.proxyhat.com", 8080)
)
val proxyAuthenticator = Authenticator { _, response ->
// 407 challenge durumunda credential yeniden eklenir
// OkHttp bunu otomatik olarak bir kez dener
val credential = Credentials.basic(
"user-country-DE-session-abc123",
"SIFRENIZ"
)
response.request.newBuilder()
.header("Proxy-Authorization", credential)
.build()
}
return OkHttpClient.Builder()
.proxy(proxy)
.proxyAuthenticator(proxyAuthenticator)
.connectTimeout(10, java.util.concurrent.TimeUnit.SECONDS)
.readTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
.writeTimeout(15, java.util.concurrent.TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.connectionPool(ConnectionPool(20, 5, java.util.concurrent.TimeUnit.MINUTES))
.build()
}
Ktor'da Retry ve Timeout
Ktor'da retry ve timeout için HttpTimeout plugin'i ve manuel retry döngüsü kullanılır:
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.HttpTimeout
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import kotlinx.coroutines.delay
suspend fun fetchWithRetry(
client: HttpClient,
url: String,
maxRetries: Int = 3
): String? {
var lastError: Exception? = null
repeat(maxRetries) { attempt ->
try {
val response = client.get(url)
if (response.status.value in 200..299) {
return response.bodyAsText()
}
// 429 veya 503 durumunda bekle ve tekrar dene
if (response.status.value == 429 || response.status.value == 503) {
delay((attempt + 1) * 1000L) // 1s, 2s, 3s
}
} catch (e: Exception) {
lastError = e
delay((attempt + 1) * 500L)
}
}
lastError?.printStackTrace()
return null
}
fun createProductionKtorClient(): HttpClient {
return HttpClient(CIO) {
install(HttpTimeout) {
connectTimeoutMillis = 10_000
requestTimeoutMillis = 30_000
socketTimeoutMillis = 30_000
}
engine {
proxyConfig = ProxyConfig(
url = "http://gate.proxyhat.com:8080",
type = ProxyType.HTTP
)
// CIO engine TLS ayarları
// httpsEndpoint = httpsEndpoint.copy(
// verifyCertificates = true
// )
}
defaultRequest {
header("Proxy-Authorization", "Basic ...")
}
}
}
Android NetworkSecurityConfig
Android'de proxy trafiği için network_security_config.xml dosyası, cleartext trafiği ve sertifika pinning yönetimi için önemlidir:
<!-- res/xml/network_security_config.xml -->
<network-security-config>
<!-- ProxyHat HTTP proxy için cleartext izni -->
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">gate.proxyhat.com</domain>
</domain-config>
<!-- Hedef HTTPS siteleri için sertifika doğrulama -->
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">api.example.com</domain>
</domain-config>
</network-security-config>
AndroidManifest.xml'de bu dosyayı referans verin:
<application
android:networkSecurityConfig="@xml/network_security_config">
...
</application>
Etik Scraping ve Yasal Hususlar
Web scraping güçlü bir araçtır ama yasal sınırları vardır. ABD'de Computer Fraud and Abuse Act (CFAA), yetkisiz erişimi yasaklar. AB'de GDPR, kişisel verilerin işlenmesinde katı kurallar koyar — IP adresleri de kişisel veri sayılabilir.
En iyi pratikler:
- Yalnızca herkese açık verileri toplayın. Login arkasındaki verilere erişmek CFAA ihlali olabilir.
- robots.txt dosyasını kontrol edin ve sayfalarını tarayın. Respect etmek yasal bir zorunluluk olmasa bile etik bir gerekliliktir.
- Rate limit'i hedef sunucu için makul tutun. Saniyede 100 istek göndermek DDoS'e yakın.
- Resmi API'leri tercih edin. Çoğu platform (Twitter, Reddit, GitHub) resmi API sunar — scraping'e göre daha güvenilir ve yasal olarak daha temizdir.
- Kullanım koşullarını (ToS) okuyun. Bazı siteler scraping'i açıkça yasaklar.
SERP tracking use case sayfamız, etik scraping pratiklerini daha detaylı ele alır.
Key Takeaways
Özet:
- Ktor'da proxy auth
defaultRequest'teProxy-Authorizationheader olarak eklenir; OkHttp'deproxyAuthenticatorkullanılır.- Geo-targeting ve sticky session, kullanıcı adına gömülür:
user-country-DE-city-berlin-session-abc123.- SOCKS5 için port 1080 ve
java.net.socks.usernamesistem özellikleri kullanılır.- Residential proxy'ler, datacenter ASN bloklarını atlatmak için gereklidir — sosyal medya ve e-ticaret sitelerinde başarı oranı %90+'ya çıkar.
- Production'da 407 challenge, retry, timeout ve connection pooling konfigürasyonu zorunludur.
- Coroutine + Semaphore ile rate-controlled fan-out, hedef sunucuyu darboğaza sokmadan ölçeklenmenizi sağlar.
ProxyHat ile Başlayın
ProxyHat, residential, mobile ve datacenter proxy'leri tek bir gateway üzerinden sunar. gate.proxyhat.com:8080 HTTP proxy veya gate.proxyhat.com:1080 SOCKS5 ile dakikalar içinde başlayın. Fiyatlandırma sayfasından planınızı seçin ve dashboard.proxyhat.com üzerinden credential'larınızı alın.
ProxyHat SDK'sı, bu makalede gösterilen pattern'leri otomatikleştirir — proxy rotation, health check ve session yönetimi dahili olarak gelir. Dokümantasyonu inceleyerek başlayın.






