İçeriğe geç
academia.sh

Ders 05 / 16

HTTP Sürümleri

Aynı alanlar üç çerçeveleme rejiminde ölçülür: metin satırı 3524 bayt ve 251 bekleme birimi, bağlamı tutulan ikili çerçeve aynı 200 kararı 427 baytla verir, bağlamı tutulmayan ikili çerçevede 189 karar ortadan uçlara taşınır.

İçindekiler

Çerez bir başlık alanıdır ve kapsamı içindeki her istekte yeniden gönderilir. Konak adı da öyle, yöntem de, istemcinin bildirdiği tercihler de. Kırk alışverişlik bir oturumda aynı dizgiler kırk kez tel üzerinden geçer ve her seferinde baştan yazılır.

Bu tekrar bir tasarım kararının sonucudur: HTTP iletisi metin satırlarından kurulur ve metin satırı kendi kendine yeter. Ayrıştırıcı bir satır okur, iki noktayı bulur, adı ve değeri ayırır. Sürümler arasındaki fark bu dersin konusudur ve fark anlamda değil, çerçevelemededir (framing): hangi alanların taşındığı değişmez, alanların tel üzerinde nasıl paketlendiği değişir. Sorumuz şudur — paketlemenin değişmesi aradaki aracıya ne kazandırır ve ne kaybettirir?

Aynı Anlam, Başka Çerçeveleme

HTTP/1.1 iletiyi satır satır yazar. İstek satırı yöntemi ve yolu taşır, ardından her satır bir başlık alanıdır, boş satır gövdenin başladığını bildirir. HTTP/2 ve HTTP/3 aynı alanları ikili çerçevelere koyar: her çerçevenin bir türü, bir uzunluğu, bir akış numarası ve bayrakları vardır; başlık alanları ayrı bir kodlamayla sıkıştırılır.

# ogretilen dokum , calistirilmamistir

# metin satiri cercevelemesi
GET /olcum/kuzey HTTP/1.1
Host: istasyon.ornek
Cookie: oturum=k7
Accept: text/csv
Connection: keep-alive

# ikili cerceveleme , ayni alanlar
CERCEVE tur=HEADERS akis=7 bayrak=END_HEADERS
  :method     -> dizin
  :path       -> sozluk  /olcum/kuzey
  :authority  -> dizin
  cookie      -> dizin
  accept      -> dizin
CERCEVE tur=DATA akis=7 bayrak=END_STREAM

İki biçim aynı şeyi söyler. Yöntem, yol, konak ve iki tercih alanı ikisinde de vardır; :method ve :path adları metin biçimindeki istek satırının karşılığıdır. Değişen üç şey şudur: alanlar satır değil çerçeve taşır, çerçevelerin bir akış numarası vardır ve başlık alanları dizinlenerek gönderilebilir.

Akış numarası çoğullamayı (multiplexing) mümkün kılar: tek bağlantı üzerinde birden çok alışveriş iç içe ilerleyebilir, çünkü her çerçeve hangi akışa ait olduğunu kendi taşır. Metin satırı çerçevelemesinde böyle bir alan yoktur; bir bağlantıda istekler ancak ardışık gidebilir, ve bu kalıcı bağlantıda da böyledir — bağlantı açık kalır ama sıra korunur.

HTTP/3 çerçevelemeyi değil, taşımayı değiştirir. Çerçeve düzeni benzer kalır; altındaki taşıma katmanı tek sıralı bayt akışı yerine birbirinden bağımsız akışlar sunar. Bu ayrımın neden önemli olduğu bir sonraki bölümün konusudur.

Sıra Başı Engellemesi İki Katmanda

Sıra başı engellemesi (head-of-line blocking), bir kuyruğun başındaki öğe ilerleyemediği için arkasındakilerin de beklemesidir. HTTP’de bunun iki ayrı biçimi vardır ve karıştırılmaları sürümler arası farkı görünmez kılar.

Uygulama katmanındaki biçim: tek bağlantıda istekler ardışıksa, yavaş bir yanıt arkasındaki bütün alışverişleri bekletir. Yavaşlık ağdan gelmez — sunucu o yanıtı üretmek için birden çok kaydı derliyordur. Çoğullama bu biçimi kaldırır.

Taşıma katmanındaki biçim: taşıma katmanı sıralı teslim veriyorsa, kaybolan bir parça onun ardından gelen her şeyi bekletir; hangi akışa ait olduklarına bakmaz, çünkü taşıma katmanı akışları bilmez. Çoğullama bu biçimi kaldırmaz, yalnız yukarı katmandan aşağıya taşır. Kaldıran şey taşımanın kendisinin akış farkındalığı kazanmasıdır.

Bu ayrım, Ağ Modelleri ve Protokoller kursunda kurulan bayt akışı soyutlamasının doğrudan sonucudur: sıralı ve kayıpsız bir akış sözü verildiğinde, o sözü tutmak için bekleyen bir kuyruk gerekir. İnternet Nasıl Çalışır kursundaki giriş düzeyi sezgi burada bir sayıya bağlanır.

Engellemenin aracı için ayrı bir anlamı vardır. Aracı iletiyi yalnız okumaz, iletir; o da bir kuyruktur. Uygulama sırası korunuyorsa aracı elindeki yanıtı sırası gelmeden gönderemez ve bir yanıtı beklerken ardındakileri tutar. Çoğullamanın kaldırdığı şey sunucunun değil, aracının kuyruğudur.

Başlık Sıkıştırması ve Aracının Bağlamı

İkili çerçeveleme başlık alanlarını dizinleyerek gönderir: bağlantı boyunca bir ad–değer tablosu tutulur, bir çift ikinci kez geçtiğinde adı ve değeri değil tablodaki sırası gönderilir. Kazanç büyüktür, çünkü konak adı ve yöntem gibi alanlar hemen hemen hiç değişmez.

Bedeli şudur: dizin, tabloyu tutmayan için anlamsızdır. Aracı bağlantının başından beri oradaysa tabloyu kendi de kurar ve her alanı çözer. Bağlantıya sonradan katılmışsa, ya da çerçeveleri çözmeden ileten bir katmansa, yalnız sözlük olarak yazılmış alanları okuyabilir.

  • HA46 — Aynı kırk alışveriş, aynı beş alan ve aynı kâhin kullanılır; değişen tek şey alanların tel üzerinde nasıl yazıldığıdır.
  • HA47 — Metin satırı çerçevelemesinde her alan her iletide baştan yazılır: ad, değer ve ayraç.
  • HA48 — İkili çerçevelemede bir ad–değer çifti ilk geçtiğinde sözlük olarak yazılır ve tabloya girer; sonraki geçişlerinde 1 baytlık dizin gönderilir.
  • HA49 — Tabloyu tutan aracı bütün alanları çözer. Tutmayan aracı yalnız sözlük olarak yazılmış alanı okur; dizinli alan onun için yoktur.
  • HA50 — Uygulama tarafında yavaş olan alışveriş /ozet yoludur; sunucu o yanıtı birden çok kayıttan derler.
  • HA51 — Taşımada kayıp yaşayan alışveriş ayrı bir üreteçle, tek modülüsle seçilir.
  • HA52 — Bekleme birimi bir süre değil bir sayımdır: bir alışveriş, aynı kuyrukta kendinden önce duran her engelin arkasında bir birim bekler.
  • HA53 — Paralel bağlantıda alışverişler sıra ile bağlantılara dağıtılır ve her bağlantının kendi tablosu vardır.
  • HA54 — Ölçüm bir ağ ölçümü değildir; bayt sayımı ileti içeriğinin sayımıdır.

Ölçüm

"""HTTP surumleri: cercevelemenin araciya kazandirdigi ve kaybettirdigi.

Bolum 1 - ayni alanlar uc cerceveleme rejiminde: karar ve bayt.
Bolum 2 - sira basi engellemesi ve cogullama: bekleyen alisveris.
"""
TOHUM = 20260809
GUVENLI = {"GET", "HEAD"}
ETKISIZ = {"GET", "HEAD", "PUT", "DELETE"}
YONTEMLER = ["GET", "GET", "GET", "HEAD", "POST", "PUT", "DELETE"]
YOLLAR = ["/olcum/kuzey", "/olcum/yamac", "/ozet", "/kayit", "/oturum"]
KARARLAR = ("saklanabilir", "paylasilabilir", "taze", "yinelenebilir",
            "yonlendirilebilir")
