actionpack 5.1.7 → 5.2.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 (144) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +132 -490
  3. data/README.rdoc +1 -1
  4. data/lib/abstract_controller.rb +2 -0
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +10 -2
  7. data/lib/abstract_controller/caching.rb +3 -2
  8. data/lib/abstract_controller/caching/fragments.rb +30 -7
  9. data/lib/abstract_controller/callbacks.rb +25 -3
  10. data/lib/abstract_controller/collector.rb +2 -0
  11. data/lib/abstract_controller/error.rb +2 -0
  12. data/lib/abstract_controller/helpers.rb +4 -5
  13. data/lib/abstract_controller/logger.rb +2 -0
  14. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  15. data/lib/abstract_controller/rendering.rb +9 -16
  16. data/lib/abstract_controller/translation.rb +2 -0
  17. data/lib/abstract_controller/url_for.rb +2 -0
  18. data/lib/action_controller.rb +3 -0
  19. data/lib/action_controller/api.rb +2 -0
  20. data/lib/action_controller/api/api_rendering.rb +2 -0
  21. data/lib/action_controller/base.rb +3 -0
  22. data/lib/action_controller/caching.rb +2 -0
  23. data/lib/action_controller/form_builder.rb +2 -0
  24. data/lib/action_controller/log_subscriber.rb +5 -3
  25. data/lib/action_controller/metal.rb +3 -2
  26. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  27. data/lib/action_controller/metal/conditional_get.rb +4 -3
  28. data/lib/action_controller/metal/content_security_policy.rb +26 -0
  29. data/lib/action_controller/metal/cookies.rb +2 -0
  30. data/lib/action_controller/metal/data_streaming.rb +7 -5
  31. data/lib/action_controller/metal/etag_with_flash.rb +2 -0
  32. data/lib/action_controller/metal/etag_with_template_digest.rb +3 -2
  33. data/lib/action_controller/metal/exceptions.rb +2 -3
  34. data/lib/action_controller/metal/flash.rb +3 -2
  35. data/lib/action_controller/metal/force_ssl.rb +2 -0
  36. data/lib/action_controller/metal/head.rb +2 -0
  37. data/lib/action_controller/metal/helpers.rb +4 -3
  38. data/lib/action_controller/metal/http_authentication.rb +8 -9
  39. data/lib/action_controller/metal/implicit_render.rb +2 -0
  40. data/lib/action_controller/metal/instrumentation.rb +4 -6
  41. data/lib/action_controller/metal/live.rb +3 -1
  42. data/lib/action_controller/metal/mime_responds.rb +3 -1
  43. data/lib/action_controller/metal/parameter_encoding.rb +2 -0
  44. data/lib/action_controller/metal/params_wrapper.rb +13 -9
  45. data/lib/action_controller/metal/redirecting.rb +21 -10
  46. data/lib/action_controller/metal/renderers.rb +4 -3
  47. data/lib/action_controller/metal/rendering.rb +2 -2
  48. data/lib/action_controller/metal/request_forgery_protection.rb +22 -6
  49. data/lib/action_controller/metal/rescue.rb +5 -3
  50. data/lib/action_controller/metal/streaming.rb +2 -0
  51. data/lib/action_controller/metal/strong_parameters.rb +19 -11
  52. data/lib/action_controller/metal/testing.rb +2 -6
  53. data/lib/action_controller/metal/url_for.rb +2 -0
  54. data/lib/action_controller/railtie.rb +16 -4
  55. data/lib/action_controller/railties/helpers.rb +2 -0
  56. data/lib/action_controller/renderer.rb +2 -0
  57. data/lib/action_controller/template_assertions.rb +2 -0
  58. data/lib/action_controller/test_case.rb +4 -1
  59. data/lib/action_dispatch.rb +3 -0
  60. data/lib/action_dispatch/http/cache.rb +15 -9
  61. data/lib/action_dispatch/http/content_security_policy.rb +233 -0
  62. data/lib/action_dispatch/http/filter_parameters.rb +4 -2
  63. data/lib/action_dispatch/http/filter_redirect.rb +2 -0
  64. data/lib/action_dispatch/http/headers.rb +2 -0
  65. data/lib/action_dispatch/http/mime_negotiation.rb +4 -13
  66. data/lib/action_dispatch/http/mime_type.rb +15 -13
  67. data/lib/action_dispatch/http/mime_types.rb +4 -2
  68. data/lib/action_dispatch/http/parameter_filter.rb +2 -0
  69. data/lib/action_dispatch/http/parameters.rb +6 -9
  70. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  71. data/lib/action_dispatch/http/request.rb +36 -16
  72. data/lib/action_dispatch/http/response.rb +11 -9
  73. data/lib/action_dispatch/http/upload.rb +2 -0
  74. data/lib/action_dispatch/http/url.rb +4 -5
  75. data/lib/action_dispatch/journey.rb +2 -0
  76. data/lib/action_dispatch/journey/formatter.rb +4 -2
  77. data/lib/action_dispatch/journey/gtg/builder.rb +2 -0
  78. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -8
  79. data/lib/action_dispatch/journey/gtg/transition_table.rb +3 -2
  80. data/lib/action_dispatch/journey/nfa/builder.rb +2 -0
  81. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  82. data/lib/action_dispatch/journey/nfa/simulator.rb +2 -0
  83. data/lib/action_dispatch/journey/nfa/transition_table.rb +2 -0
  84. data/lib/action_dispatch/journey/nodes/node.rb +2 -0
  85. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  86. data/lib/action_dispatch/journey/path/pattern.rb +2 -0
  87. data/lib/action_dispatch/journey/route.rb +15 -6
  88. data/lib/action_dispatch/journey/router.rb +3 -1
  89. data/lib/action_dispatch/journey/router/utils.rb +14 -7
  90. data/lib/action_dispatch/journey/routes.rb +2 -1
  91. data/lib/action_dispatch/journey/scanner.rb +1 -0
  92. data/lib/action_dispatch/journey/visitors.rb +5 -3
  93. data/lib/action_dispatch/middleware/callbacks.rb +2 -0
  94. data/lib/action_dispatch/middleware/cookies.rb +141 -91
  95. data/lib/action_dispatch/middleware/debug_exceptions.rb +4 -2
  96. data/lib/action_dispatch/middleware/debug_locks.rb +9 -7
  97. data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -6
  98. data/lib/action_dispatch/middleware/executor.rb +2 -0
  99. data/lib/action_dispatch/middleware/flash.rb +3 -1
  100. data/lib/action_dispatch/middleware/public_exceptions.rb +6 -4
  101. data/lib/action_dispatch/middleware/reloader.rb +2 -0
  102. data/lib/action_dispatch/middleware/remote_ip.rb +7 -5
  103. data/lib/action_dispatch/middleware/request_id.rb +2 -0
  104. data/lib/action_dispatch/middleware/session/abstract_store.rb +3 -1
  105. data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
  106. data/lib/action_dispatch/middleware/session/cookie_store.rb +13 -25
  107. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +2 -0
  108. data/lib/action_dispatch/middleware/show_exceptions.rb +3 -1
  109. data/lib/action_dispatch/middleware/ssl.rb +42 -37
  110. data/lib/action_dispatch/middleware/stack.rb +2 -0
  111. data/lib/action_dispatch/middleware/static.rb +10 -8
  112. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +1 -0
  113. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +6 -2
  114. data/lib/action_dispatch/railtie.rb +7 -0
  115. data/lib/action_dispatch/request/session.rb +8 -4
  116. data/lib/action_dispatch/request/utils.rb +4 -4
  117. data/lib/action_dispatch/routing.rb +3 -1
  118. data/lib/action_dispatch/routing/endpoint.rb +8 -4
  119. data/lib/action_dispatch/routing/inspector.rb +5 -3
  120. data/lib/action_dispatch/routing/mapper.rb +62 -51
  121. data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
  122. data/lib/action_dispatch/routing/redirection.rb +7 -5
  123. data/lib/action_dispatch/routing/route_set.rb +26 -33
  124. data/lib/action_dispatch/routing/routes_proxy.rb +5 -2
  125. data/lib/action_dispatch/routing/url_for.rb +6 -4
  126. data/lib/action_dispatch/system_test_case.rb +14 -6
  127. data/lib/action_dispatch/system_testing/driver.rb +20 -2
  128. data/lib/action_dispatch/system_testing/server.rb +2 -16
  129. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +6 -4
  130. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  131. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  132. data/lib/action_dispatch/testing/assertion_response.rb +2 -0
  133. data/lib/action_dispatch/testing/assertions.rb +2 -0
  134. data/lib/action_dispatch/testing/assertions/response.rb +4 -2
  135. data/lib/action_dispatch/testing/assertions/routing.rb +5 -5
  136. data/lib/action_dispatch/testing/integration.rb +24 -21
  137. data/lib/action_dispatch/testing/request_encoder.rb +2 -0
  138. data/lib/action_dispatch/testing/test_process.rb +2 -0
  139. data/lib/action_dispatch/testing/test_request.rb +3 -1
  140. data/lib/action_dispatch/testing/test_response.rb +23 -3
  141. data/lib/action_pack.rb +2 -0
  142. data/lib/action_pack/gem_version.rb +5 -3
  143. data/lib/action_pack/version.rb +2 -0
  144. metadata +17 -13
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "action_dispatch/http/request"
2
4
  require "action_dispatch/middleware/exception_wrapper"
3
5
  require "action_dispatch/routing/inspector"
@@ -10,7 +12,7 @@ module ActionDispatch
10
12
  # This middleware is responsible for logging exceptions and
11
13
  # showing a debugging page in case the request is local.
12
14
  class DebugExceptions
13
- RESCUES_TEMPLATE_PATH = File.expand_path("../templates", __FILE__)
15
+ RESCUES_TEMPLATE_PATH = File.expand_path("templates", __dir__)
14
16
 
15
17
  class DebugView < ActionView::Base
16
18
  def debug_params(params)
@@ -21,7 +23,7 @@ module ActionDispatch
21
23
  if clean_params.empty?
22
24
  "None"
23
25
  else
24
- PP.pp(clean_params, "", 200)
26
+ PP.pp(clean_params, "".dup, 200)
25
27
  end
26
28
  end
27
29
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionDispatch
2
4
  # This middleware can be used to diagnose deadlocks in the autoload interlock.
3
5
  #
@@ -41,7 +43,7 @@ module ActionDispatch
41
43
 
42
44
  private
43
45
  def render_details(req)
44
- threads = ActiveSupport::Dependencies.interlock.raw_state do |threads|
46
+ threads = ActiveSupport::Dependencies.interlock.raw_state do |raw_threads|
45
47
  # The Interlock itself comes to a complete halt as long as this block
46
48
  # is executing. That gives us a more consistent picture of everything,
47
49
  # but creates a pretty strong Observer Effect.
@@ -51,29 +53,29 @@ module ActionDispatch
51
53
  # strictly diagnostic tool (to be used when something has gone wrong),
52
54
  # and not for any sort of general monitoring.
53
55
 
54
- threads.each.with_index do |(thread, info), idx|
56
+ raw_threads.each.with_index do |(thread, info), idx|
55
57
  info[:index] = idx
56
58
  info[:backtrace] = thread.backtrace
57
59
  end
58
60
 
59
- threads
61
+ raw_threads
60
62
  end
61
63
 
62
64
  str = threads.map do |thread, info|
63
65
  if info[:exclusive]
64
- lock_state = "Exclusive"
66
+ lock_state = "Exclusive".dup
65
67
  elsif info[:sharing] > 0
66
- lock_state = "Sharing"
68
+ lock_state = "Sharing".dup
67
69
  lock_state << " x#{info[:sharing]}" if info[:sharing] > 1
68
70
  else
69
- lock_state = "No lock"
71
+ lock_state = "No lock".dup
70
72
  end
71
73
 
72
74
  if info[:waiting]
73
75
  lock_state << " (yielded share)"
74
76
  end
75
77
 
76
- msg = "Thread #{info[:index]} [0x#{thread.__id__.to_s(16)} #{thread.status || 'dead'}] #{lock_state}\n"
78
+ msg = "Thread #{info[:index]} [0x#{thread.__id__.to_s(16)} #{thread.status || 'dead'}] #{lock_state}\n".dup
77
79
 
78
80
  if info[:sleeper]
79
81
  msg << " Waiting in #{info[:sleeper]}"
@@ -1,11 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/attribute_accessors"
2
4
  require "rack/utils"
3
5
 
4
6
  module ActionDispatch
5
7
  class ExceptionWrapper
6
- cattr_accessor :rescue_responses
7
- @@rescue_responses = Hash.new(:internal_server_error)
8
- @@rescue_responses.merge!(
8
+ cattr_accessor :rescue_responses, default: Hash.new(:internal_server_error).merge!(
9
9
  "ActionController::RoutingError" => :not_found,
10
10
  "AbstractController::ActionNotFound" => :not_found,
11
11
  "ActionController::MethodNotAllowed" => :method_not_allowed,
@@ -21,9 +21,7 @@ module ActionDispatch
21
21
  "Rack::QueryParser::InvalidParameterError" => :bad_request
22
22
  )
23
23
 
24
- cattr_accessor :rescue_templates
25
- @@rescue_templates = Hash.new("diagnostics")
26
- @@rescue_templates.merge!(
24
+ cattr_accessor :rescue_templates, default: Hash.new("diagnostics").merge!(
27
25
  "ActionView::MissingTemplate" => "missing_template",
28
26
  "ActionController::RoutingError" => "routing_error",
29
27
  "AbstractController::ActionNotFound" => "unknown_action",
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rack/body_proxy"
2
4
 
3
5
  module ActionDispatch
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/keys"
2
4
 
3
5
  module ActionDispatch
@@ -65,7 +67,7 @@ module ActionDispatch
65
67
  self.flash = flash_hash.dup
66
68
  end
67
69
 
68
- if (!session.respond_to?(:loaded?) || session.loaded?) && # (reset_session uses {}, which doesn't implement #loaded?)
70
+ if (!session.respond_to?(:loaded?) || session.loaded?) && # reset_session uses {}, which doesn't implement #loaded?
69
71
  session.key?("flash") && session["flash"].nil?
70
72
  session.delete("flash")
71
73
  end
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionDispatch
2
4
  # When called, this middleware renders an error page. By default if an HTML
3
- # response is expected it will render static error pages from the `/public`
5
+ # response is expected it will render static error pages from the <tt>/public</tt>
4
6
  # directory. For example when this middleware receives a 500 response it will
5
- # render the template found in `/public/500.html`.
7
+ # render the template found in <tt>/public/500.html</tt>.
6
8
  # If an internationalized locale is set, this middleware will attempt to render
7
- # the template in `/public/500.<locale>.html`. If an internationalized template
8
- # is not found it will fall back on `/public/500.html`.
9
+ # the template in <tt>/public/500.<locale>.html</tt>. If an internationalized template
10
+ # is not found it will fall back on <tt>/public/500.html</tt>.
9
11
  #
10
12
  # When a request with a content type other than HTML is made, this middleware
11
13
  # will attempt to convert error information into the appropriate response type.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionDispatch
2
4
  # ActionDispatch::Reloader wraps the request with callbacks provided by ActiveSupport::Reloader
3
5
  # callbacks, intended to assist with code reloading during development.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "ipaddr"
2
4
 
3
5
  module ActionDispatch
@@ -10,7 +12,7 @@ module ActionDispatch
10
12
  # by @gingerlime. A more detailed explanation of the algorithm is given
11
13
  # at GetIp#calculate_ip.
12
14
  #
13
- # Some Rack servers concatenate repeated headers, like {HTTP RFC 2616}[http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2]
15
+ # Some Rack servers concatenate repeated headers, like {HTTP RFC 2616}[https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2]
14
16
  # requires. Some Rack servers simply drop preceding headers, and only report
15
17
  # the value that was {given in the last header}[http://andre.arko.net/2011/12/26/repeated-headers-and-ruby-web-servers].
16
18
  # If you are behind multiple proxy servers (like NGINX to HAProxy to Unicorn)
@@ -29,7 +31,7 @@ module ActionDispatch
29
31
  # The default trusted IPs list simply includes IP addresses that are
30
32
  # guaranteed by the IP specification to be private addresses. Those will
31
33
  # not be the ultimate client IP in production, and so are discarded. See
32
- # http://en.wikipedia.org/wiki/Private_network for details.
34
+ # https://en.wikipedia.org/wiki/Private_network for details.
33
35
  TRUSTED_PROXIES = [
34
36
  "127.0.0.1", # localhost IPv4
35
37
  "::1", # localhost IPv6
@@ -157,13 +159,13 @@ module ActionDispatch
157
159
 
158
160
  def ips_from(header) # :doc:
159
161
  return [] unless header
160
- # Split the comma-separated list into an array of strings
162
+ # Split the comma-separated list into an array of strings.
161
163
  ips = header.strip.split(/[,\s]+/)
162
164
  ips.select do |ip|
163
165
  begin
164
- # Only return IPs that are valid according to the IPAddr#new method
166
+ # Only return IPs that are valid according to the IPAddr#new method.
165
167
  range = IPAddr.new(ip).to_range
166
- # we want to make sure nobody is sneaking a netmask in
168
+ # We want to make sure nobody is sneaking a netmask in.
167
169
  range.begin == range.end
168
170
  rescue ArgumentError
169
171
  nil
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "securerandom"
2
4
  require "active_support/core_ext/string/access"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rack/utils"
2
4
  require "rack/request"
3
5
  require "rack/session/abstract/id"
@@ -53,7 +55,7 @@ module ActionDispatch
53
55
  rescue ArgumentError => argument_error
54
56
  if argument_error.message =~ %r{undefined class/module ([\w:]*\w)}
55
57
  begin
56
- # Note that the regexp does not allow $1 to end with a ':'
58
+ # Note that the regexp does not allow $1 to end with a ':'.
57
59
  $1.constantize
58
60
  rescue LoadError, NameError
59
61
  raise ActionDispatch::Session::SessionRestoreError
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "action_dispatch/middleware/session/abstract_store"
2
4
 
3
5
  module ActionDispatch
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/hash/keys"
2
4
  require "action_dispatch/middleware/session/abstract_store"
3
5
  require "rack/session/cookie"
@@ -19,39 +21,25 @@ module ActionDispatch
19
21
  # knowing your app's secret key, but can easily read their +user_id+. This
20
22
  # was the default for Rails 3 apps.
21
23
  #
22
- # If you have secret_key_base set, your cookies will be encrypted. This
24
+ # Your cookies will be encrypted using your apps secret_key_base. This
23
25
  # goes a step further than signed cookies in that encrypted cookies cannot
24
26
  # be altered or read by users. This is the default starting in Rails 4.
25
27
  #
26
- # If you have both secret_token and secret_key_base set, your cookies will
27
- # be encrypted, and signed cookies generated by Rails 3 will be
28
- # transparently read and encrypted to provide a smooth upgrade path.
29
- #
30
- # Configure your session store in config/initializers/session_store.rb:
28
+ # Configure your session store in <tt>config/initializers/session_store.rb</tt>:
31
29
  #
32
30
  # Rails.application.config.session_store :cookie_store, key: '_your_app_session'
33
31
  #
34
- # Configure your secret key in config/secrets.yml:
35
- #
36
- # development:
37
- # secret_key_base: 'secret key'
38
- #
39
- # To generate a secret key for an existing application, run `rails secret`.
32
+ # By default, your secret key base is derived from your application name in
33
+ # the test and development environments. In all other environments, it is stored
34
+ # encrypted in the <tt>config/credentials.yml.enc</tt> file.
40
35
  #
41
- # If you are upgrading an existing Rails 3 app, you should leave your
42
- # existing secret_token in place and simply add the new secret_key_base.
43
- # Note that you should wait to set secret_key_base until you have 100% of
44
- # your userbase on Rails 4 and are reasonably sure you will not need to
45
- # rollback to Rails 3. This is because cookies signed based on the new
46
- # secret_key_base in Rails 4 are not backwards compatible with Rails 3.
47
- # You are free to leave your existing secret_token in place, not set the
48
- # new secret_key_base, and ignore the deprecation warnings until you are
49
- # reasonably sure that your upgrade is otherwise complete. Additionally,
50
- # you should take care to make sure you are not relying on the ability to
51
- # decode signed cookies generated by your app in external applications or
52
- # JavaScript before upgrading.
36
+ # If your application was not updated to Rails 5.2 defaults, the secret_key_base
37
+ # will be found in the old <tt>config/secrets.yml</tt> file.
53
38
  #
54
- # Note that changing the secret key will invalidate all existing sessions!
39
+ # Note that changing your secret_key_base will invalidate all existing session.
40
+ # Additionally, you should take care to make sure you are not relying on the
41
+ # ability to decode signed cookies generated by your app in external
42
+ # applications or JavaScript before changing it.
55
43
  #
56
44
  # Because CookieStore extends Rack::Session::Abstract::Persisted, many of the
57
45
  # options described there can be used to customize the session cookie that
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "action_dispatch/middleware/session/abstract_store"
2
4
  begin
3
5
  require "rack/session/dalli"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "action_dispatch/http/request"
2
4
  require "action_dispatch/middleware/exception_wrapper"
3
5
 
@@ -8,7 +10,7 @@ module ActionDispatch
8
10
  # The exceptions app should be passed as parameter on initialization
9
11
  # of ShowExceptions. Every time there is an exception, ShowExceptions will
10
12
  # store the exception in env["action_dispatch.exception"], rewrite the
11
- # PATH_INFO to the exception status code and call the rack app.
13
+ # PATH_INFO to the exception status code and call the Rack app.
12
14
  #
13
15
  # If the application returns a "X-Cascade" pass response, this middleware
14
16
  # will send an empty response as result with the correct status code.
@@ -1,47 +1,52 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionDispatch
2
- # This middleware is added to the stack when `config.force_ssl = true`, and is passed
3
- # the options set in `config.ssl_options`. It does three jobs to enforce secure HTTP
4
+ # This middleware is added to the stack when <tt>config.force_ssl = true</tt>, and is passed
5
+ # the options set in +config.ssl_options+. It does three jobs to enforce secure HTTP
4
6
  # requests:
5
7
  #
6
- # 1. TLS redirect: Permanently redirects http:// requests to https://
7
- # with the same URL host, path, etc. Enabled by default. Set `config.ssl_options`
8
- # to modify the destination URL
9
- # (e.g. `redirect: { host: "secure.widgets.com", port: 8080 }`), or set
10
- # `redirect: false` to disable this feature.
8
+ # 1. <b>TLS redirect</b>: Permanently redirects +http://+ requests to +https://+
9
+ # with the same URL host, path, etc. Enabled by default. Set +config.ssl_options+
10
+ # to modify the destination URL
11
+ # (e.g. <tt>redirect: { host: "secure.widgets.com", port: 8080 }</tt>), or set
12
+ # <tt>redirect: false</tt> to disable this feature.
13
+ #
14
+ # Requests can opt-out of redirection with +exclude+:
11
15
  #
12
- # Cookies will not be flagged as secure for excluded requests.
16
+ # config.ssl_options = { redirect: { exclude: -> request { request.path =~ /healthcheck/ } } }
13
17
  #
14
- # 2. Secure cookies: Sets the `secure` flag on cookies to tell browsers they
15
- # mustn't be sent along with http:// requests. Enabled by default. Set
16
- # `config.ssl_options` with `secure_cookies: false` to disable this feature.
18
+ # 2. <b>Secure cookies</b>: Sets the +secure+ flag on cookies to tell browsers they
19
+ # must not be sent along with +http://+ requests. Enabled by default. Set
20
+ # +config.ssl_options+ with <tt>secure_cookies: false</tt> to disable this feature.
17
21
  #
18
- # 3. HTTP Strict Transport Security (HSTS): Tells the browser to remember
19
- # this site as TLS-only and automatically redirect non-TLS requests.
20
- # Enabled by default. Configure `config.ssl_options` with `hsts: false` to disable.
22
+ # 3. <b>HTTP Strict Transport Security (HSTS)</b>: Tells the browser to remember
23
+ # this site as TLS-only and automatically redirect non-TLS requests.
24
+ # Enabled by default. Configure +config.ssl_options+ with <tt>hsts: false</tt> to disable.
21
25
  #
22
- # Set `config.ssl_options` with `hsts: { }` to configure HSTS:
23
- # * `expires`: How long, in seconds, these settings will stick. The minimum
24
- # required to qualify for browser preload lists is `18.weeks`. Defaults to
25
- # `180.days` (recommended).
26
- # * `subdomains`: Set to `true` to tell the browser to apply these settings
27
- # to all subdomains. This protects your cookies from interception by a
28
- # vulnerable site on a subdomain. Defaults to `true`.
29
- # * `preload`: Advertise that this site may be included in browsers'
30
- # preloaded HSTS lists. HSTS protects your site on every visit *except the
31
- # first visit* since it hasn't seen your HSTS header yet. To close this
32
- # gap, browser vendors include a baked-in list of HSTS-enabled sites.
33
- # Go to https://hstspreload.appspot.com to submit your site for inclusion.
34
- # Defaults to `false`.
26
+ # Set +config.ssl_options+ with <tt>hsts: { ... }</tt> to configure HSTS:
35
27
  #
36
- # To turn off HSTS, omitting the header is not enough. Browsers will remember the
37
- # original HSTS directive until it expires. Instead, use the header to tell browsers to
38
- # expire HSTS immediately. Setting `hsts: false` is a shortcut for
39
- # `hsts: { expires: 0 }`.
28
+ # * +expires+: How long, in seconds, these settings will stick. The minimum
29
+ # required to qualify for browser preload lists is 18 weeks. Defaults to
30
+ # 180 days (recommended).
40
31
  #
41
- # Requests can opt-out of redirection with `exclude`:
32
+ # * +subdomains+: Set to +true+ to tell the browser to apply these settings
33
+ # to all subdomains. This protects your cookies from interception by a
34
+ # vulnerable site on a subdomain. Defaults to +true+.
42
35
  #
43
- # config.ssl_options = { redirect: { exclude: -> request { request.path =~ /healthcheck/ } } }
36
+ # * +preload+: Advertise that this site may be included in browsers'
37
+ # preloaded HSTS lists. HSTS protects your site on every visit <i>except the
38
+ # first visit</i> since it hasn't seen your HSTS header yet. To close this
39
+ # gap, browser vendors include a baked-in list of HSTS-enabled sites.
40
+ # Go to https://hstspreload.org to submit your site for inclusion.
41
+ # Defaults to +false+.
42
+ #
43
+ # To turn off HSTS, omitting the header is not enough. Browsers will remember the
44
+ # original HSTS directive until it expires. Instead, use the header to tell browsers to
45
+ # expire HSTS immediately. Setting <tt>hsts: false</tt> is a shortcut for
46
+ # <tt>hsts: { expires: 0 }</tt>.
44
47
  class SSL
48
+ # :stopdoc:
49
+
45
50
  # Default to 180 days, the low end for https://www.ssllabs.com/ssltest/
46
51
  # and greater than the 18-week requirement for browser preload lists.
47
52
  HSTS_EXPIRES_IN = 15552000
@@ -67,7 +72,7 @@ module ActionDispatch
67
72
  if request.ssl?
68
73
  @app.call(env).tap do |status, headers, body|
69
74
  set_hsts_header! headers
70
- flag_cookies_as_secure! headers if @secure_cookies && !@exclude.call(request)
75
+ flag_cookies_as_secure! headers if @secure_cookies
71
76
  end
72
77
  else
73
78
  return redirect_to_https request unless @exclude.call(request)
@@ -94,9 +99,9 @@ module ActionDispatch
94
99
  end
95
100
  end
96
101
 
97
- # http://tools.ietf.org/html/rfc6797#section-6.1
102
+ # https://tools.ietf.org/html/rfc6797#section-6.1
98
103
  def build_hsts_header(hsts)
99
- value = "max-age=#{hsts[:expires].to_i}"
104
+ value = "max-age=#{hsts[:expires].to_i}".dup
100
105
  value << "; includeSubDomains" if hsts[:subdomains]
101
106
  value << "; preload" if hsts[:preload]
102
107
  value
@@ -135,7 +140,7 @@ module ActionDispatch
135
140
  host = @redirect[:host] || request.host
136
141
  port = @redirect[:port] || request.port
137
142
 
138
- location = "https://#{host}"
143
+ location = "https://#{host}".dup
139
144
  location << ":#{port}" if port != 80 && port != 443
140
145
  location << request.fullpath
141
146
  location
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/inflector/methods"
2
4
  require "active_support/dependencies"
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rack/utils"
2
4
  require "active_support/core_ext/uri"
3
5
 
@@ -6,11 +8,11 @@ module ActionDispatch
6
8
  # When initialized, it can accept optional HTTP headers, which will be set
7
9
  # when a response containing a file's contents is delivered.
8
10
  #
9
- # This middleware will render the file specified in `env["PATH_INFO"]`
11
+ # This middleware will render the file specified in <tt>env["PATH_INFO"]</tt>
10
12
  # where the base path is in the +root+ directory. For example, if the +root+
11
- # is set to `public/`, then a request with `env["PATH_INFO"]` of
12
- # `assets/application.js` will return a response with the contents of a file
13
- # located at `public/assets/application.js` if the file exists. If the file
13
+ # is set to +public/+, then a request with <tt>env["PATH_INFO"]</tt> of
14
+ # +assets/application.js+ will return a response with the contents of a file
15
+ # located at +public/assets/application.js+ if the file exists. If the file
14
16
  # does not exist, a 404 "File not Found" response will be returned.
15
17
  class FileHandler
16
18
  def initialize(root, index: "index", headers: {})
@@ -23,8 +25,8 @@ module ActionDispatch
23
25
  # correct read permissions, the return value is a URI-escaped string
24
26
  # representing the filename. Otherwise, false is returned.
25
27
  #
26
- # Used by the `Static` class to check the existence of a valid file
27
- # in the server's `public/` directory (see Static#call).
28
+ # Used by the +Static+ class to check the existence of a valid file
29
+ # in the server's +public/+ directory (see Static#call).
28
30
  def match?(path)
29
31
  path = ::Rack::Utils.unescape_path path
30
32
  return false unless ::Rack::Utils.valid_path? path
@@ -33,7 +35,7 @@ module ActionDispatch
33
35
  paths = [path, "#{path}#{ext}", "#{path}/#{@index}#{ext}"]
34
36
 
35
37
  if match = paths.detect { |p|
36
- path = File.join(@root, p.force_encoding(Encoding::UTF_8))
38
+ path = File.join(@root, p.dup.force_encoding(Encoding::UTF_8))
37
39
  begin
38
40
  File.file?(path) && File.readable?(path)
39
41
  rescue SystemCallError
@@ -99,7 +101,7 @@ module ActionDispatch
99
101
  # This middleware will attempt to return the contents of a file's body from
100
102
  # disk in the response. If a file is not found on disk, the request will be
101
103
  # delegated to the application stack. This middleware is commonly initialized
102
- # to serve assets from a server's `public/` directory.
104
+ # to serve assets from a server's +public/+ directory.
103
105
  #
104
106
  # This middleware verifies the path to ensure that only files
105
107
  # living in the root directory can be rendered. A request cannot