Module: Cucumber::Rest::Caching

Defined in:
lib/cucumber/rest/caching.rb

Overview

Helper functions for checking the cacheability of responses.

Defined Under Namespace

Classes: EmptyHTTPDateError

Class Method Summary collapse

Class Method Details

.ensure_response_is_not_cacheable(args = {}) ⇒ nil

Ensures that a response is not cacheable.

This function uses a strict interpretation of RFC 2616, to ensure the widest interoperability with implementations, including HTTP 1.0.

Parameters:

  • response (HttpCapture::Response)

    The response to check. If not supplied defaults to the last response.

Returns:

  • (nil)


73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/cucumber/rest/caching.rb', line 73

def self.ensure_response_is_not_cacheable(args = {})
  response, * = extract_args(args)
  ensure_cache_headers(response, true)

  cache_control = parse_cache_control(response["Cache-Control"])
  ensure_cache_directives(cache_control, "no-store")
  prohibit_cache_directives(cache_control, "public", "private", "max-age") # TODO: prohibit no-cache?

  date = parse_httpdate(response["Date"])
  expires = parse_expires_httpdate(response["Expires"]) rescue nil # invalid values are treated as < now, which is fine
  raise "Expires should not be later than Date" if expires && expires > date
end

.ensure_response_is_privately_cacheable(args = {}) ⇒ nil

Ensures that a response is privately cacheable.

This function uses a strict interpretation of RFC 2616, including precedence rules for Date, Expires and Cache-Control:max-age to ensure the widest interoperability with implementations, including HTTP 1.0.

Parameters:

  • response (HttpCapture::Response)

    The response to check. If not supplied defaults to the last response.

  • min_duration (Integer)

    The minimum permitted cache duration, in seconds.

  • max_duration (Integer)

    The maximum permitted cache duration, in seconds.

  • duration (Integer)

    The required cache duration, in seconds. Convenient if min and max are the same.

Returns:

  • (nil)


51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/cucumber/rest/caching.rb', line 51

def self.ensure_response_is_privately_cacheable(args = {})
  response, min_duration, max_duration = extract_args(args)
  ensure_cache_headers(response, false)

  cache_control = parse_cache_control(response["Cache-Control"])
  ensure_cache_directives(cache_control, "private", "max-age")
  prohibit_cache_directives(cache_control, "public", "no-cache", "no-store")

  date = parse_httpdate(response["Date"])
  expires = parse_expires_httpdate(response["Expires"])
  raise "Expires should not be later than Date" if expires && expires > date

  ensure_cache_duration(cache_control["max-age"], min_duration, max_duration)
end

.ensure_response_is_publicly_cacheable(args = {}) ⇒ nil

Ensures that a response is privately cacheable.

This function uses a strict interpretation of RFC 2616 to ensure the widest interoperability with implementations, including HTTP 1.0.

Parameters:

  • response (HttpCapture::Response)

    The response to check. If not supplied defaults to the last response.

  • min_duration (Integer)

    The minimum permitted cache duration, in seconds.

  • max_duration (Integer)

    The maximum permitted cache duration, in seconds.

  • duration (Integer)

    The required cache duration, in seconds. Convenient if min and max are the same.

Returns:

  • (nil)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/cucumber/rest/caching.rb', line 21

def self.ensure_response_is_publicly_cacheable(args = {})
  response, min_duration, max_duration = extract_args(args)
  ensure_cache_headers(response, false)

  cache_control = parse_cache_control(response["Cache-Control"])
  ensure_cache_directives(cache_control, "public", "max-age")
  prohibit_cache_directives(cache_control, "private", "no-cache", "no-store")

  age = response["Age"].to_i
  date = parse_httpdate(response["Date"])
  expires = parse_expires_httpdate(response["Expires"])
  max_age = cache_control["max-age"]
  expected_max_age = age + ((expires - date) * 24 * 3600).to_i
  unless (max_age - expected_max_age).abs <= 1 # 1 second leeway
    raise "Age, Date, Expires and Cache-Control:max-age are inconsistent"
  end

  ensure_cache_duration(max_age, min_duration, max_duration)
end