Skip to content

Instantly share code, notes, and snippets.

@dblock
Created June 2, 2012 01:13
Show Gist options
  • Save dblock/2856045 to your computer and use it in GitHub Desktop.
Save dblock/2856045 to your computer and use it in GitHub Desktop.
Conditional GET helper for a RESTful API
# Written by https://github.com/macreery (c) Art.sy, 2012, MIT License
module ApiConditionalGetHelper
# Borrows generously from http://themomorohoax.com/2009/01/07/using-stale-with-rails-to-return-304-not-modified
# See also RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4
# for explanation of how If-Modified-Since and If-None-Match request headers are handled.
def fresh?(metadata = {})
self.last_modified = metadata[:last_modified]
self.etag = metadata[:etag]
case
when if_modified_since && if_none_match
not_modified?(metadata[:last_modified]) && etag_matches?(metadata[:etag])
when if_modified_since
not_modified?(metadata[:last_modified])
when if_none_match
etag_matches?(metadata[:etag])
else
false
end
end
def if_modified_since
if since = env["HTTP_IF_MODIFIED_SINCE"]
Time.rfc2822(since) rescue nil
end
end
def if_none_match
env["HTTP_IF_NONE_MATCH"]
end
def not_modified?(modified_at)
if_modified_since && modified_at && if_modified_since >= modified_at
end
def etag_matches?(etag)
if_none_match && if_none_match == etag
end
def last_modified=(utc_time)
return unless utc_time
header "Last-Modified", utc_time.httpdate
end
def etag=(etag)
return unless etag
header "ETag", etag
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment