actionpack 5.0.7.2 → 5.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (128) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +189 -1002
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/abstract_controller.rb +3 -3
  6. data/lib/abstract_controller/base.rb +10 -12
  7. data/lib/abstract_controller/caching.rb +6 -3
  8. data/lib/abstract_controller/caching/fragments.rb +1 -1
  9. data/lib/abstract_controller/callbacks.rb +2 -43
  10. data/lib/abstract_controller/collector.rb +2 -2
  11. data/lib/abstract_controller/helpers.rb +19 -19
  12. data/lib/abstract_controller/rendering.rb +9 -11
  13. data/lib/abstract_controller/translation.rb +3 -3
  14. data/lib/action_controller.rb +15 -13
  15. data/lib/action_controller/api.rb +3 -3
  16. data/lib/action_controller/base.rb +7 -12
  17. data/lib/action_controller/caching.rb +1 -1
  18. data/lib/action_controller/log_subscriber.rb +2 -2
  19. data/lib/action_controller/metal.rb +34 -43
  20. data/lib/action_controller/metal/conditional_get.rb +10 -9
  21. data/lib/action_controller/metal/data_streaming.rb +8 -9
  22. data/lib/action_controller/metal/etag_with_flash.rb +16 -0
  23. data/lib/action_controller/metal/etag_with_template_digest.rb +15 -15
  24. data/lib/action_controller/metal/exceptions.rb +4 -14
  25. data/lib/action_controller/metal/flash.rb +1 -1
  26. data/lib/action_controller/metal/force_ssl.rb +6 -6
  27. data/lib/action_controller/metal/head.rb +13 -19
  28. data/lib/action_controller/metal/helpers.rb +6 -6
  29. data/lib/action_controller/metal/http_authentication.rb +22 -23
  30. data/lib/action_controller/metal/implicit_render.rb +2 -5
  31. data/lib/action_controller/metal/instrumentation.rb +14 -14
  32. data/lib/action_controller/metal/live.rb +15 -16
  33. data/lib/action_controller/metal/mime_responds.rb +3 -3
  34. data/lib/action_controller/metal/parameter_encoding.rb +49 -0
  35. data/lib/action_controller/metal/params_wrapper.rb +32 -32
  36. data/lib/action_controller/metal/redirecting.rb +8 -24
  37. data/lib/action_controller/metal/renderers.rb +2 -3
  38. data/lib/action_controller/metal/rendering.rb +50 -60
  39. data/lib/action_controller/metal/request_forgery_protection.rb +51 -49
  40. data/lib/action_controller/metal/rescue.rb +1 -1
  41. data/lib/action_controller/metal/streaming.rb +4 -4
  42. data/lib/action_controller/metal/strong_parameters.rb +117 -250
  43. data/lib/action_controller/metal/testing.rb +1 -1
  44. data/lib/action_controller/metal/url_for.rb +4 -4
  45. data/lib/action_controller/railtie.rb +9 -13
  46. data/lib/action_controller/renderer.rb +17 -16
  47. data/lib/action_controller/test_case.rb +75 -148
  48. data/lib/action_dispatch.rb +20 -19
  49. data/lib/action_dispatch/http/cache.rb +9 -10
  50. data/lib/action_dispatch/http/filter_parameters.rb +8 -8
  51. data/lib/action_dispatch/http/filter_redirect.rb +2 -4
  52. data/lib/action_dispatch/http/headers.rb +10 -10
  53. data/lib/action_dispatch/http/mime_negotiation.rb +17 -22
  54. data/lib/action_dispatch/http/mime_type.rb +27 -52
  55. data/lib/action_dispatch/http/parameter_filter.rb +8 -6
  56. data/lib/action_dispatch/http/parameters.rb +40 -17
  57. data/lib/action_dispatch/http/request.rb +38 -34
  58. data/lib/action_dispatch/http/response.rb +16 -16
  59. data/lib/action_dispatch/http/upload.rb +6 -10
  60. data/lib/action_dispatch/http/url.rb +48 -74
  61. data/lib/action_dispatch/journey.rb +5 -5
  62. data/lib/action_dispatch/journey/formatter.rb +8 -4
  63. data/lib/action_dispatch/journey/gtg/builder.rb +5 -5
  64. data/lib/action_dispatch/journey/gtg/simulator.rb +1 -1
  65. data/lib/action_dispatch/journey/gtg/transition_table.rb +15 -15
  66. data/lib/action_dispatch/journey/nfa/builder.rb +3 -3
  67. data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
  68. data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
  69. data/lib/action_dispatch/journey/nfa/transition_table.rb +2 -2
  70. data/lib/action_dispatch/journey/nodes/node.rb +5 -5
  71. data/lib/action_dispatch/journey/parser.rb +23 -24
  72. data/lib/action_dispatch/journey/parser.y +3 -2
  73. data/lib/action_dispatch/journey/parser_extras.rb +2 -2
  74. data/lib/action_dispatch/journey/path/pattern.rb +10 -3
  75. data/lib/action_dispatch/journey/route.rb +19 -12
  76. data/lib/action_dispatch/journey/router.rb +19 -12
  77. data/lib/action_dispatch/journey/router/utils.rb +9 -9
  78. data/lib/action_dispatch/journey/scanner.rb +17 -15
  79. data/lib/action_dispatch/journey/visitors.rb +23 -23
  80. data/lib/action_dispatch/middleware/callbacks.rb +0 -12
  81. data/lib/action_dispatch/middleware/cookies.rb +39 -39
  82. data/lib/action_dispatch/middleware/debug_exceptions.rb +126 -112
  83. data/lib/action_dispatch/middleware/debug_locks.rb +8 -8
  84. data/lib/action_dispatch/middleware/exception_wrapper.rb +55 -55
  85. data/lib/action_dispatch/middleware/executor.rb +1 -1
  86. data/lib/action_dispatch/middleware/flash.rb +17 -16
  87. data/lib/action_dispatch/middleware/public_exceptions.rb +20 -20
  88. data/lib/action_dispatch/middleware/reloader.rb +3 -47
  89. data/lib/action_dispatch/middleware/remote_ip.rb +6 -8
  90. data/lib/action_dispatch/middleware/request_id.rb +6 -5
  91. data/lib/action_dispatch/middleware/session/abstract_store.rb +14 -26
  92. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  93. data/lib/action_dispatch/middleware/session/cookie_store.rb +35 -35
  94. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +2 -2
  95. data/lib/action_dispatch/middleware/show_exceptions.rb +19 -19
  96. data/lib/action_dispatch/middleware/ssl.rb +9 -27
  97. data/lib/action_dispatch/middleware/stack.rb +7 -26
  98. data/lib/action_dispatch/middleware/static.rb +13 -24
  99. data/lib/action_dispatch/railtie.rb +9 -11
  100. data/lib/action_dispatch/request/session.rb +22 -22
  101. data/lib/action_dispatch/request/utils.rb +11 -2
  102. data/lib/action_dispatch/routing.rb +8 -6
  103. data/lib/action_dispatch/routing/inspector.rb +37 -37
  104. data/lib/action_dispatch/routing/mapper.rb +296 -203
  105. data/lib/action_dispatch/routing/polymorphic_routes.rb +160 -134
  106. data/lib/action_dispatch/routing/redirection.rb +27 -22
  107. data/lib/action_dispatch/routing/route_set.rb +206 -92
  108. data/lib/action_dispatch/routing/routes_proxy.rb +2 -2
  109. data/lib/action_dispatch/routing/url_for.rb +14 -12
  110. data/lib/action_dispatch/system_test_case.rb +119 -0
  111. data/lib/action_dispatch/system_testing/browser.rb +28 -0
  112. data/lib/action_dispatch/system_testing/driver.rb +18 -0
  113. data/lib/action_dispatch/system_testing/server.rb +32 -0
  114. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +61 -0
  115. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +20 -0
  116. data/lib/action_dispatch/testing/assertion_response.rb +6 -6
  117. data/lib/action_dispatch/testing/assertions.rb +4 -4
  118. data/lib/action_dispatch/testing/assertions/response.rb +8 -3
  119. data/lib/action_dispatch/testing/assertions/routing.rb +11 -11
  120. data/lib/action_dispatch/testing/integration.rb +47 -138
  121. data/lib/action_dispatch/testing/test_process.rb +2 -2
  122. data/lib/action_dispatch/testing/test_request.rb +16 -16
  123. data/lib/action_dispatch/testing/test_response.rb +1 -1
  124. data/lib/action_pack.rb +2 -2
  125. data/lib/action_pack/gem_version.rb +3 -3
  126. data/lib/action_pack/version.rb +1 -1
  127. metadata +20 -12
  128. data/lib/action_dispatch/middleware/params_parser.rb +0 -46
