Module: ServerSide::HTTP::Caching

Defined in:
lib/serverside/http/caching.rb

Overview

HTTP Caching behavior

Constant Summary collapse

COMMA =
','.freeze

Instance Method Summary collapse

Instance Method Details

#cache(opts) ⇒ Object

Sets caching-related headers (Cache-Control and Expires).



5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/serverside/http/caching.rb', line 5

def cache(opts)
  # check cache-control
  remove_cache_control
  if cache_control = opts[:cache_control]
    add_header(CACHE_CONTROL, cache_control)
  end
  
  # add an expires header
  if expires = opts[:expires] || (opts[:ttl] && (Time.now + opts[:ttl]))
    add_header(EXPIRES, expires.httpdate)
  end
end

#etag_match(etag) ⇒ Object

Matches the supplied etag against any of the entities in the If-None-Match header.



49
50
51
52
53
54
55
56
57
58
# File 'lib/serverside/http/caching.rb', line 49

def etag_match(etag)
  return false unless @request
  matches = @request.headers[IF_NONE_MATCH]
  if matches
    matches.split(COMMA).each do |e|
      return true if e.strip == etag
    end
  end
  false
end

#modified_match(last_modified) ⇒ Object

Matches the supplied last modified date against the If-Modified-Since header.



62
63
64
65
66
67
68
69
70
71
# File 'lib/serverside/http/caching.rb', line 62

def modified_match(last_modified)
  return false unless @request
  if modified_since = @request.headers[IF_MODIFIED_SINCE]
    last_modified.to_i == Time.parse(modified_since).to_i
  else
    false
  end
rescue => e
  raise BadRequestError, "Invalid value in If-Modified-Since header"
end

#remove_cache_controlObject



82
83
84
# File 'lib/serverside/http/caching.rb', line 82

def remove_cache_control
  @headers.reject! {|h| h =~ /^#{CACHE_CONTROL}/}
end

#set_cache_control(directive) ⇒ Object

Sets the Cache-Control header.



74
75
76
# File 'lib/serverside/http/caching.rb', line 74

def set_cache_control(directive)
  add_header(CACHE_CONTROL, directive)
end

#set_no_cacheObject



78
79
80
# File 'lib/serverside/http/caching.rb', line 78

def set_no_cache
  set_cache_control(NO_CACHE)
end

#validate_cache(opts, &block) ⇒ Object

Validates the supplied request against specified validators (etag and last-modified stamp). If a match is found, the status is changed to 304 Not Modified. Otherwise, the supplied block is invoked.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/serverside/http/caching.rb', line 21

def validate_cache(opts, &block)
  valid_cache = false
  
  # check etag
  if etag = opts[:etag]
    etag = "\"#{etag}\""
    add_header(ETAG, etag) if etag
    valid_cache = etag_match(etag)
  end
  
  # check last_modified
  if last_modified = opts[:last_modified]
    add_header(LAST_MODIFIED, last_modified.httpdate)
    valid_cache ||= modified_match(last_modified)
  end
  
  # set cache-related headers
  cache(opts)
  
  # if not modified, we have a 304 response. Otherwise we yield to the
  # supplied block.
  valid_cache ? (@status = STATUS_NOT_MODIFIED) : yield(self)
end