actionpack 5.2.4.4 → 6.0.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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +111 -379
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/abstract_controller/base.rb +4 -2
  6. data/lib/abstract_controller/caching/fragments.rb +6 -21
  7. data/lib/abstract_controller/callbacks.rb +12 -0
  8. data/lib/abstract_controller/collector.rb +1 -1
  9. data/lib/abstract_controller/helpers.rb +2 -2
  10. data/lib/abstract_controller/railties/routes_helpers.rb +1 -1
  11. data/lib/action_controller.rb +1 -0
  12. data/lib/action_controller/api.rb +2 -1
  13. data/lib/action_controller/base.rb +2 -7
  14. data/lib/action_controller/caching.rb +1 -1
  15. data/lib/action_controller/log_subscriber.rb +8 -5
  16. data/lib/action_controller/metal.rb +2 -2
  17. data/lib/action_controller/metal/conditional_get.rb +9 -3
  18. data/lib/action_controller/metal/data_streaming.rb +5 -6
  19. data/lib/action_controller/metal/default_headers.rb +17 -0
  20. data/lib/action_controller/metal/exceptions.rb +22 -1
  21. data/lib/action_controller/metal/flash.rb +5 -5
  22. data/lib/action_controller/metal/force_ssl.rb +17 -57
  23. data/lib/action_controller/metal/head.rb +1 -1
  24. data/lib/action_controller/metal/helpers.rb +1 -2
  25. data/lib/action_controller/metal/http_authentication.rb +20 -21
  26. data/lib/action_controller/metal/implicit_render.rb +2 -12
  27. data/lib/action_controller/metal/instrumentation.rb +3 -5
  28. data/lib/action_controller/metal/live.rb +28 -26
  29. data/lib/action_controller/metal/mime_responds.rb +13 -2
  30. data/lib/action_controller/metal/params_wrapper.rb +18 -14
  31. data/lib/action_controller/metal/redirecting.rb +32 -11
  32. data/lib/action_controller/metal/rendering.rb +1 -1
  33. data/lib/action_controller/metal/request_forgery_protection.rb +26 -40
  34. data/lib/action_controller/metal/strong_parameters.rb +57 -34
  35. data/lib/action_controller/metal/url_for.rb +1 -1
  36. data/lib/action_controller/railties/helpers.rb +1 -1
  37. data/lib/action_controller/renderer.rb +15 -2
  38. data/lib/action_controller/test_case.rb +3 -7
  39. data/lib/action_dispatch.rb +7 -6
  40. data/lib/action_dispatch/http/cache.rb +14 -10
  41. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  42. data/lib/action_dispatch/http/content_security_policy.rb +9 -8
  43. data/lib/action_dispatch/http/filter_parameters.rb +8 -6
  44. data/lib/action_dispatch/http/filter_redirect.rb +1 -1
  45. data/lib/action_dispatch/http/headers.rb +1 -1
  46. data/lib/action_dispatch/http/mime_negotiation.rb +7 -10
  47. data/lib/action_dispatch/http/mime_type.rb +1 -5
  48. data/lib/action_dispatch/http/parameter_filter.rb +5 -79
  49. data/lib/action_dispatch/http/parameters.rb +13 -3
  50. data/lib/action_dispatch/http/request.rb +10 -13
  51. data/lib/action_dispatch/http/response.rb +14 -14
  52. data/lib/action_dispatch/http/upload.rb +5 -0
  53. data/lib/action_dispatch/http/url.rb +81 -81
  54. data/lib/action_dispatch/journey/formatter.rb +1 -1
  55. data/lib/action_dispatch/journey/nfa/simulator.rb +0 -2
  56. data/lib/action_dispatch/journey/nodes/node.rb +9 -8
  57. data/lib/action_dispatch/journey/path/pattern.rb +3 -4
  58. data/lib/action_dispatch/journey/router.rb +0 -3
  59. data/lib/action_dispatch/journey/router/utils.rb +10 -10
  60. data/lib/action_dispatch/journey/scanner.rb +11 -4
  61. data/lib/action_dispatch/journey/visitors.rb +1 -1
  62. data/lib/action_dispatch/middleware/callbacks.rb +2 -4
  63. data/lib/action_dispatch/middleware/cookies.rb +49 -70
  64. data/lib/action_dispatch/middleware/debug_exceptions.rb +32 -58
  65. data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
  66. data/lib/action_dispatch/middleware/debug_view.rb +50 -0
  67. data/lib/action_dispatch/middleware/exception_wrapper.rb +36 -7
  68. data/lib/action_dispatch/middleware/flash.rb +1 -1
  69. data/lib/action_dispatch/middleware/host_authorization.rb +103 -0
  70. data/lib/action_dispatch/middleware/remote_ip.rb +6 -8
  71. data/lib/action_dispatch/middleware/request_id.rb +2 -2
  72. data/lib/action_dispatch/middleware/session/abstract_store.rb +0 -14
  73. data/lib/action_dispatch/middleware/session/cache_store.rb +6 -11
  74. data/lib/action_dispatch/middleware/session/cookie_store.rb +11 -27
  75. data/lib/action_dispatch/middleware/ssl.rb +8 -8
  76. data/lib/action_dispatch/middleware/stack.rb +2 -2
  77. data/lib/action_dispatch/middleware/static.rb +5 -6
  78. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
  79. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  80. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  81. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  82. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +20 -2
  83. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +4 -4
  84. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +2 -2
  85. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  86. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  87. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  88. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  89. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
  90. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +3 -0
  91. data/lib/action_dispatch/railtie.rb +1 -0
  92. data/lib/action_dispatch/request/session.rb +8 -6
  93. data/lib/action_dispatch/routing.rb +3 -2
  94. data/lib/action_dispatch/routing/inspector.rb +99 -50
  95. data/lib/action_dispatch/routing/mapper.rb +36 -29
  96. data/lib/action_dispatch/routing/polymorphic_routes.rb +3 -4
  97. data/lib/action_dispatch/routing/route_set.rb +11 -12
  98. data/lib/action_dispatch/routing/url_for.rb +1 -0
  99. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +3 -3
  100. data/lib/action_dispatch/testing/assertions/response.rb +2 -3
  101. data/lib/action_dispatch/testing/assertions/routing.rb +7 -2
  102. data/lib/action_dispatch/testing/integration.rb +11 -4
  103. data/lib/action_dispatch/testing/test_process.rb +2 -2
  104. data/lib/action_dispatch/testing/test_response.rb +4 -32
  105. data/lib/action_pack.rb +1 -1
  106. data/lib/action_pack/gem_version.rb +4 -4
  107. metadata +22 -20
