WEB / WEB-09.03
ETag ve conditional requests
Validator bir representation’a ilişkin önceki gözlemi yeni request’in koşuluna dönüştürür. 304 body reuse ile If-Match write guard’ını aynı sanmadan oku.
1. Core · Mekanizma
Hareket olmadan bütün senaryoları oku
304, body retained
- Stored revision seçildi
Duru cache’teki Çay body’si ve atlas-v1 tag’iyle validation ister; origin’in current revision’ı v1 olarak verilmiştir.
- Browser / Duru
- Conditional GET ready
- Origin / Atlas
- Request absent
- Local HTTP cache
- Stored Çay; v1; max-age0
- Origin representation
- Current Çay; v1
- Conditional GET ulaştı
Origin If-None-Match W/atlas-v1 request’ini alır; normal request kontrolleri ve context bu örnekte uygundur.
- Browser / Duru
- Waiting validation
- Origin / Atlas
- GET received; no decision yet
- Local HTTP cache
- Stored Çay; v1; max-age0
- Origin representation
- Current Çay; v1
- Weak comparison sonucu
Current strong v1 ile gelen weak v1 eşleşir. If-None-Match koşulu false olduğu için 304 hazırlanır.
- Browser / Duru
- Waiting validation
- Origin / Atlas
- 304 ready; content0; metadata updated
- Local HTTP cache
- Stored Çay; v1; max-age0
- Origin representation
- Current Çay; v1
- 304 response ulaştı
Browser Date, ETag, Vary ve max-age=60 metadata’sını alır; origin’den gelen content’in boyutu sıfırdır.
- Browser / Duru
- 304 received; content0
- Origin / Atlas
- 304 ready; content0
- Local HTTP cache
- Stored Çay; v1; max-age0
- Origin representation
- Current Çay; v1
- Eşleşen entry güncellendi
Local cache, güncellemeye uygun ve strong tag’i eşleşen entry’yi seçer. Yeni header değerleri yazılır, Çay body’si korunur.
- Browser / Duru
- 304 processed locally
- Origin / Atlas
- Exchange complete
- Local HTTP cache
- Stored Çay; v1; new Date; max-age60
- Origin representation
- Current Çay; v1
- Korunan body kullanıldı
Duru eski dört byte’lık body’yi kullanır. Bu local reuse’dır; body origin’den yeniden gelmemiştir.
- Browser / Duru
- Effective content: Çay; retained4 bytes
- Origin / Atlas
- Exchange complete
- Local HTTP cache
- Stored Çay; v1; new Date; max-age60
- Origin representation
- Current Çay; v1
Changed, full 200
- Eski v1 gözlemi
Duru eski Çay/v1 kopyasıyla validation başlatır; origin artık v2 ve Atlas note representation’ını kullanmaktadır.
- Browser / Duru
- Conditional GET ready
- Origin / Atlas
- Request absent
- Local HTTP cache
- Stored Çay; v1
- Origin representation
- Current Atlas note; v2
- GET origin’e ulaştı
Origin eski v1 validator’ını alır. Request’in ulaşması, browser’ın cache’teki body’sini henüz değiştirmez.
- Browser / Duru
- Waiting response
- Origin / Atlas
- GET received; If-None-Match v1
- Local HTTP cache
- Stored Çay; v1
- Origin representation
- Current Atlas note; v2
- Representation değişti
Opaque değerler farklı olduğu için If-None-Match koşulu true olur; tam v2 representation’ı içeren 200 hazırlanır.
- Browser / Duru
- Waiting response
- Origin / Atlas
- 200 ready; Atlas note; v2
- Local HTTP cache
- Stored Çay; v1
- Origin representation
- Current Atlas note; v2
- 200 content ulaştı
Yeni content’in on UTF-8 byte’ı ve v2 tag’i browser’a ulaşır. Cached entry henüz local değiştirme adımını bekler.
- Browser / Duru
- 200 received; Atlas note10; v2
- Origin / Atlas
- 200 ready; Atlas note; v2
- Local HTTP cache
- Stored Çay; v1
- Origin representation
- Current Atlas note; v2
- Cache kopyası değişti
Bu örnekte storage eligibility uygundur; cache yeni body ve tag’i birlikte yazar.
- Browser / Duru
- Use new content
- Origin / Atlas
- Exchange complete
- Local HTTP cache
- Stored Atlas note; v2
- Origin representation
- Current Atlas note; v2
- Yeni revision gözlemi
Duru’nun sonraki validator gözlemi v2’dir; eski v1 body’si yeni tag altında tutulmaz.
- Browser / Duru
- Effective content Atlas note; v2
- Origin / Atlas
- Exchange complete
- Local HTTP cache
- Stored Atlas note; v2
- Origin representation
- Current Atlas note; v2
Stale write, 412
- Eski revision ile edit
Duru v1’e göre Updated note değişikliğini hazırlar. İzin verilmiş olduğu varsayılır; origin’in current revision’ı v2’dir.
- Browser / Duru
- PUT ready; If-Match v1
- Origin / Atlas
- Request absent
- Local HTTP cache
- Observed v1; no cache mutation
- Origin representation
- Current Atlas note; v2
- PUT origin’e ulaştı
Origin yeni content’i ve eski strong validator’ı alır; method henüz uygulanmamıştır.
- Browser / Duru
- Waiting outcome
- Origin / Atlas
- PUT received; not applied
- Local HTTP cache
- Observed v1; no cache mutation
- Origin representation
- Current Atlas note; v2
- Normal kontroller geçti
Normal request ve permission kontrollerinin geçtiği bu örnekte verilmiştir. Validator kontrolü bu izin kararının yerine geçmez.
- Browser / Duru
- Waiting outcome
- Origin / Atlas
- Checks passed; compare pending
- Local HTTP cache
- Observed v1; no cache mutation
- Origin representation
- Current Atlas note; v2
- Strong koşul karşılanmadı
v1 ile v2 strong match vermez. already-applied=false olduğu için 412 seçilir; write yapılmaz.
- Browser / Duru
- Waiting outcome
- Origin / Atlas
- 412 ready; methodApplied=false
- Local HTTP cache
- Observed v1; no cache mutation
- Origin representation
- Current Atlas note; v2
- 412 response ulaştı
Duru precondition failure status’unu alır; origin’deki v2 representation aynen korunmuştur.
- Browser / Duru
- 412 received; edit not applied
- Origin / Atlas
- 412 ready; methodApplied=false
- Local HTTP cache
- Observed v1; no cache mutation
- Origin representation
- Current Atlas note; v2
- Conflict değerlendirmesi
Current state’i yeniden okumak ve business conflict’i çözmek ayrı işlemlerdir. Bu sahne eski edit’i otomatik yeniden uygulamaz.
- Browser / Duru
- Needs current-state read/reconciliation
- Origin / Atlas
- Exchange complete
- Local HTTP cache
- Observed v1 remains old
- Origin representation
- Current Atlas note; v2
ROLLER · STATE · VERİ AKIŞI
ETag bir representation gözlemidir
Duru, Çay body’sini ETag: "atlas-v1" metadata’sıyla saklamıştır. Bu opaque değer, seçilen representation’ın validator’ıdır; password, object owner ID veya permission değildir. Client değerin nasıl üretildiğini bilmek zorunda değildir. Tag’de v1 yazması da bir timestamp veya kullanıcı identity’si göstermez. Buradaki isimler yalnız revision’ları takip etmeyi kolaylaştırır.
Strong tag, representation data değiştiğinde değişmelidir; W/ prefix’i weak validator belirtir. Weak comparison, opaque değerleri karşılaştırır ve tag’lerin weak/strong oluşunu göz ardı eder. Strong comparison ise iki tag’in de weak olmamasını ve opaque değerlerin eşitliğini ister. "atlas-v1" ile W/"atlas-v1" weak match verir, strong match vermez.
Validator belirli bir representation için geçerlidir. Aynı resource’un gzip ve uncoded representation’ları farklı byte dizileriyse aynı strong tag’i kullanamazlar; transfer coding, representation coding’den farklıdır. Ayrı resource’larda aynı tag’in görülmesi content’in veya permission’ın aynı olduğunu kanıtlamaz. Örnekte target, text/plain ve identity coding sabittir.
Conditional GET: eski body hâlâ kullanılabilir mi?
Duru If-None-Match: W/"atlas-v1" ile GET gönderir. Origin’in current tag’i "atlas-v1" ise weak match vardır: “hiçbiri eşleşmesin” koşulu false olur ve normal GET content’i yerine 304 döner. If-None-Match weak comparison kullanır; listede strong tag yazmak karşılaştırmayı strong yapmaz. Bu koşulun false olması GET/HEAD için 304, diğer method’lar için 412 sonucu verir.
304 content veya trailers taşımaz. Aynı request’e 200 verilse gönderilecek Date, ETag, Vary, Cache-Control ve diğer ilgili zorunlu alanları taşır. Örnekte Date ve max-age yenilenir. Duru’nun cache’i önce bu response’un hangi stored representation’ı güncelleyebileceğini seçer; örnekte buna uygun, eşleşen strong tag’li entry vardır. Header değerleri güncellenir, Çay body’si korunur.
Origin artık "atlas-v2" tag’li Atlas note representation’ını seçmişse eski v1 koşulu true olur ve tam 200 gelir. Eski body yerine yeni response kullanılır; storage kuralları uygunsa cached entry değiştirilir. 304, cache’e “boş representation” olarak yazılmaz. Yeni 200 content’i de eski tag altında bırakılmaz. WEB-09.02’deki age hesabı yeni timing metadata’sıyla yeniden yapılır; validator tek başına freshness süresi değildir.
If-Match: önceki state’e dayanarak write
Duru v1’e dayanarak bir not değişikliği hazırlamıştır; origin’deki current state artık v2’dir. If-Match: "atlas-v1", PUT’un uygulanmasını current tag ile strong match şartına bağlar. Normal request ve permission kontrollerinin geçtiği bu örnekte verilmiştir. Ardından precondition, method uygulanmadan değerlendirilir. Eşleşme olmadığı için bu senaryo 412 döndürür; update yapılmaz ve v2 korunur.
W/"atlas-v2" aynı opaque metni taşısa da strong If-Match şartını karşılamaz. Weak validator’ı kesin write revision’ı yerine koyma. RFC, false If-Match durumunda değişiklik daha önce uygulanmışsa belirli koşullarla success response olasılığını da tarif eder. Burada duplicate/already-applied durumu false olarak verilmiştir. Dolayısıyla 412 bu senaryonun sonucudur; her false condition için koşulsuz evrensel bir sonuç değildir.
Lost update kontrolü yalnız tag karşılaştırması değildir. Gerçek store’da current version kontrolü ile write atomik bir sınırda birleşmelidir; arada başka bir writer state’i değiştirirse amaçlanan koşul bozulur. Buradaki representation verisi sırayla, aynı process içinde işlenir; database isolation veya lock performansı ölçülmez. Retry öncesinde current state’i yeniden okumak ve business conflict’i çözmek, eski edit’i körlemesine kabul etmekten farklıdır.
2. Red · Güven ve etki
Hareket olmadan bütün senaryoları oku
Tag scope
- Opaque tag knowledge identity’den ayrıldı
atlas-v1 public representation validator’ıdır. Tag’i bilmek authenticated user veya resource grant’i sağlamaz. If-Match ve If-None-Match, seçilmiş representation state’ini karşılaştırır; user permission’ı değil.
- Validator record
- Tag known / identity-permission not inferred
- Precondition gate
- Comparison bekliyor
- Method/body boundary
- Verdict yok
- Strong ve weak match farklı garanti verdi
W/"atlas-v1" ile "atlas-v1" weak comparison’da eşleşir, strong comparison’da eşleşmez. Header’ın hangi comparison’ı istediği önemlidir. Weak match’i exact byte equality diye yorumlamak yanlış control kurar.
- Validator record
- Tag known / identity-permission not inferred
- Precondition gate
- Weak pair: weak true / strong false
- Method/body boundary
- Verdict yok
- Match ile method çalışması aynı sonuç olmadı
If-None-Match match olduğunda condition false olur; GET için bu case 304 verir. If-Match match olduğunda ise condition true olur. İki header aynı tag’i taşısa bile control mantıkları ters sorulara yanıt verir.
- Validator record
- Tag known / identity-permission not inferred
- Precondition gate
- Weak pair: weak true / strong false
- Method/body boundary
- If-None-Match match→false / If-Match match→true
- Encoded variant tag’i ayrı representation’a bağlandı
Identity variant "tea-plain-a", gzip variant "tea-gzip-a" strong tag’i taşır; encoded bytes farklı verilmiştir. Bir resource URL’si bütün representation’ların byte-for-byte aynı olduğu anlamına gelmez.
- Validator record
- Identity tag tea-plain-a / gzip tag tea-gzip-a
- Precondition gate
- Weak pair: weak true / strong false
- Method/body boundary
- If-None-Match match→false / If-Match match→true
- Normal request gate’leri precondition’dan önce korundu
Normal authentication ve resource/action authorization ayrı değerlendirilmelidir. put412 normalChecksPassedSupplied true verir; bu koşul gerçek permission engine değildir. Correct validator yanlış user policy’sini telafi etmez.
- Validator record
- Identity tag tea-plain-a / gzip tag tea-gzip-a
- Precondition gate
- Normal checks supplied / validator is not permission
- Method/body boundary
- If-None-Match match→false / If-Match match→true
- Comparison sonucu atomic persistence claim’i olmadı
Bu ledger sequential in-process state gösterir. Gerçek concurrent compare/write atomicity ayrıca doğrulanmalıdır. Validator semantics’in tutarlı olması database isolation, protected writes veya production permission kanıtı değildir.
- Validator record
- Identity tag tea-plain-a / gzip tag tea-gzip-a
- Precondition gate
- Normal checks supplied / validator is not permission
- Method/body boundary
- Validator scope known / atomic write unmeasured
Body association
- Stored candidate kendi body ve tag’iyle seçildi
storedBefore tag "atlas-v1", body Çay ve contentOctets 4 taşır. Vary match ve tek complete stored candidate verilmiştir. URL metni tek başına hangi representation’ın güncelleneceğini belirlemek için yeterli değildir.
- Validator record
- Selected stored v1 / Çay / 4 bytes
- Precondition gate
- Comparison bekliyor
- Method/body boundary
- Verdict yok
- 304 metadata update body replacement sayılmadı
304 actualContentOctets 0’dır. Matching stored candidate’ın Date ve Cache-Control metadata’sı güncellenir; body Çay olarak kalır. Empty origin content, stored body’nin silineceği anlamına gelmez.
- Validator record
- Selected stored v1 / Çay / 4 bytes
- Precondition gate
- 304: metadata updated / existing body retained
- Method/body boundary
- Verdict yok
- Cached effective content origin bytes’tan ayrıldı
Origin 304 sırasında body göndermez, fakat seçilmiş stored response okuyucuya dört byte Çay sunabilir. İki byte hesabını tek field’da birleştirmek yanlış empty-content verdict’i üretir. Gerçek browser cache davranışı burada ölçülmez.
- Validator record
- Selected stored v1 / Çay / 4 bytes
- Precondition gate
- 304: metadata updated / existing body retained
- Method/body boundary
- Origin body 0 / retained content 4
- Changed 200 yeni body ile yeni tag’i birlikte getirdi
changed200 currentTag "atlas-v2", body Atlas note ve contentOctets 10 verir. Old v1 tag artık match değildir. Yeni body’ye old v1 metadata bırakmak sonraki validation’ı yanlış representation’a bağlar.
- Validator record
- Changed 200 / v2 / Atlas note / 10 bytes
- Precondition gate
- 304: metadata updated / existing body retained
- Method/body boundary
- Origin body 0 / retained content 4
- Replacement kararının scope’u seçilmiş candidate’da kaldı
Tag ve body birlikte değiştirilir; matching context incelenmeden bütün URL copies’ine metadata yayılmaz. 304 retain ve 200 replacement farklı local store kararlarıdır. Response receipt de store update’ten ayrı aşamadır.
- Validator record
- Changed 200 / v2 / Atlas note / 10 bytes
- Precondition gate
- Replace tag and body together / candidate scoped
- Method/body boundary
- Origin body 0 / retained content 4
- Body association confidentiality garantisi olmadı
Bu public representation ledger’ında retain/replacement açıktır. Private cache recipient’i veya protected object policy için ayrı evidence gerekir. Doğru metadata/body association bütün user contexts için cache correctness garantisi değildir.
- Validator record
- Changed 200 / v2 / Atlas note / 10 bytes
- Precondition gate
- Replace tag and body together / candidate scoped
- Method/body boundary
- Association consistent / recipient policy separate
VARSAYIM · SINIR · KONTROL
Validator’ı izin belgesi yerine koyma
ETag public response’ta görülebilir. Onu bilmek resource’u değiştirme hakkı vermez; If-Match yalnız observed representation state’iyle current state’i karşılaştırır. Yanlış kabul koşulu matching tag’i authentication veya object permission yerine kullanmaktır. Bir doğru precondition yanlış user policy’yi telafi etmez.
Etki update’in doğru revision’a ama yanlış actor adına uygulanması veya cache’ten yanlış representation’ın seçilmesi olabilir. Kontrol trusted identity ve resource/action authorization kararını normal request handling’de almak, ardından applicable precondition’ı method uygulanmadan değerlendirmektir. Public tea ve supplied permissionChecksPassed bu derste normal semantics’i izole eder; gerçek izin motoru değildir.
Weak match’i byte equality diye yorumlamak da ayrı hatadır. Cache validation substitution için weak semantics yararlı olabilir; exact write veya partial-range ihtiyacını aynı guarantee ile karşılamaz. İnceleme hangi precondition’ın hangi comparison’ı kullandığını kayda geçirmelidir.
Metadata/body bağlantısını koparma
304’ün body’siz gelmesi cached Çay’ın silinmesini istemez. Hata koşulu matching context’i incelemeden bütün URL kopyalarına yeni headers’i yaymak veya body’yi boşaltmaktır. Ters hata new200 body’sine old v1 metadata bırakmaktır. Sonuç yanlış content gösterimi ve ileride hatalı validation kararı olabilir; privacy etkisi seçilen representation’a bağlıdır.
Kontrol stored candidate seçimi, validator eşlemesi, required header update ve body retain/replacement kararını tek defterde tutmaktır. Stale If-Match branch’inde 412 geldiğinde mutation false kalır. Gerçek concurrency için compare/write atomikliği ayrıca doğrulanır. Bu sahneler exploit, replay veya unauthorized edit denemesi oluşturmaz.
3. Blue · Güvenli geliştirme ve savunma
Hareket olmadan bütün senaryoları oku
304 retain
- Conditional GET kendi comparison’ıyla seçildi
Origin örneği response304 ve changed200 kayıtlarını, yerel cache defteri storedBefore ve storedAfter304 kayıtlarını üretir. PUT için requestedBody ile methodApplied/afterBody ayrı alanlardır. Origin’in sıfır content byte’ı, cache’te korunan dört byte’ı yok saymaz; request body’nin varlığı da write yapıldığını kanıtlamaz. Bu kayıtların üreticileri farklı olduğu için byte ve state sonuçlarını ayrı eşleştir. GET If-None-Match W/"atlas-v1", current strong "atlas-v1" ile weak match verir. matches true fakat conditionTrue false’tur. Review comparison sonucunu header’ın mantığıyla birlikte okur.
- Conditional ledger
- Weak match true / If-None-Match condition false
- Comparison/state review
- Comparison bekliyor
- Evidence verdict
- Verdict yok
- Origin response content’i ayrıca sayıldı
response304 status 304 ve actualContentOctets 0 verir. New Date 00:01:00, Cache-Control max-age=60’tır. Content-Length olmayan bu valid response’da body uydurulmaz; headers content değildir.
- Conditional ledger
- Weak match true / If-None-Match condition false
- Comparison/state review
- 304 origin content 0 / metadata refreshed
- Evidence verdict
- Verdict yok
- Stored body bağımsız observation olarak korundu
storedAfter304 status 200, body Çay ve contentOctets 4 olarak kalır. Date ve max-age güncellenir; ETag v1 ve media association korunur. Stored status 200 ile origin status 304 farklı kayıtların değerleridir.
- Conditional ledger
- Stored 200 / Çay 4 / metadata updated
- Comparison/state review
- 304 origin content 0 / metadata refreshed
- Evidence verdict
- Verdict yok
- Body oracle normal ve positive control ile değerlendirildi
Normal XML 304 için actualContentOctets 0 verir; count sıfırdır. Positive XML bir content byte bildirir ve count bir olur. Bu oracle body rule’ını sınar; gerçek captured response iddiası değildir.
- Conditional ledger
- Stored 200 / Çay 4 / metadata updated
- Comparison/state review
- Normal body-rule count 0 / positive 1
- Evidence verdict
- Verdict yok
- Missing response event verdict’i unknown yaptı
Gerçek bir trace’te response observation yoksa zero match complete 304 evidence değildir. Normal fixture’ın body 0 kaydı eksik capture’ı doldurmaz. Origin content ve cached effective content scope’ları ayrıca doğrulanmalıdır.
- Conditional ledger
- Stored 200 / Çay 4 / metadata updated
- Comparison/state review
- Normal body-rule count 0 / positive 1
- Evidence verdict
- UNKNOWN without response-content coverage
- Regression representation context’ini korudu
Review seçilmiş candidate, Vary context, validator comparison ve header update’i beraber tekrarlar. Range, general tag parser veya browser cache ölçülmez. Bu sequential ledger sonuçları yeni runtime evidence olmadan bütün deployments’e taşınmaz.
- Conditional ledger
- Stored 200 / Çay 4 / metadata updated
- Comparison/state review
- Normal body-rule count 0 / positive 1
- Evidence verdict
- Recheck candidate/context/validator/metadata
412 no mutation
- Requested write current state’ten ayrıldı
Origin örneği response304 ve changed200 kayıtlarını, yerel cache defteri storedBefore ve storedAfter304 kayıtlarını üretir. PUT için requestedBody ile methodApplied/afterBody ayrı alanlardır. Origin’in sıfır content byte’ı, cache’te korunan dört byte’ı yok saymaz; request body’nin varlığı da write yapıldığını kanıtlamaz. Bu kayıtların üreticileri farklı olduğu için byte ve state sonuçlarını ayrı eşleştir. PUT requestedBody Updated note taşır; currentBody Atlas note ve currentTag "atlas-v2"’dir. If-Match ise "atlas-v1" ister. Request body’nin mevcut olması, method’ün uygulandığını kanıtlamaz.
- Conditional ledger
- Requested Updated note / current v2 Atlas note
- Comparison/state review
- Comparison bekliyor
- Evidence verdict
- Verdict yok
- Strong precondition method uygulamasından önce sınandı
Normal checks passed ve alreadyApplied false verilmiştir. Strong v1-v2 match false, conditionTrue false olur. Bu case 412 verir; failed precondition ile application deny aynı reason değildir.
- Conditional ledger
- Requested Updated note / current v2 Atlas note
- Comparison/state review
- Strong mismatch / condition false / 412
- Evidence verdict
- Verdict yok
- Method state effect ayrı kaydedildi
methodApplied false’tur; afterTag "atlas-v2", afterBody Atlas note kalır. Error status tek başına bu state preservation’ı ölçmez; ledger ayrı before/after alanları sağlar. Requested edit inert data olarak durur.
- Conditional ledger
- After v2 / Atlas note / methodApplied=false
- Comparison/state review
- Strong mismatch / condition false / 412
- Evidence verdict
- Verdict yok
- Comparison matrix negative control olarak kullanıldı
Strong v1-v1 true, weak-v1/strong-v1 strong false ve v1-v2 false satırları ayrı kontrollerdir. Bu matrix exact write precondition’ının weak cache comparison’ıyla değiştirilmemesi gerektiğini gösterir.
- Conditional ledger
- After v2 / Atlas note / methodApplied=false
- Comparison/state review
- Strong-write comparison retained
- Evidence verdict
- Verdict yok
- No mutation sonucu concurrency claim’i olmadı
Bu tek sequential operation’da failed guard state’i korur. Concurrent compare/write isolation, retry ve gerçek permission engine ölçülmez. Gerçek update correctness için guard ile write’ın atomic boundary’si ayrıca incelenmelidir.
- Conditional ledger
- After v2 / Atlas note / methodApplied=false
- Comparison/state review
- Strong-write comparison retained
- Evidence verdict
- Sequential state retained / concurrency unmeasured
- Evidence collection body ve secret’i çoğaltmadı
Status, comparison class, methodApplied ve scoped revision association review için yeterli olabilir. Full private note veya credential kaydetmek gerekmez. Yeni runtime için response ve gerçek state effect ayrı gözlemlenmelidir.
- Conditional ledger
- After v2 / Atlas note / methodApplied=false
- Comparison/state review
- Strong-write comparison retained
- Evidence verdict
- Needed: status/comparison/state-effect scope
UYGULAMA · GÜVENLİK KONTROLÜ · DOĞRULAMA
304’te iki ayrı byte hesabı yap
Origin örneği response304 ve changed200 kayıtlarını, yerel cache defteri storedBefore ve storedAfter304 kayıtlarını üretir. PUT için requestedBody ile methodApplied/afterBody ayrı alanlardır. Origin’in sıfır content byte’ı, cache’te korunan dört byte’ı yok saymaz; request body’nin varlığı da write yapıldığını kanıtlamaz. Bu kayıtların üreticileri farklı olduğu için byte ve state sonuçlarını ayrı eşleştir. Artifact’taki storedBefore contentOctets=4 ile response304 actualContentOctets=0 farklı gözlemdir. Manual exercise’de new Date ve Cache-Control’ü bul; storedAfter içindeki body’nin hâlâ Çay olduğunu doğrula. Response’ın boş content’i eski body replacement olarak yazılmamıştır. Header güncelleme işlemi browser cache içindedir, yeni origin body transfer’i değildir.
Changed200 branch’inde body Atlas note ve tag atlas-v2’dir; on byte’lık yeni representation cached copy’yi ancak response ulaşıp local store update yapıldığında değiştirir. PUT412 branch’inde requested edit inerttir, current v2 state değişmez. Server’in precondition kararını client’a status ulaşmasından ayrı işaretlemek causality’yi açık tutar.
Selector status304 ve actualContentOctets>0 observation’ını seçer. Normal0/positive1/missing0 ayrımı body rule’ı sınayan sentetik gözlemdir. Eksik event varsa clean sonucu iddia edilmez; gerçek capture completeness ve method correlation gereklidir. XML alanları ürün log alanı olarak tanıtılmaz.
Precondition tablosunu elle uygula
Comparison rows’da aynı strong pair için strong/weak true; bir weak taraf için strong false/weak true; farklı opaque değer için ikisi false sonucunu yaz. Sonra header’ın mantığını ekle: If-None-Match match olduğunda condition false, If-Match match olduğunda condition true olur. “Match bulundu” ile “request method çalışır” aynı cümle değildir.
Review defterinde normal checks, selected representation, validator comparison, requested method application ve cached result ayrı alanlar olsun. 304 origin tarafında body gönderilmediğini gösterir; browser’ın okuyucuya sunduğu effective content’i sıfır diye sayma. Native normal exchange dahi bütün Browser cache davranışı, concurrency ve authorization hakkında tek başına sonuç vermez.
Write handler, If-Match değerini değişikliği uygulamadan önce current representation’ın strong validator’ıyla karşılaştırmalıdır. Örnekte client atlas-v1 gönderirken current atlas-v2’dir; 412 üretildiğinde Updated note’u kaydetme ve current body’yi koru. Request header’ının varlığı tek başına bu kontrolün uygulandığını göstermez. Matching validator da kullanıcıya izin vermez; normal permission kontrolleri ayrı gerekir. Read tarafında 304 metadata güncellemesini stored body replacement ile karıştırmadan, write tarafında ise rejected precondition’ın state’i değiştirmediğini doğrula.
ŞİMDİ VAKAYA UYGULA
Weak GET validation ile strong write precondition nasıl farklı sonuç verir?
Çay için stored v1 copy, matching conditional GET sonrası 304 alır: origin body göndermez, stored dört byte body korunur. Current state v2 olduğunda stale v1 If-Match içeren PUT ise 412 alır ve Atlas note değişmez.
Vakadaki representation hangi cache owner’dan geliyor? Key kapsamı, freshness ve kullanıcının context’ini birlikte değerlendir; hit olması doğru viewer’a ait olduğunu kanıtlamaz.
Bağlı vaka dosyasını aç ↗ÖRNEĞİ BİRLİKTE OKUYALIM
Validator, metadata ve body association defteri
Bir alan seç; hangi sonucu desteklediğini ve nerede yetersiz kaldığını incele.
Ham kaydı ve alan açıklamalarını oku
{
"target": "/tea?view=plain",
"selectedContext": {
"accept": "text/plain",
"contentCoding": "identity",
"varyMatchesSupplied": true,
"oneCompleteStoredCandidate": true
},
"storedBefore": {
"status": 200,
"body": "Çay",
"contentOctets": 4,
"headers": {
"date": "Thu, 08 Oct 2026 00:00:00 GMT",
"etag": "\"atlas-v1\"",
"cache-control": "max-age=0",
"vary": "Accept",
"content-type": "text/plain; charset=utf-8",
"content-length": "4"
}
},
"response304": {
"requestMethod": "GET",
"ifNoneMatch": "W/\"atlas-v1\"",
"currentTag": "\"atlas-v1\"",
"comparison": "weak",
"matches": true,
"conditionTrue": false,
"status": 304,
"actualContentOctets": 0,
"headers": {
"date": "Thu, 08 Oct 2026 00:01:00 GMT",
"etag": "\"atlas-v1\"",
"cache-control": "max-age=60",
"vary": "Accept"
},
"http11": "HTTP/1.1 304 Not Modified\r\nDate: Thu, 08 Oct 2026 00:01:00 GMT\r\nEtag: \"atlas-v1\"\r\nCache-Control: max-age=60\r\nVary: Accept\r\n\r\n"
},
"storedAfter304": {
"status": 200,
"body": "Çay",
"contentOctets": 4,
"headers": {
"date": "Thu, 08 Oct 2026 00:01:00 GMT",
"etag": "\"atlas-v1\"",
"cache-control": "max-age=60",
"vary": "Accept",
"content-type": "text/plain; charset=utf-8",
"content-length": "4"
}
},
"changed200": {
"ifNoneMatch": "\"atlas-v1\"",
"currentTag": "\"atlas-v2\"",
"matches": false,
"conditionTrue": true,
"status": 200,
"body": "Atlas note",
"contentOctets": 10,
"cachedAfterTag": "\"atlas-v2\"",
"cachedAfterBody": "Atlas note"
},
"put412": {
"method": "PUT",
"ifMatch": "\"atlas-v1\"",
"currentTag": "\"atlas-v2\"",
"currentBody": "Atlas note",
"requestedBody": "Updated note",
"comparison": "strong",
"matches": false,
"conditionTrue": false,
"normalChecksPassedSupplied": true,
"alreadyAppliedSupplied": false,
"status": 412,
"methodApplied": false,
"afterTag": "\"atlas-v2\"",
"afterBody": "Atlas note"
},
"comparisonRows": [
{
"left": "\"atlas-v1\"",
"right": "\"atlas-v1\"",
"strong": true,
"weak": true
},
{
"left": "W/\"atlas-v1\"",
"right": "\"atlas-v1\"",
"strong": false,
"weak": true
},
{
"left": "\"atlas-v1\"",
"right": "\"atlas-v2\"",
"strong": false,
"weak": false
}
],
"representationVariantExample": {
"resource": "/tea?view=plain",
"identityStrongTag": "\"tea-plain-a\"",
"gzipStrongTag": "\"tea-gzip-a\"",
"differentEncodedBytesSupplied": true
},
"selector": {
"language": "XPath",
"xml": "<observations><response status=\"304\" actualContentOctets=\"0\"/></observations>",
"xpath": "count(/observations/response[@status=\"304\" and number(@actualContentOctets)>0])",
"expected": 0,
"positiveFixtureXml": "<observations><response status=\"304\" actualContentOctets=\"1\"/></observations>",
"positiveExpected": 1,
"scope": "Only authored protocol-decision observations, not product log field names or a live HTTP capture.",
"missingFieldBehavior": "Missing observation is insufficient evidence; zero matches is not proof of correct runtime behavior."
}
}- comparisonRows
- Opaque comparison sonucu; precondition true/false sonucu ayrıca belirlenir.
- response304 / storedAfter304
- Origin content0; matching stored body4 korunur, Date/policy güncellenir.
- changed200
- Yeni tag/body birlikte replacement; old copy conditional match vermez.
- put412
- Normal checks passed ve duplicate false supplied; failed strong guard method’ü uygulamaz.
Same representation context ve trusted decisions supplied. Tek sequential in-process state; gerçek Browser cache, production permission, database isolation, range veya general tag parser ölçülmez.
İki yanlış kanı
ETag’i biliyorsam write hakkım var; W/ tag strong If-Match için yeterli.
Validator permission değildir. If-Match strong comparison ister; weak taraf aynı opaque değerde bile strong match vermez.
304 boş representation’dır ve cached body silinmelidir.
304 content taşımaz; uygun matching stored response metadata’sı güncellenir ve mevcut body korunarak kullanılabilir.
SIRA SENDE
Bu hikâyeyi sen çöz.
Sonucu tahmin et, kanıtın sınırını bul ve nedenini kendi cümlenle anlat.
If-Match atlas-v1, fakat currentTag atlas-v2. PUT write uygulanır mı?
- Evet. Normal kontroller geçtiyse precondition yalnız tavsiyedir.
- Hayır. 412 ve methodApplied=false.
Gerekçeli cevabı oku
Hayır. 412 ve methodApplied=false. — Normal kontroller geçse de strong tag eşleşmesi başarısızdır. Güncel body ve tag korunur.
304 content taşımıyorsa kullanıcıya Çay nasıl sağlanır?
Dersten seçilen artifact alanları; öğretim örneği
- response304.actualContentOctets
- 0
- storedAfter304.body
- Çay
- storedAfter304.headers.cache-control
- max-age=60
- Stored body korunur; 304 metadata’yı günceller.
- 304 body’sinde gizli olarak Çay taşınır.
Gerekçeli cevabı oku
Stored body korunur; 304 metadata’yı günceller. — Örnekte matching candidate Çay body’sine sahiptir. max-age=60 metadata’sı yenilenir; body 304 içinde gelmez.
W/atlas-v1 ile atlas-v1 neden If-None-Match GET’te eşleşebilir, fakat If-Match strong karşılaştırmada eşleşmez?
Gerekçeli cevabı oku
Weak comparison, weak marker farklı olsa da opaque tag değerini eşleyebilir. Strong comparison iki tarafın da strong olmasını ve tag’in eşleşmesini ister. Farklı encoded byte’lar taşıyan representation variant’ları ayrı strong tag’ler kullanabilir. Resource URL’sinin aynı olması bütün variant’ların byte olarak eşit olduğunu göstermez.
□ Weak/strong karşılaştırmayı ilgili header’a bağladım.
□ Resource ile encoded representation’ı ayırdım.
Uygulama konsolunu aç · request / response / browser
Request, URL, cookie ve DOM örneklerini ayrıca aç
Kaynaklar ve kapsam
- RFC 9110 — HTTP Semantics1.3 Core Semantics · 7.1 Determining the Target Resource · 8.6 Content-Length · 8.8.1 Weak versus Strong · 8.8.3 ETag · 8.8.3.2 Comparison · 8.8.3.3 Example: Entity Tags Varying on Content-Negotiated Resources · 13.1.1 If-Match · 13.1.2 If-None-Match · 13.2.1 When to Evaluate · 15.4.5 304 Not Modified · 15.5.13 412 Precondition Failed
- RFC 9111 — HTTP Caching1 Introduction · 3 Storing Responses in Caches · 3.2 Updating Stored Header Fields · 3.5 Storing Responses to Authenticated Requests · 4 Constructing Responses from Caches · 4.1 Calculating Cache Keys with the Vary Header Field · 4.2 Freshness · 4.2.1 Calculating Freshness Lifetime · 4.2.3 Calculating Age · 4.3.3 Handling a Validation Response · 4.3.4 Freshening Stored Responses upon Validation · 4.4 Invalidating Stored Responses · 5.2.2.4 no-cache · 5.2.2.5 no-store · 5.2.2.7 private · 5.2.2.10 s-maxage
- MDN — ETag headerAvoiding mid-air collisions · Caching of unchanged resources
- MDN — If-None-Match headerIf-None-Match header · Directives
- MDN — If-Match headerIf-Match header