@@ -1,34 +1,23 @@
1
- require 'rack/utils'
2
- require 'rack/request'
3
- require 'rack/session/abstract/id'
4
- require 'action_dispatch/middleware/cookies'
5
- require 'action_dispatch/request/session'
1
+ require "rack/utils"
2
+ require "rack/request"
3
+ require "rack/session/abstract/id"
4
+ require "action_dispatch/middleware/cookies"
5
+ require "action_dispatch/request/session"
6
6
 
7
7
  module ActionDispatch
8
8
  module Session
9
9
  class SessionRestoreError < StandardError #:nodoc:
10
-
11
- def initialize(const_error = nil)
12
- if const_error
13
- ActiveSupport::Deprecation.warn("Passing #original_exception is deprecated and has no effect. " \
14
- "Exceptions will automatically capture the original exception.", caller)
15
- end
16
-
17
- super("Session contains objects whose class definition isn't available.\n" +
18
- "Remember to require the classes for all objects kept in the session.\n" +
10
+ def initialize
11
+ super("Session contains objects whose class definition isn't available.\n" \
12
+ "Remember to require the classes for all objects kept in the session.\n" \
19
13
  "(Original exception: #{$!.message} [#{$!.class}])\n")
20
14
  set_backtrace $!.backtrace
21
15
  end
22
-
23
- def original_exception
24
- ActiveSupport::Deprecation.warn("#original_exception is deprecated. Use #cause instead.", caller)
25
- cause
26
- end
27
16
  end
28
17
 
29
18
  module Compatibility
30
19
  def initialize(app, options = {})
31
- options[:key] ||= '_session_id'
20
+ options[:key] ||= "_session_id"
32
21
  super
33
22
  end
34
23
 
@@ -38,14 +27,13 @@ module ActionDispatch
38
27
  sid
39
28
  end
40
29
 
41
- protected
30
+ private
42
31
 
43
- def initialize_sid
32
+ def initialize_sid # :doc:
44
33
  @default_options.delete(:sidbits)
45
34
  @default_options.delete(:secure_random)
46
35
  end
47
36
 
48
- private
49
37
  def make_request(env)
50
38
  ActionDispatch::Request.new env
51
39
  end
@@ -94,9 +82,9 @@ module ActionDispatch
94
82
 
95
83
  private
96
84
 
97
- def set_cookie(request, session_id, cookie)
98
- request.cookie_jar[key] = cookie
99
- end
85
+ def set_cookie(request, session_id, cookie)
86
+ request.cookie_jar[key] = cookie
87
+ end
100
88
  end
101
89
  end
102
90
  end
@@ -1,4 +1,4 @@
1
- require 'action_dispatch/middleware/session/abstract_store'
1
+ require "action_dispatch/middleware/session/abstract_store"
2
2
 
3
3
  module ActionDispatch
4
4
  module Session
@@ -19,7 +19,7 @@ module ActionDispatch
19
19
 
20
20
  # Get a session from the cache.
21
21
  def find_session(env, sid)
22
- unless sid and session = @cache.read(cache_key(sid))
22
+ unless sid && (session = @cache.read(cache_key(sid)))
23
23
  sid, session = generate_sid, {}
24
24
  end
25
25
  [sid, session]
@@ -29,7 +29,7 @@ module ActionDispatch
29
29
  def write_session(env, sid, session, options)
30
30
  key = cache_key(sid)
31
31
  if session
32
- @cache.write(key, session, :expires_in => options[:expire_after])
32
+ @cache.write(key, session, expires_in: options[:expire_after])
33
33
  else
34
34
  @cache.delete(key)
35
35
  end
@@ -1,6 +1,6 @@
1
- require 'active_support/core_ext/hash/keys'
2
- require 'action_dispatch/middleware/session/abstract_store'
3
- require 'rack/session/cookie'
1
+ require "active_support/core_ext/hash/keys"
2
+ require "action_dispatch/middleware/session/abstract_store"
3
+ require "rack/session/cookie"
4
4
 
5
5
  module ActionDispatch
6
6
  module Session
@@ -63,8 +63,8 @@ module ActionDispatch
63
63
  # Other useful options include <tt>:key</tt>, <tt>:secure</tt> and
64
64
  # <tt>:httponly</tt>.
65
65
  class CookieStore < AbstractStore
66
- def initialize(app, options={})
67
- super(app, options.merge!(:cookie_only => true))
66
+ def initialize(app, options = {})
67
+ super(app, options.merge!(cookie_only: true))
68
68
  end
69
69
 
70
70
  def delete_session(req, session_id, options)
@@ -84,46 +84,46 @@ module ActionDispatch
84
84
 
85
85
  private
86
86
 
87
- def extract_session_id(req)
88
- stale_session_check! do
89
- unpacked_cookie_data(req)["session_id"]
87
+ def extract_session_id(req)
88
+ stale_session_check! do
89
+ unpacked_cookie_data(req)["session_id"]
90
+ end
90
91
  end
91
- end
92
92
 
93
- def unpacked_cookie_data(req)
94
- req.fetch_header("action_dispatch.request.unsigned_session_cookie") do |k|
95
- v = stale_session_check! do
96
- if data = get_cookie(req)
97
- data.stringify_keys!
93
+ def unpacked_cookie_data(req)
94
+ req.fetch_header("action_dispatch.request.unsigned_session_cookie") do |k|
95
+ v = stale_session_check! do
96
+ if data = get_cookie(req)
97
+ data.stringify_keys!
98
+ end
99
+ data || {}
98
100
  end
99
- data || {}
101
+ req.set_header k, v
100
102
  end
101
- req.set_header k, v
102
103
  end
103
- end
104
104
 
105
- def persistent_session_id!(data, sid=nil)
106
- data ||= {}
107
- data["session_id"] ||= sid || generate_sid
108
- data
109
- end
105
+ def persistent_session_id!(data, sid = nil)
106
+ data ||= {}
107
+ data["session_id"] ||= sid || generate_sid
108
+ data
109
+ end
110
110
 
111
- def write_session(req, sid, session_data, options)
112
- session_data["session_id"] = sid
113
- session_data
114
- end
111
+ def write_session(req, sid, session_data, options)
112
+ session_data["session_id"] = sid
113
+ session_data
114
+ end
115
115
 
116
- def set_cookie(request, session_id, cookie)
117
- cookie_jar(request)[@key] = cookie
118
- end
116
+ def set_cookie(request, session_id, cookie)
117
+ cookie_jar(request)[@key] = cookie
118
+ end
119
119
 
120
- def get_cookie(req)
121
- cookie_jar(req)[@key]
122
- end
120
+ def get_cookie(req)
121
+ cookie_jar(req)[@key]
122
+ end
123
123
 
124
- def cookie_jar(request)
125
- request.cookie_jar.signed_or_encrypted
126
- end
124
+ def cookie_jar(request)
125
+ request.cookie_jar.signed_or_encrypted
126
+ end
127
127
  end
128
128
  end
129
129
  end
@@ -1,6 +1,6 @@
1
- require 'action_dispatch/middleware/session/abstract_store'
1
+ require "action_dispatch/middleware/session/abstract_store"
2
2
  begin
3
- require 'rack/session/dalli'
3
+ require "rack/session/dalli"
4
4
  rescue LoadError => e
5
5
  $stderr.puts "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install"
6
6
  raise e
@@ -1,5 +1,5 @@
1
- require 'action_dispatch/http/request'
2
- require 'action_dispatch/middleware/exception_wrapper'
1
+ require "action_dispatch/http/request"
2
+ require "action_dispatch/middleware/exception_wrapper"
3
3
 
4
4
  module ActionDispatch
5
5
  # This middleware rescues any exception returned by the application
@@ -15,7 +15,7 @@ module ActionDispatch
15
15
  # If any exception happens inside the exceptions app, this middleware
16
16
  # catches the exceptions and returns a FAILSAFE_RESPONSE.
17
17
  class ShowExceptions
18
- FAILSAFE_RESPONSE = [500, { 'Content-Type' => 'text/plain' },
18
+ FAILSAFE_RESPONSE = [500, { "Content-Type" => "text/plain" },
19
19
  ["500 Internal Server Error\n" \
20
20
  "If you are the administrator of this website, then please read this web " \
21
21
  "application's log file and/or the web server's log file to find out what " \
@@ -39,22 +39,22 @@ module ActionDispatch
39
39
 
40
40
  private
41
41
 
42
- def render_exception(request, exception)
43
- backtrace_cleaner = request.get_header 'action_dispatch.backtrace_cleaner'
44
- wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)
45
- status = wrapper.status_code
46
- request.set_header "action_dispatch.exception", wrapper.exception
47
- request.set_header "action_dispatch.original_path", request.path_info
48
- request.path_info = "/#{status}"
49
- response = @exceptions_app.call(request.env)
50
- response[1]['X-Cascade'] == 'pass' ? pass_response(status) : response
51
- rescue Exception => failsafe_error
52
- $stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}"
53
- FAILSAFE_RESPONSE
54
- end
42
+ def render_exception(request, exception)
43
+ backtrace_cleaner = request.get_header "action_dispatch.backtrace_cleaner"
44
+ wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)
45
+ status = wrapper.status_code
46
+ request.set_header "action_dispatch.exception", wrapper.exception
47
+ request.set_header "action_dispatch.original_path", request.path_info
48
+ request.path_info = "/#{status}"
49
+ response = @exceptions_app.call(request.env)
50
+ response[1]["X-Cascade"] == "pass" ? pass_response(status) : response
51
+ rescue Exception => failsafe_error
52
+ $stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}"
53
+ FAILSAFE_RESPONSE
54
+ end
55
55
 
