rack-contrib 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rack-contrib might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/lib/rack/contrib.rb +1 -0
- data/lib/rack/contrib/accept_format.rb +20 -0
- data/lib/rack/contrib/lazy_conditional_get.rb +113 -0
- data/lib/rack/contrib/profiler.rb +9 -1
- data/lib/rack/contrib/sendfile.rb +2 -4
- data/lib/rack/contrib/static_cache.rb +16 -6
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebb4015dc4f7430d92377b2e07290fce6b77e761
|
4
|
+
data.tar.gz: cf782e8189841d0ea1f1e8172de8eeba99a31b9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a652866eeee2c3882f693a54e7aece3b6235cd652ff9851dd06635b353896675e1f8d3a5573ef151ed56bdcb03ad2c93f05461a07adcb0a140b7c2b5ffee7fa
|
7
|
+
data.tar.gz: f4143356a5e113cd337f0a6d32e74564bc109e4cb4d3ad3bc724e53171100df19007357a0e89be91d8cd2301606a180c097d6b4b928b52632bd0b654a64d37fb
|
data/README.md
CHANGED
@@ -14,6 +14,7 @@ interface:
|
|
14
14
|
* `Rack::Evil` - Lets the rack application return a response to the client from any place.
|
15
15
|
* `Rack::HostMeta` - Configures `/host-meta` using a block
|
16
16
|
* `Rack::JSONP` - Adds JSON-P support by stripping out the callback param and padding the response with the appropriate callback format.
|
17
|
+
* `Rack::LazyConditionalGet` - Caches a global `Last-Modified` date and updates it each time there is a request that is not `GET` or `HEAD`.
|
17
18
|
* `Rack::LighttpdScriptNameFix` - Fixes how lighttpd sets the `SCRIPT_NAME` and `PATH_INFO` variables in certain configurations.
|
18
19
|
* `Rack::Locale` - Detects the client locale using the Accept-Language request header and sets a `rack.locale` variable in the environment.
|
19
20
|
* `Rack::MailExceptions` - Rescues exceptions raised from the app and sends a useful email with the exception, stacktrace, and contents of the environment.
|
data/lib/rack/contrib.rb
CHANGED
@@ -19,6 +19,7 @@ module Rack
|
|
19
19
|
autoload :HostMeta, "rack/contrib/host_meta"
|
20
20
|
autoload :GarbageCollector, "rack/contrib/garbagecollector"
|
21
21
|
autoload :JSONP, "rack/contrib/jsonp"
|
22
|
+
autoload :LazyConditionalGet, "rack/contrib/lazy_conditional_get"
|
22
23
|
autoload :LighttpdScriptNameFix, "rack/contrib/lighttpd_script_name_fix"
|
23
24
|
autoload :Locale, "rack/contrib/locale"
|
24
25
|
autoload :MailExceptions, "rack/contrib/mailexceptions"
|
@@ -1,4 +1,13 @@
|
|
1
1
|
module Rack
|
2
|
+
#
|
3
|
+
# CAUTION: THIS MIDDLEWARE IS DEPRECATED. DO NOT USE IT.
|
4
|
+
#
|
5
|
+
# This middleware is slated for removal as of rack-contrib 2.0.0, because
|
6
|
+
# it is terribad. Applications should *always* use the `Accept` header to
|
7
|
+
# detect response formats (when it is available), rather than ignoring
|
8
|
+
# that and instead examining the extension of the request. We recommend
|
9
|
+
# using the `rack-accept` gem for handling the `Accept` family of entity
|
10
|
+
# request headers.
|
2
11
|
#
|
3
12
|
# A Rack middleware for automatically adding a <tt>format</tt> token at the end of the request path
|
4
13
|
# when there is none. It can detect formats passed in the HTTP_ACCEPT header to populate this token.
|
@@ -24,8 +33,19 @@ module Rack
|
|
24
33
|
# MIT-License - Cyril Rohr
|
25
34
|
#
|
26
35
|
class AcceptFormat
|
36
|
+
def self.deprecation_acknowledged
|
37
|
+
@deprecation_acknowledged
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.acknowledge_deprecation
|
41
|
+
@deprecation_acknowledged = true
|
42
|
+
end
|
27
43
|
|
28
44
|
def initialize(app, default_extention = '.html')
|
45
|
+
unless self.class.deprecation_acknowledged
|
46
|
+
warn "Rack::AcceptFormat is DEPRECATED and will be removed in rack-contrib 2.0.0"
|
47
|
+
warn "Please see this middleware's documentation for more info."
|
48
|
+
end
|
29
49
|
@ext = default_extention.to_s.strip
|
30
50
|
@ext = ".#{@ext}" unless @ext[0] == ?.
|
31
51
|
@app = app
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Rack
|
2
|
+
|
3
|
+
##
|
4
|
+
# This middleware is like Rack::ConditionalGet except that it does
|
5
|
+
# not have to go down the rack stack and build the resource to check
|
6
|
+
# the modification date or the ETag.
|
7
|
+
#
|
8
|
+
# Instead it makes the assumption that only non-reading requests can
|
9
|
+
# potentially change the content, meaning any request which is not
|
10
|
+
# GET or HEAD. Each time you make one of these request, the date is cached
|
11
|
+
# and any resource is considered identical until the next non-reading request.
|
12
|
+
#
|
13
|
+
# Basically you use it this way:
|
14
|
+
#
|
15
|
+
# ``` ruby
|
16
|
+
# use Rack::LazyConditionalGet
|
17
|
+
# ```
|
18
|
+
#
|
19
|
+
# Although if you have multiple instances, it is better to use something like
|
20
|
+
# memcached. An argument can be passed to give the cache object. By default
|
21
|
+
# it is just a Hash. But it can take other objects, including objects which
|
22
|
+
# respond to `:get` and `:set`. Here is how you would use it with Dalli.
|
23
|
+
#
|
24
|
+
# ``` Ruby
|
25
|
+
# dalli_client = Dalli::Client.new
|
26
|
+
# use Rack::LazyConditionalGet, dalli_client
|
27
|
+
# ```
|
28
|
+
#
|
29
|
+
# By default, the middleware only delegates to Rack::ConditionalGet to avoid
|
30
|
+
# any unwanted behaviour. You have to set a header to any resource which you
|
31
|
+
# want to be cached. And it will be cached until the next "potential update"
|
32
|
+
# of your site, that is whenever the next POST/PUT/PATCH/DELETE request
|
33
|
+
# is received.
|
34
|
+
#
|
35
|
+
# The header is `Rack-Lazy-Conditional-Get`. You have to set it to 'yes'
|
36
|
+
# if you want the middleware to set `Last-Modified` for you.
|
37
|
+
#
|
38
|
+
# Bear in mind that if you set `Last-Modified` as well, the middleware will
|
39
|
+
# not change it.
|
40
|
+
#
|
41
|
+
# Regarding the POST/PUT/PATCH/DELETE... requests, they will always reset your
|
42
|
+
# global modification date. But if you have one of these request and you
|
43
|
+
# know for sure that it does not modify the cached content, you can set the
|
44
|
+
# `Rack-Lazy-Conditional-Get` on response to `skip`. This will not update the
|
45
|
+
# global modification date.
|
46
|
+
|
47
|
+
class LazyConditionalGet
|
48
|
+
|
49
|
+
KEY = 'global_last_modified'.freeze
|
50
|
+
READ_METHODS = ['GET','HEAD']
|
51
|
+
|
52
|
+
def self.new(*)
|
53
|
+
# This code automatically uses `Rack::ConditionalGet` before
|
54
|
+
# our middleware. It is equivalent to:
|
55
|
+
#
|
56
|
+
# ``` ruby
|
57
|
+
# use Rack::ConditionalGet
|
58
|
+
# use Rack::LazyConditionalGet
|
59
|
+
# ```
|
60
|
+
::Rack::ConditionalGet.new(super)
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize app, cache={}
|
64
|
+
@app = app
|
65
|
+
@cache = cache
|
66
|
+
update_cache
|
67
|
+
end
|
68
|
+
|
69
|
+
def call env
|
70
|
+
if reading? env and fresh? env
|
71
|
+
return [304, {'Last-Modified' => env['HTTP_IF_MODIFIED_SINCE']}, []]
|
72
|
+
end
|
73
|
+
status, headers, body = @app.call env
|
74
|
+
update_cache unless (reading?(env) or skipping?(headers))
|
75
|
+
headers['Last-Modified'] = cached_value if stampable? headers
|
76
|
+
[status, headers, body]
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def fresh? env
|
82
|
+
env['HTTP_IF_MODIFIED_SINCE'] == cached_value
|
83
|
+
end
|
84
|
+
|
85
|
+
def reading? env
|
86
|
+
READ_METHODS.include?(env['REQUEST_METHOD'])
|
87
|
+
end
|
88
|
+
|
89
|
+
def skipping? headers
|
90
|
+
headers['Rack-Lazy-Conditional-Get'] == 'skip'
|
91
|
+
end
|
92
|
+
|
93
|
+
def stampable? headers
|
94
|
+
!headers.has_key?('Last-Modified') and headers['Rack-Lazy-Conditional-Get'] == 'yes'
|
95
|
+
end
|
96
|
+
|
97
|
+
def update_cache
|
98
|
+
stamp = Time.now.httpdate
|
99
|
+
if @cache.respond_to?(:set)
|
100
|
+
@cache.set(KEY,stamp)
|
101
|
+
else
|
102
|
+
@cache[KEY] = stamp
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def cached_value
|
107
|
+
@cache.respond_to?(:get) ? @cache.get(KEY) : @cache[KEY]
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
113
|
+
|
@@ -5,6 +5,12 @@ module Rack
|
|
5
5
|
# calltree profile of the request.
|
6
6
|
#
|
7
7
|
# Pass the :printer option to pick a different result format.
|
8
|
+
#
|
9
|
+
# You can cause every request to be run multiple times by passing the
|
10
|
+
# `:times` option to the `use Rack::Profiler` call. You can also run a
|
11
|
+
# given request multiple times, by setting the `profiler_runs` query
|
12
|
+
# parameter in the request URL.
|
13
|
+
#
|
8
14
|
class Profiler
|
9
15
|
MODES = %w(process_time wall_time cpu_time
|
10
16
|
allocations memory gc_runs gc_time)
|
@@ -53,8 +59,10 @@ module Rack
|
|
53
59
|
::RubyProf.measure_mode = ::RubyProf.const_get(mode.upcase)
|
54
60
|
|
55
61
|
GC.enable_stats if GC.respond_to?(:enable_stats)
|
62
|
+
request = Rack::Request.new(env.clone)
|
63
|
+
runs = (request.params['profiler_runs'] || @times).to_i
|
56
64
|
result = ::RubyProf.profile do
|
57
|
-
|
65
|
+
runs.times { @app.call(env) }
|
58
66
|
end
|
59
67
|
GC.disable_stats if GC.respond_to?(:disable_stats)
|
60
68
|
|
@@ -94,8 +94,6 @@ module Rack
|
|
94
94
|
# XSendFile on
|
95
95
|
|
96
96
|
class Sendfile
|
97
|
-
F = ::File
|
98
|
-
|
99
97
|
def initialize(app, variation=nil)
|
100
98
|
@app = app
|
101
99
|
@variation = variation
|
@@ -106,7 +104,7 @@ module Rack
|
|
106
104
|
if body.respond_to?(:to_path)
|
107
105
|
case type = variation(env)
|
108
106
|
when 'X-Accel-Redirect'
|
109
|
-
path =
|
107
|
+
path = ::File.expand_path(body.to_path)
|
110
108
|
if url = map_accel_path(env, path)
|
111
109
|
headers[type] = url
|
112
110
|
body = []
|
@@ -114,7 +112,7 @@ module Rack
|
|
114
112
|
env['rack.errors'] << "X-Accel-Mapping header missing"
|
115
113
|
end
|
116
114
|
when 'X-Sendfile', 'X-Lighttpd-Send-File'
|
117
|
-
path =
|
115
|
+
path = ::File.expand_path(body.to_path)
|
118
116
|
headers[type] = path
|
119
117
|
body = []
|
120
118
|
when '', nil
|
@@ -24,6 +24,12 @@ module Rack
|
|
24
24
|
#
|
25
25
|
# You can use Rack::Deflater along with Rack::StaticCache for further improvements in page loading time.
|
26
26
|
#
|
27
|
+
# If you'd like to use a non-standard version identifier in your URLs, you
|
28
|
+
# can set the regex to remove with the `:version_regex` option. If you
|
29
|
+
# want to capture something after the regex (such as file extensions), you
|
30
|
+
# should capture that as `\1`. All other captured subexpressions will be
|
31
|
+
# discarded. You may find the `?:` capture modifier helpful.
|
32
|
+
#
|
27
33
|
# Examples:
|
28
34
|
# use Rack::StaticCache, :urls => ["/images", "/css", "/js", "/documents*"], :root => "statics"
|
29
35
|
# will serve all requests beginning with /images, /css or /js from the
|
@@ -57,8 +63,10 @@ module Rack
|
|
57
63
|
root = options[:root] || Dir.pwd
|
58
64
|
@file_server = Rack::File.new(root)
|
59
65
|
@cache_duration = options[:duration] || 1
|
60
|
-
@versioning_enabled = true
|
61
|
-
@versioning_enabled
|
66
|
+
@versioning_enabled = options.fetch(:versioning, true)
|
67
|
+
if @versioning_enabled
|
68
|
+
@version_regex = options.fetch(:version_regex, /-[\d.]+([.][a-zA-Z][\w]+)?$/)
|
69
|
+
end
|
62
70
|
@duration_in_seconds = self.duration_in_seconds
|
63
71
|
@duration_in_words = self.duration_in_words
|
64
72
|
end
|
@@ -66,16 +74,18 @@ module Rack
|
|
66
74
|
def call(env)
|
67
75
|
path = env["PATH_INFO"]
|
68
76
|
url = @urls.detect{ |u| path.index(u) == 0 }
|
69
|
-
|
70
|
-
|
77
|
+
if url.nil?
|
78
|
+
@app.call(env)
|
79
|
+
else
|
80
|
+
if @versioning_enabled
|
81
|
+
path.sub!(@version_regex, '\1')
|
82
|
+
end
|
71
83
|
status, headers, body = @file_server.call(env)
|
72
84
|
if @no_cache[url].nil?
|
73
85
|
headers['Cache-Control'] ="max-age=#{@duration_in_seconds}, public"
|
74
86
|
headers['Expires'] = @duration_in_words
|
75
87
|
end
|
76
88
|
[status, headers, body]
|
77
|
-
else
|
78
|
-
@app.call(env)
|
79
89
|
end
|
80
90
|
end
|
81
91
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-contrib
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- rack-devel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -100,14 +100,14 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '5.
|
103
|
+
version: '5.6'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '5.
|
110
|
+
version: '5.6'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: minitest-hooks
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,6 +226,7 @@ files:
|
|
226
226
|
- lib/rack/contrib/garbagecollector.rb
|
227
227
|
- lib/rack/contrib/host_meta.rb
|
228
228
|
- lib/rack/contrib/jsonp.rb
|
229
|
+
- lib/rack/contrib/lazy_conditional_get.rb
|
229
230
|
- lib/rack/contrib/lighttpd_script_name_fix.rb
|
230
231
|
- lib/rack/contrib/locale.rb
|
231
232
|
- lib/rack/contrib/mailexceptions.rb
|