Ana içeriğe geç

Bölüm 1: Adres Çubuğundan İsteğe

10 dakikalık okumaGüncelleme:

Ağlar'a “Sen”i Katmak kitabının bir bölümü: adres çubuğuna yazdığın tek bir isteğin peşinden bakırla fiberin fiziğine inip karşı taraftan geri dönen uzun bir teknik yolculuk.

Kısım 1: Yola Çıkmadan Önce (Bölüm 1-5)

Tüm bölümler
  1. Giriş
  2. Adres Çubuğundan İsteğe
  3. Paket Anahtarlamalı Yol
  4. İsimden Adrese
  5. DNS Kayıtları
  6. Önbellek, Tazelik ve Güven
  7. Port Numarası ve Soket
  8. Bağlantısız Taşıma: UDP
  9. Üç Adımlı El Sıkışma
  10. Simetrik Şifreleme
  11. Açık Anahtarlı Kriptografi
  12. TLS El Sıkışması
  13. Sertifika Zinciri
  14. HTTP Mesajının Anatomisi
  15. Durum, Çerez ve Oturum
  16. HTTP/2'den HTTP/3'e
  17. İçerik Dağıtım Ağları
  18. Diğer Uygulama Protokolleri
  19. Katmanlı Mimari
  20. Hizmet ve Protokol
  21. Encapsulation ve Başlıklar
  22. Paket Yakalama ve Çözümleme
  23. Ağ Interface Kartı
  24. Fiziksel Adresleme
  25. Hata Sezme ve CRC
  26. Adres Çözümleme: ARP
  27. Ortam Erişimi: CSMA/CD
  28. Switch'ler
  29. Ağ Topolojileri
  30. Sanal Yerel Ağlar
  31. Kablosuz Erişim: 802.11
  32. Radyo Kanalı ve Kapasite
  33. Kablosuz Ağ Güvenliği
  34. Hücresel Ağlar
  35. Spektrum ve Kuşaklar
  36. Hareketlilik ve Aktarma
  37. Adres Kiralama: DHCP
  38. Adresin Anatomisi
  39. Adres Tükenmesi ve IPv6
  40. Router Mimarisi
  41. Kuyruk Yönetimi
  42. Cihaz Yapılandırma
  43. Routing Protokolleri
  44. Kontrol Düzlemi ve SDN
  45. Ağ İzleme ve Yönetimi
  46. Alanlar Arası Routing
  47. Adres Çevirisi
  48. Ara Kutular
  49. Tünelleme ve IPsec
  50. Firewall'lar
  51. Ağ Saldırıları
  52. Operatör ve Metro Ağları
  53. Bitten Sinyale
  54. Sembol Hızı ve Kanal Kapasitesi
  55. Multiplexing Teknikleri
  56. İletim Ortamları
  57. Bakır Kablo Sonlandırma
  58. Fiber Sonlandırma
  59. Fiber Optik İletim
  60. Bakır Erişim Ağı: DSL
  61. DSL'de Hız ve Mesafe
  62. Pasif Optik Ağlar
  63. Kablo Erişim Ağları
  64. Kablo Modem ve CMTS
  65. Denizaltı Kabloları
  66. Veri Merkezi Ağları
  67. Encapsulation Çözme
  68. Güvenilir Aktarım
  69. Tıkanıklık Denetimi
  70. Trafik Çözümleme
  71. Gecikme Bütçesi
  72. Soket Programlama
  73. Eşten Eşe ve Protokol Tasarımı
  74. Uyarlanır Video Akışı
  75. Gerçek Zamanlı Ses ve Görüntü
  76. Kablosuz Sensör Ağlarının Mimarisi
  77. Sensör Ağlarında Ortam Erişimi
  78. Sensör Ağlarında Yönlendirme ve IP
  79. Zaman Eşitleme ve Konum Bulma
  80. Sensör Ağı Uygulamaları
  81. Mobil Kablosuz Sensör Ağları
  82. Son Söz

Adres çubuğuna bir şeyler yazdın, Enter’a bastın, sayfa geldi. Aradaki süre belki üçte bir saniyeydi ve o sürede olan şey bu kitabın tamamı.

Yazdığın metin ise hâlâ senin makinende; henüz hiçbir yere gitmedi. Tarayıcı o metinden bir isteği nasıl çıkarıyor?

Yazdığın şey bir adres değil, bir tarif

Adres çubuğuna yazılan metne genellikle adres deniyor ama bu ad yanıltıyor. Yazdığın şey bir konum bildirmiyor, bir tarif veriyor ve tarifin parçaları standartla tanımlı:

https://aglar.emircandemir.com/bolum/yol?dil=tr#kuyruk
└─┬─┘   └──────────┬─────────┘└───┬────┘└──┬──┘└──┬──┘
şema        yetkili alan         yol     sorgu  parça

Bu biçimi RFC 3986 tanımlıyor ve belgenin kendisi de “adres” demiyor: URI, açılımıyla Uniform Resource Identifier, tekbiçimli kaynak tanımlayıcısı. Gündelik dilde aynı şeye URL deniyor; standart URL’yi, kaynağın yerini de söyleyen URI alt kümesi olarak tanımlıyor ve adres çubuğuna yazdığın her şey o alt kümeye giriyor.

Şemayı bir sunucu adı olarak okuma; o bir yöntem adı ve harfle başlamak zorunda, sonrasında harf, rakam ve birkaç işaret gelebiliyor. Yetkili alan (authority) makineyi gösteriyor ve yanında isteğe bağlı bir port taşıyabiliyor: aynı makinede çalışan programlardan hangisine gidileceğini söyleyen bir sayı. Portu 6. bölümde ayrıntısıyla açacağız. Yol makinenin içindeki kaynağı gösteriyor, sorgu ise sunucuya ilettiğin ayrıntıyı.

Portu yazmadığın zaman boş kalmıyor; şemanın varsayılanı devreye giriyor.

şemavarsayılan portne için
http80şifresiz web
https443şifreli web
ws / wss80 / 443çift yönlü web bağlantısı
ftp21eski dosya aktarımı
ssh22şifreli uzak oturum

https://example.com ile https://example.com:443 bu yüzden aynı adres. Tarayıcı ikincisini yazsan bile adres çubuğunda birincisini gösterir, çünkü normalleştirme varsayılan portu siliyor.

Parçaların hepsi aynı kurallara da tabi değil. Şema ile makine adını büyük-küçük harf duyarsız yazabiliyorsun; HTTPS://Example.COM ile https://example.com aynı yere gidiyor. Standart ikisinin de küçük harfe normalleştirilmesini öneriyor. Tarayıcı bunu senin adına yapıyor, üstelik daha adres çubuğunu terk etmeden. Yol için aynı şey geçerli olmuyor: /Belgeler ile /belgeler iki ayrı kaynağı gösterebiliyor, çoğu sunucuda gösteriyor da. Sebebi tarihsel: makine adları en baştan harf duyarsız yazılmış bir sistemin kuralına tabi kalıyor. Yol ise sunucunun dosya sistemine bakıyor ve dosya sistemleri her zaman aynı davranmıyor.

Bunun pratik bedeli, bağlantıların uyarı vermeden kırılması. Bir belgeyi /Rapor.pdf diye yayımlayıp bağlantıyı /rapor.pdf diye paylaştığını düşün. Windows üstünde çalışan bir sunucuda hiçbir sorun çıkmıyor, çünkü orada dosya adı harf duyarsız. Linux üstünde çalışan bir sunucuda ise dosya bulunamıyor. Türkçe tuzağı derinleştiriyor. Büyük harfe çevirme kuralları dile bağlı. Türkçede i harfinin büyüğü noktalı İ, ı harfinin büyüğü noktasız I olur. Bu kuralı İngilizceye göre uygulayan bir kütüphane ilan kelimesini ILAN yapıyor. Sonra yanlış dosyaya bakıyor. Çoğu kütüphanenin varsayılanı İngilizce kuralı olduğu için bu hata sık görülüyor.

Yetkili alanın isteğe bağlı kullanıcı bilgisi taşıyabilmesi klasik bir tuzak doğuruyor. Standart, makine adından önce @ işaretiyle ayrılmış bir bölüm tanıyor: https://a@b.com adresinde makine b.com, a ise yalnızca kullanıcı bilgisi. Gözün soldan sağa okuduğu ilk ad, gidilen yer olmuyor. Uzun bir kullanıcı bilgisi yazıp adresi tanıdık gösteren eski bir kandırma yöntemi bu; tarayıcılar bugün o bölümü ya gizliyor ya da uyarı veriyor.

Sondaki parça tanımlayıcıyı ise sunucu hiç görmüyor. Tarayıcıda kalıyor ve belgenin neresine kaydırılacağını belirliyor. Bir bağlantıyı paylaştığında kare işaretinden sonrası sunucunun kayıtlarında görünmez.

Yazamadığın karakterler de var. Standart bunları iki kümeye ayırıyor: harfler, rakamlar ve - . _ ~ her yerde olduğu gibi yazılabiliyor; / ? # & = gibi yapı taşıyan karakterler ise veri olarak kullanılacaksa kodlanmak zorunda. Kodlama yüzde işareti ve iki onaltılık basamak: boşluk %20 oluyor, ç harfi ise iki bayta açılıp %C3%A7 hâline geliyor.