56
- def pass_response(status)
57
- [status, {"Content-Type" => "text/html; charset=#{Response.default_charset}", "Content-Length" => "0"}, []]
58
- end
56
+ def pass_response(status)
57
+ [status, { "Content-Type" => "text/html; charset=#{Response.default_charset}", "Content-Length" => "0" }, []]
58
+ end
59
59
  end
60
60
  end
@@ -23,7 +23,7 @@ module ActionDispatch
23
23
  # `180.days` (recommended).
24
24
  # * `subdomains`: Set to `true` to tell the browser to apply these settings
25
25
  # to all subdomains. This protects your cookies from interception by a
26
- # vulnerable site on a subdomain. Defaults to `false`.
26
+ # vulnerable site on a subdomain. Defaults to `true`.
27
27
  # * `preload`: Advertise that this site may be included in browsers'
28
28
  # preloaded HSTS lists. HSTS protects your site on every visit *except the
29
29
  # first visit* since it hasn't seen your HSTS header yet. To close this
@@ -45,35 +45,17 @@ module ActionDispatch
45
45
  HSTS_EXPIRES_IN = 15552000
46
46
 
47
47
  def self.default_hsts_options
48
- { expires: HSTS_EXPIRES_IN, subdomains: false, preload: false }
48
+ { expires: HSTS_EXPIRES_IN, subdomains: true, preload: false }
49
49
  end
