actionpack-page_caching 1.1.0 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bcc463b295ac09cfa6b0ca15557d7e00da2bf92b
4
- data.tar.gz: 1ca39e53842cb9446214249e47cfe791596e763e
2
+ SHA256:
3
+ metadata.gz: 89bc2dc16c419dd0cc85e43d0318d2cf25698aadf2e5b52f79188038a4159bd9
4
+ data.tar.gz: 1ee8bbc284ae4ccf1249648779edd731dd856102886eda5ceffe6827b46c7bbb
5
5
  SHA512:
6
- metadata.gz: cd19ec3f9214460795607de16e4d66769b7621cac4caa329ada8ec810b9414a6f1e5280b8132d683adcba70343b85750356c8d0d3d017f7d98ed199384ad1b14
7
- data.tar.gz: afa5b80f7c9ce7c54e284fa35bc3c484d7c0552aff051999dd668edd99827059570b019a01e00da544d23c68a78e9427354f68e5b36981221fc808f38f283912
6
+ metadata.gz: c62d167b5f9b06ec6ae84253cab216544d9e887da74b5dc860fc75655bbea488349eb2b85cea21609ad4ce5fd4abe0c815acb09c05d489af968d7f5e8f1a6d52
7
+ data.tar.gz: adb8c87f834ad88955f8c0d8e5282b64a41ac5948e235d923647164d68d30bac56b4ee4b4de50b9d587a0c48e5835981162873c6f59e6e557d2e3af9d86e41e0
@@ -0,0 +1,78 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - 'master'
7
+ pull_request:
8
+
9
+ jobs:
10
+ build:
11
+ strategy:
12
+ matrix:
13
+ gemfile:
14
+ - '4-2-stable'
15
+ - '5-0-stable'
16
+ - '5-1-stable'
17
+ - '5-2-stable'
18
+ - '6-0-stable'
19
+ - '6-1-stable'
20
+ - 'edge'
21
+ ruby:
22
+ - '2.4'
23
+ - '2.5'
24
+ - '2.6'
25
+ - '2.7'
26
+ - '3.0'
27
+ exclude:
28
+ - gemfile: '4-2-stable'
29
+ ruby: '2.5'
30
+ - gemfile: '4-2-stable'
31
+ ruby: '2.6'
32
+ - gemfile: '4-2-stable'
33
+ ruby: '2.7'
34
+ - gemfile: '4-2-stable'
35
+ ruby: '3.0'
36
+ - gemfile: '5-0-stable'
37
+ ruby: '2.7'
38
+ - gemfile: '5-0-stable'
39
+ ruby: '3.0'
40
+ - gemfile: '5-1-stable'
41
+ ruby: '2.7'
42
+ - gemfile: '5-1-stable'
43
+ ruby: '3.0'
44
+ - gemfile: '5-2-stable'
45
+ ruby: '2.7'
46
+ - gemfile: '5-2-stable'
47
+ ruby: '3.0'
48
+ - gemfile: '6-0-stable'
49
+ ruby: '2.4'
50
+ - gemfile: '6-1-stable'
51
+ ruby: '2.4'
52
+ - gemfile: 'edge'
53
+ ruby: '2.4'
54
+ - gemfile: 'edge'
55
+ ruby: '2.5'
56
+ - gemfile: 'edge'
57
+ ruby: '2.6'
58
+ fail-fast: false
59
+
60
+ runs-on: ubuntu-latest
61
+ name: ${{ matrix.ruby }} rails-${{ matrix.gemfile }}
62
+
63
+ steps:
64
+ - uses: actions/checkout@v2
65
+
66
+ - uses: ruby/setup-ruby@v1
67
+ with:
68
+ ruby-version: ${{ matrix.ruby }}
69
+ bundler-cache: true
70
+ bundler: ${{ fromJSON('["2", "1"]')[matrix.ruby == '2.4'] }}
71
+
72
+ - run: bundle exec rake test
73
+
74
+ env:
75
+ BUNDLE_GEMFILE: gemfiles/Gemfile-${{ matrix.gemfile }}
76
+ BUNDLE_JOBS: 4
77
+ BUNDLE_RETRY: 3
78
+
data/.rubocop.yml CHANGED
@@ -1,116 +1,192 @@
1
1
  AllCops:
