Geliştirici Rehberleri6 dk okuma

curl ve Node.js ile proxy kullanımı: komut satırından koda

curl’de proxy tek bir seçenektir; Node.js’te ise yerleşik fetch proxy ortam değişkenlerini varsayılan olarak okumaz ve bir ajan ya da dağıtıcı (dispatcher) gerekir. Bu rehber ikisini de çalışır örneklerle anlatıyor.

FİG. 01 — Komut satırı ve JSON yanıtı

Kısa cevap: curl’de -x http://PROXY_ADRESI:PORT --proxy-user KULLANICI:PAROLA; Node.js’te undici paketinin ProxyAgent sınıfı ya da node:https ile https-proxy-agent. Aşağıda önce curl’ün proxy ile ilgili seçeneklerini, zaman ölçümünü ve ortam değişkenlerini, ardından Node.js 20 ve üzeri için üç yaklaşımı ele alıyoruz. Farklı dillerde kısa bağlantı örnekleri Geliştirici sayfasında; Python için ayrıntılı rehber Python ile proxy kullanımı.

curl: temel kullanım

HTTP ve SOCKS5 proxy ile istek
# HTTP proxy, kimlik bilgisi ayrı seçenekte
curl -x http://PROXY_ADRESI:PORT --proxy-user KULLANICI:PAROLA "https://api.ipify.org?format=json"

# Aynısı, kimlik bilgisi proxy URL’sinin içinde
curl -x "http://KULLANICI:PAROLA@PROXY_ADRESI:PORT" "https://api.ipify.org?format=json"

# SOCKS5, hedef adını proxy çözer
curl --socks5-hostname PROXY_ADRESI:PORT --proxy-user KULLANICI:PAROLA "https://api.ipify.org?format=json"

# Aynısı, URL biçimiyle
curl -x "socks5h://KULLANICI:PAROLA@PROXY_ADRESI:PORT" "https://api.ipify.org?format=json"
  • URL’yi tırnak içine alın. ? ve & kabukta özel anlam taşır; tırnaksız bir sorgu dizesi bölünebilir.
  • Windows PowerShell 5.1’de curl adı Invoke-WebRequest komutunun takma adıdır; bu seçeneklerle gerçek curl’ü çalıştırmak için curl.exe yazın.
  • Şema belirtilmezse -x değeri HTTP proxy sayılır; port yazılmazsa curl 1080 varsayar.
  • HTTPS hedeflerde curl CONNECT tünelini kendisi kurar. Düz HTTP hedeflerde de tünel istiyorsanız -p (--proxytunnel) ekleyin.
  • Paroladaki özel karakterler: curl, proxy URL’sindeki kullanıcı adı ve parolanın URL kodlamasını çözer; @ için %40, : için %3a yazabilirsiniz.
  • --socks5 ile --socks5-hostname farkı: ilki hedef adını yerelde çözer, ikincisi proxy’ye bırakır. Ayrıntı: DNS sızıntısı nedir?

Zaman aşımı ve ayrıntılı çıktı

Sınırlı süre, ayrıntılı çıktı
curl -v --connect-timeout 5 --max-time 20 \
  -x "http://KULLANICI:PAROLA@PROXY_ADRESI:PORT" \
  "https://api.ipify.org?format=json"

--connect-timeout yalnızca bağlantı aşamasını, --max-time ise bütün işlemi sınırlar. -v çıktısında CONNECT isteğini, proxy’nin yanıt kodunu ve ardından tünelin içindeki TLS el sıkışmasını görürsünüz; 407 yanıtı alıyorsanız sorun kimlik bilgisindedir. Ayrıntılı çıktı Proxy-Authorization başlığını içerebilir; paylaşmadan önce o satırı silin. Seçeneklerin tamamı curl kılavuzunda (yeni sekmede açılır).

-w ile bağlantının aşamalarını ölçmek

Aşama süreleri (bash; Windows’ta komutu tek satıra yazın, /dev/null yerine NUL kullanın)
curl -s -o /dev/null \
  -x "http://KULLANICI:PAROLA@PROXY_ADRESI:PORT" \
  -w "dns: %{time_namelookup}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nttfb: %{time_starttransfer}\ntotal: %{time_total}\ncode: %{http_code}\n" \
  "https://api.ipify.org?format=json"
Bütün değerler isteğin başından itibaren saniye cinsindendir ve yalnızca o anki bağlantınızı ölçer.
DeğişkenProxy kullanırken neyi ölçer?
time_namelookupAd çözümlemesinin bittiği an. HTTP proxy’de hedef adını proxy çözdüğü için bu değer proxy’nin kendi adının çözümlenmesini yansıtır.
time_connectProxy sunucusuna TCP bağlantısının kurulduğu an.
time_appconnectHedefle TLS el sıkışmasının, tünelin içinden, tamamlandığı an.
time_starttransferİlk yanıt baytının geldiği an; hedef sunucunun işlem süresini de içerir.
time_totalİşlemin toplam süresi.

Ortam değişkenleri ve NO_PROXY

Proxy’yi ortamdan vermek
export http_proxy="http://KULLANICI:PAROLA@PROXY_ADRESI:PORT"
export HTTPS_PROXY="http://KULLANICI:PAROLA@PROXY_ADRESI:PORT"
export NO_PROXY="localhost,127.0.0.1,.dahili.ornek"

curl "https://api.ipify.org?format=json"

curl’de http_proxy yalnızca küçük harfle okunur

curl ortam değişkenlerini büyük ya da küçük harfle kabul eder ve küçük harfliye öncelik verir; tek istisna http_proxy’dir, yalnızca küçük harfle okunur. ALL_PROXY, şemaya özel bir değişken yoksa kullanılır. -x ortam değişkenlerini geçersiz kılar; NO_PROXY ise -x verilmiş olsa bile listedeki adlar için proxy’yi devre dışı bırakır. Windows ortam değişkenlerinde büyük-küçük harf ayrımı yapmaz.

Parolayı ortam değişkenine ya da komut satırına yazmak pratik ama iz bırakan bir yöntemdir: komut satırı kabuk geçmişine düşer, ortam değişkenleri alt işlemlere geçer. Tekrarlanan işlerde -K ile okunan, izinleri kısıtlanmış bir curl yapılandırma dosyası daha temizdir; örneği Proxy kimlik doğrulama rehberinde bulabilirsiniz.

Node.js: fetch neden proxy’yi görmüyor?

Node.js’in yerleşik fetch işlevi (Node.js belgeleri (yeni sekmede açılır)) undici üzerine kuruludur ve HTTP_PROXY, HTTPS_PROXY gibi ortam değişkenlerini varsayılan olarak kullanmaz; terminalde curl proxy’den çıkarken aynı makinedeki bir Node betiği doğrudan bağlanabilir. Daha yeni sürümlerde (Node.js 24.0.0 ve 22.21.0’dan itibaren) NODE_USE_ENV_PROXY=1 ortam değişkeniyle, 24.5.0 ve 22.21.0’dan itibaren --use-env-proxy bayrağıyla da, Node.js HTTP_PROXY, HTTPS_PROXY ve NO_PROXY değişkenlerine göre istekleri proxy’ye yönlendirebilir; belgeler bu özelliği “aktif geliştirme” aşamasında gösterir ve Node.js 20’de bu seçenek yoktur. Sürümden bağımsız çalışan yol, isteğe bir dağıtıcı (dispatcher) vermektir. En doğrudan yol, npm’deki undici paketinin ProxyAgent (yeni sekmede açılır) sınıfıdır. Örnekler ES modülüdür; dosyayı .mjs uzantısıyla kaydedin.

undici ProxyAgent ile fetch (npm install undici)
import { ProxyAgent, fetch } from 'undici';

const dispatcher = new ProxyAgent({
  uri: 'http://PROXY_ADRESI:PORT',
  token: 'Basic ' + Buffer.from('KULLANICI:PAROLA').toString('base64'),
});