Hangi karakterin kodlanmadan geçebileceği tahmine bırakılmamış:

kümekarakterlerkural
ayrılmamışA-Z a-z 0-9 - . _ ~her zaman olduğu gibi yazılır
genel ayırıcı: / ? # [ ] @adresin bölümlerini ayırır
alt ayırıcı! $ & ' ( ) * + , ; =bir bölümün içini ayırır
geri kalan her şeyboşluk, <, ", ASCII dışıkodlanmadan yazılamaz

Tablodaki asıl haber ikinci ve üçüncü satırda. O karakterler yasak değil; yapısal. Yol ayırıcısı olarak kullanılan / olduğu gibi yazılır, ama bir dosya adının içinde geçmesi gerekiyorsa %2F diye kodlanmak zorundadır. Aynı karakter, aynı adreste iki farklı anlam taşıyor ve ayrımı yalnızca kodlama yapıyor.

Ayrımın sinsi bir sonucu var ve adı çift kodlama. Zaten kodlanmış bir adresi ikinci kez kodlarsan yüzde işaretinin kendisi de kodlanıyor ve ortaya %2520 gibi bir dizi çıkıyor. Sunucu bunu boşluk yerine metin olarak okuyor. Bir bağlantının neden “bulunamadı” dediğini çözemediğinde ilk bakacağın yerlerden biri burasıdır.

Şemanın bir yöntem adı olduğunu görmenin en hızlı yolu, ağa hiç çıkmayan şemalara bakmak. file: yerel diskteki bir dosyayı açıyor, data: içeriğin kendisini adresin içinde taşıyor, mailto: ise tarayıcıyı bırakıp posta programını çağırıyor. Üçünde de ortada ne sunucu var ne paket. Tarayıcı ilk parçaya bakıp hangi mekanizmayı çalıştıracağına karar veriyor; geri kalan parçaların anlamı bile o karara bağlı.

Adresin ne kadar uzayabileceği de sık sorulan bir soru ve cevabı şaşırtıyor: standart hiçbir üst sınır koymuyor, sınırı uygulamalar koyuyor. Tarayıcılar ve sunucular kendi tamponlarına göre bir yerde kesiyor, araya giren proxy’ler daha erken kesebiliyor; kesen taraf çoğu zaman hata da vermiyor. Bu yüzden uzun veri adres satırında değil, isteğin gövdesinde taşınır.

Yukarıda saydığım parçaların çoğunu da aslında yazmıyorsun. example.com yazdığında ortada ne şema var ne yol; tarayıcı önce güvenli şemayı deniyor, sonra kök yolu ve şemanın varsayılan portunu ekliyor. Hiçbiri adres çubuğunda görünmüyor.

Zarfın üstünde şehir, sokak ve kapı numarası ayrı ayrı yazar ve her satırı yolun başka bir durağı kullanır: şehri ayırma merkezi, sokağı dağıtım şubesi, kapı numarasını postacı. Adres de böyle katmanlı. Şemayı tarayıcı okuyor, makine adını resolver (ad çözümleyici), yolu karşıdaki sunucu. Benzerlik gizlilikte kırılıyor: zarfın her satırını eline alan herkes okuyabilir, oysa https ile giden bir istekte yol ve sorgu şifreli taşınıyor. Aradaki cihazlar en fazla makine adını görebiliyor.

Türkçe bir alan adı ağa nasıl çıkıyor?

Alan adı sistemi doğduğunda yalnızca harf, rakam ve tire tanıyordu. Bu kısıt hâlâ yerinde, çünkü dünyadaki milyonlarca sunucu o varsayımla yazıldı.

Çözüm, adı ağa çıkmadan önce çevirmek oldu. ASCII dışı harf taşıyan bu adların ortak adı uluslararası alan adı (IDN). Tarayıcı böyle bir adı Punycode adlı bir kodlamayla ASCII’ye çeviriyor ve sonuç her zaman xn-- önekiyle başlıyor:

türkçe.com     ->  xn--trke-2oa7j.com
ağ.com         ->  xn--a-eja.com
İstanbul.com   ->  xn--istanbul-o0e.com

Numaranın kendisi de zarif: kodlama önce ASCII harfleri sırasıyla yazıyor, sonra tireden sonra kalan harflerin hangi konumda ve hangi karakter olduğunu sıkıştırılmış biçimde ekliyor: türkçe kelimesinden geriye trke kalıyor ve gerisi 2oa7j içinde saklı duruyor, yani dönüşüm kayıpsız ve geri çevrilebilir.