2
- TargetRubyVersion: 2.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
6
6
 
7
- # Prefer &&/|| over and/or.
8
- Style/AndOr:
7
+ # Align `when` with `case`.
8
+ Layout/CaseIndentation:
9
9
  Enabled: true
10
10
 
11
- # Do not use braces for hash literals when they are the last argument of a
12
- # method call.
13
- Style/BracesAroundHashParameters:
11
+ Layout/ClosingHeredocIndentation:
14
12
  Enabled: true
15
13
 
16
- # Align `when` with `case`.
17
- Style/CaseIndentation:
14
+ # Align comments with method definitions.
15
+ Layout/CommentIndentation:
18
16
  Enabled: true
19
17
 
20
- # Align comments with method definitions.
21
- Style/CommentIndentation:
18
+ Layout/ElseAlignment:
22
19
  Enabled: true
23
20
 
24
- # No extra empty lines.
25
- Style/EmptyLines:
21
+ Layout/EmptyLineAfterMagicComment:
22
+ Enabled: true
23
+
24
+ Layout/EmptyLinesAroundAccessModifier:
25
+ Enabled: true
26
+ EnforcedStyle: only_before
27
+
28
+ Layout/EmptyLinesAroundBlockBody:
26
29
  Enabled: true
27
30
 
28
31
  # In a regular class definition, no empty lines around the body.
29
- Style/EmptyLinesAroundClassBody:
32
+ Layout/EmptyLinesAroundClassBody:
33
+ Enabled: true
34
+
35
+ # In a regular method definition, no empty lines around the body.
36
+ Layout/EmptyLinesAroundMethodBody:
30
37
  Enabled: true
31
38
 
32
39
  # In a regular module definition, no empty lines around the body.
33
- Style/EmptyLinesAroundModuleBody:
40
+ Layout/EmptyLinesAroundModuleBody:
34
41
  Enabled: true
35
42
 
36
- # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
37
- Style/HashSyntax:
43
+ # Align `end` with the matching keyword or starting expression except for
44
+ # assignments, where it should be aligned with the LHS.
45
+ Layout/EndAlignment:
46
+ Enabled: true
47
+ EnforcedStyleAlignWith: variable
48
+ AutoCorrect: true
49
+
50
+ Layout/FirstArgumentIndentation:
38
51
  Enabled: true
39
52
 
40
53
  # Method definitions after `private` or `protected` isolated calls need one
41
54
  # extra level of indentation.
42
- Style/IndentationConsistency:
55
+ Layout/IndentationConsistency:
43
56
  Enabled: true
44
- EnforcedStyle: rails
57
+ EnforcedStyle: indented_internal_methods
45
58
 
46
59
  # Two spaces, no tabs (for indentation).
47
- Style/IndentationWidth:
60
+ Layout/IndentationWidth:
48
61
  Enabled: true
49
62
 
50
- Style/SpaceAfterColon:
63
+ Layout/LeadingCommentSpace:
51
64
  Enabled: true
52
65
 
53
- Style/SpaceAfterComma:
66
+ Layout/SpaceAfterColon:
54
67
  Enabled: true
55
68
 
56
- Style/SpaceAroundEqualsInParameterDefault:
69
+ Layout/SpaceAfterComma:
57
70
  Enabled: true
58
71
 
59
- Style/SpaceAroundKeyword:
72
+ Layout/SpaceAfterSemicolon:
60
73
  Enabled: true
61
74
 
62
- Style/SpaceAroundOperators:
75
+ Layout/SpaceAroundEqualsInParameterDefault:
63
76
  Enabled: true
64
77
 
65
- Style/SpaceBeforeFirstArg:
66
- Enabled: true
67
-
68
- # Defining a method with parameters needs parentheses.
69
- Style/MethodDefParentheses:
78
+ Layout/SpaceAroundKeyword:
70
79
  Enabled: true