@@ -32,7 +32,7 @@ module ActionDispatch
32
32
  req = ActionDispatch::Request.new env
33
33
 
34
34
  if req.get?
35
- path = req.path_info.chomp("/".freeze)
35
+ path = req.path_info.chomp("/")
36
36
  if path == @path
37
37
  return render_details(req)
38
38
  end
@@ -63,19 +63,19 @@ module ActionDispatch
63
63
 
64
64
  str = threads.map do |thread, info|
65
65
  if info[:exclusive]
66
- lock_state = "Exclusive".dup
66
+ lock_state = +"Exclusive"
67
67
  elsif info[:sharing] > 0
68
- lock_state = "Sharing".dup
68
+ lock_state = +"Sharing"
69
69
  lock_state << " x#{info[:sharing]}" if info[:sharing] > 1
70
70
  else
71
- lock_state = "No lock".dup
71
+ lock_state = +"No lock"
72
72
  end
73
73
 
74
74
  if info[:waiting]
75
75
  lock_state << " (yielded share)"
76
76
  end
77
77
 
78
- msg = "Thread #{info[:index]} [0x#{thread.__id__.to_s(16)} #{thread.status || 'dead'}] #{lock_state}\n".dup
78
+ msg = +"Thread #{info[:index]} [0x#{thread.__id__.to_s(16)} #{thread.status || 'dead'}] #{lock_state}\n"
79
79
 
80
80
  if info[:sleeper]