try {
  const res = await fetch('https://api.ipify.org?format=json', {
    dispatcher,
    signal: AbortSignal.timeout(20000),
  });
  console.log(res.status, await res.json());
} catch (err) {
  console.error('İstek başarısız:', err.cause ?? err);
}
  • Sürüm uyumu: npm’deki güncel undici 8.x sürümü Node.js 22.19.0 veya üzerini ister. Node.js 20 kullanıyorsanız npm install undici@7 ile 7.x sürümünü kurun; 7.x de Node.js 20.18.1 veya üzerini ister. Bu örnekteki ProxyAgent, token ve fetch iki sürümde de vardır.
  • token, proxy’ye gönderilecek Proxy-Authorization değeridir. Kullanıcı adı ve parolayı http://KULLANICI:PAROLA@PROXY_ADRESI:PORT biçiminde URL içine yazmak da desteklenir.
  • HTTPS hedeflerde ProxyAgent CONNECT tüneli kurar; tünel kurulamazsa hata fırlatılır. fetch hatalarında asıl neden çoğunlukla err.cause içindedir.
  • Bütün istekleri proxy’den geçirmek için setGlobalDispatcher(new ProxyAgent(…)) kullanılabilir. Yerleşik fetch ile npm’deki undici sürümü arasındaki uyumsuzluklardan kaçınmak için örnekte fetch’i de undici paketinden alıyoruz.
  • Ortam değişkenlerini okuyan bir dağıtıcı isterseniz undici’nin EnvHttpProxyAgent sınıfı http_proxy, https_proxy ve no_proxy değişkenlerini (büyük harfli karşılıklarıyla birlikte) kullanır; ALL_PROXY bu listede yoktur.

node:https ve https-proxy-agent

node:https ile HTTP proxy (npm install https-proxy-agent)
import https from 'node:https';
import { HttpsProxyAgent } from 'https-proxy-agent';

const agent = new HttpsProxyAgent('http://KULLANICI:PAROLA@PROXY_ADRESI:PORT');

const req = https.get('https://api.ipify.org?format=json', { agent, timeout: 20000 }, (res) => {
  let body = '';
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    body += chunk;
  });
  res.on('end', () => console.log(res.statusCode, body));
});

req.on('timeout', () => req.destroy(new Error('Zaman aşımı')));
req.on('error', (err) => console.error('Hata:', err.message));

HttpsProxyAgent, HTTPS hedefler için CONNECT tüneli kurar ve URL’deki kimlik bilgilerinden Proxy-Authorization başlığını üretir. Düz HTTP hedefler için aynı ailenin http-proxy-agent paketindeki HttpProxyAgent kullanılır. Bu ajanlar node:http / node:https tabanlı kütüphanelerle çalışır; ortam değişkenlerini kendileri okumaz. Güncel sürümleri (https-proxy-agent 9, http-proxy-agent 9, socks-proxy-agent 10) yalnızca ES modülü olarak dağıtılır ve Node.js 20 veya üzerini ister; require() yerine örneklerdeki gibi import kullanın.

SOCKS5: socks-proxy-agent

node:https ile SOCKS5 (npm install socks-proxy-agent)
import https from 'node:https';
import { SocksProxyAgent } from 'socks-proxy-agent';

const agent = new SocksProxyAgent('socks5h://KULLANICI:PAROLA@PROXY_ADRESI:PORT');

const req = https.get('https://api.ipify.org?format=json', { agent, timeout: 20000 }, (res) => {
  let body = '';
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    body += chunk;
  });
  res.on('end', () => console.log(res.statusCode, body));
});

req.on('timeout', () => req.destroy(new Error('Zaman aşımı')));
req.on('error', (err) => console.error('Hata:', err.message));

socks-proxy-agent’ta da şema DNS davranışını belirler: socks5h:// hedef adını proxy’ye bırakır, socks5:// yerelde çözer. SOCKS5 kimlik doğrulaması RFC 1929’a göre açık metin gider; ayrıntılar Proxy kimlik doğrulama rehberinde. SOCKS5’in hangi paketlerde seçilebildiğini HTTP & SOCKS5 Proxy sayfasında görebilirsiniz.