71
80
 
72
81
  # Use `foo {}` not `foo{}`.
73
- Style/SpaceBeforeBlockBraces:
82
+ Layout/SpaceBeforeBlockBraces:
74
83
  Enabled: true
75
84
 
76
- # Use `foo { bar }` not `foo {bar}`.
77
- Style/SpaceInsideBlockBraces:
85
+ Layout/SpaceBeforeComma:
78
86
  Enabled: true
79
87
 
80
- # Use `{ a: 1 }` not `{a:1}`.
81
- Style/SpaceInsideHashLiteralBraces:
88
+ Layout/SpaceBeforeComment:
82
89
  Enabled: true
83
90
 
84
- Style/SpaceInsideParens:
91
+ Layout/SpaceBeforeFirstArg:
85
92
  Enabled: true
86
93
 
87
- # Check quotes usage according to lint rule below.
88
- Style/StringLiterals:
94
+ # Use `foo { bar }` not `foo {bar}`.
95
+ Layout/SpaceInsideBlockBraces:
96
+ Enabled: true
97
+ EnforcedStyleForEmptyBraces: space
98
+
99
+ # Use `{ a: 1 }` not `{a:1}`.
100
+ Layout/SpaceInsideHashLiteralBraces:
101
+ Enabled: true
102
+
103
+ Layout/SpaceInsideParens:
89
104
  Enabled: true
90
- EnforcedStyle: double_quotes
91
105
 
92
106
  # Detect hard tabs, no hard tabs.
93
- Style/Tab:
107
+ Layout/Tab:
94
108
  Enabled: true
95
109
 
96
- # Blank lines should not have any spaces.
97
- Style/TrailingBlankLines:
110
+ # Empty lines should not have any spaces.
111
+ Layout/TrailingEmptyLines:
98
112
  Enabled: true
99
113
 
100
114
  # No trailing whitespace.
101
- Style/TrailingWhitespace:
115
+ Layout/TrailingWhitespace:
102
116
  Enabled: true
103
117
 
104
- # Use quotes for string literals when they are enough.
105
- Style/UnneededPercentQ:
118
+ Lint/AmbiguousOperator:
106
119
  Enabled: true
107
120
 
108
- # Align `end` with the matching keyword or starting expression except for
109
- # assignments, where it should be aligned with the LHS.
110
- Lint/EndAlignment:
121
+ Lint/AmbiguousRegexpLiteral:
122
+ Enabled: true
123
+
124
+ Lint/DeprecatedClassMethods:
125
+ Enabled: true
126
+
127
+ Lint/ErbNewArguments:
128
+ Enabled: true
129
+
130
+ Lint/RedundantStringCoercion:
111
131
  Enabled: true
112
- AlignWith: variable
113
132
 
114
133
  # Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
115
134
  Lint/RequireParentheses:
116
135
  Enabled: true
136
+
137
+ Lint/ShadowingOuterLocalVariable:
138
+ Enabled: true
139
+
140
+ Lint/UselessAssignment:
141
+ Enabled: true
142
+
143
+ Lint/UriEscapeUnescape:
144
+ Enabled: true
145
+
146
+ # Prefer &&/|| over and/or.
147
+ Style/AndOr:
148
+ Enabled: true
149
+
150
+ # Prefer Foo.method over Foo::method
151
+ Style/ColonMethodCall:
152
+ Enabled: true
153
+
154
+ Style/DefWithParentheses:
155
+ Enabled: true
156
+
157
+ # Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
158
+ Style/HashSyntax:
159
+ Enabled: true
160
+
161
+ # Defining a method with parameters needs parentheses.
162
+ Style/MethodDefParentheses:
163
+ Enabled: true
164
+
165
+ Style/ParenthesesAroundCondition:
166
+ Enabled: true
167
+
168
+ Style/RedundantBegin:
169
+ Enabled: true
170
+
171
+ Style/RedundantFreeze:
172
+ Enabled: true
173
+
174
+ # Use quotes for string literals when they are enough.
175
+ Style/RedundantPercentQ:
176
+ Enabled: true
177
+
178
+ Style/RedundantReturn:
179
+ Enabled: true
180
+ AllowMultipleReturnValues: true
181
+
182
+ Style/Semicolon:
183
+ Enabled: true
184
+ AllowAsExpressionSeparator: true
185
+
186
+ # Check quotes usage according to lint rule below.
187
+ Style/StringLiterals:
188
+ Enabled: true
189
+ EnforcedStyle: double_quotes
190
+
191
+ Style/TrivialAccessors:
192
+ Enabled: true
data/CHANGELOG.md CHANGED
@@ -1,36 +1,89 @@
1
- ## 1.1.0 (January 23, 2017)
1
+ ## 1.2.4 (May 15, 2021)
2
2
 
3
- * Support dynamic `page_cache_directory` using a Proc, Symbol or callable
3
+ - Fix `URI.parser` deprecation warning in Rails 6.1
4
4
 
5
- *Andrew White*
5
+ _Andrew White_
6
6
 
7
- * Support instance level setting of `page_cache_directory`
7
+ ## 1.2.3 (June 12, 2020)
8
8
 
9
- *Andrew White*
9
+ - Simplifies code in `page_caching.rb`
10
10
 
11
- * Add support for Rails 5.0 and master
11
+ _Xavier Noria_
12
12
 
13
- *Andrew White*
13
+ ## 1.2.2 (May 6, 2020)
14
14
 
15
+ - Fix variable name
15
16
 
16
- ## 1.0.2 (November 15, 2013)
17
+ _Jack McCracken_
17
18
 
18
- * Fix load order problem with other gems.
19
+ ## 1.2.1 (May 6, 2020)
19
20
 
20
- *Rafael Mendonça França*
21
+ - Only write relative URIs when their normalized path begins with the normalized cache directory path
21
22
 
23
+ _Jack McCracken_
22
24
 
23
- ## 1.0.1 (October 24, 2013)
25
+ ## 1.2.0 (December 11, 2019)
26
+
27
+ - Update RuboCop config
28
+
29
+ _Rafael Mendonça França_
30
+
31
+ - Fix for Rails 6 MIME lookups
32
+
33
+ _Rob Zolkos_
34
+
35
+ - Remove Rails 4.2 from testing matrix
36
+
37
+ _Rob Zolkos_
38
+
39
+ - Minimum of Ruby 2.4 required
40
+
41
+ _Rob Zolkos_
42
+
43
+ - Remove upper dependency for `actionpack`
44
+
45
+ _Anton Kolodii_
46
+
47
+ ## 1.1.1 (September 25, 2018)
48
+
49
+ - Fixes handling of several forward slashes as root path
50
+
51
+ _Xavier Noria_
24
52
 
25
- * Add Railtie to set `page_cache_directory` by default to `public` folder.
53
+ - Documentation overhaul
54
+
55
+ _Xavier Noria_
56
+
57
+ ## 1.1.0 (January 23, 2017)
58
+
59
+ - Support dynamic `page_cache_directory` using a Proc, Symbol or callable
60
+
61
+ _Andrew White_
62
+
63
+ - Support instance level setting of `page_cache_directory`
64
+
65
+ _Andrew White_
66
+
67
+ - Add support for Rails 5.0 and master
68
+
69
+ _Andrew White_
70
+
71
+ ## 1.0.2 (November 15, 2013)
72
+
73
+ - Fix load order problem with other gems.
74
+
75
+ _Rafael Mendonça França_
76
+
77
+ ## 1.0.1 (October 24, 2013)
26
78
 
27
- Fixes #5.
79
+ - Add Railtie to set `page_cache_directory` by default to `public` folder.
28
80
 
29
- *Žiga Vidic*
81
+ Fixes #5.
30
82
 
83
+ _Žiga Vidic_
31
84
 
32
85
  ## 1.0.0 (February 27, 2013)
33
86
 
34
- * Extract Action Pack - Action Caching from Rails core.
87
+ - Extract Action Pack - Action Caching from Rails core.
35
88
 
36
- *Francesco Rodriguez*, *Rafael Mendonça França*, *Michiel Sikkes*
89
+ _Francesco Rodriguez_, _Rafael Mendonça França_, _Michiel Sikkes_
data/Gemfile CHANGED
@@ -3,3 +3,4 @@ source "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  gem "rails"
6
+ gem "rubocop", ">= 0.77.0", require: false
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
- Installation
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
- Add this line to your application's Gemfile:
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
- $ bundle
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
- Or install it yourself as:
74
+ #### Default Cache Directory
20
75
 
21
- $ gem install actionpack-page_caching
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
- Usage
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
- Page caching is an approach to caching where the entire action output is
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
- First you need to set `page_cache_directory` in your configuration file:
86
+ The default page caching directory can be overridden:
36
87
 
37
88
  ``` ruby
38
- config.action_controller.page_cache_directory = "#{Rails.root}/public/cached_pages"
89
+ config.action_controller.page_cache_directory = Rails.root.join("public", "cached_pages")
39
90
  ```
40
91
 
41
- The `page_cache_directory` setting can be used with a Proc:
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 = -> { Rails.root.join("public", request.domain) }
104
+ self.page_cache_directory = -> {
105
+ Rails.root.join("public", request.domain)
106
+ }
46
107
  end
