HTTP cache yöntemleri nelerdir?

Bu flood’da HTTP’de kullanılan çeşitli cache yöntemlerinden bahsedeceğim.

Web uygulama performansı, uygulamayı oluşturan bileşenler istemci tarafında cache’lenerek fark edilebilir biçimde iyileştirilebilir. Cache’lenen kaynaklar (HTTP Resource — js, css, imaj) sayesinde sunucu kaynaklarından ve bant genişliğinden tasarruf sağlanır.

Web sunucu, istemcinin bir kaynak için yaptığı isteğe verdiği cevabın HTTP header’ında ilgili kaynağın belirli bir süre boyunca cache’lemesini söyleyebilir. Örneğin aşağıdaki ekran görüntüsünde sunucu istemciye web sayfasını 7200 saniye boyunca cache’leyebileceğini söylemiştir.

Aynı kaynak Cache süresi içerisinde (7200 saniye) kullanıcı tarafından tekrar istendiğinde, web tarayıcı aşağıdaki ekran görüntüsünde olduğu gibi ilgili kaynağı kendi cache’inden sunar ve bu işlem için ağ ve sunucu kaynağı kullanmaz.

Yukarıdaki örneklerde Cache-Control: public, max-age=7200 HTTP header'ındaki public anahtar kelimesi ile kaynağın istemci ve sunucu arasındaki bütün ilgililer tarafından cache'lenebileceği belirtilmiştir. İstemci ile sunucu arasında istemcinin internet servis sağlayıcısı, sunucunun internet servis sağlayıcısı ve belki ikisinin arasında da başka taşıyıcı servis sağlayıcılar bulunmaktadır. İstemcinin internet servis sağlayıcısı public olan bu kaynağı cache'lemek isterse hizmet verdiği başka müşterilerine aynı kaynağı belirtilen süre içerisinde sunucuya hiç gitmeden sunma şansına sahip olacak ve böylece hem bant genişliğini daha tasarruflu kullanacak hem de daha iyi bir müşteri deneyimi sağlayacaktır. Bununla birlikte anlatılanların olabilmesi için istemci ve sunucu arasındaki trafiğin servis sağlayıcılar tarafından anlaşılabilmesi gereklidir, dolayısıyla HTTPS olarak iletilen kaynaklar aracılar tarafından cache'lenemeyecektir. Cache-Control: private header'ına sahip olan kaynaklar kullanıcıya özeldir ve aracılar tarafından cache'lenemezler.

Yukarıda bahsedilen ve etkin olarak kullanılan cache yöntemine ek olarak kullanılan başka bir yöntem de Last-Modified header'ıdır. Sunucu sunduğu kaynakları istemciye gönderirken HTTP cevap Header'ında o kaynağın ne zaman değiştirildiği ekler. Aşağıda bir örnek gösterilmiştir.

İlk istek sonucunda ilgili kaynağı cache’ine alan istemci bir sonraki istekte Last-Modified header'ında yazan tarihi istek header'ına If-Modified-Since: XXX olarak ekleyerek gönderir. Sunucu eğer ilgili dosyanın değiştirilme tarihi değişmediyse istemciye 304 - Not Modified ile karşılık verir. 304 cevabını alan istemci kendi cache'inde olan versiyonu kullanır. Bu yöntem sayesinde istemci cache'indeki kaynağın tazeliğini sunucudan sorgulamış ancak kaynağı tekrar indirmek zorunda kalmamış ve sunucu kaynaklarından tasarruf sağlamıştır.

Aşağıdaki ekran görüntüsünde bir önceki örnekte verilen sayfa If-Modified-Since header'ı ile birlikte çağrılmış ve HTTP - 304 cevabı alınmıştır.

ETag header'ı, Last-Modified'a benzer şekilde kullanılır. ETag - Entity Tag, web sunucu tarafından bir kaynağa verilen ve kaynağın içeriği değiştikçe değişen bir değerdir. Ne şekilde üretileceğine dair herhangi bir spesifikasyon bulunmasa da web sunucular tarafından bir hash fonksiyonu vb ile üretilebilirler. Bir kaynağın değişip değişmediğini anlamak için istemci, HTTP header'ına If-None-Match: XXX header'ını ekler, sunucu ilgili kaynak değişmemişse içeriği göndermeden 304 - Not Modified, değişmişse ise 200 - OK ve içeriği gönderir.

İlk bölümde bahsedilen Cache-Control header'ıyla sunucu bazı kaynaklar için istemcinin sürekli olarak kendisine gelmesini isteyebilir. Burada iki opsiyon vardır. Eğer sunucu Cache-Control: no-cache kullanır ise istemci içeriği cache'ler ancak içeriği tekrar kullanmadan sunucu tarafında değişip değişmediğini If-Modified-Since ya da If-None-Match header'larıyla kontrol eder. Sunucu, Cache-Control: no-store kullanır ise istemciye cevabı hiçbir şekilde kaydetmemesini söylemiş olur ve her defasında kaynak sunucudan indirilir.

Hassas bilgilerin istemciye no-store ile gönderilmesi güvenlik açısından önemlidir. Web uygulama tasarımcı, uygulamanın kullandığı kaynakları etkin biçimde cache'leyerek performansı artıracak fakat fonksiyonaliteden de taviz vermeyecek ince dengeyi kurabilmelidir.