Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 373
- Log:
Initial import of Radiant 0.9.1, which is now packaged as a gem. This is an
import of the tagged 0.9.1 source checked out from GitHub, which isn't quite
the same as the gem distribution - but it doesn't seem to be available in an
archived form and the installed gem already has modifications, so this is
the closest I can get.
- Author:
- rool
- Date:
- Mon Mar 21 13:40:05 +0000 2011
- Size:
- 9496 Bytes
1 | module Rack |
2 | module Cache |
3 | |
4 | # Parses a Cache-Control header and exposes the directives as a Hash. |
5 | # Directives that do not have values are set to +true+. |
6 | class CacheControl < Hash |
7 | def initialize(value=nil) |
8 | parse(value) |
9 | end |
10 | |
11 | # Indicates that the response MAY be cached by any cache, even if it |
12 | # would normally be non-cacheable or cacheable only within a non- |
13 | # shared cache. |
14 | # |
15 | # A response may be considered public without this directive if the |
16 | # private directive is not set and the request does not include an |
17 | # Authorization header. |
18 | def public? |
19 | self['public'] |
20 | end |
21 | |
22 | # Indicates that all or part of the response message is intended for |
23 | # a single user and MUST NOT be cached by a shared cache. This |
24 | # allows an origin server to state that the specified parts of the |
25 | # response are intended for only one user and are not a valid |
26 | # response for requests by other users. A private (non-shared) cache |
27 | # MAY cache the response. |
28 | # |
29 | # Note: This usage of the word private only controls where the |
30 | # response may be cached, and cannot ensure the privacy of the |
31 | # message content. |
32 | def private? |
33 | self['private'] |
34 | end |
35 | |
36 | # When set in a response, a cache MUST NOT use the response to satisfy a |
37 | # subsequent request without successful revalidation with the origin |
38 | # server. This allows an origin server to prevent caching even by caches |
39 | # that have been configured to return stale responses to client requests. |
40 | # |
41 | # Note that this does not necessary imply that the response may not be |
42 | # stored by the cache, only that the cache cannot serve it without first |
43 | # making a conditional GET request with the origin server. |
44 | # |
45 | # When set in a request, the server MUST NOT use a cached copy for its |
46 | # response. This has quite different semantics compared to the no-cache |
47 | # directive on responses. When the client specifies no-cache, it causes |
48 | # an end-to-end reload, forcing each cache to update their cached copies. |
49 | def no_cache? |
50 | self['no-cache'] |
51 | end |
52 | |
53 | # Indicates that the response MUST NOT be stored under any circumstances. |
54 | # |
55 | # The purpose of the no-store directive is to prevent the |
56 | # inadvertent release or retention of sensitive information (for |
57 | # example, on backup tapes). The no-store directive applies to the |
58 | # entire message, and MAY be sent either in a response or in a |
59 | # request. If sent in a request, a cache MUST NOT store any part of |
60 | # either this request or any response to it. If sent in a response, |
61 | # a cache MUST NOT store any part of either this response or the |
62 | # request that elicited it. This directive applies to both non- |
63 | # shared and shared caches. "MUST NOT store" in this context means |
64 | # that the cache MUST NOT intentionally store the information in |
65 | # non-volatile storage, and MUST make a best-effort attempt to |
66 | # remove the information from volatile storage as promptly as |
67 | # possible after forwarding it. |
68 | # |
69 | # The purpose of this directive is to meet the stated requirements |
70 | # of certain users and service authors who are concerned about |
71 | # accidental releases of information via unanticipated accesses to |
72 | # cache data structures. While the use of this directive might |
73 | # improve privacy in some cases, we caution that it is NOT in any |
74 | # way a reliable or sufficient mechanism for ensuring privacy. In |
75 | # particular, malicious or compromised caches might not recognize or |
76 | # obey this directive, and communications networks might be |
77 | # vulnerable to eavesdropping. |
78 | def no_store? |
79 | self['no-store'] |
80 | end |
81 | |
82 | # The expiration time of an entity MAY be specified by the origin |
83 | # server using the Expires header (see section 14.21). Alternatively, |
84 | # it MAY be specified using the max-age directive in a response. When |
85 | # the max-age cache-control directive is present in a cached response, |
86 | # the response is stale if its current age is greater than the age |
87 | # value given (in seconds) at the time of a new request for that |
88 | # resource. The max-age directive on a response implies that the |
89 | # response is cacheable (i.e., "public") unless some other, more |
90 | # restrictive cache directive is also present. |
91 | # |
92 | # If a response includes both an Expires header and a max-age |
93 | # directive, the max-age directive overrides the Expires header, even |
94 | # if the Expires header is more restrictive. This rule allows an origin |
95 | # server to provide, for a given response, a longer expiration time to |
96 | # an HTTP/1.1 (or later) cache than to an HTTP/1.0 cache. This might be |
97 | # useful if certain HTTP/1.0 caches improperly calculate ages or |
98 | # expiration times, perhaps due to desynchronized clocks. |
99 | # |
100 | # Many HTTP/1.0 cache implementations will treat an Expires value that |
101 | # is less than or equal to the response Date value as being equivalent |
102 | # to the Cache-Control response directive "no-cache". If an HTTP/1.1 |
103 | # cache receives such a response, and the response does not include a |
104 | # Cache-Control header field, it SHOULD consider the response to be |
105 | # non-cacheable in order to retain compatibility with HTTP/1.0 servers. |
106 | # |
107 | # When the max-age directive is included in the request, it indicates |
108 | # that the client is willing to accept a response whose age is no |
109 | # greater than the specified time in seconds. |
110 | def max_age |
111 | self['max-age'].to_i if key?('max-age') |
112 | end |
113 | |
114 | # If a response includes an s-maxage directive, then for a shared |
115 | # cache (but not for a private cache), the maximum age specified by |
116 | # this directive overrides the maximum age specified by either the |
117 | # max-age directive or the Expires header. The s-maxage directive |
118 | # also implies the semantics of the proxy-revalidate directive. i.e., |
119 | # that the shared cache must not use the entry after it becomes stale |
120 | # to respond to a subsequent request without first revalidating it with |
121 | # the origin server. The s-maxage directive is always ignored by a |
122 | # private cache. |
123 | def shared_max_age |
124 | self['s-maxage'].to_i if key?('s-maxage') |
125 | end |
126 | alias_method :s_maxage, :shared_max_age |
127 | |
128 | # Because a cache MAY be configured to ignore a server's specified |
129 | # expiration time, and because a client request MAY include a max- |
130 | # stale directive (which has a similar effect), the protocol also |
131 | # includes a mechanism for the origin server to require revalidation |
132 | # of a cache entry on any subsequent use. When the must-revalidate |
133 | # directive is present in a response received by a cache, that cache |
134 | # MUST NOT use the entry after it becomes stale to respond to a |
135 | # subsequent request without first revalidating it with the origin |
136 | # server. (I.e., the cache MUST do an end-to-end revalidation every |
137 | # time, if, based solely on the origin server's Expires or max-age |
138 | # value, the cached response is stale.) |
139 | # |
140 | # The must-revalidate directive is necessary to support reliable |
141 | # operation for certain protocol features. In all circumstances an |
142 | # HTTP/1.1 cache MUST obey the must-revalidate directive; in |
143 | # particular, if the cache cannot reach the origin server for any |
144 | # reason, it MUST generate a 504 (Gateway Timeout) response. |
145 | # |
146 | # Servers SHOULD send the must-revalidate directive if and only if |
147 | # failure to revalidate a request on the entity could result in |
148 | # incorrect operation, such as a silently unexecuted financial |
149 | # transaction. Recipients MUST NOT take any automated action that |
150 | # violates this directive, and MUST NOT automatically provide an |
151 | # unvalidated copy of the entity if revalidation fails. |
152 | def must_revalidate? |
153 | self['must-revalidate'] |
154 | end |
155 | |
156 | # The proxy-revalidate directive has the same meaning as the must- |
157 | # revalidate directive, except that it does not apply to non-shared |
158 | # user agent caches. It can be used on a response to an |
159 | # authenticated request to permit the user's cache to store and |
160 | # later return the response without needing to revalidate it (since |
161 | # it has already been authenticated once by that user), while still |
162 | # requiring proxies that service many users to revalidate each time |
163 | # (in order to make sure that each user has been authenticated). |
164 | # Note that such authenticated responses also need the public cache |
165 | # control directive in order to allow them to be cached at all. |
166 | def proxy_revalidate? |
167 | self['proxy-revalidate'] |
168 | end |
169 | |
170 | def to_s |
171 | bools, vals = [], [] |
172 | each do |key,value| |
173 | if value == true |
174 | bools << key |
175 | elsif value |
176 | vals << "#{key}=#{value}" |
177 | end |
178 | end |
179 | (bools.sort + vals.sort).join(', ') |
180 | end |
181 | |
182 | private |
183 | def parse(value) |
184 | return if value.nil? || value.empty? |
185 | value.delete(' ').split(',').inject(self) do |hash,part| |
186 | name, value = part.split('=', 2) |
187 | hash[name.downcase] = (value || true) unless name.empty? |
188 | hash |
189 | end |
190 | end |
191 | end |
192 | end |
193 | end |