Üçüncü satır ayrıca dikkat çekici. Alan adlarında büyük-küçük harf farkı olmadığı için ad kodlanmadan önce küçük harfe indiriliyor. Unicode’un dile bakmayan kuralında noktalı büyük İ’nin küçüğü düz i değil, i ile üstüne binen ayrı bir nokta işareti. Kodlama o noktayı da taşıyor, bu yüzden İstanbul.com ile istanbul.com iki ayrı alan adı: ikincisi olduğu gibi ASCII kalıyor, birincisi xn-- ile başlıyor. Yoldaki büyük-küçük harf tuzağında gördüğün Türkçe i, burada alan adının içine taşınmış oluyor.

Unicode’un zenginliği bir güvenlik sorunu da doğuruyor. Bazı alfabelerde Latin harflerine tıpatıp benzeyen karakterler var; kötü niyetli biri tanıdık bir markanın adını bu harflerle kaydedip ayırt edilemeyen bir adres üretebilir. Tarayıcılar buna karşı kural koyuyor: ad alfabeleri karıştırıyorsa ya da tanınmış bir adı taklit ediyorsa, adres çubuğunda okunur hâli yerine xn-- hâli gösteriliyor. Çirkin görünmesi de kasıtlı.

Tarayıcı önce kendi cebine bakıyor

Tarayıcının ilk işi ağa çıkmak değil. Önce bu yolculuğu hiç yapmadan kurtulup kurtulamayacağına, kurtulamıyorsa yolu nasıl kısaltacağına bakıyor. Dört cebi var ve biri Enter’a basmadan önce bile devrede.

İlki tahmin. Tarayıcı sen yazarken nereye gitmek istediğini kestirmeye çalışıyor ve yeterince eminse adı çözüp bağlantıyı kurmaya başlıyor. Enter’a bastığında yolun bir kısmı çoktan yürünmüş oluyor. Tahmin yanlışsa gitmek istemediğin bir sunucu senin geldiğini görmüş oluyor.

İkincisi bir liste. Tarayıcı, daha önce yalnızca güvenli bağlantı kabul ettiğini bildirmiş siteleri saklıyor; o listedeki bir adrese http yazsan bile istek hiç gönderilmeden https hâline çevriliyor. Ağda tek bir şifresiz istek görünmüyor. Mekanizmanın adı HSTS (HTTP Strict Transport Security): site bu isteği bir yanıt başlığıyla bildiriyor, tarayıcı da onu süresi dolana kadar hatırlıyor. Kuralın bir kör noktası var: siteye ilk kez gidiyorsan o başlığı henüz hiç görmedin. İlk isteği de korumak için tarayıcılar, kendi içlerine gömülü bir ön yükleme listesiyle (preload list) geliyor.

Adres kesinleşince sıra kopyalara geliyor. En hızlısı bellekteki kopya: sayfayı biraz önce açtıysan resimler ve stil dosyaları hâlâ işlemin belleğinde durabilir. Sonra diskteki kopya geliyor ve tarayıcı orada nesnenin yanına ne kadar taze sayılacağını da yazmış oluyor.

Süre dolmuşsa ağa çıkıyor ama kopyayı çöpe atmıyor: isteğe elindeki kopyanın tarihini ekleyip “bundan sonra değişti mi” diye soruyor. Bu biçimin adı koşullu istek. Değişmediyse sunucu gövdeyi hiç göndermiyor, kısa bir yanıtla yetiniyor. Tazeliğin nasıl hesaplandığını 14. bölümde web önbelleğini kurarken açacağız.

Sayfa tek dosya değil

Tek bir adres yazdın ama karşılığında tek bir dosya gelmiyor. Bir web sayfası nesnelerin toplamı: gelen ilk şey taban HTML dosyası, içinde resimlere, stil dosyalarına, yazı tiplerine ve betiklere göndermeler var; her birinin de kendi adresi var.

Tarayıcı belgeyi baştan sona beklemiyor. Parça parça alıyor, elindekini hemen ayrıştırıyor ve ilk resmin adresini gördüğü anda onu istemeye başlıyor. Sayfanın üst kısmının alttan önce görünmesinin sebebi bu.

Ayrıştırma her zaman kesintisiz de ilerlemiyor. Bir betik etiketi geldiğinde tarayıcı durur. Betik indirilip çalışana kadar belgenin geri kalanı beklemede kalır. Sebep, betiğin belgeyi değiştirebilme ihtimali. Sayfa başına düşen betik sayısının neden bu kadar konuşulduğunu bu kural açıklıyor. Etikete async ya da defer ekleyen geliştirici bu beklemeyi kaldırmış oluyor: betik arka planda iniyor, ayrıştırma durmuyor.

Göndermelerin çoğu tam adres taşımıyor ve tarayıcı bunları belgenin kendi adresine göre tamamlıyor. Kural iki satırla yazılabiliyor:

belge /a/b/  içindeyken   c.png  ->  /a/b/c.png
belge /a/b   içindeyken   c.png  ->  /a/c.png

Aradaki fark tek bir karakter. Sondaki eğik çizgi, tarayıcının b parçasını dizin mi dosya mı saydığını değiştiriyor. Bir sayfayı taşırken o çizgiyi kaybetmek, belgedeki bütün göreli bağlantıları tek seferde kırabiliyor.

Sayı da hızla büyüyor: sıradan bir haber sayfası kolayca yüzden fazla nesne isteyebiliyor ve hepsi aynı makinede durmak zorunda değil. Bedeli gecikmeye yazılıyor, çünkü her yeni bağlantı en az bir round-trip time (gidiş-dönüş süresi) istiyor; kısaca RTT.

İstek nasıl bir şeye dönüşüyor

Tarayıcı ceplerini yokladı ve ağa çıkmaya karar verdi. Elindeki şey şaşırtıcı derecede sade, birkaç satır okunabilir metinden ibaret:

GET /bolum/yol?dil=tr HTTP/1.1
Host: aglar.emircandemir.com
Accept: text/html
Accept-Language: tr
If-Modified-Since: Thu, 20 Aug 2026 09:14:22 GMT

İlk satır ne istediğini, hangi yolu istediğini ve hangi sürümü konuştuğunu söylüyor, altında da başlıklar duruyor. Parça tanımlayıcının burada olmadığına dikkat et: #kuyruk ağa hiç çıkmadı.

İkinci satır ilk bakışta gereksiz görünüyor. Tarayıcı zaten o makineye bağlandıysa, adını tekrar yazmasının anlamı ne?

Anlamı, bir makinenin tek bir siteye ev sahipliği yapmak zorunda olmamasında. Aynı sunucu yüzlerce alan adına birden hizmet verebiliyor ve gelen bağlantı hepsi için aynı görünüyor; sunucu hangi siteyi istediğini ancak bu satırdan öğreniyor. Paylaşımlı barındırmanın ucuz olmasının sebebi burada.

Aynı sorun şifreli bağlantılarda bir kez daha çıkıyor. Sunucu, kimliğini kanıtlayan bir belge sunuyor; adı sertifika ve her site için ayrı. Hangi sertifikayı sunacağına karar verebilmesi için siteyi bilmesi gerekiyor, ama sertifika gelmeden istek de şifrelenemiyor. Bu düğümü 11. bölümde şifreli bağlantıyı kurarken çözeceğiz.

Metin bir sokete yazılacak. Soket, işletim sisteminin uygulamaya verdiği bir tutamak; uygulama oraya yazıyor, gerisini işletim sisteminin çekirdeği, yani kernel hallediyor. Bu tutamağın kernel tarafını başka bir kitapta ele almıştım.

Ama soketi açmak için karşı tarafın adresi gerekiyor ve o adres bu metinde yok. Elindeki şey bir isim; ağın taşıdığı şey bir sayı.

Özet

  • Adres çubuğuna yazdığın metin parçalara ayrılmış bir tarif. Parçalar aynı kurallara tabi değil ve parça tanımlayıcı sunucuya hiç gitmiyor.
  • Yapı taşıyan karakterler veri olacaksa kodlanıyor: boşluk %20, ç harfi %C3%A7. Aynı adresi iki kez kodlamak %2520 üretiyor.
  • Türkçe harf taşıyan alan adı ağa xn-- önekiyle çıkıyor ve dönüşüm kayıpsız; karma alfabede bu hâlin gösterilmesi bir güvenlik kuralı.
  • Tarayıcı ağa çıkmadan önce dört cebini yokluyor: tahmin, güvenli bağlantı listesi, bellek ve disk. Yolculuğun en hızlısı, hiç yapılmayanıdır.
  • İstek birkaç satır okunabilir metinden ibaret ve Host satırı olmadan tek bir makine tek bir siteye hizmet etmek zorunda kalırdı.

Tarayıcı hazır, metin hazır, soket açılmayı bekliyor. Elinde bir isim var ama ağ isimden anlamıyor; peki neden anlamıyor?

2. bölüme devam et: Paket Anahtarlamalı Yol