81
81
  msg << " Waiting in #{info[:sleeper]}"
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pp"
4
+
5
+ require "action_view"
6
+ require "action_view/base"
7
+
8
+ module ActionDispatch
9
+ class DebugView < ActionView::Base # :nodoc:
10
+ RESCUES_TEMPLATE_PATH = File.expand_path("templates", __dir__)
11
+
12
+ def initialize(assigns)
13
+ super([RESCUES_TEMPLATE_PATH], assigns)
14
+ end
15
+
16
+ def debug_params(params)
17
+ clean_params = params.clone
18
+ clean_params.delete("action")
19
+ clean_params.delete("controller")
20
+
21
+ if clean_params.empty?
22
+ "None"
23
+ else
24
+ PP.pp(clean_params, +"", 200)
25
+ end
26
+ end
27
+
28
+ def debug_headers(headers)
29
+ if headers.present?
30
+ headers.inspect.gsub(",", ",\n")
31
+ else
32
+ "None"
33
+ end
34
+ end
35
+
36
+ def debug_hash(object)
37
+ object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
38
+ end
39
+
40
+ def render(*)
41
+ logger = ActionView::Base.logger
42
+
43
+ if logger && logger.respond_to?(:silence)
44
+ logger.silence { super }
45
+ else
46
+ super
47
+ end
48
+ end
49
+ end
50
+ end
@@ -12,6 +12,7 @@ module ActionDispatch
12
12
  "ActionController::UnknownHttpMethod" => :method_not_allowed,
13
13
  "ActionController::NotImplemented" => :not_implemented,
14
14
  "ActionController::UnknownFormat" => :not_acceptable,
15
+ "ActionController::MissingExactTemplate" => :not_acceptable,
15
16
  "ActionController::InvalidAuthenticityToken" => :unprocessable_entity,
16
17
  "ActionController::InvalidCrossOriginRequest" => :unprocessable_entity,
17
18
  "ActionDispatch::Http::Parameters::ParseError" => :bad_request,
@@ -22,18 +23,20 @@ module ActionDispatch
22
23
  )
23
24
 
24
25
  cattr_accessor :rescue_templates, default: Hash.new("diagnostics").merge!(
25
- "ActionView::MissingTemplate" => "missing_template",
26
- "ActionController::RoutingError" => "routing_error",
27
- "AbstractController::ActionNotFound" => "unknown_action",
28
- "ActiveRecord::StatementInvalid" => "invalid_statement",
29
- "ActionView::Template::Error" => "template_error"
26
+ "ActionView::MissingTemplate" => "missing_template",
27
+ "ActionController::RoutingError" => "routing_error",
28
+ "AbstractController::ActionNotFound" => "unknown_action",
29
+ "ActiveRecord::StatementInvalid" => "invalid_statement",
30
+ "ActionView::Template::Error" => "template_error",
31
+ "ActionController::MissingExactTemplate" => "missing_exact_template",
30
32
  )
31
33
 
32
- attr_reader :backtrace_cleaner, :exception, :line_number, :file
34
+ attr_reader :backtrace_cleaner, :exception, :wrapped_causes, :line_number, :file
33
35
 
34
36
  def initialize(backtrace_cleaner, exception)
35
37
  @backtrace_cleaner = backtrace_cleaner
36
38
  @exception = original_exception(exception)
39
+ @wrapped_causes = wrapped_causes_for(exception, backtrace_cleaner)
37
40
 
38
41
  expand_backtrace if exception.is_a?(SyntaxError) || exception.cause.is_a?(SyntaxError)
39
42
  end
@@ -64,7 +67,11 @@ module ActionDispatch
64
67
  full_trace_with_ids = []
65
68
 
66
69
  full_trace.each_with_index do |trace, idx|
67
- trace_with_id = { id: idx, trace: trace }
70
+ trace_with_id = {
71
+ exception_object_id: @exception.object_id,
72
+ id: idx,
73
+ trace: trace
74
+ }
68
75
 
69
76
  if application_trace.include?(trace)
70
77
  application_trace_with_ids << trace_with_id
@@ -97,6 +104,18 @@ module ActionDispatch
97
104
  end
98
105
  end
99
106
 
107
+ def trace_to_show
108
+ if traces["Application Trace"].empty? && rescue_template != "routing_error"
109
+ "Full Trace"
110
+ else
111
+ "Application Trace"
112
+ end
113
+ end
114
+
115
+ def source_to_show_id
116
+ (traces[trace_to_show].first || {})[:id]
117
+ end
118
+
100
119
  private
101
120
 
102
121
  def backtrace
@@ -111,6 +130,16 @@ module ActionDispatch
111
130
  end
112
131
  end
113
132
 
133
+ def causes_for(exception)
134
+ return enum_for(__method__, exception) unless block_given?
135
+
136
+ yield exception while exception = exception.cause
137
+ end
138
+
139
+ def wrapped_causes_for(exception, backtrace_cleaner)
140
+ causes_for(exception).map { |cause| self.class.new(backtrace_cleaner, cause) }
141
+ end
142
+
114
143
  def clean_backtrace(*args)
115
144
  if backtrace_cleaner
116
145
  backtrace_cleaner.clean(backtrace, *args)
@@ -38,7 +38,7 @@ module ActionDispatch
38
38
  #
39
39
  # See docs on the FlashHash class for more details about the flash.
40
40
  class Flash
41
- KEY = "action_dispatch.request.flash_hash".freeze
41
+ KEY = "action_dispatch.request.flash_hash"
42
42
 
43
43
  module RequestMethods
44
44
  # Access the contents of the flash. Use <tt>flash["notice"]</tt> to
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action_dispatch/http/request"
4
+
5
+ module ActionDispatch
6
+ # This middleware guards from DNS rebinding attacks by white-listing the
7
+ # hosts a request can be sent to.
8
+ #
9
+ # When a request comes to an unauthorized host, the +response_app+
10
+ # application will be executed and rendered. If no +response_app+ is given, a
11
+ # default one will run, which responds with +403 Forbidden+.
12
+ class HostAuthorization
13
+ class Permissions # :nodoc:
14
+ def initialize(hosts)
15
+ @hosts = sanitize_hosts(hosts)
16
+ end
17
+
18
+ def empty?
19
+ @hosts.empty?
20
+ end
21
+
22
+ def allows?(host)
23
+ @hosts.any? do |allowed|
24
+ allowed === host
25
+ rescue
26
+ # IPAddr#=== raises an error if you give it a hostname instead of
27
+ # IP. Treat similar errors as blocked access.
28
+ false
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def sanitize_hosts(hosts)
35
+ Array(hosts).map do |host|
36
+ case host
37
+ when Regexp then sanitize_regexp(host)
38
+ when String then sanitize_string(host)
39
+ else host
40
+ end
41
+ end
42
+ end
43
+
44
+ def sanitize_regexp(host)
45
+ /\A#{host}\z/
46
+ end
47
+
48
+ def sanitize_string(host)
49
+ if host.start_with?(".")
50
+ /\A(.+\.)?#{Regexp.escape(host[1..-1])}\z/
51
+ else
52
+ host
53
+ end
54
+ end
55
+ end
56
+
57
+ DEFAULT_RESPONSE_APP = -> env do
58
+ request = Request.new(env)
59
+
60
+ format = request.xhr? ? "text/plain" : "text/html"
61
+ template = DebugView.new(host: request.host)
62
+ body = template.render(template: "rescues/blocked_host", layout: "rescues/layout")
63
+
64
+ [403, {
65
+ "Content-Type" => "#{format}; charset=#{Response.default_charset}",
66
+ "Content-Length" => body.bytesize.to_s,
67
+ }, [body]]
68
+ end
69
+
70
+ def initialize(app, hosts, response_app = nil)
71
+ @app = app
72
+ @permissions = Permissions.new(hosts)
73
+ @response_app = response_app || DEFAULT_RESPONSE_APP
74
+ end
75
+
76
+ def call(env)
77
+ return @app.call(env) if @permissions.empty?
78
+
79
+ request = Request.new(env)
80
+
81
+ if authorized?(request)
82
+ mark_as_authorized(request)
83
+ @app.call(env)
84
+ else
85
+ @response_app.call(env)
86
+ end
87
+ end
88
+
89
+ private
90
+
91
+ def authorized?(request)
92
+ origin_host = request.get_header("HTTP_HOST").to_s.sub(/:\d+\z/, "")
93
+ forwarded_host = request.x_forwarded_host.to_s.split(/,\s?/).last.to_s.sub(/:\d+\z/, "")
94
+
95
+ @permissions.allows?(origin_host) &&
96
+ (forwarded_host.blank? || @permissions.allows?(forwarded_host))
97
+ end
98
+
99
+ def mark_as_authorized(request)
100
+ request.set_header("action_dispatch.authorized_host", request.host)
101
+ end
102
+ end
103
+ end
@@ -162,14 +162,12 @@ module ActionDispatch
162
162
  # Split the comma-separated list into an array of strings.
163
163
  ips = header.strip.split(/[,\s]+/)
164
164
  ips.select do |ip|
165
- begin
166
- # Only return IPs that are valid according to the IPAddr#new method.
167
- range = IPAddr.new(ip).to_range
168
- # We want to make sure nobody is sneaking a netmask in.
169
- range.begin == range.end
170
- rescue ArgumentError
171
- nil
172
- end
165
+ # Only return IPs that are valid according to the IPAddr#new method.
166
+ range = IPAddr.new(ip).to_range
167
+ # We want to make sure nobody is sneaking a netmask in.
168
+ range.begin == range.end
169
+ rescue ArgumentError
170
+ nil
173
171
  end
174
172
  end
175
173
 
@@ -15,7 +15,7 @@ module ActionDispatch
15
15
  # The unique request id can be used to trace a request end-to-end and would typically end up being part of log files
16
16
  # from multiple pieces of the stack.
17
17
  class RequestId
18
- X_REQUEST_ID = "X-Request-Id".freeze #:nodoc:
18
+ X_REQUEST_ID = "X-Request-Id" #:nodoc:
19
19
 
20
20
  def initialize(app)
21
21
  @app = app
@@ -30,7 +30,7 @@ module ActionDispatch
30
30
  private
31
31
  def make_request_id(request_id)
32
32
  if request_id.presence
33
- request_id.gsub(/[^\w\-@]/, "".freeze).first(255)
33
+ request_id.gsub(/[^\w\-@]/, "").first(255)
34
34
  else
35
35
  internal_request_id
36
36
  end
@@ -83,21 +83,7 @@ module ActionDispatch
83
83
  include SessionObject
84
84
 
85
85
  private
86
- def set_cookie(request, session_id, cookie)
87
- request.cookie_jar[key] = cookie
88
- end
89
- end
90
-
91
- class AbstractSecureStore < Rack::Session::Abstract::PersistedSecure
92
- include Compatibility
93
- include StaleSessionCheck
94
- include SessionObject
95
-
96
- def generate_sid
97
- Rack::Session::SessionId.new(super)
98
- end
99
86
 
100
- private
101
87
  def set_cookie(request, session_id, cookie)
102
88
  request.cookie_jar[key] = cookie
103
89
  end
@@ -12,7 +12,7 @@ module ActionDispatch
12
12
  # * <tt>cache</tt> - The cache to use. If it is not specified, <tt>Rails.cache</tt> will be used.
13
13
  # * <tt>expire_after</tt> - The length of time a session will be stored before automatically expiring.
14
14
  # By default, the <tt>:expires_in</tt> option of the cache is used.
15
- class CacheStore < AbstractSecureStore
15
+ class CacheStore < AbstractStore
16
16
  def initialize(app, options = {})
17
17
  @cache = options[:cache] || Rails.cache
18
18
  options[:expire_after] ||= @cache.options[:expires_in]
@@ -21,7 +21,7 @@ module ActionDispatch
21
21
 
22
22
  # Get a session from the cache.
23
23
  def find_session(env, sid)
24
- unless sid && (session = get_session_with_fallback(sid))
24
+ unless sid && (session = @cache.read(cache_key(sid)))
25
25
  sid, session = generate_sid, {}
26
26
  end
27
27
  [sid, session]
@@ -29,7 +29,7 @@ module ActionDispatch
29
29
 
30
30
  # Set a session in the cache.
31
31
  def write_session(env, sid, session, options)
32
- key = cache_key(sid.private_id)
32
+ key = cache_key(sid)
33
33
  if session
34
34
  @cache.write(key, session, expires_in: options[:expire_after])
35
35
  else
@@ -40,19 +40,14 @@ module ActionDispatch
40
40
 
41
41
  # Remove a session from the cache.
42
42
  def delete_session(env, sid, options)
43
- @cache.delete(cache_key(sid.private_id))
44
- @cache.delete(cache_key(sid.public_id))
43
+ @cache.delete(cache_key(sid))
45
44
  generate_sid
46
45
  end
47
46
 
48
47
  private
49
48
  # Turn the session id into a cache key.
50
- def cache_key(id)
51
- "_session_id:#{id}"
52
- end
53
-
54
- def get_session_with_fallback(sid)
55
- @cache.read(cache_key(sid.private_id)) || @cache.read(cache_key(sid.public_id))
49
+ def cache_key(sid)
50
+ "_session_id:#{sid}"
56
51
  end
57
52
  end