ALANLAR = ("yontem", "yol", "konak", "ozel_imi", "dogrulayici")


def uretec(tohum):
    d = tohum % 2147483646 + 1

    def r(n):
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def alisverisler(sayi=40):
    r, liste = uretec(TOHUM), []
    for i in range(sayi):
        yontem, yol = YONTEMLER[r(7)], YOLLAR[r(5)]
        ozel = yol == "/oturum" or r(5) == 0
        degisti = r(3) == 0
        liste.append({"no": i + 1, "yontem": yontem, "yol": yol,
                      "ozel": ozel, "degisti": degisti,
                      "ozel_imi": ozel and r(4) != 0,
                      "damga_atladi": degisti and r(6) == 0})
    return liste


def kahin(a):
    return {"saklanabilir": a["yontem"] in GUVENLI and not a["ozel"],
            "paylasilabilir": not a["ozel"], "taze": not a["degisti"],
            "yinelenebilir": a["yontem"] in ETKISIZ,
            "yonlendirilebilir": True}


def ileti(a):
    return {"yontem": a["yontem"], "yol": a["yol"], "konak": "istasyon.ornek",
            "ozel_imi": a["ozel_imi"],
            "dogrulayici": a["degisti"] and not a["damga_atladi"]}


def araci(i):
    k = {}
    if "yontem" in i:
        k["yinelenebilir"] = i["yontem"] in ETKISIZ
    if "ozel_imi" in i:
        k["paylasilabilir"] = not i["ozel_imi"]
        if "yontem" in i:
            k["saklanabilir"] = i["yontem"] in GUVENLI and not i["ozel_imi"]
    if "dogrulayici" in i:
        k["taze"] = not i["dogrulayici"]
    if "konak" in i:
        k["yonlendirilebilir"] = True
    return k


def cercevele(A, baglanti=1, sikistir=True):
    """Her iletiyi (bayt, sozluk-olarak-yazilan alanlar) ciftine cevirir.
    Ayni baglantida daha once gecen ad-deger cifti dizin olarak gonderilir:
    1 bayt tutar ve tabloyu tutmayan araci onu cozemez."""
    tablo, cikti = [set() for _ in range(baglanti)], []
    for i, a in enumerate(A):
        t, b, sozluk = tablo[i % baglanti], 0, set()
        for k, v in ileti(a).items():
            if not sikistir or (k, v) not in t:
                b += len(k) + len(str(v)) + 4
                sozluk.add(k)
                t.add((k, v))
            else:
                b += 1
        cikti.append((b, sozluk))
    return cikti


def olc(A, cerceve, baglam):
    d = y = e = t = b = 0
    for a, (bayt, sozluk) in zip(A, cerceve):
        gorunur = set(ALANLAR) if baglam else sozluk
        gercek = kahin(a)
        verilen = araci({k: v for k, v in ileti(a).items() if k in gorunur})
        eksik = False
        for karar in KARARLAR:
            if karar not in verilen:
                e += 1
                eksik = True
            elif verilen[karar] == gercek[karar]:
                d += 1
            else:
                y += 1
        t += 1 if eksik else 0
        b += bayt
    return d, y, e, t, b


def bekleme(A, engel, baglanti=1):
    """Bir alisveris, ayni kuyrukta kendinden once duran her engelin
    arkasinda bir birim bekler."""
    onceki, toplam = [0] * baglanti, 0
    for i, e in enumerate(engel):
        toplam += onceki[i % baglanti]
        onceki[i % baglanti] += 1 if e else 0
    return toplam


A = alisverisler()
kayip = uretec(TOHUM + 1)
YAVAS = [a["yol"] == "/ozet" for a in A]
KAYIP = [kayip(5) == 0 for _ in A]
IKISI = [u or k for u, k in zip(YAVAS, KAYIP)]
print(f"alışveriş {len(A)} | karar {len(A) * len(KARARLAR)} | "
      f"derlenen yanıt {sum(YAVAS)} | taşımada kayıp yaşayan {sum(KAYIP)}")
