rack-cache 1.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/doc/rack-cache.css DELETED
@@ -1,362 +0,0 @@
1
- /* rack-cache.css
2
- *---------------------------------------------------------------------------
3
- * Copyright (C) 2005-08 Ryan Tomayko <r@tomayko.com>
4
- */
5
-
6
-
7
- /* 18px base font size / 25px baseline */
8
- body {
9
- font-size:112.5%; /* 18px (probably) */
10
- line-height:1.3888; /* 25px */
11
- letter-spacing:-0.02em;
12
- margin:0 10px;
13
- font-family: 'lucida sans unicode', 'lucida grande',
14
- helvetica, 'bitstream vera sans', sans-serif;
15
- color:#556;
16
- background-color:#fff;
17
- }
18
-
19
- #container {
20
- max-width:45em;
21
- margin:0 auto;
22
- }
23
-
24
- h1, h2, h3 {
25
- font-family:georgia, 'bitstream vera sans serif', 'lucida grande',
26
- helvetica, verdana, sans-serif;
27
- font-weight:normal;
28
- letter-spacing:-0.05em;
29
- color:#000;
30
- }
31
- i, em {
32
- font-style:italic;
33
- }
34
- b, strong {
35
- font-weight:normal;
36
- color:#000;
37
- }
38
- blockquote {
39
- color:#555;
40
- }
41
- blockquote em {
42
- color:#333;
43
- font-style:italic;
44
- }
45
- blockquote strong {
46
- color:#333;
47
- font-weight: normal;
48
- }
49
- dt {
50
- font-weight:bold;
51
- color:#000;
52
- }
53
- tt, pre, code, samp, kbd {
54
- font-family: consolas, 'lucida console', 'bitstream vera sans mono',
55
- 'courier new', monospace;
56
- color: #000;
57
- }
58
- pre {
59
- color:#333;
60
- background-color:#f9f9f9;
61
- }
62
- code {
63
- color:#007A00;
64
- }
65
- pre code {
66
- color:#333;
67
- }
68
- pre.license {
69
- border:0;
70
- background:#fff;
71
- padding:0;
72
- font-size:1.1em;
73
- }
74
- a, a:link {
75
- color:#023;
76
- background:#eef;
77
- }
78
- a:visited {
79
- color:#345;
80
- background:#fff;
81
- }
82
- a:hover {
83
- background:#ccf;
84
- color:#000;
85
- text-decoration:none;
86
- }
87
-
88
-
89
- /* TYPOGRAPHY */
90
-
91
- p, ul, ol, dl, pre, blockquote, table, form {
92
- margin:1em 0;
93
- }
94
- dl {
95
- margin-left:2em;
96
- }
97
- hr {
98
- color:#eee;
99
- background-color:#ccc;
100
- border:0;
101
- height:1px;
102
- margin:1.5em 0;
103
- }
104
- blockquote {
105
- font-size:0.83333em; /* 15px */
106
- line-height:1.66666; /* 25px */
107
- margin:1.2em 3em;
108
- padding:0;
109
- }
110
- tt, pre, code, samp, kbd {
111
- font-size: 16px;
112
- line-height:1.1;
113
- }
114
- pre {
115
- margin:1.5em 0;
116
- padding:6px 4px 4px 6px;
117
- border:1px solid #eee;
118
- border-left-width:20px;
119
- overflow:auto;
120
- }
121
- h1 {
122
- font-size:2.3333em; /* 42px */
123
- line-height:1.1904; /* 50px */
124
- margin:0.5952em 0; /* 25px */
125
- }
126
- h2 {
127
- font-size:1.66666667em; /* 30px */
128
- line-height:1.2; /* 36px */
129
- margin:1em 0;
130
- }
131
- h3 {
132
- font-size:1.33333333em; /* 22px */
133
- line-height:1.13636363; /* 25px */
134
- margin:1em 0;
135
- }
136
- h3 code{
137
- font-size:0.95em;
138
- color:#000;
139
- }
140
- h4 {
141
- font-size:1em;
142
- font-weight:bold;
143
- line-height:1.5;
144
- margin:1em 0;
145
- }
146
- p small {
147
- font-size:0.8333; /* 15px */
148
- line-height:1.2;
149
- }
150
-
151
- /* Tables
152
- --------------------------------------------------------------------------- */
153
-
154
- table {
155
- width:100%;
156
- border-style:none;
157
- border-color:#ddd;
158
- padding:0;
159
- }
160
-
161
- th, td {
162
- padding: 4px 10px 4px 5px;
163
- border-style:solid;
164
- border-color:#fff;
165
- }
166
-
167
- th {
168
- font-weight: bold;
169
- background: #eef;
170
- }
171
-
172
- td {
173
- background: #f9f9f9;
174
- }
175
-
176
- tfoot {
177
- font-style: italic;
178
- }
179
-
180
- caption {
181
- background: #eee;
182
- }
183
-
184
- /* Header / Titling
185
- --------------------------------------------------------------------------- */
186
-
187
- #header {
188
- text-align:left;
189
- margin:1.5em auto 2em;
190
- float:left;
191
- width:100%;
192
- padding-bottom:1.5em;
193
- border-bottom:1px solid #777;
194
- }
195
- #header h1 {
196
- font-family: 'lucida sans unicode', 'lucida grande',
197
- helvetica, 'bitstream vera sans', sans-serif;
198
- font-size:5em;
199
- font-weight:bold;
200
- line-height:1;
201
- margin:0;
202
- float:left;
203
- color:#000;
204
- letter-spacing:-0.08em;
205
- }
206
- #header h1 a, #header h1 a:link, #header h1 a:visited, #header h1 a:hover {
207
- color:#000;
208
- text-decoration:none;
209
- background:transparent;
210
- }
211
- #header p {
212
- margin: 0;
213
- line-height:1.8;
214
- color: #777;
215
- text-transform:capitalize;
216
- font-variant:small-caps;
217
- float:right;
218
- }
219
- #header a, #header a:link, #header a:visited {
220
- color:#445;
221
- background:#fff;
222
- }
223
- #header a:hover {
224
- background:#ccf;
225
- color:#000;
226
- text-decoration:none;
227
- }
228
- #content {
229
- clear:both;
230
- }
231
-
232
- /* FOOTER */
233
-
234
- #footer {
235
- clear:both;
236
- color:#555;
237
- font-size:0.88888888em;
238
- line-height:1.5625;
239
- border-top:1px solid #ddd;
240
- padding:19px 0 0 0;
241
- margin:40px 0 20px 0;
242
- text-align:center;
243
- }
244
- #footer p {
245
- margin:0;
246
- }
247
- #footer form {
248
- float:right;
249
- }
250
- #footer input{
251
- font-size:10px;
252
- }
253
-
254
- /* MISC HELPER STYLES */
255
-
256
- ul.clean, ol.clean {
257
- list-style-type: none;
258
- padding-left: 0;
259
- }
260
- .caps {
261
- font-variant:small-caps;
262
- }
263
- .clear {
264
- clear:both;
265
- }
266
- .left{
267
- float:left;
268
- }
269
- .right{
270
- float:right;
271
- }
272
- .center{
273
- text-align:center;
274
- }
275
- .intro {
276
- font-size:0.833333em; /* 15px */
277
- line-height:1.666667; /* 25px */
278
- border:1px solid #ccc;
279
- padding:0.5em;
280
- font-style:italic;
281
- color:#555;
282
- }
283
- a.hash,
284
- a.hash:link,
285
- a.hash:visited {
286
- display:block;
287
- float:right;
288
- background:#fff;
289
- font-size:0.8em;
290
- text-decoration:none;
291
- line-height:2;
292
- color:#999;
293
- }
294
- a.hash:hover {
295
- color:MediumOrchid;
296
- }
297
-
298
- /* PRINT */
299
-
300
- @media print {
301
- html, body, #container {
302
- margin:0;
303
- }
304
- #container {
305
- width:100%;
306
- max-width:100%;
307
- }
308
- #header {
309
- margin-top:0;
310
- }
311
- #header p {
312
- display:none;
313
- }
314
- #footer {
315
- display:none;
316
- }
317
- a, a:link, a:visited {
318
- color:#000;
319
- background:#fff;
320
- text-decoration:none;
321
- }
322
- pre.license {
323
- font-size:0.95em;
324
- }
325
- @page {
326
- size:8.5in 11in;
327
- }
328
- }
329
-
330
- /* PRETTIFICATION OF SOURCE CODE */
331
-
332
- .str { color: #181; font-style:italic; }
333
- .kwd { color: #369; }
334
- .com { color: #666; }
335
- .typ { color: #c40; }
336
- .lit { color: #900; }
337
- .pun { color: #000; font-weight: bold; }
338
- .pln { color: #333; }
339
- .tag { color: #369; font-weight: bold; }
340
- .atn { color: #939; font-weight: bold }
341
- .atv { color: #181; }
342
- .dec { color: #606; }
343
-
344
- @media print {
345
- .str { color: #060; }
346
- .kwd { color: #006; font-weight: bold; }
347
- .com { color: #600; font-style: italic; }
348
- .typ { color: #404; font-weight: bold; }
349
- .lit { color: #044; }
350
- .pun { color: #440; }
351
- .pln { color: #000; }
352
- .tag { color: #006; font-weight: bold; }
353
- .atn { color: #404; }
354
- .atv { color: #060; }
355
- }
356
-
357
- /* FUCKING IE */
358
-
359
- * html body{width:40em}
360
- * html div.index{width:34.5em}
361
-
362
- /* vim: set ft=css ts=4 sw=4 noexpandtab: */
data/doc/server.ru DELETED
@@ -1,34 +0,0 @@
1
- # Rackup config that serves the contents of Rack::Cache's
2
- # doc directory. The documentation is rebuilt on each request.
3
-
4
- # Rewrites URLs like conventional web server configs.
5
- class Rewriter < Struct.new(:app)
6
- def call(env)
7
- if env['PATH_INFO'] =~ /\/$/
8
- env['PATH_INFO'] += 'index.html'
9
- elsif env['PATH_INFO'] !~ /\.\w+$/
10
- env['PATH_INFO'] += '.html'
11
- end
12
- app.call(env)
13
- end
14
- end
15
-
16
- # Rebuilds documentation on each request.
17
- class DocBuilder < Struct.new(:app)
18
- def call(env)
19
- if env['PATH_INFO'] !~ /\.(css|js|gif|jpg|png|ico)$/
20
- env['rack.errors'] << "*** rebuilding documentation (rake -s doc)\n"
21
- system "rake -s doc"
22
- end
23
- app.call(env)
24
- end
25
- end
26
-
27
- use Rack::CommonLogger
28
- use DocBuilder
29
- use Rewriter
30
- use Rack::Static, :root => File.dirname(__FILE__), :urls => ["/"]
31
-
32
- run(lambda{|env| [404,{},'<h1>Not Found</h1>']})
33
-
34
- # vim: ft=ruby
data/doc/storage.markdown DELETED
@@ -1,164 +0,0 @@
1
- Storage
2
- =======
3
-
4
- __Rack::Cache__ runs within each of your backend application processes and does not
5
- rely on a single intermediary process like most types of proxy cache
6
- implementations. Because of this, the storage subsystem has implications on not
7
- only where cache data is stored but whether the cache is properly distributed
8
- between multiple backend processes. It is highly recommended that you read and
9
- understand the following before choosing a storage implementation.
10
-
11
- Storage Areas
12
- -------------
13
-
14
- __Rack::Cache__ stores cache entries in two separate configurable storage
15
- areas: a _MetaStore_ and an _EntityStore_.
16
-
17
- The _MetaStore_ keeps high level information about each cache entry, including
18
- the request/response headers and other status information. When a request is
19
- received, the core caching logic uses this meta information to determine whether
20
- a fresh cache entry exists that can satisfy the request.
21
-
22
- The _EntityStore_ is where the actual response body content is stored. When a
23
- response is entered into the cache, a SHA1 digest of the response body content
24
- is calculated and used as a key. The entries stored in the MetaStore reference
25
- their response bodies using this SHA1 key.
26
-
27
- Separating request/response meta-data from response content has a few important
28
- advantages:
29
-
30
- * Different storage types can be used for meta and entity storage. For
31
- example, it may be desirable to use memcached to store meta information
32
- while using the filesystem for entity storage.
33
-
34
- * Cache entry meta-data may be retrieved quickly without also retrieving
35
- response bodies. This avoids significant overhead when the cache misses
36
- or only requires validation.
37
-
38
- * Multiple different responses may include the same exact response body. In
39
- these cases, the actual body content is stored once and referenced from
40
- each of the meta store entries.
41
-
42
- You should consider how the meta and entity stores differ when choosing a storage
43
- implementation. The MetaStore does not require nearly as much memory as the
44
- EntityStore and is accessed much more frequently. The EntityStore can grow quite
45
- large and raw performance is less of a concern. Using a memory based storage
46
- implementation (`heap` or `memcached`) for the MetaStore is strongly advised,
47
- while a disk based storage implementation (`file`) is often satisfactory for
48
- the EntityStore and uses much less memory.
49
-
50
- Storage Configuration
51
- ---------------------
52
-
53
- The MetaStore and EntityStore used for a particular request is determined by
54
- inspecting the `rack-cache.metastore` and `rack-cache.entitystore` Rack env
55
- variables. The value of these variables is a URI that identifies the storage
56
- type and location (URI formats are documented in the following section).
57
-
58
- The `heap:/` storage is assumed if either storage type is not explicitly
59
- provided. This storage type has significant drawbacks for most types of
60
- deployments so explicit configuration is advised.
61
-
62
- The default metastore and entitystore values can be specified when the
63
- __Rack::Cache__ object is added to the Rack middleware pipeline as follows:
64
-
65
- use Rack::Cache,
66
- :metastore => 'file:/var/cache/rack/meta',
67
- :entitystore => 'file:/var/cache/rack/body'
68
-
69
- Alternatively, the `rack-cache.metastore` and `rack-cache.entitystore`
70
- variables may be set in the Rack environment by an upstream component.
71
-
72
- Storage Implementations
73
- -----------------------
74
-
75
- __Rack::Cache__ includes meta and entity storage implementations backed by local
76
- process memory ("heap storage"), the file system ("disk storage"), and
77
- memcached. This section includes information on configuring __Rack::Cache__ to
78
- use a specific storage implementation as well as pros and cons of each.
79
-
80
- ### Heap Storage
81
-
82
- Uses local process memory to store cached entries.
83
-
84
- use Rack::Cache,
85
- :metastore => 'heap:/',
86
- :entitystore => 'heap:/'
87
-
88
- The heap storage backend is simple, fast, and mostly useless. All cache
89
- information is stored in each backend application's local process memory (using
90
- a normal Hash, in fact), which means that data cached under one backend is
91
- invisible to all other backends. This leads to low cache hit rates and excessive
92
- memory use, the magnitude of which is a function of the number of backends in
93
- use. Further, the heap storage provides no mechanism for purging unused entries
94
- so memory use is guaranteed to exceed that available, given enough time and
95
- utilization.
96
-
97
- Use of heap storage is recommended only for testing purposes or for very
98
- simple/single-backend deployment scenarios where the number of resources served
99
- is small and well understood.
100
-
101
- ### Disk Storage
102
-
103
- Stores cached entries on the filesystem.
104
-
105
- use Rack::Cache,
106
- :metastore => 'file:/var/cache/rack/meta',
107
- :entitystore => 'file:/var/cache/rack/body'
108
-
109
- The URI may specify an absolute, relative, or home-rooted path:
110
-
111
- * `file:/storage/path` - absolute path to storage directory.
112
- * `file:storage/path` - relative path to storage directory, rooted at the
113
- process's current working directory (`Dir.pwd`).
114
- * `file:~user/storage/path` - path to storage directory, rooted at the
115
- specified user's home directory.
116
- * `file:~/storage/path` - path to storage directory, rooted at the current
117
- user's home directory.
118
-
119
- File system storage is simple, requires no special daemons or libraries, has a
120
- tiny memory footprint, and allows multiple backends to share a single cache; it
121
- is one of the slower storage implementations, however. Its use is recommended in
122
- cases where memory is limited or in environments where more complex storage
123
- backends (i.e., memcached) are not available. In many cases, it may be
124
- acceptable (and even optimal) to use file system storage for the entitystore and
125
- a more performant storage implementation (i.e. memcached) for the metastore.
126
-
127
- __NOTE:__ When both the metastore and entitystore are configured to use file
128
- system storage, they should be set to different paths to prevent any chance of
129
- collision.
130
-
131
- ### Memcached Storage
132
-
133
- Stores cached entries in a remote [memcached](http://www.danga.com/memcached/)
134
- instance.
135
-
136
- use Rack::Cache,
137
- :metastore => 'memcached://localhost:11211/meta',
138
- :entitystore => 'memcached://localhost:11211/body'
139
-
140
- The URI must specify the host and port of a remote memcached daemon. The path
141
- portion is an optional (but recommended) namespace that is prepended to each
142
- cache key.
143
-
144
- The memcached storage backend requires either the `dalli` or `memcached`
145
- libraries. By default, the `dalli` library is used; require the `memcached`
146
- library explicitly to use it instead.
147
-
148
- gem install dalli
149
-
150
- Memcached storage is reasonably fast and allows multiple backends to share a
151
- single cache. It is also the only storage implementation that allows the cache
152
- to reside somewhere other than the local machine. The memcached daemon stores
153
- all data in local process memory so using it for the entitystore can result in
154
- heavy memory usage. It is by far the best option for the metastore in
155
- deployments with multiple backend application processes since it allows the
156
- cache to be properly distributed and provides fast access to the
157
- meta-information required to perform cache logic. Memcached is considerably more
158
- complex than the other storage implementations, requiring a separate daemon
159
- process and extra libraries. Still, its use is recommended in all cases where
160
- you can get away with it.
161
-
162
- [e]: http://blog.evanweaver.com/files/doc/fauna/memcached/files/README.html
163
- [f]: http://blog.evanweaver.com/articles/2008/01/21/b-the-fastest-u-can-b-memcached/
164
- [l]: http://tangent.org/552/libmemcached.html
@@ -1,21 +0,0 @@
1
- require 'sinatra'
2
- require 'rack/cache'
3
-
4
- use Rack::Cache do
5
- set :verbose, true
6
- set :metastore, 'heap:/'
7
- set :entitystore, 'heap:/'
8
- end
9
-
10
- before do
11
- last_modified $updated_at ||= Time.now
12
- end
13
-
14
- get '/' do
15
- erb :index
16
- end
17
-
18
- put '/' do
19
- $updated_at = nil
20
- redirect '/'
21
- end
@@ -1,44 +0,0 @@
1
- <html>
2
- <head>
3
- <title>Sample Rack::Cache Sinatra app</title>
4
- <style type="text/css" media="screen">
5
- body {
6
- font-family: Georgia;
7
- font-size: 24px;
8
- text-align: center;
9
- }
10
-
11
- #headers {
12
- font-size: 16px;
13
- }
14
-
15
- input {
16
- font-size: 24px;
17
- cursor: pointer;
18
- }
19
- </style>
20
- </head>
21
- <body>
22
- <h1>Last updated at: <%= $updated_at.strftime('%l:%m:%S%P') %></h1>
23
-
24
- <p>
25
- <form action="/" method="post">
26
- <input type="hidden" name="_method" value="PUT">
27
- <input type="submit" value="Expire the cache.">
28
- </form>
29
- </p>
30
-
31
- <div id="headers">
32
- <h3>Headers:</h3>
33
-
34
- <% response.headers.each do |key, value| %>
35
- <p><%= key %>: <%= value %></p>
36
- <% end %>
37
-
38
- <h3>Params:</h3>
39
- <% params.each do |key, value| %>
40
- <p><%= key %>: <%= value || '(blank)' %></p>
41
- <% end %>
42
- </div>
43
- </body>
44
- </html>
data/rack-cache.gemspec DELETED
@@ -1,75 +0,0 @@
1
- Gem::Specification.new do |s|
2
- s.specification_version = 2 if s.respond_to? :specification_version=
3
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
-
5
- s.name = 'rack-cache'
6
- s.version = '1.2'
7
- s.date = '2012-03-05'
8
-
9
- s.summary = "HTTP Caching for Rack"
10
- s.description = "Rack::Cache is suitable as a quick drop-in component to enable HTTP caching for Rack-based applications that produce freshness (Expires, Cache-Control) and/or validation (Last-Modified, ETag) information."
11
-
12
- s.authors = ["Ryan Tomayko"]
13
- s.email = "r@tomayko.com"
14
-
15
- # = MANIFEST =
16
- s.files = %w[
17
- CHANGES
18
- COPYING
19
- Gemfile
20
- README
21
- Rakefile
22
- TODO
23
- doc/configuration.markdown
24
- doc/faq.markdown
25
- doc/index.markdown
26
- doc/layout.html.erb
27
- doc/license.markdown
28
- doc/rack-cache.css
29
- doc/server.ru
30
- doc/storage.markdown
31
- example/sinatra/app.rb
32
- example/sinatra/views/index.erb
33
- lib/rack-cache.rb
34
- lib/rack/cache.rb
35
- lib/rack/cache/appengine.rb
36
- lib/rack/cache/cachecontrol.rb
37
- lib/rack/cache/context.rb
38
- lib/rack/cache/entitystore.rb
39
- lib/rack/cache/key.rb
40
- lib/rack/cache/metastore.rb
41
- lib/rack/cache/options.rb
42
- lib/rack/cache/request.rb
43
- lib/rack/cache/response.rb
44
- lib/rack/cache/storage.rb
45
- rack-cache.gemspec
46
- test/cache_test.rb
47
- test/cachecontrol_test.rb
48
- test/context_test.rb
49
- test/entitystore_test.rb
50
- test/key_test.rb
51
- test/metastore_test.rb
52
- test/options_test.rb
53
- test/pony.jpg
54
- test/request_test.rb
55
- test/response_test.rb
56
- test/spec_setup.rb
57
- test/storage_test.rb
58
- ]
59
- # = MANIFEST =
60
-
61
- s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/}
62
-
63
- s.extra_rdoc_files = %w[README COPYING TODO CHANGES]
64
- s.add_dependency 'rack', '>= 0.4'
65
-
66
- s.add_development_dependency 'bacon'
67
- s.add_development_dependency 'memcached'
68
- s.add_development_dependency 'dalli'
69
-
70
- s.has_rdoc = true
71
- s.homepage = "http://tomayko.com/src/rack-cache/"
72
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rack::Cache", "--main", "Rack::Cache"]
73
- s.require_paths = %w[lib]
74
- s.rubygems_version = '1.1.1'
75
- end