Saya bingung tentang cache HTTP

Saya telah memikirkan tentang pembacaan dan penulisan batch dalam lingkungan yang tenang, dan saya rasa saya menyadari bahwa saya memiliki pertanyaan yang lebih luas tentang cache HTTP. (Di bawah ini saya menggunakan koma (",") untuk membatasi beberapa ID rekaman, namun detail tersebut tidak khusus untuk diskusi.)

Saya mulai dengan masalah ini:

1. Tunggal GET tidak valid karena pembaruan batch

GET /farms/123         # get info about Old MacDonald's Farm
PUT /farms/123,234,345 # update info on Old MacDonald's Farm and some others
GET /farms/123

Bagaimana server cache di antara klien dan server Farms mengetahui untuk membatalkan cache /farms/123 ketika melihat PUT?

Kemudian saya menyadari ini juga merupakan masalah:

2. Batch GET tidak valid karena pembaruan tunggal (atau batch).

GET /farms/123,234,345 # get info about a few farms
PUT /farms/123         # update Old MacDonald's Farm
GET /farms/123,234,345

Bagaimana cache mengetahui untuk membatalkan validitas multi-pertanian GET ketika melihat PUT berlalu?

Jadi saya pikir masalahnya sebenarnya hanya pada operasi batch. Kemudian saya menyadari bahwa hubungan apa pun dapat menyebabkan masalah serupa. Katakanlah sebuah peternakan mempunyai nol atau satu pemilik, dan seorang pemilik dapat memiliki nol atau satu peternakan.

3. Tunggal GET tidak valid karena memperbarui catatan terkait

GET /farms/123   # get info about Old MacDonald's Farm
PUT /farmers/987 # Old MacDonald sells his farm and buys another one
GET /farms/123

Bagaimana cache mengetahui untuk membatalkan GET tunggal ketika ia melihat PUT berlalu?

Bahkan jika Anda mengubah model menjadi lebih RESTful, dengan menggunakan model hubungan, Anda mendapatkan masalah yang sama:

GET    /farms/123           # get info about Old MacDonald's Farm
DELETE /farm_ownerships/456 # Old MacDonald sells his farm...
POST   /farm_ownerships     # and buys another one
GET    /farms/123

Di kedua versi #3, GET pertama harus mengembalikan sesuatu seperti (dalam JSON):

farm: {
  id: 123,
  name: "Shady Acres",
  size: "60 acres",
  farmer_id: 987
}

Dan GET kedua akan mengembalikan sesuatu seperti:

farm: {
  id: 123,
  name: "Shady Acres",
  size: "60 acres",
  farmer_id: null
}

Tapi itu tidak bisa! Bahkan jika Anda menggunakan ETags dengan tepat. Anda tidak dapat mengharapkan server cache memeriksa konten ETags -- konten dapat dienkripsi. Dan Anda tidak dapat mengharapkan server memberi tahu cache bahwa catatan harus dibatalkan -- cache tidak mendaftarkan dirinya ke server.

Jadi, apakah ada header yang saya lewatkan? Hal-hal yang menunjukkan bahwa cache harus melakukan HEAD sebelum GETs untuk sumber daya tertentu? Saya kira saya dapat menerima permintaan ganda untuk setiap sumber daya jika saya dapat memberi tahu cache sumber daya mana yang mungkin sering diperbarui.

Dan bagaimana dengan masalah satu cache menerima PUT dan mengetahui untuk membatalkan cache-nya dan cache lainnya tidak melihatnya?


person James A. Rosen    schedule 11.01.2009    source sumber
comment
Baru saja membangun aplikasi web ajax respon cepat, saya cukup tertarik dengan bagaimana pertanyaan ini akan dijawab. +1 dan Bintang!   -  person Karl    schedule 11.01.2009
comment
Mungkin yang saya cari adalah header invalidates-other yang bisa ditambahkan server saat kembali dari PUT, POST, atau DELETE. Sayangnya, sepertinya itu tidak ada.   -  person James A. Rosen    schedule 11.01.2009
comment
Dalam kasus HTTPS, proxy tidak melihat apa pun selain nama host dan port. Mereka tidak melihat header maupun pathInfo, jadi masalahnya tidak ada. +++ Invalidates-Other adalah hal yang membuat saya kesulitan merumuskan pertanyaan sebelum saya menemukan pertanyaan bagus Anda.   -  person maaartinus    schedule 22.10.2016