50
50
 
51
- def initialize(app, redirect: {}, hsts: {}, secure_cookies: true, **options)
51
+ def initialize(app, redirect: {}, hsts: {}, secure_cookies: true)
52
52
  @app = app
53
53
 
54
- if options[:host] || options[:port]
55
- ActiveSupport::Deprecation.warn <<-end_warning.strip_heredoc
56
- The `:host` and `:port` options are moving within `:redirect`:
57
- `config.ssl_options = { redirect: { host: …, port: … } }`.
58
- end_warning
59
- @redirect = options.slice(:host, :port)
60
- else
61
- @redirect = redirect
62
- end
54
+ @redirect = redirect
63
55
 
64
56
  @exclude = @redirect && @redirect[:exclude] || proc { !@redirect }
65
57
  @secure_cookies = secure_cookies
66
58
 
67
- if hsts != true && hsts != false && hsts[:subdomains].nil?
68
- hsts[:subdomains] = false
69
-
70
- ActiveSupport::Deprecation.warn <<-end_warning.strip_heredoc
71
- In Rails 5.1, The `:subdomains` option of HSTS config will be treated as true if
72
- unspecified. Set `config.ssl_options = { hsts: { subdomains: false } }` to opt out
73
- of this behavior.
74
- end_warning
75
- end
76
-
77
59
  @hsts_header = build_hsts_header(normalize_hsts_options(hsts))