print()
print("çerçeveleme rejimi        doğru  yanlış  alınamayan  fazladan tur   bayt")
for ad, cerceve, baglam in (
        ("metin satırı", cercevele(A, 1, False), True),
        ("ikili, bağlam tutulur", cercevele(A), True),
        ("ikili, bağlam yok", cercevele(A), False)):
    d, y, e, t, b = olc(A, cerceve, baglam)
    print(f"  {ad:23s} {d:5d} {y:7d} {e:11d} {t:13d} {b:6d}")
print()
print("çerçeveleme rejimi        uygulama sırası  taşıma sırası  bekleyen alışveriş")
for ad, u, ta in (("metin satırı, tek bağlantı", True, True),
                  ("ikili, tek taşıma akışı", False, True),
                  ("ikili, ayrı taşıma akışları", False, False)):
    engel = IKISI if u and ta else KAYIP if ta else [False] * len(A)
    print(f"  {ad:27s} {'var' if u else 'yok':>10s}"
          f" {'var' if ta else 'yok':>14s} {bekleme(A, engel):18d}")
print()
print("paralel bağlantı  bekleyen alışveriş  sözlük olarak yazılan alan   bayt")
for n in (1, 2, 6):
    c = cercevele(A, n)
    print(f"  {n:14d} {bekleme(A, IKISI, n):19d}"
          f" {sum(len(s) for _, s in c):27d} {sum(b for b, _ in c):6d}")
alışveriş 40 | karar 200 | derlenen yanıt 9 | taşımada kayıp yaşayan 7

çerçeveleme rejimi        doğru  yanlış  alınamayan  fazladan tur   bayt
  metin satırı              195       5           0             0   3524
  ikili, bağlam tutulur     195       5           0             0    427
  ikili, bağlam yok          10       1         189            39    427

çerçeveleme rejimi        uygulama sırası  taşıma sırası  bekleyen alışveriş
  metin satırı, tek bağlantı         var            var                251
  ikili, tek taşıma akışı            yok            var                 83
  ikili, ayrı taşıma akışları        yok            yok                  0

paralel bağlantı  bekleyen alışveriş  sözlük olarak yazılan alan   bayt
               1                 251                          15    427
               2                 121                          29    636
               6                  36                          74   1321

Kazanç: Aynı Karar, Sekizde Bir Bayt

İlk tablonun ilk iki satırı yan yana okunmalıdır. Metin satırı çerçevelemesi 195 doğru, 5 yanlış, 0 alınamayan veriyor ve 3524 bayt harcıyor. Bağlamı tutulan ikili çerçeveleme aynı üç sayıyı veriyor ve 427 bayt harcıyor. Karar tablosu değişmiyor; bayt %87,9 azalıyor.

Bu, ortak kurgunun ikinci iddiasının tersten okunuşudur. Alan eklemek karar kazandırmıyordu; şimdi görülüyor ki alanı ucuzlatmak da karar kaybettirmiyor. Aracının çözebildiği sürece alanın kaç bayt tuttuğu kararla ilgisizdir. Kırk alışverişte iki yüz alan geçiyor ve bunların yalnız 15’i ayrı bir ad–değer çifti; kalan 185 geçiş aynı on beş çiftin tekrarı. Sıkıştırmanın kazandığı yer tam burasıdır.

İkinci tablo ikinci kazancı veriyor. Metin satırı çerçevelemesinde tek bağlantıda toplam 251 bekleme birimi doğuyor: dokuz derlenen yanıt ve yedi kayıp, arkalarındaki her alışverişi bekletiyor. Çoğullama uygulama sırasını kaldırınca bekleme 83’e iniyor — kalan tamamı taşıma katmanından geliyor. Taşıma da akışları ayırdığında 0.

Üç satırın sırası önemlidir: çoğullama beklemeyi sıfırlamaz, üçte birine indirir; sıfırlayan şey taşımanın değişmesidir. Çerçeveleme katmanında çözülen sorunun kalanı aşağıdaki katmandaydı.

Kayıp: Çözülemeyen Alan Yok Sayılır

