rack 1.6.13 → 2.2.3
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/CHANGELOG.md +694 -0
- data/CONTRIBUTING.md +136 -0
- data/{COPYING → MIT-LICENSE} +4 -2
- data/README.rdoc +157 -163
- data/Rakefile +38 -32
- data/{SPEC → SPEC.rdoc} +41 -13
- data/bin/rackup +1 -0
- data/contrib/rack_logo.svg +164 -111
- data/example/lobster.ru +2 -0
- data/example/protectedlobster.rb +4 -2
- data/example/protectedlobster.ru +3 -1
- data/lib/rack/auth/abstract/handler.rb +3 -1
- data/lib/rack/auth/abstract/request.rb +6 -2
- data/lib/rack/auth/basic.rb +7 -4
- data/lib/rack/auth/digest/md5.rb +13 -11
- data/lib/rack/auth/digest/nonce.rb +6 -3
- data/lib/rack/auth/digest/params.rb +5 -4
- data/lib/rack/auth/digest/request.rb +6 -4
- data/lib/rack/body_proxy.rb +21 -15
- data/lib/rack/builder.rb +119 -26
- data/lib/rack/cascade.rb +28 -12
- data/lib/rack/chunked.rb +70 -22
- data/lib/rack/common_logger.rb +80 -0
- data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -16
- data/lib/rack/config.rb +2 -0
- data/lib/rack/content_length.rb +9 -8
- data/lib/rack/content_type.rb +5 -4
- data/lib/rack/core_ext/regexp.rb +14 -0
- data/lib/rack/deflater.rb +60 -70
- data/lib/rack/directory.rb +117 -85
- data/lib/rack/etag.rb +9 -7
- data/lib/rack/events.rb +153 -0
- data/lib/rack/file.rb +4 -149
- data/lib/rack/files.rb +218 -0
- data/lib/rack/handler/cgi.rb +17 -19
- data/lib/rack/handler/fastcgi.rb +17 -18
- data/lib/rack/handler/lsws.rb +14 -14
- data/lib/rack/handler/scgi.rb +22 -21
- data/lib/rack/handler/thin.rb +6 -3
- data/lib/rack/handler/webrick.rb +39 -32
- data/lib/rack/handler.rb +9 -26
- data/lib/rack/head.rb +16 -18
- data/lib/rack/lint.rb +110 -64
- data/lib/rack/lobster.rb +10 -10
- data/lib/rack/lock.rb +17 -11
- data/lib/rack/logger.rb +4 -2
- data/lib/rack/media_type.rb +43 -0
- data/lib/rack/{methodoverride.rb → method_override.rb} +10 -8
- data/lib/rack/mime.rb +27 -6
- data/lib/rack/mock.rb +124 -65
- data/lib/rack/multipart/generator.rb +20 -16
- data/lib/rack/multipart/parser.rb +273 -162
- data/lib/rack/multipart/uploaded_file.rb +15 -8
- data/lib/rack/multipart.rb +39 -8
- data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
- data/lib/rack/query_parser.rb +217 -0
- data/lib/rack/recursive.rb +11 -9
- data/lib/rack/reloader.rb +8 -4
- data/lib/rack/request.rb +553 -305
- data/lib/rack/response.rb +244 -88
- data/lib/rack/rewindable_input.rb +5 -15
- data/lib/rack/runtime.rb +12 -18
- data/lib/rack/sendfile.rb +17 -15
- data/lib/rack/server.rb +125 -47
- data/lib/rack/session/abstract/id.rb +141 -93
- data/lib/rack/session/cookie.rb +35 -29
- data/lib/rack/session/memcache.rb +4 -93
- data/lib/rack/session/pool.rb +13 -11
- data/lib/rack/show_exceptions.rb +390 -0
- data/lib/rack/{showstatus.rb → show_status.rb} +12 -12
- data/lib/rack/static.rb +48 -11
- data/lib/rack/tempfile_reaper.rb +3 -3
- data/lib/rack/urlmap.rb +26 -19
- data/lib/rack/utils.rb +212 -294
- data/lib/rack/version.rb +29 -0
- data/lib/rack.rb +76 -33
- data/rack.gemspec +43 -30
- metadata +65 -187
- data/HISTORY.md +0 -375
- data/KNOWN-ISSUES +0 -44
- data/lib/rack/backports/uri/common_18.rb +0 -56
- data/lib/rack/backports/uri/common_192.rb +0 -52
- data/lib/rack/backports/uri/common_193.rb +0 -29
- data/lib/rack/commonlogger.rb +0 -72
- data/lib/rack/handler/evented_mongrel.rb +0 -8
- data/lib/rack/handler/mongrel.rb +0 -106
- data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/lib/rack/showexceptions.rb +0 -387
- data/lib/rack/utils/okjson.rb +0 -600
- 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 -8
- data/test/cgi/test.ru +0 -5
- data/test/gemloader.rb +0 -10
- 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_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_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/semicolon +0 -6
- data/test/multipart/text +0 -15
- data/test/multipart/three_files_three_fields +0 -31
- 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 -81
- data/test/spec_auth_digest.rb +0 -259
- data/test/spec_body_proxy.rb +0 -85
- data/test/spec_builder.rb +0 -223
- data/test/spec_cascade.rb +0 -61
- data/test/spec_cgi.rb +0 -102
- data/test/spec_chunked.rb +0 -101
- data/test/spec_commonlogger.rb +0 -93
- data/test/spec_conditionalget.rb +0 -102
- data/test/spec_config.rb +0 -22
- data/test/spec_content_length.rb +0 -85
- data/test/spec_content_type.rb +0 -45
- data/test/spec_deflater.rb +0 -339
- data/test/spec_directory.rb +0 -88
- data/test/spec_etag.rb +0 -107
- data/test/spec_fastcgi.rb +0 -107
- data/test/spec_file.rb +0 -221
- data/test/spec_handler.rb +0 -72
- data/test/spec_head.rb +0 -45
- data/test/spec_lint.rb +0 -550
- data/test/spec_lobster.rb +0 -58
- data/test/spec_lock.rb +0 -164
- data/test/spec_logger.rb +0 -23
- data/test/spec_methodoverride.rb +0 -111
- data/test/spec_mime.rb +0 -51
- data/test/spec_mock.rb +0 -297
- data/test/spec_mongrel.rb +0 -182
- data/test/spec_multipart.rb +0 -600
- data/test/spec_nulllogger.rb +0 -20
- data/test/spec_recursive.rb +0 -72
- data/test/spec_request.rb +0 -1232
- data/test/spec_response.rb +0 -407
- data/test/spec_rewindable_input.rb +0 -118
- data/test/spec_runtime.rb +0 -49
- data/test/spec_sendfile.rb +0 -130
- data/test/spec_server.rb +0 -167
- data/test/spec_session_abstract_id.rb +0 -53
- data/test/spec_session_cookie.rb +0 -410
- data/test/spec_session_memcache.rb +0 -358
- data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
- data/test/spec_session_pool.rb +0 -246
- data/test/spec_showexceptions.rb +0 -98
- data/test/spec_showstatus.rb +0 -103
- data/test/spec_static.rb +0 -145
- data/test/spec_tempfile_reaper.rb +0 -63
- data/test/spec_thin.rb +0 -91
- data/test/spec_urlmap.rb +0 -236
- data/test/spec_utils.rb +0 -647
- data/test/spec_version.rb +0 -17
- data/test/spec_webrick.rb +0 -184
- data/test/static/another/index.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/static.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Rack
|
2
4
|
|
3
5
|
# The Rack::Static middleware intercepts requests for static files
|
4
6
|
# (javascript files, images, stylesheets, etc) based on the url prefixes or
|
5
|
-
# route mappings passed in the options, and serves them using a Rack::
|
7
|
+
# route mappings passed in the options, and serves them using a Rack::Files
|
6
8
|
# object. This allows a Rack stack to serve both static and dynamic content.
|
7
9
|
#
|
8
10
|
# Examples:
|
@@ -12,6 +14,11 @@ module Rack
|
|
12
14
|
#
|
13
15
|
# use Rack::Static, :urls => ["/media"]
|
14
16
|
#
|
17
|
+
# Same as previous, but instead of returning 404 for missing files under
|
18
|
+
# /media, call the next middleware:
|
19
|
+
#
|
20
|
+
# use Rack::Static, :urls => ["/media"], :cascade => true
|
21
|
+
#
|
15
22
|
# Serve all requests beginning with /css or /images from the folder "public"
|
16
23
|
# in the current directory (ie public/css/* and public/images/*):
|
17
24
|
#
|
@@ -79,23 +86,30 @@ module Rack
|
|
79
86
|
# ]
|
80
87
|
#
|
81
88
|
class Static
|
89
|
+
(require_relative 'core_ext/regexp'; using ::Rack::RegexpExtensions) if RUBY_VERSION < '2.4'
|
82
90
|
|
83
|
-
def initialize(app, options={})
|
91
|
+
def initialize(app, options = {})
|
84
92
|
@app = app
|
85
93
|
@urls = options[:urls] || ["/favicon.ico"]
|
86
94
|
@index = options[:index]
|
95
|
+
@gzip = options[:gzip]
|
96
|
+
@cascade = options[:cascade]
|
87
97
|
root = options[:root] || Dir.pwd
|
88
98
|
|
89
99
|
# HTTP Headers
|
90
100
|
@header_rules = options[:header_rules] || []
|
91
101
|
# Allow for legacy :cache_control option while prioritizing global header_rules setting
|
92
|
-
@header_rules.
|
102
|
+
@header_rules.unshift([:all, { CACHE_CONTROL => options[:cache_control] }]) if options[:cache_control]
|
103
|
+
|
104
|
+
@file_server = Rack::Files.new(root)
|
105
|
+
end
|
93
106
|
|
94
|
-
|
107
|
+
def add_index_root?(path)
|
108
|
+
@index && route_file(path) && path.end_with?('/')
|
95
109
|
end
|
96
110
|
|
97
111
|
def overwrite_file_path(path)
|
98
|
-
@urls.kind_of?(Hash) && @urls.key?(path) ||
|
112
|
+
@urls.kind_of?(Hash) && @urls.key?(path) || add_index_root?(path)
|
99
113
|
end
|
100
114
|
|
101
115
|
def route_file(path)
|
@@ -110,9 +124,32 @@ module Rack
|
|
110
124
|
path = env[PATH_INFO]
|
111
125
|
|
112
126
|
if can_serve(path)
|
113
|
-
|
114
|
-
|
115
|
-
|
127
|
+
if overwrite_file_path(path)
|
128
|
+
env[PATH_INFO] = (add_index_root?(path) ? path + @index : @urls[path])
|
129
|
+
elsif @gzip && env['HTTP_ACCEPT_ENCODING'] && /\bgzip\b/.match?(env['HTTP_ACCEPT_ENCODING'])
|
130
|
+
path = env[PATH_INFO]
|
131
|
+
env[PATH_INFO] += '.gz'
|
132
|
+
response = @file_server.call(env)
|
133
|
+
env[PATH_INFO] = path
|
134
|
+
|
135
|
+
if response[0] == 404
|
136
|
+
response = nil
|
137
|
+
elsif response[0] == 304
|
138
|
+
# Do nothing, leave headers as is
|
139
|
+
else
|
140
|
+
if mime_type = Mime.mime_type(::File.extname(path), 'text/plain')
|
141
|
+
response[1][CONTENT_TYPE] = mime_type
|
142
|
+
end
|
143
|
+
response[1]['Content-Encoding'] = 'gzip'
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
path = env[PATH_INFO]
|
148
|
+
response ||= @file_server.call(env)
|
149
|
+
|
150
|
+
if @cascade && response[0] == 404
|
151
|
+
return @app.call(env)
|
152
|
+
end
|
116
153
|
|
117
154
|
headers = response[1]
|
118
155
|
applicable_rules(path).each do |rule, new_headers|
|
@@ -132,14 +169,14 @@ module Rack
|
|
132
169
|
when :all
|
133
170
|
true
|
134
171
|
when :fonts
|
135
|
-
|
172
|
+
/\.(?:ttf|otf|eot|woff2|woff|svg)\z/.match?(path)
|
136
173
|
when String
|
137
174
|
path = ::Rack::Utils.unescape(path)
|
138
175
|
path.start_with?(rule) || path.start_with?('/' + rule)
|
139
176
|
when Array
|
140
|
-
|
177
|
+
/\.(#{rule.join('|')})\z/.match?(path)
|
141
178
|
when Regexp
|
142
|
-
path
|
179
|
+
rule.match?(path)
|
143
180
|
else
|
144
181
|
false
|
145
182
|
end
|
data/lib/rack/tempfile_reaper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Rack
|
4
4
|
|
@@ -11,10 +11,10 @@ module Rack
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
|
-
env[
|
14
|
+
env[RACK_TEMPFILES] ||= []
|
15
15
|
status, headers, body = @app.call(env)
|
16
16
|
body_proxy = BodyProxy.new(body) do
|
17
|
-
env[
|
17
|
+
env[RACK_TEMPFILES].each(&:close!) unless env[RACK_TEMPFILES].nil?
|
18
18
|
end
|
19
19
|
[status, headers, body_proxy]
|
20
20
|
end
|
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
|
@@ -12,17 +16,16 @@ module Rack
|
|
12
16
|
# first, since they are most specific.
|
13
17
|
|
14
18
|
class URLMap
|
15
|
-
NEGATIVE_INFINITY = -1.0 / 0.0
|
16
|
-
INFINITY = 1.0 / 0.0
|
17
|
-
|
18
19
|
def initialize(map = {})
|
19
20
|
remap(map)
|
20
21
|
end
|
21
22
|
|
22
23
|
def remap(map)
|
24
|
+
@known_hosts = Set[]
|
23
25
|
@mapping = map.map { |location, app|
|
24
26
|
if location =~ %r{\Ahttps?://(.*?)(/.*)}
|
25
27
|
host, location = $1, $2
|
28
|
+
@known_hosts << host
|
26
29
|
else
|
27
30
|
host = nil
|
28
31
|
end
|
@@ -36,22 +39,27 @@ module Rack
|
|
36
39
|
|
37
40
|
[host, location, match, app]
|
38
41
|
}.sort_by do |(host, location, _, _)|
|
39
|
-
[host ? -host.size : INFINITY, -location.size]
|
42
|
+
[host ? -host.size : Float::INFINITY, -location.size]
|
40
43
|
end
|
41
44
|
end
|
42
45
|
|
43
46
|
def call(env)
|
44
|
-
path
|
45
|
-
script_name = env[
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
path = env[PATH_INFO]
|
48
|
+
script_name = env[SCRIPT_NAME]
|
49
|
+
http_host = env[HTTP_HOST]
|
50
|
+
server_name = env[SERVER_NAME]
|
51
|
+
server_port = env[SERVER_PORT]
|
52
|
+
|
53
|
+
is_same_server = casecmp?(http_host, server_name) ||
|
54
|
+
casecmp?(http_host, "#{server_name}:#{server_port}")
|
55
|
+
|
56
|
+
is_host_known = @known_hosts.include? http_host
|
49
57
|
|
50
58
|
@mapping.each do |host, location, match, app|
|
51
|
-
unless casecmp?(
|
52
|
-
|| casecmp?(
|
53
|
-
|| (!host &&
|
54
|
-
|
59
|
+
unless casecmp?(http_host, host) \
|
60
|
+
|| casecmp?(server_name, host) \
|
61
|
+
|| (!host && is_same_server) \
|
62
|
+
|| (!host && !is_host_known) # If we don't have a matching host, default to the first without a specified host
|
55
63
|
next
|
56
64
|
end
|
57
65
|
|
@@ -60,17 +68,17 @@ module Rack
|
|
60
68
|
rest = m[1]
|
61
69
|
next unless !rest || rest.empty? || rest[0] == ?/
|
62
70
|
|
63
|
-
env[
|
64
|
-
env[
|
71
|
+
env[SCRIPT_NAME] = (script_name + location)
|
72
|
+
env[PATH_INFO] = rest
|
65
73
|
|
66
74
|
return app.call(env)
|
67
75
|
end
|
68
76
|
|
69
|
-
[404, {CONTENT_TYPE => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]]
|
77
|
+
[404, { CONTENT_TYPE => "text/plain", "X-Cascade" => "pass" }, ["Not Found: #{path}"]]
|
70
78
|
|
71
79
|
ensure
|
72
|
-
env[
|
73
|
-
env[
|
80
|
+
env[PATH_INFO] = path
|
81
|
+
env[SCRIPT_NAME] = script_name
|
74
82
|
end
|
75
83
|
|
76
84
|
private
|
@@ -87,4 +95,3 @@ module Rack
|
|
87
95
|
end
|
88
96
|
end
|
89
97
|
end
|
90
|
-
|