File: cache_control.rb

package info (click to toggle)
ruby-protocol-http 0.55.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 840 kB
  • sloc: ruby: 6,904; makefile: 4
file content (134 lines) | stat: -rw-r--r-- 4,914 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# frozen_string_literal: true

# Released under the MIT License.
# Copyright, 2020-2025, by Samuel Williams.
# Copyright, 2023, by Thomas Morgan.

require_relative "split"

module Protocol
	module HTTP
		module Header
			# Represents the `cache-control` header, which is a list of cache directives.
			class CacheControl < Split
				# The `private` directive indicates that the response is intended for a single user and must not be stored by shared caches.
				PRIVATE = "private"
				
				# The `public` directive indicates that the response may be stored by any cache, even if it would normally be considered non-cacheable.
				PUBLIC = "public"
				
				# The `no-cache` directive indicates that caches must revalidate the response with the origin server before serving it to clients.
				NO_CACHE = "no-cache"
				
				# The `no-store` directive indicates that caches must not store the response under any circumstances.
				NO_STORE = "no-store"
				
				# The `max-age` directive indicates the maximum amount of time, in seconds, that a response is considered fresh.
				MAX_AGE = "max-age"
				
				# The `s-maxage` directive is similar to `max-age` but applies only to shared caches. If both `s-maxage` and `max-age` are present, `s-maxage` takes precedence in shared caches.
				S_MAXAGE = "s-maxage"
				
				# The `static` directive is a custom directive often used to indicate that the resource is immutable or rarely changes, allowing longer caching periods.
				STATIC = "static"
				
				# The `dynamic` directive is a custom directive used to indicate that the resource is generated dynamically and may change frequently, requiring shorter caching periods.
				DYNAMIC = "dynamic"
				
				# The `streaming` directive is a custom directive used to indicate that the resource is intended for progressive or chunked delivery, such as live video streams.
				STREAMING = "streaming"
				
				# The `must-revalidate` directive indicates that once a response becomes stale, caches must not use it to satisfy subsequent requests without revalidating it with the origin server.
				MUST_REVALIDATE = "must-revalidate"
				
				# The `proxy-revalidate` directive is similar to `must-revalidate` but applies only to shared caches.
				PROXY_REVALIDATE = "proxy-revalidate"
				
				# Initializes the cache control header with the given value. The value is expected to be a comma-separated string of cache directives.
				#
				# @parameter value [String | Nil] the raw Cache-Control header value.
				def initialize(value = nil)
					super(value&.downcase)
				end
				
				# Adds a directive to the Cache-Control header. The value will be normalized to lowercase before being added.
				#
				# @parameter value [String] the directive to add.
				def << value
					super(value.downcase)
				end
				
				# @returns [Boolean] whether the `static` directive is present.
				def static?
					self.include?(STATIC)
				end
				
				# @returns [Boolean] whether the `dynamic` directive is present.
				def dynamic?
					self.include?(DYNAMIC)
				end
				
				# @returns [Boolean] whether the `streaming` directive is present.
				def streaming?
					self.include?(STREAMING)
				end
				
				# @returns [Boolean] whether the `private` directive is present.
				def private?
					self.include?(PRIVATE)
				end
				
				# @returns [Boolean] whether the `public` directive is present.
				def public?
					self.include?(PUBLIC)
				end
				
				# @returns [Boolean] whether the `no-cache` directive is present.
				def no_cache?
					self.include?(NO_CACHE)
				end
				
				# @returns [Boolean] whether the `no-store` directive is present.
				def no_store?
					self.include?(NO_STORE)
				end
				
				# @returns [Boolean] whether the `must-revalidate` directive is present.
				def must_revalidate?
					self.include?(MUST_REVALIDATE)
				end
				
				# @returns [Boolean] whether the `proxy-revalidate` directive is present.
				def proxy_revalidate?
					self.include?(PROXY_REVALIDATE)
				end
				
				# @returns [Integer | Nil] the value of the `max-age` directive in seconds, or `nil` if the directive is not present or invalid.
				def max_age
					find_integer_value(MAX_AGE)
				end
				
				# @returns [Integer | Nil] the value of the `s-maxage` directive in seconds, or `nil` if the directive is not present or invalid.
				def s_maxage
					find_integer_value(S_MAXAGE)
				end
				
				private
				
				# Finds and parses an integer value from a directive.
				#
				# @parameter value_name [String] the directive name to search for (e.g., "max-age").
				# @returns [Integer | Nil] the parsed integer value, or `nil` if not found or invalid.
				def find_integer_value(value_name)
					if value = self.find{|value| value.start_with?(value_name)}
						_, age = value.split("=", 2)
						
						if age =~ /\A[0-9]+\z/
							return Integer(age)
						end
					end
				end
			end
		end
	end
end