Üçüncü satır bu dersin asıl bulgusudur. Bayt aynı 427, ama karar tablosu çöküyor: 10 doğru, 1 yanlış, 189 alınamayan, 39 fazladan tur.

Nedeni şudur: kırk iletide yalnız 15 alan sözlük olarak yazılmış; kalan 185 alan dizinle gönderilmiş. Tabloyu tutmayan aracı o 185 alanı okuyamıyor ve okuyamadığı alandan karar çıkaramıyor. İki yüz kararın 189‘u ortadan uçlara taşınıyor — zarf rejiminin taşıdığı 160’tan da fazla. Alanlar iletide duruyor; aracı için var olmuyorlar.

Kalan on bir karar ilk alışverişten ve tablonun kurulduğu birkaç ilk geçişten geliyor. Tek yanlış karar da orada: birinci alışveriş POST /kayit ve kişiye özel bir yanıt üretiyor ama sunucu imi koymamış. Aracı o iletide alanı okuyabildiği için karar veriyor ve yanlış veriyor. Örüntü değişmiyor — okunabilen alan yanlış olabilir, okunamayan alan yalnız eksiktir.

Buradan çıkan kural şudur: sıkıştırma bir görünürlük kararıdır. Bağlantının başında duran aracı hiçbir şey kaybetmez; sonradan katılan ya da çerçeveyi çözmeden ileten aracı neredeyse her şeyi kaybeder. Metin satırı çerçevelemesinde böyle bir ayrım yoktu, çünkü her ileti kendi kendine yeterdi.

Paralel Bağlantı: Aynı Sorunun Başka Bedeli

Üçüncü tablo, çoğullamadan önceki çözümü ölçüyor: aynı konağa birden çok bağlantı açmak. Bekleme gerçekten düşüyor — 251’den iki bağlantıda 121’e, altı bağlantıda 36’ya.

Bedeli sağdaki iki sütunda. Her bağlantının kendi başlık tablosu vardır; alışverişler bölündükçe aynı ad–değer çiftleri her bağlantıda yeniden sözlük olarak yazılır. Sözlük olarak yazılan alan sayısı 15’ten 29’a, sonra 74’e çıkıyor; bayt 427’den 636’ya, sonra 1321’e. Altı bağlantıda beklemenin yedide birine inmesi, baytın üç katına çıkmasıyla ödeniyor.

Çoğullamanın farkı buradan çıkıyor: tek bağlantıda hem beklemeyi taşıma katmanına indiriyor hem tabloyu tek parça tutuyor. Paralel bağlantı ise iki maliyeti takas ediyor, birini ortadan kaldırmıyor.

Özet

  • Sürümler arasındaki fark anlamda değil çerçevelemededir: aynı alanlar metin satırı ya da akış numaralı ikili çerçeve olarak yazılır.
  • Bağlamı tutulan ikili çerçeveleme aynı 195 doğru ve 5 yanlış kararı 3524 yerine 427 baytla verir; kırk alışverişteki 200 alan geçişinin yalnız 15’i ayrı bir ad–değer çiftidir.
  • Sıra başı engellemesinin iki biçimi vardır; çoğullama uygulama katmanındakini kaldırır ve beklemeyi 251’den 83’e indirir, taşıma katmanındakini ancak taşımanın akış farkındalığı 0’a indirir.
  • Bağlamı tutmayan aracı yalnız sözlük olarak yazılmış alanı okur: 189 karar uçlara taşınır, 39 tur borcu doğar ve bayt hiç değişmez.
  • Paralel bağlantı beklemeyi 36’ya indirir ama tabloyu böler; sözlük olarak yazılan alan 74’e, bayt 1321’e çıkar.

Sonraki Adım

Çerçeveleme aracının alanı okuyup okumadığını belirliyor. Ama okuyabildiği hâlde bile bir karar var ki alanın kendisinden değil, iki değerin karşılaştırılmasından geliyor: elde tutulan kopya ile yeni gelen ileti aynı şeyi mi anlatıyor? Sonraki ders bu karşılaştırmayı ölçer. Aracının sakladığı kopyanın hâlâ geçerli olup olmadığını hangi alan söyler, o alanın çözünürlüğü nedir ve çözünürlük yetmediğinde aracı ne der.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat