prerender_rails 1.3.0 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +3 -1
- data/README.md +11 -18
- data/lib/prerender_rails.rb +54 -12
- data/prerender_rails.gemspec +3 -3
- data/test/lib/prerender_rails.rb +73 -11
- metadata +21 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 31eaea5bcb5ca7912fe4702e55d5ad48834c5c4912026b3c7c5b80e8b67c2273
|
4
|
+
data.tar.gz: b93d84f1616b9338507cbd976dcf0b0e5e2b1e8676fb9543364f606bd8df0652
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea3b84d1fa613248dace19ffee4b66ef4014b42da4c558db1e22663a5de8c7d3c8969abb84ac3ab18743155a5e5026e5b54e1b6a72f803c5917a64d98f6a7b77
|
7
|
+
data.tar.gz: d51a0feaa238dd3b88e87aa83a6388c96f06bb1d4313fa6ba2273a43e8c9b04250f5cd9523c9b5dbf9a0123eea87c9247ad3a99c3d80fb4b1a50e174488869fd
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
-
Prerender Rails [![
|
1
|
+
Prerender Rails [![Build Status](https://travis-ci.org/prerender/prerender_rails.png)](https://travis-ci.org/prerender/prerender_rails) [![Gem Version](https://badge.fury.io/rb/prerender_rails.png)](http://badge.fury.io/rb/prerender_rails)
|
2
2
|
===========================
|
3
3
|
|
4
|
-
Google, Facebook, Twitter,
|
4
|
+
Google, Facebook, Twitter, and Bing are constantly trying to view your website... but Google is the only crawler that executes a meaningful amount of JavaScript and Google even admits that they can execute JavaScript weeks after actually crawling. Prerender allows you to serve the full HTML of your website back to Google and other crawlers so that they don't have to execute any JavaScript. [Google recommends using Prerender.io](https://developers.google.com/search/docs/guides/dynamic-rendering) to prevent indexation issues on sites with large amounts of JavaScript.
|
5
5
|
|
6
|
-
|
6
|
+
Prerender is perfect for Angular SEO, React SEO, Vue SEO, and any other JavaScript framework.
|
7
7
|
|
8
|
-
|
9
|
-
- Just add <meta name="fragment" content="!"> to the <head> of all of your pages
|
10
|
-
- If you use hash urls (#), change them to the hash-bang (#!)
|
11
|
-
- That's it! Perfect SEO on javascript pages.
|
8
|
+
This middleware intercepts requests to your Node.js website from crawlers, and then makes a call to the (external) Prerender Service to get the static HTML instead of the JavaScript for that page. That HTML is then returned to the crawler.
|
12
9
|
|
13
10
|
`Note` Make sure you have more than one webserver thread/process running because the prerender service will make a request to your server to render the HTML.
|
14
11
|
|
@@ -22,7 +19,7 @@ And in `config/environment/production.rb`, add this line:
|
|
22
19
|
config.middleware.use Rack::Prerender
|
23
20
|
```
|
24
21
|
|
25
|
-
or if you have an account on [prerender.io](
|
22
|
+
or if you have an account on [prerender.io](https://prerender.io/) and want to use your token:
|
26
23
|
|
27
24
|
```ruby
|
28
25
|
config.middleware.use Rack::Prerender, prerender_token: 'YOUR_TOKEN'
|
@@ -32,19 +29,15 @@ or if you have an account on [prerender.io](http://prerender.io) and want to use
|
|
32
29
|
|
33
30
|
## Testing
|
34
31
|
|
35
|
-
|
32
|
+
When testing make sure you're not using a single threaded application server like default WEBrick one, use Puma or Unicorn to prevent a deadlock when the Prerender Service needs to render your HTML on the fly.
|
36
33
|
|
37
|
-
|
38
|
-
Then go to `http://localhost:5000/?_escaped_fragment_=/profiles/1234`
|
34
|
+
The best way to test the prerendered page is to [set the User Agent of your browser to Googlebot's user agent](https://developers.google.com/web/tools/chrome-devtools/device-mode/override-user-agent) and visit your URL directly. If you View Source on that URL, you should see the static HTML version of the page with the `<script>` tags removed from the page. If you still see `<script>` tags then that means the middleware isn't set up properly yet.
|
39
35
|
|
40
|
-
If
|
41
|
-
|
42
|
-
If you want to see `http://localhost:5000/profiles/1234`
|
43
|
-
Then go to `http://localhost:5000/profiles/1234?_escaped_fragment_=`
|
36
|
+
`Note` If you're testing locally, you'll need to run the [prerender server](https://github.com/prerender/prerender) locally so that it has access to your server.
|
44
37
|
|
45
38
|
## How it works
|
46
39
|
1. The middleware checks to make sure we should show a prerendered page
|
47
|
-
1. The middleware checks if the request is from a crawler
|
40
|
+
1. The middleware checks if the request is from a crawler by checking the user agent string against a default list of crawler user agents
|
48
41
|
2. The middleware checks to make sure we aren't requesting a resource (js, css, etc...)
|
49
42
|
3. (optional) The middleware checks to make sure the url is in the whitelist
|
50
43
|
4. (optional) The middleware checks to make sure the url isn't in the blacklist
|
@@ -135,7 +128,7 @@ config.middleware.use Rack::Prerender,
|
|
135
128
|
|
136
129
|
## Using your own prerender service
|
137
130
|
|
138
|
-
We host a Prerender server at [prerender.io](
|
131
|
+
We host a Prerender server at [prerender.io](https://prerender.io/) so that you can work on more important things, but if you've deployed the prerender service on your own... set the `PRERENDER_SERVICE_URL` environment variable so that this middleware points there instead. Otherwise, it will default to the service already deployed by [prerender.io](https://prerender.io/).
|
139
132
|
|
140
133
|
$ export PRERENDER_SERVICE_URL=<new url>
|
141
134
|
|
@@ -146,7 +139,7 @@ Or on heroku:
|
|
146
139
|
As an alternative, you can pass `prerender_service_url` in the options object during initialization of the middleware
|
147
140
|
|
148
141
|
``` ruby
|
149
|
-
config.middleware.use Rack::Prerender, prerender_service_url: '
|
142
|
+
config.middleware.use Rack::Prerender, prerender_service_url: '<new url>'
|
150
143
|
```
|
151
144
|
|
152
145
|
## License
|
data/lib/prerender_rails.rb
CHANGED
@@ -4,13 +4,24 @@ module Rack
|
|
4
4
|
require 'active_support'
|
5
5
|
|
6
6
|
def initialize(app, options={})
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
@connection_header_values = [
|
8
|
+
'close',
|
9
|
+
'keep-alive'
|
10
|
+
].freeze
|
11
|
+
@hop_by_hop_headers = [
|
12
|
+
'Connection',
|
13
|
+
'Keep-Alive',
|
14
|
+
'Public',
|
15
|
+
'Proxy-Authenticate',
|
16
|
+
'Transfer-Encoding',
|
17
|
+
'Upgrade'
|
18
|
+
].freeze
|
19
|
+
|
10
20
|
@crawler_user_agents = [
|
11
|
-
|
12
|
-
|
13
|
-
|
21
|
+
'googlebot',
|
22
|
+
'Google-InspectionTool',
|
23
|
+
'yahoo',
|
24
|
+
'bingbot',
|
14
25
|
'baiduspider',
|
15
26
|
'facebookexternalhit',
|
16
27
|
'twitterbot',
|
@@ -21,13 +32,25 @@ module Rack
|
|
21
32
|
'quora link preview',
|
22
33
|
'showyoubot',
|
23
34
|
'outbrain',
|
24
|
-
'pinterest',
|
35
|
+
'pinterest/0.',
|
25
36
|
'developers.google.com/+/web/snippet',
|
37
|
+
'www.google.com/webmasters/tools/richsnippets',
|
26
38
|
'slackbot',
|
27
39
|
'vkShare',
|
28
40
|
'W3C_Validator',
|
29
41
|
'redditbot',
|
30
|
-
'Applebot'
|
42
|
+
'Applebot',
|
43
|
+
'WhatsApp',
|
44
|
+
'flipboard',
|
45
|
+
'tumblr',
|
46
|
+
'bitlybot',
|
47
|
+
'SkypeUriPreview',
|
48
|
+
'nuzzel',
|
49
|
+
'Discordbot',
|
50
|
+
'Google Page Speed',
|
51
|
+
'Qwantify',
|
52
|
+
'Chrome-Lighthouse',
|
53
|
+
'TelegramBot'
|
31
54
|
]
|
32
55
|
|
33
56
|
@extensions_to_ignore = [
|
@@ -104,7 +127,8 @@ module Rack
|
|
104
127
|
|
105
128
|
def should_show_prerendered_page(env)
|
106
129
|
user_agent = env['HTTP_USER_AGENT']
|
107
|
-
buffer_agent = env['
|
130
|
+
buffer_agent = env['HTTP_X_BUFFERBOT']
|
131
|
+
prerender_agent = env['HTTP_X_PRERENDER']
|
108
132
|
is_requesting_prerendered_page = false
|
109
133
|
|
110
134
|
return false if !user_agent
|
@@ -120,13 +144,16 @@ module Rack
|
|
120
144
|
#if it is BufferBot...show prerendered page
|
121
145
|
is_requesting_prerendered_page = true if buffer_agent
|
122
146
|
|
147
|
+
#if it is Prerender...don't show prerendered page
|
148
|
+
is_requesting_prerendered_page = false if prerender_agent
|
149
|
+
|
123
150
|
#if it is a bot and is requesting a resource...dont prerender
|
124
151
|
return false if @extensions_to_ignore.any? { |extension| request.fullpath.include? extension }
|
125
152
|
|
126
153
|
#if it is a bot and not requesting a resource and is not whitelisted...dont prerender
|
127
154
|
return false if @options[:whitelist].is_a?(Array) && @options[:whitelist].all? { |whitelisted| !Regexp.new(whitelisted).match(request.fullpath) }
|
128
155
|
|
129
|
-
#if it is a bot and not requesting a resource and is
|
156
|
+
#if it is a bot and not requesting a resource and is blacklisted(url or referer)...dont prerender
|
130
157
|
if @options[:blacklist].is_a?(Array) && @options[:blacklist].any? { |blacklisted|
|
131
158
|
blacklistedUrl = false
|
132
159
|
blacklistedReferer = false
|
@@ -155,12 +182,27 @@ module Rack
|
|
155
182
|
headers['X-Prerender-Token'] = @options[:prerender_token] if @options[:prerender_token]
|
156
183
|
req = Net::HTTP::Get.new(url.request_uri, headers)
|
157
184
|
req.basic_auth(ENV['PRERENDER_USERNAME'], ENV['PRERENDER_PASSWORD']) if @options[:basic_auth]
|
158
|
-
|
185
|
+
http = Net::HTTP.new(url.host, url.port)
|
186
|
+
http.use_ssl = true if url.scheme == 'https'
|
187
|
+
response = http.request(req)
|
159
188
|
if response['Content-Encoding'] == 'gzip'
|
160
189
|
response.body = ActiveSupport::Gzip.decompress(response.body)
|
161
190
|
response['Content-Length'] = response.body.length
|
162
191
|
response.delete('Content-Encoding')
|
163
192
|
end
|
193
|
+
|
194
|
+
hop_by_hop_headers = @hop_by_hop_headers
|
195
|
+
connection = response['Connection']
|
196
|
+
if connection
|
197
|
+
connection_hop_by_hop_headers = connection.split(',').
|
198
|
+
map(&:strip).
|
199
|
+
map(&:downcase).
|
200
|
+
difference(@connection_header_values)
|
201
|
+
hop_by_hop_headers = connection_hop_by_hop_headers.
|
202
|
+
concat(hop_by_hop_headers)
|
203
|
+
end
|
204
|
+
hop_by_hop_headers.each { |h| response.delete(h) }
|
205
|
+
|
164
206
|
response
|
165
207
|
rescue
|
166
208
|
nil
|
@@ -199,7 +241,7 @@ module Rack
|
|
199
241
|
|
200
242
|
|
201
243
|
def build_rack_response_from_prerender(prerendered_response)
|
202
|
-
response = Rack::Response.new(prerendered_response.body, prerendered_response.code, prerendered_response
|
244
|
+
response = Rack::Response.new(prerendered_response.body, prerendered_response.code, prerendered_response)
|
203
245
|
|
204
246
|
@options[:build_rack_response_from_prerender].call(response, prerendered_response) if @options[:build_rack_response_from_prerender]
|
205
247
|
|
data/prerender_rails.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = "prerender_rails"
|
5
|
-
spec.version = "1.
|
5
|
+
spec.version = "1.9.0"
|
6
6
|
spec.authors = ["Todd Hooper"]
|
7
7
|
spec.email = ["todd@prerender.io"]
|
8
8
|
spec.description = %q{Rails middleware to prerender your javascript heavy pages on the fly by a phantomjs service}
|
@@ -15,10 +15,10 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
16
16
|
spec.require_paths = ["lib"]
|
17
17
|
|
18
|
-
spec.add_dependency 'rack', '
|
18
|
+
spec.add_dependency 'rack', '~> 2.2.2'
|
19
19
|
spec.add_dependency 'activesupport', '>= 0'
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.
|
21
|
+
spec.add_development_dependency "bundler", "~> 2.1.2"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "webmock"
|
24
24
|
end
|
data/test/lib/prerender_rails.rb
CHANGED
@@ -19,9 +19,9 @@ describe Rack::Prerender do
|
|
19
19
|
stub_request(:get, @prerender.build_api_url(request)).with(:headers => { 'User-Agent' => bot }).to_return(:body => "<html></html>", :status => 301, :headers => { 'Location' => 'http://google.com'})
|
20
20
|
response = Rack::Prerender.new(@app).call(request)
|
21
21
|
|
22
|
-
assert_equal response[2]
|
23
|
-
assert_equal response[
|
24
|
-
assert_equal( { 'location' => 'http://google.com'
|
22
|
+
assert_equal response[2], ["<html></html>"]
|
23
|
+
assert_equal response[0], 301
|
24
|
+
assert_equal( { 'location' => 'http://google.com'}, response[1] )
|
25
25
|
end
|
26
26
|
|
27
27
|
|
@@ -30,7 +30,7 @@ describe Rack::Prerender do
|
|
30
30
|
stub_request(:get, @prerender.build_api_url(request)).with(:headers => { 'User-Agent' => user }).to_return(:body => "<html></html>")
|
31
31
|
response = Rack::Prerender.new(@app).call(request)
|
32
32
|
|
33
|
-
assert_equal ["<html></html>"], response[2]
|
33
|
+
assert_equal ["<html></html>"], response[2]
|
34
34
|
end
|
35
35
|
|
36
36
|
|
@@ -58,6 +58,14 @@ describe Rack::Prerender do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
|
61
|
+
it "should continue to app routes if contains X-Prerender header" do
|
62
|
+
request = Rack::MockRequest.env_for "/path?_escaped_fragment_=", "HTTP_USER_AGENT" => user, "HTTP_X_PRERENDER" => "1"
|
63
|
+
response = Rack::Prerender.new(@app).call(request)
|
64
|
+
|
65
|
+
assert_equal "", response[2]
|
66
|
+
end
|
67
|
+
|
68
|
+
|
61
69
|
it "should continue to app routes if user is a bot, but the bot is requesting a resource file" do
|
62
70
|
request = Rack::MockRequest.env_for "/main.js?anyQueryParam=true", "HTTP_USER_AGENT" => bot
|
63
71
|
response = Rack::Prerender.new(@app).call(request)
|
@@ -74,12 +82,23 @@ describe Rack::Prerender do
|
|
74
82
|
end
|
75
83
|
|
76
84
|
|
85
|
+
it "should set use_ssl to true for https prerender_service_url" do
|
86
|
+
@prerender = Rack::Prerender.new(@app, prerender_service_url: 'https://service.prerender.io/')
|
87
|
+
|
88
|
+
request = Rack::MockRequest.env_for "/search/things/123/page?_escaped_fragment_=", "HTTP_USER_AGENT" => bot
|
89
|
+
stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
|
90
|
+
response = @prerender.call(request)
|
91
|
+
|
92
|
+
assert_equal ["<html></html>"], response[2]
|
93
|
+
end
|
94
|
+
|
95
|
+
|
77
96
|
it "should return a prerendered response if the url is part of the regex specific whitelist" do
|
78
97
|
request = Rack::MockRequest.env_for "/search/things/123/page?_escaped_fragment_=", "HTTP_USER_AGENT" => bot
|
79
98
|
stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
|
80
99
|
response = Rack::Prerender.new(@app, whitelist: ['^/search.*page', '/help']).call(request)
|
81
100
|
|
82
|
-
assert_equal ["<html></html>"], response[2]
|
101
|
+
assert_equal ["<html></html>"], response[2]
|
83
102
|
end
|
84
103
|
|
85
104
|
|
@@ -102,7 +121,7 @@ describe Rack::Prerender do
|
|
102
121
|
stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
|
103
122
|
response = Rack::Prerender.new(@app, blacklist: ['^/search', '/help']).call(request)
|
104
123
|
|
105
|
-
assert_equal ["<html></html>"], response[2]
|
124
|
+
assert_equal ["<html></html>"], response[2]
|
106
125
|
end
|
107
126
|
|
108
127
|
|
@@ -119,7 +138,7 @@ describe Rack::Prerender do
|
|
119
138
|
stub_request(:get, @prerender.build_api_url(request)).to_return(:body => "<html></html>")
|
120
139
|
response = Rack::Prerender.new(@app, blacklist: ['^/search', '/help']).call(request)
|
121
140
|
|
122
|
-
assert_equal ["<html></html>"], response[2]
|
141
|
+
assert_equal ["<html></html>"], response[2]
|
123
142
|
end
|
124
143
|
|
125
144
|
|
@@ -127,7 +146,7 @@ describe Rack::Prerender do
|
|
127
146
|
request = Rack::MockRequest.env_for "/", "HTTP_USER_AGENT" => bot
|
128
147
|
response = Rack::Prerender.new(@app, before_render: Proc.new do |env| '<html>cached</html>' end).call(request)
|
129
148
|
|
130
|
-
assert_equal ["<html>cached</html>"], response[2]
|
149
|
+
assert_equal ["<html>cached</html>"], response[2]
|
131
150
|
end
|
132
151
|
|
133
152
|
|
@@ -135,11 +154,47 @@ describe Rack::Prerender do
|
|
135
154
|
request = Rack::MockRequest.env_for "/", "HTTP_USER_AGENT" => bot
|
136
155
|
response = Rack::Prerender.new(@app, before_render: Proc.new do |env| Rack::Response.new('<html>cached2</html>', 200, { 'test' => 'test2Header'}) end).call(request)
|
137
156
|
|
138
|
-
assert_equal ["<html>cached2</html>"], response[2]
|
139
|
-
assert_equal response[
|
140
|
-
assert_equal( { 'test' => 'test2Header'
|
157
|
+
assert_equal ["<html>cached2</html>"], response[2]
|
158
|
+
assert_equal response[0], 200
|
159
|
+
assert_equal( { 'test' => 'test2Header'}, response[1] )
|
141
160
|
end
|
142
161
|
|
162
|
+
it "should return a prerendered response stripped of hop-by-hop headers" do
|
163
|
+
request = Rack::MockRequest.env_for "/", "HTTP_USER_AGENT" => bot
|
164
|
+
stub_request(:get, @prerender.build_api_url(request)).
|
165
|
+
with(:headers => { 'User-Agent' => bot }).
|
166
|
+
to_return(:body => "<html></html>", :status => 401, :headers => {
|
167
|
+
'Content-Type' => 'text/html',
|
168
|
+
'Transfer-Encoding' => 'Chunked',
|
169
|
+
'Connection' => 'Keep-Alive',
|
170
|
+
'Keep-Alive' => 'timeout=5, max=100',
|
171
|
+
'Public' => 'GET HEAD',
|
172
|
+
'Proxy-Authenticate' => 'Basic',
|
173
|
+
'X-Drop-Test' => 'ShouldAlwaysHappen',
|
174
|
+
'Upgrade' => 'dummy'
|
175
|
+
})
|
176
|
+
response = Rack::Prerender.new(@app).call(request)
|
177
|
+
|
178
|
+
assert_equal response[2], ["<html></html>"]
|
179
|
+
assert_equal response[0], 401
|
180
|
+
assert_equal( { 'content-type' => 'text/html', 'x-drop-test' => 'ShouldAlwaysHappen'}, response[1] )
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should return a prerendered response stripped of custom-defined hop-by-hop headers" do
|
184
|
+
request = Rack::MockRequest.env_for "/", "HTTP_USER_AGENT" => bot
|
185
|
+
stub_request(:get, @prerender.build_api_url(request)).
|
186
|
+
with(:headers => { 'User-Agent' => bot }).
|
187
|
+
to_return(:body => "<html></html>", :status => 200, :headers => {
|
188
|
+
'Content-Type' => 'text/html',
|
189
|
+
'Connection' => 'Close, X-Drop-Test',
|
190
|
+
'X-Drop-Test' => 'ShouldNeverHappen'
|
191
|
+
})
|
192
|
+
response = Rack::Prerender.new(@app).call(request)
|
193
|
+
|
194
|
+
assert_equal response[2], ["<html></html>"]
|
195
|
+
assert_equal response[0], 200
|
196
|
+
assert_equal( { 'content-type' => 'text/html' }, response[1] )
|
197
|
+
end
|
143
198
|
|
144
199
|
describe '#buildApiUrl' do
|
145
200
|
it "should build the correct api url with the default url" do
|
@@ -164,6 +219,13 @@ describe Rack::Prerender do
|
|
164
219
|
end
|
165
220
|
|
166
221
|
|
222
|
+
it "should build the correct https api url with an initialization variable url" do
|
223
|
+
@prerender = Rack::Prerender.new(@app, prerender_service_url: 'https://prerenderurl.com')
|
224
|
+
request = Rack::MockRequest.env_for "https://google.com/search?q=javascript"
|
225
|
+
assert_equal 'https://prerenderurl.com/https://google.com/search?q=javascript', @prerender.build_api_url(request)
|
226
|
+
end
|
227
|
+
|
228
|
+
|
167
229
|
# Check CF-Visitor header in order to Work behind CloudFlare with Flexible SSL (https://support.cloudflare.com/hc/en-us/articles/200170536)
|
168
230
|
it "should build the correct api url for the Cloudflare Flexible SSL support" do
|
169
231
|
request = Rack::MockRequest.env_for "http://google.com/search?q=javascript", { 'CF-VISITOR' => '"scheme":"https"'}
|
metadata
CHANGED
@@ -1,83 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prerender_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Todd Hooper
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 2.2.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 2.2.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 2.1.2
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 2.1.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: webmock
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
description: Rails middleware to prerender your javascript heavy pages on the fly
|
@@ -88,8 +88,8 @@ executables: []
|
|
88
88
|
extensions: []
|
89
89
|
extra_rdoc_files: []
|
90
90
|
files:
|
91
|
-
- .gitignore
|
92
|
-
- .travis.yml
|
91
|
+
- ".gitignore"
|
92
|
+
- ".travis.yml"
|
93
93
|
- Gemfile
|
94
94
|
- LICENSE.txt
|
95
95
|
- README.md
|
@@ -108,17 +108,16 @@ require_paths:
|
|
108
108
|
- lib
|
109
109
|
required_ruby_version: !ruby/object:Gem::Requirement
|
110
110
|
requirements:
|
111
|
-
- -
|
111
|
+
- - ">="
|
112
112
|
- !ruby/object:Gem::Version
|
113
113
|
version: '0'
|
114
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
115
|
requirements:
|
116
|
-
- -
|
116
|
+
- - ">="
|
117
117
|
- !ruby/object:Gem::Version
|
118
118
|
version: '0'
|
119
119
|
requirements: []
|
120
|
-
|
121
|
-
rubygems_version: 2.0.14
|
120
|
+
rubygems_version: 3.0.3.1
|
122
121
|
signing_key:
|
123
122
|
specification_version: 4
|
124
123
|
summary: Prerender your backbone/angular/javascript rendered application on the fly
|