actionpack-page_caching 1.1.0 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +110 -34
- data/.travis.yml +9 -30
- data/CHANGELOG.md +11 -0
- data/Gemfile +1 -0
- data/README.md +130 -41
- data/actionpack-page_caching.gemspec +4 -4
- data/gemfiles/Gemfile-5-1-stable +5 -0
- data/gemfiles/Gemfile-5-2-stable +5 -0
- data/gemfiles/Gemfile-6-0-stable +5 -0
- data/lib/action_controller/caching/pages.rb +21 -6
- data/lib/action_controller/page_caching.rb +1 -5
- data/test/caching_test.rb +30 -12
- metadata +9 -16
- data/gemfiles/Gemfile-4-0-stable +0 -6
- data/gemfiles/Gemfile-4-1-stable +0 -6
- data/gemfiles/Gemfile-4-2-stable +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b3c84b38d08e6b8ec36bf104688be7f8a9a1de1c05bdf10796289cb27a8e9883
|
4
|
+
data.tar.gz: 9b05d100d1820f6a0b480b015d8123ce4d0bae52229ac16d6d5833d787e265c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9583f9359843f6fa8b86cf3db2d46a5597cc7bc9c96fef71d741e30c01d04efda3b7f78642bf7d4a67f7421b3c1630c17099897381139573bb0500c41a824fb5
|
7
|
+
data.tar.gz: cb7f51ee9ce237b63ea2a5e8ecd88b1d33cc83483660939608c62b8ea8d1804fdd854cbd11c914010963b0fa7f8b5f25d06926444ba10164819b8b3fe6f0ed14
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
AllCops:
|
2
|
-
TargetRubyVersion: 2.
|
2
|
+
TargetRubyVersion: 2.4
|
3
3
|
# RuboCop has a bunch of cops enabled by default. This setting tells RuboCop
|
4
4
|
# to ignore them, so only the ones explicitly set in this file are enabled.
|
5
5
|
DisabledByDefault: true
|
@@ -8,80 +8,117 @@ AllCops:
|
|
8
8
|
Style/AndOr:
|
9
9
|
Enabled: true
|
10
10
|
|
11
|
-
#
|
12
|
-
|
13
|
-
Style/BracesAroundHashParameters:
|
11
|
+
# Align `when` with `case`.
|
12
|
+
Layout/CaseIndentation:
|
14
13
|
Enabled: true
|
15
14
|
|
16
|
-
|
17
|
-
Style/CaseIndentation:
|
15
|
+
Layout/ClosingHeredocIndentation:
|
18
16
|
Enabled: true
|
19
17
|
|
20
18
|
# Align comments with method definitions.
|
21
|
-
|
19
|
+
Layout/CommentIndentation:
|
20
|
+
Enabled: true
|
21
|
+
|
22
|
+
Layout/ElseAlignment:
|
23
|
+
Enabled: true
|
24
|
+
|
25
|
+
# Align `end` with the matching keyword or starting expression except for
|
26
|
+
# assignments, where it should be aligned with the LHS.
|
27
|
+
Layout/EndAlignment:
|
28
|
+
Enabled: true
|
29
|
+
EnforcedStyleAlignWith: variable
|
30
|
+
AutoCorrect: true
|
31
|
+
|
32
|
+
Layout/EmptyLineAfterMagicComment:
|
22
33
|
Enabled: true
|
23
34
|
|
24
|
-
|
25
|
-
|
35
|
+
Layout/EmptyLinesAroundAccessModifier:
|
36
|
+
Enabled: true
|
37
|
+
EnforcedStyle: only_before
|
38
|
+
|
39
|
+
Layout/EmptyLinesAroundBlockBody:
|
26
40
|
Enabled: true
|
27
41
|
|
28
42
|
# In a regular class definition, no empty lines around the body.
|
29
|
-
|
43
|
+
Layout/EmptyLinesAroundClassBody:
|
44
|
+
Enabled: true
|
45
|
+
|
46
|
+
# In a regular method definition, no empty lines around the body.
|
47
|
+
Layout/EmptyLinesAroundMethodBody:
|
30
48
|
Enabled: true
|
31
49
|
|
32
50
|
# In a regular module definition, no empty lines around the body.
|
33
|
-
|
51
|
+
Layout/EmptyLinesAroundModuleBody:
|
34
52
|
Enabled: true
|
35
53
|
|
36
54
|
# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
|
37
55
|
Style/HashSyntax:
|
38
56
|
Enabled: true
|
39
57
|
|
58
|
+
Layout/FirstArgumentIndentation:
|
59
|
+
Enabled: true
|
60
|
+
|
40
61
|
# Method definitions after `private` or `protected` isolated calls need one
|
41
62
|
# extra level of indentation.
|
42
|
-
|
63
|
+
Layout/IndentationConsistency:
|
43
64
|
Enabled: true
|
44
|
-
EnforcedStyle:
|
65
|
+
EnforcedStyle: indented_internal_methods
|
45
66
|
|
46
67
|
# Two spaces, no tabs (for indentation).
|
47
|
-
|
68
|
+
Layout/IndentationWidth:
|
69
|
+
Enabled: true
|
70
|
+
|
71
|
+
Layout/LeadingCommentSpace:
|
72
|
+
Enabled: true
|
73
|
+
|
74
|
+
Layout/SpaceAfterColon:
|
75
|
+
Enabled: true
|
76
|
+
|
77
|
+
Layout/SpaceAfterComma:
|
78
|
+
Enabled: true
|
79
|
+
|
80
|
+
Layout/SpaceAfterSemicolon:
|
48
81
|
Enabled: true
|
49
82
|
|
50
|
-
|
83
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
51
84
|
Enabled: true
|
52
85
|
|
53
|
-
|
86
|
+
Layout/SpaceAroundKeyword:
|
54
87
|
Enabled: true
|
55
88
|
|
56
|
-
|
89
|
+
Layout/SpaceBeforeComma:
|
57
90
|
Enabled: true
|
58
91
|
|
59
|
-
|
92
|
+
Layout/SpaceBeforeComment:
|
60
93
|
Enabled: true
|
61
94
|
|
62
|
-
|
95
|
+
Layout/SpaceBeforeFirstArg:
|
63
96
|
Enabled: true
|
64
97
|
|
65
|
-
Style/
|
66
|
-
|
98
|
+
Style/DefWithParentheses:
|
99
|
+
Enabled: true
|
67
100
|
|
68
101
|
# Defining a method with parameters needs parentheses.
|
69
102
|
Style/MethodDefParentheses:
|
70
103
|
Enabled: true
|
71
104
|
|
105
|
+
Style/RedundantFreeze:
|
106
|
+
Enabled: true
|
107
|
+
|
72
108
|
# Use `foo {}` not `foo{}`.
|
73
|
-
|
109
|
+
Layout/SpaceBeforeBlockBraces:
|
74
110
|
Enabled: true
|
75
111
|
|
76
112
|
# Use `foo { bar }` not `foo {bar}`.
|
77
|
-
|
113
|
+
Layout/SpaceInsideBlockBraces:
|
78
114
|
Enabled: true
|
115
|
+
EnforcedStyleForEmptyBraces: space
|
79
116
|
|
80
117
|
# Use `{ a: 1 }` not `{a:1}`.
|
81
|
-
|
118
|
+
Layout/SpaceInsideHashLiteralBraces:
|
82
119
|
Enabled: true
|
83
120
|
|
84
|
-
|
121
|
+
Layout/SpaceInsideParens:
|
85
122
|
Enabled: true
|
86
123
|
|
87
124
|
# Check quotes usage according to lint rule below.
|
@@ -90,27 +127,66 @@ Style/StringLiterals:
|
|
90
127
|
EnforcedStyle: double_quotes
|
91
128
|
|
92
129
|
# Detect hard tabs, no hard tabs.
|
93
|
-
|
130
|
+
Layout/Tab:
|
94
131
|
Enabled: true
|
95
132
|
|
96
|
-
#
|
97
|
-
|
133
|
+
# Empty lines should not have any spaces.
|
134
|
+
Layout/TrailingEmptyLines:
|
98
135
|
Enabled: true
|
99
136
|
|
100
137
|
# No trailing whitespace.
|
101
|
-
|
138
|
+
Layout/TrailingWhitespace:
|
102
139
|
Enabled: true
|
103
140
|
|
104
141
|
# Use quotes for string literals when they are enough.
|
105
|
-
Style/
|
142
|
+
Style/RedundantPercentQ:
|
106
143
|
Enabled: true
|
107
144
|
|
108
|
-
|
109
|
-
|
110
|
-
|
145
|
+
Lint/AmbiguousOperator:
|
146
|
+
Enabled: true
|
147
|
+
|
148
|
+
Lint/AmbiguousRegexpLiteral:
|
149
|
+
Enabled: true
|
150
|
+
|
151
|
+
Lint/ErbNewArguments:
|
111
152
|
Enabled: true
|
112
|
-
AlignWith: variable
|
113
153
|
|
114
154
|
# Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
|
115
155
|
Lint/RequireParentheses:
|
116
156
|
Enabled: true
|
157
|
+
|
158
|
+
Lint/ShadowingOuterLocalVariable:
|
159
|
+
Enabled: true
|
160
|
+
|
161
|
+
Lint/RedundantStringCoercion:
|
162
|
+
Enabled: true
|
163
|
+
|
164
|
+
Lint/UriEscapeUnescape:
|
165
|
+
Enabled: true
|
166
|
+
|
167
|
+
Lint/UselessAssignment:
|
168
|
+
Enabled: true
|
169
|
+
|
170
|
+
Lint/DeprecatedClassMethods:
|
171
|
+
Enabled: true
|
172
|
+
|
173
|
+
Style/ParenthesesAroundCondition:
|
174
|
+
Enabled: true
|
175
|
+
|
176
|
+
Style/RedundantBegin:
|
177
|
+
Enabled: true
|
178
|
+
|
179
|
+
Style/RedundantReturn:
|
180
|
+
Enabled: true
|
181
|
+
AllowMultipleReturnValues: true
|
182
|
+
|
183
|
+
Style/Semicolon:
|
184
|
+
Enabled: true
|
185
|
+
AllowAsExpressionSeparator: true
|
186
|
+
|
187
|
+
# Prefer Foo.method over Foo::method
|
188
|
+
Style/ColonMethodCall:
|
189
|
+
Enabled: true
|
190
|
+
|
191
|
+
Style/TrivialAccessors:
|
192
|
+
Enabled: true
|
data/.travis.yml
CHANGED
@@ -8,47 +8,26 @@ before_install:
|
|
8
8
|
- gem install bundler
|
9
9
|
|
10
10
|
rvm:
|
11
|
-
-
|
12
|
-
- 2.
|
13
|
-
- 2.
|
14
|
-
- 2.2.6
|
15
|
-
- 2.3.3
|
16
|
-
- 2.4.0
|
11
|
+
- 2.4.6
|
12
|
+
- 2.5.5
|
13
|
+
- 2.6.3
|
17
14
|
|
18
15
|
gemfile:
|
19
16
|
- Gemfile
|
20
|
-
- gemfiles/Gemfile-4-0-stable
|
21
|
-
- gemfiles/Gemfile-4-1-stable
|
22
|
-
- gemfiles/Gemfile-4-2-stable
|
23
17
|
- gemfiles/Gemfile-5-0-stable
|
18
|
+
- gemfiles/Gemfile-5-1-stable
|
19
|
+
- gemfiles/Gemfile-5-2-stable
|
20
|
+
- gemfiles/Gemfile-6-0-stable
|
24
21
|
- gemfiles/Gemfile-edge
|
25
22
|
|
26
23
|
matrix:
|
27
24
|
allow_failures:
|
28
25
|
- gemfile: gemfiles/Gemfile-edge
|
29
26
|
exclude:
|
30
|
-
- rvm:
|
31
|
-
gemfile: Gemfile
|
32
|
-
- rvm: 2.
|
33
|
-
gemfile: Gemfile
|
34
|
-
- rvm: 2.1.9
|
35
|
-
gemfile: Gemfile
|
36
|
-
- rvm: 1.9.3
|
37
|
-
gemfile: gemfiles/Gemfile-5-0-stable
|
38
|
-
- rvm: 2.0.0
|
39
|
-
gemfile: gemfiles/Gemfile-5-0-stable
|
40
|
-
- rvm: 2.1.9
|
41
|
-
gemfile: gemfiles/Gemfile-5-0-stable
|
42
|
-
- rvm: 1.9.3
|
27
|
+
- rvm: 2.4.6
|
28
|
+
gemfile: gemfiles/Gemfile-6-0-stable
|
29
|
+
- rvm: 2.4.6
|
43
30
|
gemfile: gemfiles/Gemfile-edge
|
44
|
-
- rvm: 2.0.0
|
45
|
-
gemfile: gemfiles/Gemfile-edge
|
46
|
-
- rvm: 2.1.9
|
47
|
-
gemfile: gemfiles/Gemfile-edge
|
48
|
-
- rvm: 2.4.0
|
49
|
-
gemfile: gemfiles/Gemfile-4-0-stable
|
50
|
-
- rvm: 2.4.0
|
51
|
-
gemfile: gemfiles/Gemfile-4-1-stable
|
52
31
|
|
53
32
|
notifications:
|
54
33
|
email: false
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
## 1.1.1 (September 25, 2018)
|
2
|
+
|
3
|
+
* Fixes handling of several forward slashes as root path.
|
4
|
+
|
5
|
+
*Xavier Noria*
|
6
|
+
|
7
|
+
* Documentation overhaul.
|
8
|
+
|
9
|
+
*Xavier Noria*
|
10
|
+
|
11
|
+
|
1
12
|
## 1.1.0 (January 23, 2017)
|
2
13
|
|
3
14
|
* Support dynamic `page_cache_directory` using a Proc, Symbol or callable
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,41 @@
|
|
1
|
-
actionpack-page_caching
|
2
|
-
=======================
|
1
|
+
# actionpack-page_caching
|
3
2
|
|
4
3
|
Static page caching for Action Pack (removed from core in Rails 4.0).
|
5
4
|
|
6
|
-
|
7
|
-
|
5
|
+
## Introduction
|
6
|
+
|
7
|
+
Page caching is an approach to caching in which response bodies are stored in
|
8
|
+
files that the web server can serve directly:
|
9
|
+
|
10
|
+
1. A request to endpoint _E_ arrives.
|
11
|
+
2. Its response is calculated and stored in a file _F_.
|
12
|
+
3. Next time _E_ is requested, the web server sends _F_ directly.
|
13
|
+
|
14
|
+
That applies only to GET or HEAD requests whose response code is 200, the rest
|
15
|
+
are ignored.
|
16
|
+
|
17
|
+
Unlike caching proxies or other more sophisticated setups, page caching results
|
18
|
+
in a dramatic speed up while being dead simple at the same time. Awesome
|
19
|
+
cost/benefit.
|
20
|
+
|
21
|
+
The reason for such performance boost is that cached endpoints are
|
22
|
+
short-circuited by the web server, which is very efficient at serving static
|
23
|
+
files. Requests to cached endpoints do not even reach your Rails application.
|
8
24
|
|
9
|
-
|
25
|
+
This technique, however, is only suitable for pages that do not need to go
|
26
|
+
through your Rails stack, precisely. For example, content management systems
|
27
|
+
like wikis have typically many pages that are a great fit for this approach, but
|
28
|
+
account-based systems where people log in and manipulate their own data are
|
29
|
+
often less likely candidates. As a use case you can check, [Rails
|
30
|
+
Contributors](https://contributors.rubyonrails.org/) makes heavy use of page
|
31
|
+
caching. Its source code is [here](https://github.com/rails/rails-contributors).
|
32
|
+
|
33
|
+
It is not all or nothing, though, in HTML cached pages JavaScript can still
|
34
|
+
tweak details here and there dynamically as a trade-off.
|
35
|
+
|
36
|
+
## Installation
|
37
|
+
|
38
|
+
Add this line to your application's `Gemfile`:
|
10
39
|
|
11
40
|
``` ruby
|
12
41
|
gem "actionpack-page_caching"
|
@@ -14,39 +43,71 @@ gem "actionpack-page_caching"
|
|
14
43
|
|
15
44
|
And then execute:
|
16
45
|
|
17
|
-
|
46
|
+
```
|
47
|
+
$ bundle
|
48
|
+
```
|
49
|
+
|
50
|
+
## Usage
|
51
|
+
|
52
|
+
### Enable Caching
|
53
|
+
|
54
|
+
Page caching needs caching enabled:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
config.action_controller.perform_caching = true
|
58
|
+
```
|
59
|
+
|
60
|
+
That goes typically in `config/environments/production.rb`, but you can activate
|
61
|
+
that flag in any mode.
|
62
|
+
|
63
|
+
Since Rails 5 there is a special toggler to easily enable/disable caching in
|
64
|
+
`development` mode without editing its configuration file. Just execute
|
65
|
+
|
66
|
+
```
|
67
|
+
$ bin/rails dev:cache
|
68
|
+
```
|
69
|
+
|
70
|
+
to enable/disable caching in `development` mode.
|
71
|
+
|
72
|
+
### Configure the Cache Directory
|
18
73
|
|
19
|
-
|
74
|
+
#### Default Cache Directory
|
20
75
|
|
21
|
-
|
76
|
+
By default, files are stored below the `public` directory of your Rails
|
77
|
+
application, with a path that matches the one in the URL.
|
22
78
|
|
23
|
-
|
24
|
-
|
79
|
+
For example, a page-cached request to `/posts/what-is-new-in-rails-6` would be
|
80
|
+
stored by default in the file `public/posts/what-is-new-in-rails-6.html`, and
|
81
|
+
the web server would be configured to check that path in the file system before
|
82
|
+
falling back to Rails. More on this later.
|
25
83
|
|
26
|
-
|
27
|
-
stored as a HTML file that the web server can serve without going through
|
28
|
-
Action Pack. This is the fastest way to cache your content as opposed to going
|
29
|
-
dynamically through the process of generating the content. Unfortunately, this
|
30
|
-
incredible speed-up is only available to stateless pages where all visitors are
|
31
|
-
treated the same. Content management systems -- including weblogs and wikis --
|
32
|
-
have many pages that are a great fit for this approach, but account-based systems
|
33
|
-
where people log in and manipulate their own data are often less likely candidates.
|
84
|
+
#### Custom Cache Directory
|
34
85
|
|
35
|
-
|
86
|
+
The default page caching directory can be overridden:
|
36
87
|
|
37
88
|
``` ruby
|
38
|
-
config.action_controller.page_cache_directory =
|
89
|
+
config.action_controller.page_cache_directory = Rails.root.join("public", "cached_pages")
|
39
90
|
```
|
40
91
|
|
41
|
-
|
92
|
+
There is no need to ensure the directory exists when the application boots,
|
93
|
+
whenever a page has to be cached, the page cache directory is created if needed.
|
94
|
+
|
95
|
+
#### Custom Cache Directory per Controller
|
96
|
+
|
97
|
+
The globally configured cache directory, default or custom, can be overridden in
|
98
|
+
each controller. There are three ways of doing this.
|
99
|
+
|
100
|
+
With a lambda:
|
42
101
|
|
43
102
|
``` ruby
|
44
103
|
class WeblogController < ApplicationController
|
45
|
-
self.page_cache_directory = -> {
|
104
|
+
self.page_cache_directory = -> {
|
105
|
+
Rails.root.join("public", request.domain)
|
106
|
+
}
|
46
107
|
end
|
47
108
|
```
|
48
109
|
|
49
|
-
a
|
110
|
+
a symbol:
|
50
111
|
|
51
112
|
``` ruby
|
52
113
|
class WeblogController < ApplicationController
|
@@ -73,7 +134,11 @@ class WeblogController < ApplicationController
|
|
73
134
|
end
|
74
135
|
```
|
75
136
|
|
76
|
-
|
137
|
+
Intermediate directories are created as needed also in this case.
|
138
|
+
|
139
|
+
### Specify Actions to be Cached
|
140
|
+
|
141
|
+
Specifying which actions have to be cached is done through the `caches_page` class method:
|
77
142
|
|
78
143
|
``` ruby
|
79
144
|
class WeblogController < ActionController::Base
|
@@ -81,17 +146,44 @@ class WeblogController < ActionController::Base
|
|
81
146
|
end
|
82
147
|
```
|
83
148
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
149
|
+
### Configure The Web Server
|
150
|
+
|
151
|
+
The [wiki](https://github.com/rails/actionpack-page_caching/wiki) of the project
|
152
|
+
has some examples of web server configuration.
|
153
|
+
|
154
|
+
### Cache Expiration
|
155
|
+
|
156
|
+
Expiration of the cache is handled by deleting the cached files, which results
|
157
|
+
in a lazy regeneration approach in which the content is stored again as cached
|
158
|
+
endpoints are hit.
|
90
159
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
160
|
+
#### Full Cache Expiration
|
161
|
+
|
162
|
+
If the cache is stored in a separate directory like `public/cached_pages`, you
|
163
|
+
can easily expire the whole thing by removing said directory.
|
164
|
+
|
165
|
+
Removing a directory recursively with something like `rm -rf` is unreliable
|
166
|
+
because that operation is not atomic and can mess up with concurrent page cache
|
167
|
+
generation.
|
168
|
+
|
169
|
+
In POSIX systems moving a file is atomic, so the recommended approach would be
|
170
|
+
to move the directory first out of the way, and then recursively delete that
|
171
|
+
one. Something like
|
172
|
+
|
173
|
+
```bash
|
174
|
+
#!/bin/bash
|
175
|
+
|
176
|
+
tmp=public/cached_pages-$(date +%s)
|
177
|
+
mv public/cached_pages $tmp
|
178
|
+
rm -rf $tmp
|
179
|
+
```
|
180
|
+
|
181
|
+
As noted before, the page cache directory is created if it does not exist, so
|
182
|
+
moving the directory is enough to have a clean cache, no need to recreate.
|
183
|
+
|
184
|
+
#### Fine-grained Cache Expiration
|
185
|
+
|
186
|
+
The API for doing so mimics the options from `url_for` and friends:
|
95
187
|
|
96
188
|
``` ruby
|
97
189
|
class WeblogController < ActionController::Base
|
@@ -103,12 +195,10 @@ class WeblogController < ActionController::Base
|
|
103
195
|
end
|
104
196
|
```
|
105
197
|
|
106
|
-
Additionally, you can expire caches using
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
rather than the original files. See the [project wiki][1] for example configurations.
|
111
|
-
[1]: https://github.com/rails/actionpack-page_caching/wiki
|
198
|
+
Additionally, you can expire caches using
|
199
|
+
[Sweepers](https://github.com/rails/rails-observers#action-controller-sweeper)
|
200
|
+
that act on changes in the model to determine when a cache is supposed to be
|
201
|
+
expired.
|
112
202
|
|
113
203
|
Contributing
|
114
204
|
------------
|
@@ -123,4 +213,3 @@ Code Status
|
|
123
213
|
-----------
|
124
214
|
|
125
215
|
* [![Build Status](https://travis-ci.org/rails/actionpack-page_caching.svg?branch=master)](https://travis-ci.org/rails/actionpack-page_caching)
|
126
|
-
* [![Dependency Status](https://gemnasium.com/rails/actionpack-page_caching.svg)](https://gemnasium.com/rails/actionpack-page_caching)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
2
|
gem.name = "actionpack-page_caching"
|
3
|
-
gem.version = "1.
|
3
|
+
gem.version = "1.2.3"
|
4
4
|
gem.author = "David Heinemeier Hansson"
|
5
5
|
gem.email = "david@loudthinking.com"
|
6
6
|
gem.description = "Static page caching for Action Pack (removed from core in Rails 4.0)"
|
@@ -8,14 +8,14 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.homepage = "https://github.com/rails/actionpack-page_caching"
|
9
9
|
gem.license = "MIT"
|
10
10
|
|
11
|
-
gem.required_ruby_version =
|
11
|
+
gem.required_ruby_version = ">= 2.4.6"
|
12
12
|
gem.files = `git ls-files`.split($/)
|
13
13
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
14
14
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
15
|
gem.require_paths = ["lib"]
|
16
|
-
gem.license =
|
16
|
+
gem.license = "MIT"
|
17
17
|
|
18
|
-
gem.add_dependency "actionpack", ">=
|
18
|
+
gem.add_dependency "actionpack", ">= 5.0.0"
|
19
19
|
|
20
20
|
gem.add_development_dependency "mocha"
|
21
21
|
end
|
@@ -93,6 +93,10 @@ module ActionController
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
+
def normalized_cache_directory
|
97
|
+
File.expand_path(cache_directory)
|
98
|
+
end
|
99
|
+
|
96
100
|
def handle_proc_cache_directory
|
97
101
|
if @controller
|
98
102
|
@controller.instance_exec(&@cache_directory)
|
@@ -136,12 +140,10 @@ module ActionController
|
|
136
140
|
MSG
|
137
141
|
end
|
138
142
|
|
139
|
-
|
140
|
-
@default_extension
|
141
|
-
end
|
143
|
+
attr_reader :default_extension
|
142
144
|
|
143
145
|
def cache_file(path, extension)
|
144
|
-
if path.empty? || path
|
146
|
+
if path.empty? || path =~ %r{\A/+\z}
|
145
147
|
name = "/index"
|
146
148
|
else
|
147
149
|
name = URI.parser.unescape(path.chomp("/"))
|
@@ -155,15 +157,22 @@ module ActionController
|
|
155
157
|
end
|
156
158
|
|
157
159
|
def cache_path(path, extension = nil)
|
158
|
-
File.join(
|
160
|
+
unnormalized_path = File.join(normalized_cache_directory, cache_file(path, extension))
|
161
|
+
normalized_path = File.expand_path(unnormalized_path)
|
162
|
+
|
163
|
+
normalized_path if normalized_path.start_with?(normalized_cache_directory)
|
159
164
|
end
|
160
165
|
|
161
166
|
def delete(path)
|
167
|
+
return unless path
|
168
|
+
|
162
169
|
File.delete(path) if File.exist?(path)
|
163
170
|
File.delete(path + ".gz") if File.exist?(path + ".gz")
|
164
171
|
end
|
165
172
|
|
166
173
|
def write(content, path, gzip)
|
174
|
+
return unless path
|
175
|
+
|
167
176
|
FileUtils.makedirs(File.dirname(path))
|
168
177
|
File.open(path, "wb+") { |f| f.write(content) }
|
169
178
|
|
@@ -275,7 +284,13 @@ module ActionController
|
|
275
284
|
request.path
|
276
285
|
end
|
277
286
|
|
278
|
-
|
287
|
+
type = if self.respond_to?(:media_type)
|
288
|
+
Mime::LOOKUP[self.media_type]
|
289
|
+
else
|
290
|
+
Mime::LOOKUP[self.content_type]
|
291
|
+
end
|
292
|
+
|
293
|
+
if type && (type_symbol = type.symbol).present?
|
279
294
|
extension = ".#{type_symbol}"
|
280
295
|
end
|
281
296
|
|
@@ -2,12 +2,8 @@ require "action_controller/caching/pages"
|
|
2
2
|
|
3
3
|
module ActionController
|
4
4
|
module Caching
|
5
|
-
eager_autoload do
|
6
|
-
autoload :Pages
|
7
|
-
end
|
8
|
-
|
9
5
|
include Pages
|
10
6
|
end
|
11
7
|
end
|
12
8
|
|
13
|
-
ActionController::Base.
|
9
|
+
ActionController::Base.include(ActionController::Caching::Pages)
|
data/test/caching_test.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
require "abstract_unit"
|
2
2
|
require "mocha/setup"
|
3
|
+
require "find"
|
3
4
|
|
4
5
|
CACHE_DIR = "test_cache"
|
5
6
|
# Don't change "../tmp" cavalierly or you might hose something you don't want hosed
|
6
7
|
TEST_TMP_DIR = File.expand_path("../tmp", __FILE__)
|
7
8
|
FILE_STORE_PATH = File.join(TEST_TMP_DIR, CACHE_DIR)
|
8
9
|
|
10
|
+
|
9
11
|
module PageCachingTestHelpers
|
10
12
|
def setup
|
11
13
|
super
|
@@ -24,7 +26,6 @@ module PageCachingTestHelpers
|
|
24
26
|
end
|
25
27
|
|
26
28
|
private
|
27
|
-
|
28
29
|
def assert_page_cached(action, options = {})
|
29
30
|
expected = options[:content] || action.to_s
|
30
31
|
path = cache_file(action, options)
|
@@ -176,6 +177,25 @@ class PageCachingTest < ActionController::TestCase
|
|
176
177
|
include PageCachingTestHelpers
|
177
178
|
tests PageCachingTestController
|
178
179
|
|
180
|
+
def test_cache_does_not_escape
|
181
|
+
draw do
|
182
|
+
get "/page_caching_test/ok/:id", to: "page_caching_test#ok"
|
183
|
+
end
|
184
|
+
|
185
|
+
project_root = File.expand_path("../../", __FILE__)
|
186
|
+
|
187
|
+
|
188
|
+
# Make a path that escapes the cache directory
|
189
|
+
get_to_root = "../../../"
|
190
|
+
|
191
|
+
# Make sure this relative path points at the project root
|
192
|
+
assert_equal project_root, File.expand_path(File.join(FILE_STORE_PATH, get_to_root))
|
193
|
+
|
194
|
+
get :ok, params: { id: "#{get_to_root}../pwnd" }
|
195
|
+
|
196
|
+
assert_predicate Find.find(File.join(project_root, "test")).grep(/pwnd/), :empty?
|
197
|
+
end
|
198
|
+
|
179
199
|
def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
|
180
200
|
draw do
|
181
201
|
get "posts.:format", to: "posts#index", as: :formatted_posts
|
@@ -330,19 +350,17 @@ class PageCachingTest < ActionController::TestCase
|
|
330
350
|
end
|
331
351
|
|
332
352
|
def test_page_caching_directory_set_as_pathname
|
333
|
-
|
334
|
-
ActionController::Base.page_cache_directory = Pathname.new(FILE_STORE_PATH)
|
353
|
+
ActionController::Base.page_cache_directory = Pathname.new(FILE_STORE_PATH)
|
335
354
|
|
336
|
-
|
337
|
-
|
338
|
-
end
|
339
|
-
|
340
|
-
get :ok
|
341
|
-
assert_response :ok
|
342
|
-
assert_page_cached :ok
|
343
|
-
ensure
|
344
|
-
ActionController::Base.page_cache_directory = FILE_STORE_PATH
|
355
|
+
draw do
|
356
|
+
get "/page_caching_test/ok", to: "page_caching_test#ok"
|
345
357
|
end
|
358
|
+
|
359
|
+
get :ok
|
360
|
+
assert_response :ok
|
361
|
+
assert_page_cached :ok
|
362
|
+
ensure
|
363
|
+
ActionController::Base.page_cache_directory = FILE_STORE_PATH
|
346
364
|
end
|
347
365
|
|
348
366
|
def test_page_caching_directory_set_on_controller_instance
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actionpack-page_caching
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -16,20 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '6'
|
19
|
+
version: 5.0.0
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '6'
|
26
|
+
version: 5.0.0
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: mocha
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -60,10 +54,10 @@ files:
|
|
60
54
|
- README.md
|
61
55
|
- Rakefile
|
62
56
|
- actionpack-page_caching.gemspec
|
63
|
-
- gemfiles/Gemfile-4-0-stable
|
64
|
-
- gemfiles/Gemfile-4-1-stable
|
65
|
-
- gemfiles/Gemfile-4-2-stable
|
66
57
|
- gemfiles/Gemfile-5-0-stable
|
58
|
+
- gemfiles/Gemfile-5-1-stable
|
59
|
+
- gemfiles/Gemfile-5-2-stable
|
60
|
+
- gemfiles/Gemfile-6-0-stable
|
67
61
|
- gemfiles/Gemfile-edge
|
68
62
|
- lib/action_controller/caching/pages.rb
|
69
63
|
- lib/action_controller/page_caching.rb
|
@@ -84,15 +78,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
78
|
requirements:
|
85
79
|
- - ">="
|
86
80
|
- !ruby/object:Gem::Version
|
87
|
-
version:
|
81
|
+
version: 2.4.6
|
88
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
83
|
requirements:
|
90
84
|
- - ">="
|
91
85
|
- !ruby/object:Gem::Version
|
92
86
|
version: '0'
|
93
87
|
requirements: []
|
94
|
-
|
95
|
-
rubygems_version: 2.6.8
|
88
|
+
rubygems_version: 3.1.2
|
96
89
|
signing_key:
|
97
90
|
specification_version: 4
|
98
91
|
summary: Static page caching for Action Pack (removed from core in Rails 4.0)
|
data/gemfiles/Gemfile-4-0-stable
DELETED
data/gemfiles/Gemfile-4-1-stable
DELETED