rack 2.0.4 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/{HISTORY.md → CHANGELOG.md} +220 -155
- data/{COPYING → MIT-LICENSE} +4 -2
- data/README.rdoc +77 -119
- data/Rakefile +25 -18
- data/SPEC +3 -4
- data/bin/rackup +1 -0
- data/example/lobster.ru +2 -0
- data/example/protectedlobster.rb +3 -1
- data/example/protectedlobster.ru +2 -0
- data/lib/rack.rb +63 -60
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +2 -0
- data/lib/rack/auth/basic.rb +4 -1
- data/lib/rack/auth/digest/md5.rb +9 -7
- data/lib/rack/auth/digest/nonce.rb +6 -3
- data/lib/rack/auth/digest/params.rb +4 -2
- data/lib/rack/auth/digest/request.rb +2 -0
- data/lib/rack/body_proxy.rb +3 -6
- data/lib/rack/builder.rb +38 -15
- data/lib/rack/cascade.rb +6 -5
- data/lib/rack/chunked.rb +29 -6
- data/lib/rack/common_logger.rb +9 -8
- data/lib/rack/conditional_get.rb +3 -1
- data/lib/rack/config.rb +2 -0
- data/lib/rack/content_length.rb +3 -1
- data/lib/rack/content_type.rb +3 -1
- data/lib/rack/core_ext/regexp.rb +14 -0
- data/lib/rack/deflater.rb +28 -17
- data/lib/rack/directory.rb +17 -14
- data/lib/rack/etag.rb +3 -1
- data/lib/rack/events.rb +5 -3
- data/lib/rack/file.rb +5 -173
- data/lib/rack/files.rb +178 -0
- data/lib/rack/handler.rb +7 -2
- data/lib/rack/handler/cgi.rb +3 -1
- data/lib/rack/handler/fastcgi.rb +4 -2
- data/lib/rack/handler/lsws.rb +3 -1
- data/lib/rack/handler/scgi.rb +9 -6
- data/lib/rack/handler/thin.rb +3 -1
- data/lib/rack/handler/webrick.rb +4 -2
- data/lib/rack/head.rb +2 -0
- data/lib/rack/lint.rb +14 -11
- data/lib/rack/lobster.rb +7 -5
- data/lib/rack/lock.rb +2 -0
- data/lib/rack/logger.rb +2 -0
- data/lib/rack/media_type.rb +10 -5
- data/lib/rack/method_override.rb +9 -3
- data/lib/rack/mime.rb +9 -1
- data/lib/rack/mock.rb +74 -15
- data/lib/rack/multipart.rb +5 -3
- data/lib/rack/multipart/generator.rb +6 -7
- data/lib/rack/multipart/parser.rb +54 -51
- data/lib/rack/multipart/uploaded_file.rb +2 -0
- data/lib/rack/null_logger.rb +2 -0
- data/lib/rack/query_parser.rb +51 -25
- data/lib/rack/recursive.rb +7 -5
- data/lib/rack/reloader.rb +10 -4
- data/lib/rack/request.rb +89 -23
- data/lib/rack/response.rb +71 -31
- data/lib/rack/rewindable_input.rb +4 -2
- data/lib/rack/runtime.rb +4 -2
- data/lib/rack/sendfile.rb +15 -8
- data/lib/rack/server.rb +88 -16
- data/lib/rack/session/abstract/id.rb +104 -21
- data/lib/rack/session/cookie.rb +21 -11
- data/lib/rack/session/memcache.rb +4 -87
- data/lib/rack/session/pool.rb +17 -8
- data/lib/rack/show_exceptions.rb +16 -10
- data/lib/rack/show_status.rb +4 -2
- data/lib/rack/static.rb +15 -10
- data/lib/rack/tempfile_reaper.rb +2 -0
- data/lib/rack/urlmap.rb +11 -2
- data/lib/rack/utils.rb +55 -70
- data/rack.gemspec +19 -9
- metadata +32 -173
- data/test/builder/an_underscore_app.rb +0 -5
- data/test/builder/anything.rb +0 -5
- data/test/builder/comment.ru +0 -4
- data/test/builder/end.ru +0 -5
- data/test/builder/line.ru +0 -1
- data/test/builder/options.ru +0 -2
- data/test/cgi/assets/folder/test.js +0 -1
- data/test/cgi/assets/fonts/font.eot +0 -1
- data/test/cgi/assets/images/image.png +0 -1
- data/test/cgi/assets/index.html +0 -1
- data/test/cgi/assets/javascripts/app.js +0 -1
- data/test/cgi/assets/stylesheets/app.css +0 -1
- data/test/cgi/lighttpd.conf +0 -26
- data/test/cgi/rackup_stub.rb +0 -6
- data/test/cgi/sample_rackup.ru +0 -5
- data/test/cgi/test +0 -9
- data/test/cgi/test+directory/test+file +0 -1
- data/test/cgi/test.fcgi +0 -9
- data/test/cgi/test.gz +0 -0
- data/test/cgi/test.ru +0 -5
- data/test/gemloader.rb +0 -10
- data/test/helper.rb +0 -34
- data/test/multipart/bad_robots +0 -259
- data/test/multipart/binary +0 -0
- data/test/multipart/content_type_and_no_filename +0 -6
- data/test/multipart/empty +0 -10
- data/test/multipart/fail_16384_nofile +0 -814
- data/test/multipart/file1.txt +0 -1
- data/test/multipart/filename_and_modification_param +0 -7
- data/test/multipart/filename_and_no_name +0 -6
- data/test/multipart/filename_with_encoded_words +0 -7
- data/test/multipart/filename_with_escaped_quotes +0 -6
- data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
- data/test/multipart/filename_with_null_byte +0 -7
- data/test/multipart/filename_with_percent_escaped_quotes +0 -6
- data/test/multipart/filename_with_single_quote +0 -7
- data/test/multipart/filename_with_unescaped_percentages +0 -6
- data/test/multipart/filename_with_unescaped_percentages2 +0 -6
- data/test/multipart/filename_with_unescaped_percentages3 +0 -6
- data/test/multipart/filename_with_unescaped_quotes +0 -6
- data/test/multipart/ie +0 -6
- data/test/multipart/invalid_character +0 -6
- data/test/multipart/mixed_files +0 -21
- data/test/multipart/nested +0 -10
- data/test/multipart/none +0 -9
- data/test/multipart/quoted +0 -15
- data/test/multipart/rack-logo.png +0 -0
- data/test/multipart/semicolon +0 -6
- data/test/multipart/text +0 -15
- data/test/multipart/three_files_three_fields +0 -31
- data/test/multipart/unity3d_wwwform +0 -11
- data/test/multipart/webkit +0 -32
- data/test/rackup/config.ru +0 -31
- data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
- data/test/spec_auth_basic.rb +0 -89
- data/test/spec_auth_digest.rb +0 -260
- data/test/spec_body_proxy.rb +0 -85
- data/test/spec_builder.rb +0 -233
- data/test/spec_cascade.rb +0 -63
- data/test/spec_cgi.rb +0 -84
- data/test/spec_chunked.rb +0 -103
- data/test/spec_common_logger.rb +0 -95
- data/test/spec_conditional_get.rb +0 -103
- data/test/spec_config.rb +0 -23
- data/test/spec_content_length.rb +0 -86
- data/test/spec_content_type.rb +0 -46
- data/test/spec_deflater.rb +0 -375
- data/test/spec_directory.rb +0 -148
- data/test/spec_etag.rb +0 -108
- data/test/spec_events.rb +0 -133
- data/test/spec_fastcgi.rb +0 -85
- data/test/spec_file.rb +0 -264
- data/test/spec_handler.rb +0 -57
- data/test/spec_head.rb +0 -46
- data/test/spec_lint.rb +0 -515
- data/test/spec_lobster.rb +0 -59
- data/test/spec_lock.rb +0 -204
- data/test/spec_logger.rb +0 -24
- data/test/spec_media_type.rb +0 -42
- data/test/spec_method_override.rb +0 -96
- data/test/spec_mime.rb +0 -51
- data/test/spec_mock.rb +0 -359
- data/test/spec_multipart.rb +0 -722
- data/test/spec_null_logger.rb +0 -21
- data/test/spec_recursive.rb +0 -75
- data/test/spec_request.rb +0 -1393
- data/test/spec_response.rb +0 -510
- data/test/spec_rewindable_input.rb +0 -128
- data/test/spec_runtime.rb +0 -50
- data/test/spec_sendfile.rb +0 -125
- data/test/spec_server.rb +0 -193
- data/test/spec_session_abstract_id.rb +0 -31
- data/test/spec_session_abstract_session_hash.rb +0 -45
- data/test/spec_session_cookie.rb +0 -442
- data/test/spec_session_memcache.rb +0 -320
- data/test/spec_session_pool.rb +0 -210
- data/test/spec_show_exceptions.rb +0 -80
- data/test/spec_show_status.rb +0 -104
- data/test/spec_static.rb +0 -184
- data/test/spec_tempfile_reaper.rb +0 -64
- data/test/spec_thin.rb +0 -96
- data/test/spec_urlmap.rb +0 -237
- data/test/spec_utils.rb +0 -742
- data/test/spec_version.rb +0 -11
- data/test/spec_webrick.rb +0 -206
- data/test/static/another/index.html +0 -1
- data/test/static/foo.html +0 -1
- data/test/static/index.html +0 -1
- data/test/testrequest.rb +0 -78
- data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
- data/test/unregistered_handler/rack/handler/unregistered_long_one.rb +0 -7
data/lib/rack/session/cookie.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'openssl'
|
2
4
|
require 'zlib'
|
3
5
|
require 'rack/request'
|
4
6
|
require 'rack/response'
|
5
7
|
require 'rack/session/abstract/id'
|
6
8
|
require 'json'
|
9
|
+
require 'base64'
|
7
10
|
|
8
11
|
module Rack
|
9
12
|
|
@@ -45,15 +48,15 @@ module Rack
|
|
45
48
|
# })
|
46
49
|
#
|
47
50
|
|
48
|
-
class Cookie < Abstract::
|
51
|
+
class Cookie < Abstract::PersistedSecure
|
49
52
|
# Encode session cookies as Base64
|
50
53
|
class Base64
|
51
54
|
def encode(str)
|
52
|
-
|
55
|
+
::Base64.strict_encode64(str)
|
53
56
|
end
|
54
57
|
|
55
58
|
def decode(str)
|
56
|
-
|
59
|
+
::Base64.decode64(str)
|
57
60
|
end
|
58
61
|
|
59
62
|
# Encode session cookies as Marshaled Base64 data
|
@@ -103,7 +106,7 @@ module Rack
|
|
103
106
|
|
104
107
|
attr_reader :coder
|
105
108
|
|
106
|
-
def initialize(app, options={})
|
109
|
+
def initialize(app, options = {})
|
107
110
|
@secrets = options.values_at(:secret, :old_secret).compact
|
108
111
|
@hmac = options.fetch(:hmac, OpenSSL::Digest::SHA1)
|
109
112
|
|
@@ -116,8 +119,8 @@ module Rack
|
|
116
119
|
|
117
120
|
Called from: #{caller[0]}.
|
118
121
|
MSG
|
119
|
-
@coder
|
120
|
-
super(app, options.merge!(:
|
122
|
+
@coder = options[:coder] ||= Base64::Marshal.new
|
123
|
+
super(app, options.merge!(cookie_only: true))
|
121
124
|
end
|
122
125
|
|
123
126
|
private
|
@@ -137,9 +140,7 @@ module Rack
|
|
137
140
|
session_data = request.cookies[@key]
|
138
141
|
|
139
142
|
if @secrets.size > 0 && session_data
|
140
|
-
|
141
|
-
digest.reverse! if digest
|
142
|
-
session_data.reverse! if session_data
|
143
|
+
session_data, _, digest = session_data.rpartition('--')
|
143
144
|
session_data = nil unless digest_match?(session_data, digest)
|
144
145
|
end
|
145
146
|
|
@@ -147,12 +148,21 @@ module Rack
|
|
147
148
|
end
|
148
149
|
end
|
149
150
|
|
150
|
-
def persistent_session_id!(data, sid=nil)
|
151
|
+
def persistent_session_id!(data, sid = nil)
|
151
152
|
data ||= {}
|
152
153
|
data["session_id"] ||= sid || generate_sid
|
153
154
|
data
|
154
155
|
end
|
155
156
|
|
157
|
+
class SessionId < DelegateClass(Session::SessionId)
|
158
|
+
attr_reader :cookie_value
|
159
|
+
|
160
|
+
def initialize(session_id, cookie_value)
|
161
|
+
super(session_id)
|
162
|
+
@cookie_value = cookie_value
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
156
166
|
def write_session(req, session_id, session, options)
|
157
167
|
session = session.merge("session_id" => session_id)
|
158
168
|
session_data = coder.encode(session)
|
@@ -165,7 +175,7 @@ module Rack
|
|
165
175
|
req.get_header(RACK_ERRORS).puts("Warning! Rack::Session::Cookie data size exceeds 4K.")
|
166
176
|
nil
|
167
177
|
else
|
168
|
-
session_data
|
178
|
+
SessionId.new(session_id, session_data)
|
169
179
|
end
|
170
180
|
end
|
171
181
|
|
@@ -1,93 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rack/session/
|
4
|
-
require 'memcache'
|
3
|
+
require 'rack/session/dalli'
|
5
4
|
|
6
5
|
module Rack
|
7
6
|
module Session
|
8
|
-
|
9
|
-
|
10
|
-
# maintained in the cookie.
|
11
|
-
# You may treat Session::Memcache as you would Session::Pool with the
|
12
|
-
# following caveats.
|
13
|
-
#
|
14
|
-
# * Setting :expire_after to 0 would note to the Memcache server to hang
|
15
|
-
# onto the session data until it would drop it according to it's own
|
16
|
-
# specifications. However, the cookie sent to the client would expire
|
17
|
-
# immediately.
|
18
|
-
#
|
19
|
-
# Note that memcache does drop data before it may be listed to expire. For
|
20
|
-
# a full description of behaviour, please see memcache's documentation.
|
21
|
-
|
22
|
-
class Memcache < Abstract::ID
|
23
|
-
attr_reader :mutex, :pool
|
24
|
-
|
25
|
-
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge \
|
26
|
-
:namespace => 'rack:session',
|
27
|
-
:memcache_server => 'localhost:11211'
|
28
|
-
|
29
|
-
def initialize(app, options={})
|
30
|
-
super
|
31
|
-
|
32
|
-
@mutex = Mutex.new
|
33
|
-
mserv = @default_options[:memcache_server]
|
34
|
-
mopts = @default_options.reject{|k,v| !MemCache::DEFAULT_OPTIONS.include? k }
|
35
|
-
|
36
|
-
@pool = options[:cache] || MemCache.new(mserv, mopts)
|
37
|
-
unless @pool.active? and @pool.servers.any?(&:alive?)
|
38
|
-
raise 'No memcache servers'
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def generate_sid
|
43
|
-
loop do
|
44
|
-
sid = super
|
45
|
-
break sid unless @pool.get(sid, true)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def get_session(env, sid)
|
50
|
-
with_lock(env) do
|
51
|
-
unless sid and session = @pool.get(sid)
|
52
|
-
sid, session = generate_sid, {}
|
53
|
-
unless /^STORED/ =~ @pool.add(sid, session)
|
54
|
-
raise "Session collision on '#{sid.inspect}'"
|
55
|
-
end
|
56
|
-
end
|
57
|
-
[sid, session]
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def set_session(env, session_id, new_session, options)
|
62
|
-
expiry = options[:expire_after]
|
63
|
-
expiry = expiry.nil? ? 0 : expiry + 1
|
64
|
-
|
65
|
-
with_lock(env) do
|
66
|
-
@pool.set session_id, new_session, expiry
|
67
|
-
session_id
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def destroy_session(env, session_id, options)
|
72
|
-
with_lock(env) do
|
73
|
-
@pool.delete(session_id)
|
74
|
-
generate_sid unless options[:drop]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def with_lock(env)
|
79
|
-
@mutex.lock if env[RACK_MULTITHREAD]
|
80
|
-
yield
|
81
|
-
rescue MemCache::MemCacheError, Errno::ECONNREFUSED
|
82
|
-
if $VERBOSE
|
83
|
-
warn "#{self} is unable to find memcached server."
|
84
|
-
warn $!.inspect
|
85
|
-
end
|
86
|
-
raise
|
87
|
-
ensure
|
88
|
-
@mutex.unlock if @mutex.locked?
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
7
|
+
warn "Rack::Session::Memcache is deprecated, please use Rack::Session::Dalli from 'dalli' gem instead."
|
8
|
+
Memcache = Dalli
|
92
9
|
end
|
93
10
|
end
|
data/lib/rack/session/pool.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# AUTHOR: blink <blinketje@gmail.com>; blink#ruby-lang@irc.freenode.net
|
2
4
|
# THANKS:
|
3
5
|
# apeiros, for session id generation, expiry setup, and threadiness
|
@@ -24,11 +26,11 @@ module Rack
|
|
24
26
|
# )
|
25
27
|
# Rack::Handler::WEBrick.run sessioned
|
26
28
|
|
27
|
-
class Pool < Abstract::
|
29
|
+
class Pool < Abstract::PersistedSecure
|
28
30
|
attr_reader :mutex, :pool
|
29
|
-
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge :
|
31
|
+
DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge drop: false
|
30
32
|
|
31
|
-
def initialize(app, options={})
|
33
|
+
def initialize(app, options = {})
|
32
34
|
super
|
33
35
|
@pool = Hash.new
|
34
36
|
@mutex = Mutex.new
|
@@ -37,15 +39,15 @@ module Rack
|
|
37
39
|
def generate_sid
|
38
40
|
loop do
|
39
41
|
sid = super
|
40
|
-
break sid unless @pool.key? sid
|
42
|
+
break sid unless @pool.key? sid.private_id
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
46
|
def find_session(req, sid)
|
45
47
|
with_lock(req) do
|
46
|
-
unless sid and session =
|
48
|
+
unless sid and session = get_session_with_fallback(sid)
|
47
49
|
sid, session = generate_sid, {}
|
48
|
-
@pool.store sid, session
|
50
|
+
@pool.store sid.private_id, session
|
49
51
|
end
|
50
52
|
[sid, session]
|
51
53
|
end
|
@@ -53,14 +55,15 @@ module Rack
|
|
53
55
|
|
54
56
|
def write_session(req, session_id, new_session, options)
|
55
57
|
with_lock(req) do
|
56
|
-
@pool.store session_id, new_session
|
58
|
+
@pool.store session_id.private_id, new_session
|
57
59
|
session_id
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
63
|
def delete_session(req, session_id, options)
|
62
64
|
with_lock(req) do
|
63
|
-
@pool.delete(session_id)
|
65
|
+
@pool.delete(session_id.public_id)
|
66
|
+
@pool.delete(session_id.private_id)
|
64
67
|
generate_sid unless options[:drop]
|
65
68
|
end
|
66
69
|
end
|
@@ -71,6 +74,12 @@ module Rack
|
|
71
74
|
ensure
|
72
75
|
@mutex.unlock if @mutex.locked?
|
73
76
|
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def get_session_with_fallback(sid)
|
81
|
+
@pool[sid.private_id] || @pool[sid.public_id]
|
82
|
+
end
|
74
83
|
end
|
75
84
|
end
|
76
85
|
end
|
data/lib/rack/show_exceptions.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'ostruct'
|
2
4
|
require 'erb'
|
3
5
|
require 'rack/request'
|
@@ -46,7 +48,7 @@ module Rack
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def prefers_plaintext?(env)
|
49
|
-
!accepts_html(env)
|
51
|
+
!accepts_html?(env)
|
50
52
|
end
|
51
53
|
|
52
54
|
def accepts_html?(env)
|
@@ -55,7 +57,7 @@ module Rack
|
|
55
57
|
private :accepts_html?
|
56
58
|
|
57
59
|
def dump_exception(exception)
|
58
|
-
string = "#{exception.class}: #{exception.message}\n"
|
60
|
+
string = "#{exception.class}: #{exception.message}\n".dup
|
59
61
|
string << exception.backtrace.map { |l| "\t#{l}" }.join("\n")
|
60
62
|
string
|
61
63
|
end
|
@@ -77,13 +79,13 @@ module Rack
|
|
77
79
|
frame.function = $4
|
78
80
|
|
79
81
|
begin
|
80
|
-
lineno = frame.lineno-1
|
82
|
+
lineno = frame.lineno - 1
|
81
83
|
lines = ::File.readlines(frame.filename)
|
82
|
-
frame.pre_context_lineno = [lineno-CONTEXT, 0].max
|
84
|
+
frame.pre_context_lineno = [lineno - CONTEXT, 0].max
|
83
85
|
frame.pre_context = lines[frame.pre_context_lineno...lineno]
|
84
86
|
frame.context_line = lines[lineno].chomp
|
85
|
-
frame.post_context_lineno = [lineno+CONTEXT, lines.size].min
|
86
|
-
frame.post_context = lines[lineno+1..frame.post_context_lineno]
|
87
|
+
frame.post_context_lineno = [lineno + CONTEXT, lines.size].min
|
88
|
+
frame.post_context = lines[lineno + 1..frame.post_context_lineno]
|
87
89
|
rescue
|
88
90
|
end
|
89
91
|
|
@@ -93,7 +95,11 @@ module Rack
|
|
93
95
|
end
|
94
96
|
}.compact
|
95
97
|
|
96
|
-
|
98
|
+
template.result(binding)
|
99
|
+
end
|
100
|
+
|
101
|
+
def template
|
102
|
+
TEMPLATE
|
97
103
|
end
|
98
104
|
|
99
105
|
def h(obj) # :nodoc:
|
@@ -107,8 +113,8 @@ module Rack
|
|
107
113
|
|
108
114
|
# :stopdoc:
|
109
115
|
|
110
|
-
# adapted from Django <djangoproject.com>
|
111
|
-
# Copyright (c)
|
116
|
+
# adapted from Django <www.djangoproject.com>
|
117
|
+
# Copyright (c) Django Software Foundation and individual contributors.
|
112
118
|
# Used under the modified BSD license:
|
113
119
|
# http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
|
114
120
|
TEMPLATE = ERB.new(<<-'HTML'.gsub(/^ /, ''))
|
@@ -363,7 +369,7 @@ module Rack
|
|
363
369
|
<% env.sort_by { |k, v| k.to_s }.each { |key, val| %>
|
364
370
|
<tr>
|
365
371
|
<td><%=h key %></td>
|
366
|
-
<td class="code"><div><%=h val %></div></td>
|
372
|
+
<td class="code"><div><%=h val.inspect %></div></td>
|
367
373
|
</tr>
|
368
374
|
<% } %>
|
369
375
|
</tbody>
|
data/lib/rack/show_status.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'erb'
|
2
4
|
require 'rack/request'
|
3
5
|
require 'rack/utils'
|
@@ -52,8 +54,8 @@ module Rack
|
|
52
54
|
|
53
55
|
# :stopdoc:
|
54
56
|
|
55
|
-
# adapted from Django <djangoproject.com>
|
56
|
-
# Copyright (c)
|
57
|
+
# adapted from Django <www.djangoproject.com>
|
58
|
+
# Copyright (c) Django Software Foundation and individual contributors.
|
57
59
|
# Used under the modified BSD license:
|
58
60
|
# http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
|
59
61
|
TEMPLATE = <<'HTML'
|
data/lib/rack/static.rb
CHANGED
@@ -1,11 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rack/files"
|
2
4
|
require "rack/utils"
|
3
5
|
|
6
|
+
require_relative 'core_ext/regexp'
|
7
|
+
|
4
8
|
module Rack
|
5
9
|
|
6
10
|
# The Rack::Static middleware intercepts requests for static files
|
7
11
|
# (javascript files, images, stylesheets, etc) based on the url prefixes or
|
8
|
-
# route mappings passed in the options, and serves them using a Rack::
|
12
|
+
# route mappings passed in the options, and serves them using a Rack::Files
|
9
13
|
# object. This allows a Rack stack to serve both static and dynamic content.
|
10
14
|
#
|
11
15
|
# Examples:
|
@@ -82,8 +86,9 @@ module Rack
|
|
82
86
|
# ]
|
83
87
|
#
|
84
88
|
class Static
|
89
|
+
using ::Rack::RegexpExtensions
|
85
90
|
|
86
|
-
def initialize(app, options={})
|
91
|
+
def initialize(app, options = {})
|
87
92
|
@app = app
|
88
93
|
@urls = options[:urls] || ["/favicon.ico"]
|
89
94
|
@index = options[:index]
|
@@ -93,13 +98,13 @@ module Rack
|
|
93
98
|
# HTTP Headers
|
94
99
|
@header_rules = options[:header_rules] || []
|
95
100
|
# Allow for legacy :cache_control option while prioritizing global header_rules setting
|
96
|
-
@header_rules.unshift([:all, {CACHE_CONTROL => options[:cache_control]}]) if options[:cache_control]
|
101
|
+
@header_rules.unshift([:all, { CACHE_CONTROL => options[:cache_control] }]) if options[:cache_control]
|
97
102
|
|
98
|
-
@file_server = Rack::
|
103
|
+
@file_server = Rack::Files.new(root)
|
99
104
|
end
|
100
105
|
|
101
106
|
def add_index_root?(path)
|
102
|
-
@index && path
|
107
|
+
@index && route_file(path) && path.end_with?('/')
|
103
108
|
end
|
104
109
|
|
105
110
|
def overwrite_file_path(path)
|
@@ -120,7 +125,7 @@ module Rack
|
|
120
125
|
if can_serve(path)
|
121
126
|
if overwrite_file_path(path)
|
122
127
|
env[PATH_INFO] = (add_index_root?(path) ? path + @index : @urls[path])
|
123
|
-
elsif @gzip && env['HTTP_ACCEPT_ENCODING']
|
128
|
+
elsif @gzip && env['HTTP_ACCEPT_ENCODING'] && /\bgzip\b/.match?(env['HTTP_ACCEPT_ENCODING'])
|
124
129
|
path = env[PATH_INFO]
|
125
130
|
env[PATH_INFO] += '.gz'
|
126
131
|
response = @file_server.call(env)
|
@@ -157,14 +162,14 @@ module Rack
|
|
157
162
|
when :all
|
158
163
|
true
|
159
164
|
when :fonts
|
160
|
-
|
165
|
+
/\.(?:ttf|otf|eot|woff2|woff|svg)\z/.match?(path)
|
161
166
|
when String
|
162
167
|
path = ::Rack::Utils.unescape(path)
|
163
168
|
path.start_with?(rule) || path.start_with?('/' + rule)
|
164
169
|
when Array
|
165
|
-
|
170
|
+
/\.(#{rule.join('|')})\z/.match?(path)
|
166
171
|
when Regexp
|
167
|
-
path
|
172
|
+
rule.match?(path)
|
168
173
|
else
|
169
174
|
false
|
170
175
|
end
|
data/lib/rack/tempfile_reaper.rb
CHANGED
data/lib/rack/urlmap.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
1
5
|
module Rack
|
2
6
|
# Rack::URLMap takes a hash mapping urls or paths to apps, and
|
3
7
|
# dispatches accordingly. Support for HTTP/1.1 host names exists if
|
@@ -20,9 +24,11 @@ module Rack
|
|
20
24
|
end
|
21
25
|
|
22
26
|
def remap(map)
|
27
|
+
@known_hosts = Set[]
|
23
28
|
@mapping = map.map { |location, app|
|
24
29
|
if location =~ %r{\Ahttps?://(.*?)(/.*)}
|
25
30
|
host, location = $1, $2
|
31
|
+
@known_hosts << host
|
26
32
|
else
|
27
33
|
host = nil
|
28
34
|
end
|
@@ -50,10 +56,13 @@ module Rack
|
|
50
56
|
is_same_server = casecmp?(http_host, server_name) ||
|
51
57
|
casecmp?(http_host, "#{server_name}:#{server_port}")
|
52
58
|
|
59
|
+
is_host_known = @known_hosts.include? http_host
|
60
|
+
|
53
61
|
@mapping.each do |host, location, match, app|
|
54
62
|
unless casecmp?(http_host, host) \
|
55
63
|
|| casecmp?(server_name, host) \
|
56
|
-
|| (!host && is_same_server)
|
64
|
+
|| (!host && is_same_server) \
|
65
|
+
|| (!host && !is_host_known) # If we don't have a matching host, default to the first without a specified host
|
57
66
|
next
|
58
67
|
end
|
59
68
|
|
@@ -68,7 +77,7 @@ module Rack
|
|
68
77
|
return app.call(env)
|
69
78
|
end
|
70
79
|
|
71
|
-
[404, {CONTENT_TYPE => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]]
|
80
|
+
[404, { CONTENT_TYPE => "text/plain", "X-Cascade" => "pass" }, ["Not Found: #{path}"]]
|
72
81
|
|
73
82
|
ensure
|
74
83
|
env[PATH_INFO] = path
|