Node.js’te zaman aşımı ve hata ayıklama

Yerleşik ya da undici fetch kullanırken süreyi AbortSignal.timeout(ms) ile sınırlayın; süre dolduğunda istek, adı TimeoutError olan bir hatayla reddedilir. Ağ katmanındaki hatalarda fetch genel bir TypeError: fetch failed mesajı verir; işe yarayan bilgi err.cause içindedir. Orada çoğunlukla ECONNREFUSED (proxy portu kapalı ya da adres yanlış), ENOTFOUND (proxy’nin adı çözülemedi) veya undici’ye özgü UND_ERR_ önekli kodlar görürsünüz. node:https örneklerinde timeout seçeneği soket hareketsiz kaldığında timeout olayını tetikler; isteği kendiniz sonlandırmanız gerekir, örnekteki req.destroy(…) bunu yapar.

Sorunun proxy’de mi kodda mı olduğunu ayırmanın en hızlı yolu aynı proxy’yi önce curl ile denemektir. curl -v ile çalışıyor ama Node betiği çalışmıyorsa sorun büyük olasılıkla ajan, dağıtıcı ya da URL yazımındadır; ikisi de çalışmıyorsa proxy adresini, portu ve kimlik bilgilerini kontrol edin. Her iki aracın aynı test adresinde aynı çıkış adresini göstermesi, yapılandırmanın tutarlı olduğunun iyi bir işaretidir.

Sık görülen sorunlar

curl ve Node.js’te ilk bakılacak yerler.
BelirtiOlası neden
curl proxy’den çıkıyor, Node betiği gerçek adresinizi gösteriyorYerleşik fetch ortam değişkenlerini okumuyor; dağıtıcı ya da ajan verilmedi.
HTTP_PROXY tanımlı ama curl düz HTTP isteklerde kullanmıyorcurl bu değişkeni yalnızca küçük harfle (http_proxy) okur.
curl ile 407Kimlik bilgisi eksik veya hatalı; paroladaki özel karakterler kodlanmamış olabilir.
fetch fetch failed hatası veriyorGerçek neden err.cause içindedir: bağlantı reddi, zaman aşımı ya da tünel kurulamaması.
SOCKS5 ile bağlanıyor ama yerel DNS sorgusu görülüyorŞema socks5:// yazılmış; socks5h:// kullanın.

Özet: hangi araçta ne kullanılır?

curl ve Node.js’te proxy yapılandırmasının özeti.
AraçHTTP proxySOCKS5Ortam değişkenleri
curl-x http://… ve --proxy-user--socks5-hostname veya socks5h://Okunur; http_proxy yalnızca küçük harf
Node.js, undici fetchProxyAgent ile dispatcherBu rehberde node:https + socks-proxy-agentEnvHttpProxyAgent ile
Node.js, node:httpshttps-proxy-agentsocks-proxy-agentAjan kendisi okumaz

Kod yazmadan önce proxy’nin canlı olup olmadığını ve hangi adresten çıktığını görmek isterseniz Proxy Kontrol aracını, CONNECT tünelinin doğru çalışıp çalışmadığını görmek için HTTP Proxy Kontrol aracını kullanabilirsiniz.

Sık sorulanlar

Akılda kalan sorular

02Okumaya devam

Devamını okuyun

03Konuyla bağlantılı

Ürünler ve araçlar

Ürün sayfaları paketleri ve fiyatları gösterir; araçlar ise elinizdeki bir proxy’yi ya da adresi sınamanız içindir.

Ürünler

Araçlar

  • Proxy Kontrol

    HTTP, HTTPS ve SOCKS5 proxy listelerini canlılık, gecikme ve çıkış IP’si açısından test edin.

  • HTTP Proxy Kontrol

    HTTP proxy’nizin düz istekleri ve HTTPS tünelini (CONNECT) doğru taşıyıp taşımadığını ölçün.

  • SOCKS5 Kontrol

    SOCKS5 el sıkışmasını, kullanıcı adı / parola doğrulamasını ve çıkış adresini sınayın.