78
60
  end
79
61
 
@@ -93,7 +75,7 @@ module ActionDispatch
93
75
 
94
76
  private
95
77
  def set_hsts_header!(headers)
96
- headers['Strict-Transport-Security'.freeze] ||= @hsts_header
78
+ headers["Strict-Transport-Security".freeze] ||= @hsts_header
97
79
  end
98
80
 
99
81
  def normalize_hsts_options(options)
@@ -119,10 +101,10 @@ module ActionDispatch
119
101
  end
120
102
 
121
103
  def flag_cookies_as_secure!(headers)
122
- if cookies = headers['Set-Cookie'.freeze]
104
+ if cookies = headers["Set-Cookie".freeze]
123
105
  cookies = cookies.split("\n".freeze)
124
106
 
125
- headers['Set-Cookie'.freeze] = cookies.map { |cookie|
107
+ headers["Set-Cookie".freeze] = cookies.map { |cookie|
126
108
  if cookie !~ /;\s*secure\s*(;|$)/i
127
109
  "#{cookie}; secure"
128
110
  else
@@ -134,8 +116,8 @@ module ActionDispatch
134
116
 
135
117
  def redirect_to_https(request)
136
118
  [ @redirect.fetch(:status, redirection_status(request)),
137
- { 'Content-Type' => 'text/html',
138
- 'Location' => https_location_for(request) },
119
+ { "Content-Type" => "text/html",
120
+ "Location" => https_location_for(request) },
139
121
  @redirect.fetch(:body, []) ]
140
122
  end
141
123
 
@@ -88,7 +88,6 @@ module ActionDispatch
88
88
  end
89
89
 
90
90
  def delete(target)
91
- target = get_class target
92
91
  middlewares.delete_if { |m| m.klass == target }
93
92
  end
94
93
 
@@ -102,32 +101,14 @@ module ActionDispatch
102
101
 
103
102
  private
104
103
 
105
- def assert_index(index, where)
106
- index = get_class index
107
- i = index.is_a?(Integer) ? index : middlewares.index { |m| m.klass == index }
108
- raise "No such middleware to insert #{where}: #{index.inspect}" unless i
109
- i
110
- end
111
-
112
- def get_class(klass)
113
- if klass.is_a?(String) || klass.is_a?(Symbol)
114
- classcache = ActiveSupport::Dependencies::Reference
115
- converted_klass = classcache[klass.to_s]
116
- ActiveSupport::Deprecation.warn <<-eowarn
117
- Passing strings or symbols to the middleware builder is deprecated, please change
118
- them to actual class references. For example:
119
-
120
- "#{klass}" => #{converted_klass}
121
-
122
- eowarn
123
- converted_klass
124
- else
125
- klass
104
+ def assert_index(index, where)
105
+ i = index.is_a?(Integer) ? index : middlewares.index { |m| m.klass == index }
106
+ raise "No such middleware to insert #{where}: #{index.inspect}" unless i
107
+ i
126
108
  end
127
- end
128
109
 
129
- def build_middleware(klass, args, block)
130
- Middleware.new(get_class(klass), args, block)
131
- end
110
+ def build_middleware(klass, args, block)
111
+ Middleware.new(klass, args, block)
112
+ end
132
113
  end
133
114
  end
@@ -1,5 +1,5 @@
1
- require 'rack/utils'
2
- require 'active_support/core_ext/uri'
1
+ require "rack/utils"
2
+ require "active_support/core_ext/uri"
3
3
 
4
4
  module ActionDispatch
5
5
  # This middleware returns a file's contents from disk in the body response.
@@ -13,8 +13,8 @@ module ActionDispatch
13
13
  # located at `public/assets/application.js` if the file exists. If the file
14
14
  # does not exist, a 404 "File not Found" response will be returned.
15
15
  class FileHandler
16
- def initialize(root, index: 'index', headers: {})
17
- @root = root.chomp('/')
16
+ def initialize(root, index: "index", headers: {})
17
+ @root = root.chomp("/")
18
18
  @file_server = ::Rack::File.new(@root, headers)
19
19
  @index = index
20
20
  end
@@ -27,13 +27,13 @@ module ActionDispatch
27
27
  # in the server's `public/` directory (see Static#call).
28
28
  def match?(path)
29
29
  path = ::Rack::Utils.unescape_path path
30
- return false unless valid_path?(path)
31
- path = Rack::Utils.clean_path_info path
30
+ return false unless ::Rack::Utils.valid_path? path
31
+ path = ::Rack::Utils.clean_path_info path
32
32
 
33
33
  paths = [path, "#{path}#{ext}", "#{path}/#{@index}#{ext}"]
34
34
 
35
35
  if match = paths.detect { |p|
36
- path = File.join(@root, p.force_encoding('UTF-8'.freeze))
36
+ path = File.join(@root, p.force_encoding(Encoding::UTF_8))
37
37
  begin
38
38
  File.file?(path) && File.readable?(path)
39
39
  rescue SystemCallError
@@ -59,13 +59,13 @@ module ActionDispatch
59
59
  if status == 304
60
60
  return [status, headers, body]
61
61
  end
62
- headers['Content-Encoding'] = 'gzip'
63
- headers['Content-Type'] = content_type(path)
62
+ headers["Content-Encoding"] = "gzip"
63
+ headers["Content-Type"] = content_type(path)
64
64
  else
65
65
  status, headers, body = @file_server.call(request.env)
66
66
  end
67
67
 
68
- headers['Vary'] = 'Accept-Encoding' if gzip_path
68
+ headers["Vary"] = "Accept-Encoding" if gzip_path
69
69
 
70
70
  return [status, headers, body]
71
71
  ensure
@@ -78,7 +78,7 @@ module ActionDispatch
78
78
  end
79
79
 
80
80
  def content_type(path)
81
- ::Rack::Mime.mime_type(::File.extname(path), 'text/plain'.freeze)
81
+ ::Rack::Mime.mime_type(::File.extname(path), "text/plain".freeze)
82
82
  end
83
83
 
84
84
  def gzip_encoding_accepted?(request)
@@ -94,10 +94,6 @@ module ActionDispatch
94
94
  false
95
95
  end
96
96
  end
97
-
98
- def valid_path?(path)
99
- path.valid_encoding? && !path.include?("\0")
100
- end
101
97
  end
102
98
 
103
99
  # This middleware will attempt to return the contents of a file's body from
@@ -110,14 +106,7 @@ module ActionDispatch
110
106
  # produce a directory traversal using this middleware. Only 'GET' and 'HEAD'
111
107
  # requests will result in a file being returned.
112
108
  class Static
113
- def initialize(app, path, deprecated_cache_control = :not_set, index: 'index', headers: {})
114
- if deprecated_cache_control != :not_set
115
- ActiveSupport::Deprecation.warn("The `cache_control` argument is deprecated," \
116
- "replaced by `headers: { 'Cache-Control' => #{deprecated_cache_control} }`, " \
117
- " and will be removed in Rails 5.1.")
118
- headers['Cache-Control'.freeze] = deprecated_cache_control
119
- end
120
-
109
+ def initialize(app, path, index: "index", headers: {})
121
110
  @app = app
122
111
  @file_handler = FileHandler.new(path, index: index, headers: headers)
123
112
  end
@@ -126,7 +115,7 @@ module ActionDispatch
126
115
  req = Rack::Request.new env
127
116
 
128
117
  if req.get? || req.head?
129
- path = req.path_info.chomp('/'.freeze)
118
+ path = req.path_info.chomp("/".freeze)
130
119
  if match = @file_handler.match?(path)
131
120
  req.path_info = match
132
121
  return @file_handler.serve(req)