58
53
  end
@@ -16,23 +16,17 @@ module ActionDispatch
16
16
  # The cookie jar used for storage is automatically configured to be the
17
17
  # best possible option given your application's configuration.
18
18
  #
19
- # If you only have secret_token set, your cookies will be signed, but
20
- # not encrypted. This means a user cannot alter their +user_id+ without
21
- # knowing your app's secret key, but can easily read their +user_id+. This
22
- # was the default for Rails 3 apps.
23
- #
24
19
  # Your cookies will be encrypted using your apps secret_key_base. This
25
20
  # goes a step further than signed cookies in that encrypted cookies cannot
26
21
  # be altered or read by users. This is the default starting in Rails 4.
27
22
  #
28
- # Configure your session store in <tt>config/initializers/session_store.rb</tt>:
23
+ # Configure your session store in an initializer:
29
24
  #
30
25
  # Rails.application.config.session_store :cookie_store, key: '_your_app_session'
31
26
  #
32
- # In the development and test environments your application's secret key base is
33
- # generated by Rails and stored in a temporary file in <tt>tmp/development_secret.txt</tt>.
34
- # In all other environments, it is stored encrypted in the
35
- # <tt>config/credentials.yml.enc</tt> file.
27
+ # By default, your secret key base is derived from your application name in
28
+ # the test and development environments. In all other environments, it is stored
29
+ # encrypted in the <tt>config/credentials.yml.enc</tt> file.
36
30
  #
37
31
  # If your application was not updated to Rails 5.2 defaults, the secret_key_base
38
32
  # will be found in the old <tt>config/secrets.yml</tt> file.
@@ -51,16 +45,7 @@ module ActionDispatch
51
45
  # would set the session cookie to expire automatically 14 days after creation.
52
46
  # Other useful options include <tt>:key</tt>, <tt>:secure</tt> and
53
47
  # <tt>:httponly</tt>.
54
- class CookieStore < AbstractSecureStore
55
- class SessionId < DelegateClass(Rack::Session::SessionId)
56
- attr_reader :cookie_value
57
-
58
- def initialize(session_id, cookie_value = {})
59
- super(session_id)
60
- @cookie_value = cookie_value
61
- end
62
- end
63
-
48
+ class CookieStore < AbstractStore
64
49
  def initialize(app, options = {})
65
50
  super(app, options.merge!(cookie_only: true))
66
51
  end
@@ -68,7 +53,7 @@ module ActionDispatch
68
53
  def delete_session(req, session_id, options)
69
54
  new_sid = generate_sid unless options[:drop]
70
55
  # Reset hash and Assign the new session id
71
- req.set_header("action_dispatch.request.unsigned_session_cookie", new_sid ? { "session_id" => new_sid.public_id } : {})
56
+ req.set_header("action_dispatch.request.unsigned_session_cookie", new_sid ? { "session_id" => new_sid } : {})
72
57
  new_sid
73
58
  end
74
59
 
@@ -76,7 +61,7 @@ module ActionDispatch
76
61
  stale_session_check! do
77
62
  data = unpacked_cookie_data(req)
78
63
  data = persistent_session_id!(data)
79
- [Rack::Session::SessionId.new(data["session_id"]), data]
64
+ [data["session_id"], data]
80
65
  end
81
66
  end
82
67
 
@@ -84,8 +69,7 @@ module ActionDispatch
84
69
 
85
70
  def extract_session_id(req)
86
71
  stale_session_check! do
87
- sid = unpacked_cookie_data(req)["session_id"]
88
- sid && Rack::Session::SessionId.new(sid)
72
+ unpacked_cookie_data(req)["session_id"]
89
73
  end
90
74
  end
91
75
 
@@ -103,13 +87,13 @@ module ActionDispatch
103
87
 
104
88
  def persistent_session_id!(data, sid = nil)
105
89
  data ||= {}
106
- data["session_id"] ||= sid || generate_sid.public_id
90
+ data["session_id"] ||= sid || generate_sid
107
91
  data
108
92
  end
109
93
 
110
94
  def write_session(req, sid, session_data, options)
111
- session_data["session_id"] = sid.public_id
112
- SessionId.new(sid, session_data)
95
+ session_data["session_id"] = sid
96
+ session_data
113
97
  end
114
98
 
115
99
  def set_cookie(request, session_id, cookie)