47
108
  ```
48
109
 
49
- a Symbol:
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
- Specifying which actions to cache is done through the `caches_page` class method:
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
- This will generate cache files such as `weblog/show/5.html` and
85
- `weblog/new.html`, which match the URLs used that would normally trigger
86
- dynamic page generation. Page caching works by configuring a web server to first
87
- check for the existence of files on disk, and to serve them directly when found,
88
- without passing the request through to Action Pack. This is much faster than
89
- handling the full dynamic request in the usual way.
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
- Expiration of the cache is handled by deleting the cached file, which results
92
- in a lazy regeneration approach where the cache is not restored before another
93
- hit is made against it. The API for doing so mimics the options from `url_for`
94
- and friends:
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 [Sweepers](https://github.com/rails/rails-observers#action-controller-sweeper)
107
- that act on changes in the model to determine when a cache is supposed to be expired.
108
-
109
- Finally, configure your web server to serve these static pages when they are present
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
  ------------
@@ -122,5 +212,4 @@ Contributing
122
212
  Code Status
123
213
  -----------
124
214
 
125
- * [![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)
215
+ * [![Build Status](https://github.com/rails/actionpack-page_caching/actions/workflows/ci.yml/badge.svg)](https://github.com/rails/actionpack-page_caching/actions/workflows/ci.yml)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = "actionpack-page_caching"
3
- gem.version = "1.1.0"
3
+ gem.version = "1.2.4"
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 = '>= 1.9.3'
11
+ gem.required_ruby_version = ">= 1.9.3"
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 = 'MIT'
16
+ gem.license = "MIT"
17
17
 
18
- gem.add_dependency "actionpack", ">= 4.0.0", "< 6"
18
+ gem.add_dependency "actionpack", ">= 4.0.0"
19
19
 
20
20
  gem.add_development_dependency "mocha"
21
21
  end
@@ -3,8 +3,3 @@ source "https://rubygems.org"
3
3
  gemspec path: ".."
4
4
 
5
5
  gem "rails", github: "rails/rails", branch: "4-2-stable"
6
- gem "mime-types", "< 3"
7
-
8
- if RUBY_VERSION < "2.1"
9
- gem "nokogiri", "< 1.7"
10
- end
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "rails", github: "rails/rails", branch: "5-1-stable"
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "rails", github: "rails/rails", branch: "5-2-stable"
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "rails", github: "rails/rails", branch: "6-0-stable"
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec path: ".."
4
+
5
+ gem "rails", github: "rails/rails", branch: "6-1-stable"
@@ -2,5 +2,4 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec path: ".."
4
4
 
5
- gem "rails", github: "rails/rails", branch: "master"
6
- gem "arel", github: "rails/arel", branch: "master"
5
+ gem "rails", github: "rails/rails", branch: "main"
@@ -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,15 +140,13 @@ module ActionController
136
140
  MSG
137
141
  end
138
142
 
139
- def default_extension
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
- name = URI.parser.unescape(path.chomp("/"))
149
+ name = URI::DEFAULT_PARSER.unescape(path.chomp("/"))
148
150
  end
149
151
 
150
152
  if File.extname(name).empty?
@@ -155,15 +157,22 @@ module ActionController
155
157
  end
156
158
 
157
159
  def cache_path(path, extension = nil)
158
- File.join(cache_directory, cache_file(path, extension))
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
- if (type = Mime::LOOKUP[self.content_type]) && (type_symbol = type.symbol).present?
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.send(:include, ActionController::Caching::Pages)
9
+ ActionController::Base.include(ActionController::Caching::Pages)
data/test/caching_test.rb CHANGED
@@ -1,11 +1,14 @@
1
+ require "rails/version"
1
2
  require "abstract_unit"
2
- require "mocha/setup"
3
+ require "mocha/minitest"
4
+ require "find"
3
5
 
4
6
  CACHE_DIR = "test_cache"
5
7
  # Don't change "../tmp" cavalierly or you might hose something you don't want hosed
6
8
  TEST_TMP_DIR = File.expand_path("../tmp", __FILE__)
7
9
  FILE_STORE_PATH = File.join(TEST_TMP_DIR, CACHE_DIR)
8
10
 
11
+
9
12
  module PageCachingTestHelpers
10
13
  def setup
11
14
  super
@@ -24,7 +27,6 @@ module PageCachingTestHelpers
24
27
  end
25
28
 
26
29
  private
27
-
28
30
  def assert_page_cached(action, options = {})
29
31
  expected = options[:content] || action.to_s
30
32
  path = cache_file(action, options)
@@ -176,6 +178,28 @@ class PageCachingTest < ActionController::TestCase
176
178
  include PageCachingTestHelpers
177
179
  tests PageCachingTestController
178
180
 
181
+ def test_cache_does_not_escape
182
+ draw do
183
+ get "/page_caching_test/ok/:id", to: "page_caching_test#ok"
184
+ end
185
+
186
+ project_root = File.expand_path("../../", __FILE__)
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
+ if Rails.version =~ /^4\./
195
+ get :ok, id: "#{get_to_root}../pwnd"
196
+ else
197
+ get :ok, params: { id: "#{get_to_root}../pwnd" }
198
+ end
199
+
200
+ assert_predicate Find.find(File.join(project_root, "test")).grep(/pwnd/), :empty?
201
+ end
202
+
179
203
  def test_page_caching_resources_saves_to_correct_path_with_extension_even_if_default_route
180
204
  draw do
181
205
  get "posts.:format", to: "posts#index", as: :formatted_posts
@@ -330,19 +354,17 @@ class PageCachingTest < ActionController::TestCase
330
354
  end
331
355
 
332
356
  def test_page_caching_directory_set_as_pathname
333
- begin
334
- ActionController::Base.page_cache_directory = Pathname.new(FILE_STORE_PATH)
357
+ ActionController::Base.page_cache_directory = Pathname.new(FILE_STORE_PATH)
335
358
 
336
- draw do
337
- get "/page_caching_test/ok", to: "page_caching_test#ok"
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
359
+ draw do
360
+ get "/page_caching_test/ok", to: "page_caching_test#ok"
345
361
  end
362
+
363
+ get :ok
364
+ assert_response :ok
365
+ assert_page_cached :ok
366
+ ensure
367
+ ActionController::Base.page_cache_directory = FILE_STORE_PATH
346
368
  end
347
369
 
348
370
  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.1.0
4
+ version: 1.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-23 00:00:00.000000000 Z
11
+ date: 2021-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -17,9 +17,6 @@ dependencies:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 4.0.0
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '6'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
@@ -27,9 +24,6 @@ dependencies:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: 4.0.0
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '6'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: mocha
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -51,19 +45,21 @@ extensions: []
51
45
  extra_rdoc_files: []
52
46
  files:
53
47
  - ".codeclimate.yml"
48
+ - ".github/workflows/ci.yml"
54
49
  - ".gitignore"
55
50
  - ".rubocop.yml"
56
- - ".travis.yml"
57
51
  - CHANGELOG.md
58
52
  - Gemfile
59
53
  - LICENSE.txt
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
57
  - gemfiles/Gemfile-4-2-stable
66
58
  - gemfiles/Gemfile-5-0-stable
59
+ - gemfiles/Gemfile-5-1-stable
60
+ - gemfiles/Gemfile-5-2-stable
61
+ - gemfiles/Gemfile-6-0-stable
62
+ - gemfiles/Gemfile-6-1-stable
67
63
  - gemfiles/Gemfile-edge
68
64
  - lib/action_controller/caching/pages.rb
69
65
  - lib/action_controller/page_caching.rb
@@ -76,7 +72,7 @@ homepage: https://github.com/rails/actionpack-page_caching
76
72
  licenses:
77
73
  - MIT
78
74
  metadata: {}
79
- post_install_message:
75
+ post_install_message:
80
76
  rdoc_options: []
81
77
  require_paths:
82
78
  - lib
@@ -91,9 +87,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
87
  - !ruby/object:Gem::Version
92
88
  version: '0'
93
89
  requirements: []
94
- rubyforge_project:
95
- rubygems_version: 2.6.8
96
- signing_key:
90
+ rubygems_version: 3.2.15
91
+ signing_key:
97
92
  specification_version: 4
98
93
  summary: Static page caching for Action Pack (removed from core in Rails 4.0)
99
94
  test_files:
data/.travis.yml DELETED
@@ -1,64 +0,0 @@
1
- language: ruby
2
- sudo: false
3
-
4
- cache:
5
- bundler: true
6
-
7
- before_install:
8
- - gem install bundler
9
-
10
- rvm:
11
- - 1.9.3
12
- - 2.0.0
13
- - 2.1.9
14
- - 2.2.6
15
- - 2.3.3
16
- - 2.4.0
17
-
18
- gemfile:
19
- - Gemfile
20
- - gemfiles/Gemfile-4-0-stable
21
- - gemfiles/Gemfile-4-1-stable
22
- - gemfiles/Gemfile-4-2-stable
23
- - gemfiles/Gemfile-5-0-stable
24
- - gemfiles/Gemfile-edge
25
-
26
- matrix:
27
- allow_failures:
28
- - gemfile: gemfiles/Gemfile-edge
29
- exclude:
30
- - rvm: 1.9.3
31
- gemfile: Gemfile
32
- - rvm: 2.0.0
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
43
- 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
-
53
- notifications:
54
- email: false
55
- irc:
56
- on_success: change
57
- on_failure: always
58
- channels:
59
- - "irc.freenode.org#rails-contrib"
60
- campfire:
61
- on_success: change
62
- on_failure: always
63
- rooms:
64
- - secure: "eRCx+FMvH50pmLu0GZTF7NN+2X+CesgodYUlHvCr5EXQ0ZO/YUmeW8vAh/N8\njSrLWYpk/4P/JA63JGWsvFor/zpkTnfwzX3LWgw04GV0V3T9jsn9CD2Coiu6\nFll5u4fUCUwpfbB4RlCkjvFdQmW+F9mmbRGMCDO5CmuPHOyyPH0="
@@ -1,6 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec path: ".."
4
-
5
- gem "rails", github: "rails/rails", branch: "4-0-stable"
6
- gem "mime-types", "< 3"
@@ -1,6 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec path: ".."
4
-
5
- gem "rails", github: "rails/rails", branch: "4-1-stable"
6
- gem "mime-types", "< 3"