Jawaban (5)


Server cache seharusnya membatalkan entitas yang dirujuk oleh URI saat menerima PUT (tetapi seperti yang Anda perhatikan, ini tidak mencakup semua kasus).

Selain itu, Anda dapat menggunakan header kontrol cache pada respons Anda untuk membatasi atau mencegah cache, dan mencoba memproses header permintaan yang menanyakan apakah URI telah diubah sejak terakhir kali diambil.

Masalah ini masih sangat rumit dan masih dalam tahap penyelesaian (misalnya lihat http://www.ietf.org/internet-drafts/draft-ietf-httpbis-p6-cache-05.txt)

Caching dalam proxy tidak benar-benar berlaku jika kontennya dienkripsi (setidaknya dengan SSL), jadi itu tidak akan menjadi masalah (meskipun demikian mungkin masih menjadi masalah pada klien).

person frankodwyer    schedule 11.01.2009
comment
Pertanyaan awal tidak menyebutkan server cache, saya pikir ini tentang cache lokal browser. - person Karl; 11.01.2009
comment
Tidak, pertanyaan awal saya menyatakan, Bagaimana server caching di antara klien dan server Farms mengetahui untuk membatalkan cache /farms/123 ketika melihat PUT? Maksud saya server cache dan cache lokal. - person James A. Rosen; 11.01.2009
comment
Perihal: SSL: lihat komentar saya tentang konten terenkripsi melalui saluran tidak terenkripsi. - person James A. Rosen; 11.01.2009

Protokol HTTP mendukung jenis permintaan yang disebut "Jika-Dimodifikasi-Sejak" yang pada dasarnya memungkinkan server cache menanyakan server web apakah item telah berubah. Protokol HTTP juga mendukung header "Kontrol Cache" di dalam respons server HTTP yang memberi tahu server cache apa yang harus dilakukan dengan konten (seperti jangan pernah menyimpan konten ini dalam cache, atau menganggapnya kedaluwarsa dalam 1 hari, dll).

Anda juga menyebutkan tanggapan terenkripsi. Server cache HTTP tidak dapat melakukan cache SSL karena untuk melakukan hal tersebut mereka harus mendekripsi halaman sebagai "orang di tengah". Melakukan hal ini akan menantang secara teknis (mendekripsi halaman, menyimpannya, dan mengenkripsi ulang untuk klien) dan juga akan melanggar keamanan halaman yang menyebabkan peringatan "sertifikat tidak valid" di sisi klien. Secara teknis dimungkinkan untuk meminta server cache melakukan hal ini, namun hal ini menyebabkan lebih banyak masalah daripada penyelesaiannya, dan merupakan ide yang buruk. Saya ragu server cache mana pun yang benar-benar melakukan hal semacam ini.

person SoapBox    schedule 11.01.2009

Sayangnya cache HTTP didasarkan pada URI yang tepat, dan Anda tidak dapat mencapai perilaku yang masuk akal dalam kasus Anda tanpa memaksa klien melakukan validasi ulang cache.

Jika Anda pernah mengalami:

GET /farm/123
POST /farm_update/123

Anda dapat menggunakan header Content-Location untuk menentukan permintaan kedua yang mengubah permintaan pertama. AFAIK Anda tidak dapat melakukan itu dengan banyak URI dan saya belum memeriksa apakah ini berfungsi di klien populer.

Solusinya adalah membuat halaman kadaluwarsa dengan cepat dan menangani If-Modified-Since atau E-Tag dengan status 304 Not Modified.

person Kornel    schedule 11.01.2009

Anda tidak dapat menyimpan konten dinamis dalam cache (tanpa kekurangan), karena... itu dinamis.

person Karsten    schedule 11.01.2009

Dalam hal: jawaban SoapBox:

  1. Saya pikir If-Modified-Since adalah dua tahap GET yang saya sarankan di akhir pertanyaan saya. Sepertinya solusi yang OK jika kontennya besar (yaitu di mana biaya menggandakan jumlah permintaan, dan dengan demikian biaya overhead diatasi dengan keuntungan jika tidak mengirim ulang konten. Hal ini tidak berlaku dalam contoh saya di Farms, karena informasi masing-masing Peternakan singkat.)

  2. Sangat masuk akal untuk membangun sistem yang mengirimkan konten terenkripsi melalui saluran tidak terenkripsi (HTTP). Bayangkan skenario Arsitektur Berorientasi Layanan di mana pembaruan jarang terjadi dan GETs (a) sering, (b) harus sangat cepat, dan (c) harus dienkripsi. Anda akan membangun server yang memerlukan header FROM (atau, yang setara, kunci API dalam parameter permintaan), dan mengirimkan kembali versi konten yang dienkripsi secara asimetris untuk pemohon. Enkripsi asimetris lambat, namun jika disimpan dalam cache dengan benar, akan mengalahkan gabungan jabat tangan SSL (enkripsi asimetris) dan enkripsi konten simetris. Menambahkan cache di depan server ini akan mempercepat GETs secara drastis.

  3. Server caching dapat melakukan cache HTTPS GET dalam jangka waktu singkat. Bank saya mungkin memasang kontrol cache sekitar 5 menit di halaman beranda akun saya dan transaksi terkini. Saya kemungkinan besar tidak akan menghabiskan waktu lama di situs ini, jadi sesinya tidak akan terlalu lama, dan saya mungkin akan membuka halaman utama akun saya beberapa kali saat saya mencari cek yang baru saja saya kirimkan. ke SnorgTees.

person Community    schedule 11.01.2009
comment
Jika-dimodifikasi-sejak tidak menambah jumlah permintaan. - person Kornel; 11.01.2009
comment
Saya cukup yakin itu benar. Jika cache dapat mengetahui entri apa yang terkini, cache tidak perlu mengirimkan permintaan Jika-Dimodifikasi-Sejak. Anda benar bahwa jumlahnya tidak menggandakan. Itu tergantung pada rasio membaca dan menulis. - person James A. Rosen; 11.01.2009
comment
If-Modified- Since tidak menggandakan permintaan -- server hanya merespons dengan sumber daya (jika telah berubah) atau respons Tidak diubah, yang mana klien seharusnya menggunakan versi yang sudah mereka miliki. - person Rowland Shaw; 11.01.2009
comment
Anda berdua benar -- jumlahnya tidak berlipat ganda. Namun HTTP §13.2.1 ¶1 mengatakan, cache HTTP berfungsi paling baik ketika cache sepenuhnya dapat menghindari pembuatan permintaan ke server asal. Itulah yang saya tuju. - person James A. Rosen; 11.01.2009
comment
Saat saya mempelajari lebih dalam, saya melihat semakin banyak bahwa cache HTTP dibuat dengan gagasan cache menjangkau kembali untuk memverifikasi melalui If-Modified- Since. Ini sepertinya memerlukan banyak biaya tambahan, tetapi sepertinya ini menjawab semua masalah saya. - person James A. Rosen; 11.01.2009
comment
Tidak mungkin bagi server caching untuk melakukan cache https karena saluran SSL tidak tembus pandang ke server - sebenarnya ia bahkan tidak melihatnya sebagai HTTP normal. Hal ini dilakukan dengan metode CONNECT, yang pada dasarnya membuat koneksi soket melalui proxy. - person frankodwyer; 11.01.2009
comment
(sebenarnya saya harus menambahkan bahwa ada beberapa proxy komersial yang dapat melakukan spoofing buruk pada CA untuk menghindari peringatan sertifikat SSL, tetapi ini adalah solusi yang sangat buruk dan mengharuskan proxy tersebut diperlakukan sebagai CA tepercaya) - person frankodwyer; 11.01.2009
comment
@frankodwyer -- Saya rasa saya selalu berpikir proxy dapat melihat header pada lalu lintas SSL. Saya akan mengambil topi di tangan pada #3. Komentar yang bagus. - person James A. Rosen; 11.01.2009
comment
Pendapat pribadi saya adalah aplikasi web perbankan apa pun harus TIDAK menyimpan cache apa pun. Jika berhubungan dengan uang, hal ini penting dan jika itu adalah bank, maka harus menyediakan perangkat keras untuk melayani semua permintaan yang tidak di-cache. - person Andrei Rînea; 10.05.2009