-
-
Notifications
You must be signed in to change notification settings - Fork 140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide a helper to add Etag headers to responses #41
Comments
Thanks. I plan to look at |
@tmattio It seems that this will work only for small files (so typical assets and pages, which is fine). Is that right? So the helper would check that the response body is not a stream. If it is a stream, it would leave the request alone. Otherwise, it seems that it would have to buffer the entire stream, which could be disastrous. |
That sounds good, for larger files, if they are embedded with But having Etag for small files and pages would be great already! |
I think looking at Ruby on Rails' support for Conditional GET requests would be instructive: https://guides.rubyonrails.org/caching_with_rails.html#conditional-get-support class ProductsController < ApplicationController
def show
@product = Product.find(params[:id])
if stale?(@product)
respond_to do |wants|
# ... normal response processing
end
end
end
end One way to adapt this might be: let show req =
let product = ... in
if stale req product.etag then
(* Send a 200 OK response rendering the product. Remember to add the new
ETag value to the response headers. *)
else
Dream.empty `Not_Modified We can perhaps help the user a bit more: let etag product = product.etag
let show req =
let product = ... in
if_stale req etag (fun () ->
(* Render the product again *)
) And let etag str = {|"|} ^ str ^ {|"|}
let if_stale req hash refresh =
let new_etag = etag hash in
let resp = match Dream.header req "If-None-Match" with
| Some old_etag when old_etag = new_etag -> Dream.empty `Not_Modified
| _ ->
let resp = refresh () in
Dream.add_header resp "ETag" new_etag;
resp
in
Dream.add_header resp "Cache-Control" "no-cache";
Dream.add_header resp "Vary" "ETag";
resp |
It would be really useful to have a helper
val with_etag : request -> response -> response
(or similar) that computes a hash of the response body and compare it with the request'sEtag
. It would transform the response to a304 Not modified
if they match, or add theEtag
header with the computed hash if they don'tThe text was updated successfully, but these errors were encountered: