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.

Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +694 -0
  3. data/CONTRIBUTING.md +136 -0
  4. data/{COPYING → MIT-LICENSE} +4 -2
  5. data/README.rdoc +157 -163
  6. data/Rakefile +38 -32
  7. data/{SPEC → SPEC.rdoc} +41 -13
  8. data/bin/rackup +1 -0
  9. data/contrib/rack_logo.svg +164 -111
  10. data/example/lobster.ru +2 -0
  11. data/example/protectedlobster.rb +4 -2
  12. data/example/protectedlobster.ru +3 -1
  13. data/lib/rack/auth/abstract/handler.rb +3 -1
  14. data/lib/rack/auth/abstract/request.rb +6 -2
  15. data/lib/rack/auth/basic.rb +7 -4
  16. data/lib/rack/auth/digest/md5.rb +13 -11
  17. data/lib/rack/auth/digest/nonce.rb +6 -3
  18. data/lib/rack/auth/digest/params.rb +5 -4
  19. data/lib/rack/auth/digest/request.rb +6 -4
  20. data/lib/rack/body_proxy.rb +21 -15
  21. data/lib/rack/builder.rb +119 -26
  22. data/lib/rack/cascade.rb +28 -12
  23. data/lib/rack/chunked.rb +70 -22
  24. data/lib/rack/common_logger.rb +80 -0
  25. data/lib/rack/{conditionalget.rb → conditional_get.rb} +20 -16
  26. data/lib/rack/config.rb +2 -0
  27. data/lib/rack/content_length.rb +9 -8
  28. data/lib/rack/content_type.rb +5 -4
  29. data/lib/rack/core_ext/regexp.rb +14 -0
  30. data/lib/rack/deflater.rb +60 -70
  31. data/lib/rack/directory.rb +117 -85
  32. data/lib/rack/etag.rb +9 -7
  33. data/lib/rack/events.rb +153 -0
  34. data/lib/rack/file.rb +4 -149
  35. data/lib/rack/files.rb +218 -0
  36. data/lib/rack/handler/cgi.rb +17 -19
  37. data/lib/rack/handler/fastcgi.rb +17 -18
  38. data/lib/rack/handler/lsws.rb +14 -14
  39. data/lib/rack/handler/scgi.rb +22 -21
  40. data/lib/rack/handler/thin.rb +6 -3
  41. data/lib/rack/handler/webrick.rb +39 -32
  42. data/lib/rack/handler.rb +9 -26
  43. data/lib/rack/head.rb +16 -18
  44. data/lib/rack/lint.rb +110 -64
  45. data/lib/rack/lobster.rb +10 -10
  46. data/lib/rack/lock.rb +17 -11
  47. data/lib/rack/logger.rb +4 -2
  48. data/lib/rack/media_type.rb +43 -0
  49. data/lib/rack/{methodoverride.rb → method_override.rb} +10 -8
  50. data/lib/rack/mime.rb +27 -6
  51. data/lib/rack/mock.rb +124 -65
  52. data/lib/rack/multipart/generator.rb +20 -16
  53. data/lib/rack/multipart/parser.rb +273 -162
  54. data/lib/rack/multipart/uploaded_file.rb +15 -8
  55. data/lib/rack/multipart.rb +39 -8
  56. data/lib/rack/{nulllogger.rb → null_logger.rb} +3 -1
  57. data/lib/rack/query_parser.rb +217 -0
  58. data/lib/rack/recursive.rb +11 -9
  59. data/lib/rack/reloader.rb +8 -4
  60. data/lib/rack/request.rb +553 -305
  61. data/lib/rack/response.rb +244 -88
  62. data/lib/rack/rewindable_input.rb +5 -15
  63. data/lib/rack/runtime.rb +12 -18
  64. data/lib/rack/sendfile.rb +17 -15
  65. data/lib/rack/server.rb +125 -47
  66. data/lib/rack/session/abstract/id.rb +141 -93
  67. data/lib/rack/session/cookie.rb +35 -29
  68. data/lib/rack/session/memcache.rb +4 -93
  69. data/lib/rack/session/pool.rb +13 -11
  70. data/lib/rack/show_exceptions.rb +390 -0
  71. data/lib/rack/{showstatus.rb → show_status.rb} +12 -12
  72. data/lib/rack/static.rb +48 -11
  73. data/lib/rack/tempfile_reaper.rb +3 -3
  74. data/lib/rack/urlmap.rb +26 -19
  75. data/lib/rack/utils.rb +212 -294
  76. data/lib/rack/version.rb +29 -0
  77. data/lib/rack.rb +76 -33
  78. data/rack.gemspec +43 -30
  79. metadata +65 -187
  80. data/HISTORY.md +0 -375
  81. data/KNOWN-ISSUES +0 -44
  82. data/lib/rack/backports/uri/common_18.rb +0 -56
  83. data/lib/rack/backports/uri/common_192.rb +0 -52
  84. data/lib/rack/backports/uri/common_193.rb +0 -29
  85. data/lib/rack/commonlogger.rb +0 -72
  86. data/lib/rack/handler/evented_mongrel.rb +0 -8
  87. data/lib/rack/handler/mongrel.rb +0 -106
  88. data/lib/rack/handler/swiftiplied_mongrel.rb +0 -8
  89. data/lib/rack/showexceptions.rb +0 -387
  90. data/lib/rack/utils/okjson.rb +0 -600
  91. data/test/builder/anything.rb +0 -5
  92. data/test/builder/comment.ru +0 -4
  93. data/test/builder/end.ru +0 -5
  94. data/test/builder/line.ru +0 -1
  95. data/test/builder/options.ru +0 -2
  96. data/test/cgi/assets/folder/test.js +0 -1
  97. data/test/cgi/assets/fonts/font.eot +0 -1
  98. data/test/cgi/assets/images/image.png +0 -1
  99. data/test/cgi/assets/index.html +0 -1
  100. data/test/cgi/assets/javascripts/app.js +0 -1
  101. data/test/cgi/assets/stylesheets/app.css +0 -1
  102. data/test/cgi/lighttpd.conf +0 -26
  103. data/test/cgi/rackup_stub.rb +0 -6
  104. data/test/cgi/sample_rackup.ru +0 -5
  105. data/test/cgi/test +0 -9
  106. data/test/cgi/test+directory/test+file +0 -1
  107. data/test/cgi/test.fcgi +0 -8
  108. data/test/cgi/test.ru +0 -5
  109. data/test/gemloader.rb +0 -10
  110. data/test/multipart/bad_robots +0 -259
  111. data/test/multipart/binary +0 -0
  112. data/test/multipart/content_type_and_no_filename +0 -6
  113. data/test/multipart/empty +0 -10
  114. data/test/multipart/fail_16384_nofile +0 -814
  115. data/test/multipart/file1.txt +0 -1
  116. data/test/multipart/filename_and_modification_param +0 -7
  117. data/test/multipart/filename_and_no_name +0 -6
  118. data/test/multipart/filename_with_escaped_quotes +0 -6
  119. data/test/multipart/filename_with_escaped_quotes_and_modification_param +0 -7
  120. data/test/multipart/filename_with_null_byte +0 -7
  121. data/test/multipart/filename_with_percent_escaped_quotes +0 -6
  122. data/test/multipart/filename_with_unescaped_percentages +0 -6
  123. data/test/multipart/filename_with_unescaped_percentages2 +0 -6
  124. data/test/multipart/filename_with_unescaped_percentages3 +0 -6
  125. data/test/multipart/filename_with_unescaped_quotes +0 -6
  126. data/test/multipart/ie +0 -6
  127. data/test/multipart/invalid_character +0 -6
  128. data/test/multipart/mixed_files +0 -21
  129. data/test/multipart/nested +0 -10
  130. data/test/multipart/none +0 -9
  131. data/test/multipart/semicolon +0 -6
  132. data/test/multipart/text +0 -15
  133. data/test/multipart/three_files_three_fields +0 -31
  134. data/test/multipart/webkit +0 -32
  135. data/test/rackup/config.ru +0 -31
  136. data/test/registering_handler/rack/handler/registering_myself.rb +0 -8
  137. data/test/spec_auth_basic.rb +0 -81
  138. data/test/spec_auth_digest.rb +0 -259
  139. data/test/spec_body_proxy.rb +0 -85
  140. data/test/spec_builder.rb +0 -223
  141. data/test/spec_cascade.rb +0 -61
  142. data/test/spec_cgi.rb +0 -102
  143. data/test/spec_chunked.rb +0 -101
  144. data/test/spec_commonlogger.rb +0 -93
  145. data/test/spec_conditionalget.rb +0 -102
  146. data/test/spec_config.rb +0 -22
  147. data/test/spec_content_length.rb +0 -85
  148. data/test/spec_content_type.rb +0 -45
  149. data/test/spec_deflater.rb +0 -339
  150. data/test/spec_directory.rb +0 -88
  151. data/test/spec_etag.rb +0 -107
  152. data/test/spec_fastcgi.rb +0 -107
  153. data/test/spec_file.rb +0 -221
  154. data/test/spec_handler.rb +0 -72
  155. data/test/spec_head.rb +0 -45
  156. data/test/spec_lint.rb +0 -550
  157. data/test/spec_lobster.rb +0 -58
  158. data/test/spec_lock.rb +0 -164
  159. data/test/spec_logger.rb +0 -23
  160. data/test/spec_methodoverride.rb +0 -111
  161. data/test/spec_mime.rb +0 -51
  162. data/test/spec_mock.rb +0 -297
  163. data/test/spec_mongrel.rb +0 -182
  164. data/test/spec_multipart.rb +0 -600
  165. data/test/spec_nulllogger.rb +0 -20
  166. data/test/spec_recursive.rb +0 -72
  167. data/test/spec_request.rb +0 -1232
  168. data/test/spec_response.rb +0 -407
  169. data/test/spec_rewindable_input.rb +0 -118
  170. data/test/spec_runtime.rb +0 -49
  171. data/test/spec_sendfile.rb +0 -130
  172. data/test/spec_server.rb +0 -167
  173. data/test/spec_session_abstract_id.rb +0 -53
  174. data/test/spec_session_cookie.rb +0 -410
  175. data/test/spec_session_memcache.rb +0 -358
  176. data/test/spec_session_persisted_secure_secure_session_hash.rb +0 -73
  177. data/test/spec_session_pool.rb +0 -246
  178. data/test/spec_showexceptions.rb +0 -98
  179. data/test/spec_showstatus.rb +0 -103
  180. data/test/spec_static.rb +0 -145
  181. data/test/spec_tempfile_reaper.rb +0 -63
  182. data/test/spec_thin.rb +0 -91
  183. data/test/spec_urlmap.rb +0 -236
  184. data/test/spec_utils.rb +0 -647
  185. data/test/spec_version.rb +0 -17
  186. data/test/spec_webrick.rb +0 -184
  187. data/test/static/another/index.html +0 -1
  188. data/test/static/index.html +0 -1
  189. data/test/testrequest.rb +0 -78
  190. data/test/unregistered_handler/rack/handler/unregistered.rb +0 -7
  191. 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::File
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.insert(0, [:all, {'Cache-Control' => options[:cache_control]}]) if options[:cache_control]
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
- @file_server = Rack::File.new(root)
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) || @index && 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
- env["PATH_INFO"] = (path =~ /\/$/ ? path + @index : @urls[path]) if overwrite_file_path(path)
114
- path = env["PATH_INFO"]
115
- response = @file_server.call(env)
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
- path =~ /\.(?:ttf|otf|eot|woff2|woff|svg)\z/
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
- path =~ /\.(#{rule.join('|')})\z/
177
+ /\.(#{rule.join('|')})\z/.match?(path)
141
178
  when Regexp
142
- path =~ rule
179
+ rule.match?(path)
143
180
  else
144
181
  false
145
182
  end
@@ -1,4 +1,4 @@
1
- require 'rack/body_proxy'
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['rack.tempfiles'] ||= []
14
+ env[RACK_TEMPFILES] ||= []
15
15
  status, headers, body = @app.call(env)
16
16
  body_proxy = BodyProxy.new(body) do
17
- env['rack.tempfiles'].each { |f| f.close! } unless env['rack.tempfiles'].nil?
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 = env[PATH_INFO]
45
- script_name = env['SCRIPT_NAME']
46
- hHost = env['HTTP_HOST']
47
- sName = env['SERVER_NAME']
48
- sPort = env['SERVER_PORT']
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?(hHost, host) \
52
- || casecmp?(sName, host) \
53
- || (!host && (casecmp?(hHost, sName) ||
54
- casecmp?(hHost, sName+':'+sPort)))
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['SCRIPT_NAME'] = (script_name + location)
64
- env['PATH_INFO'] = rest
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['PATH_INFO'] = path
73
- env['SCRIPT_NAME'] = script_name
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
-