actionpack 5.0.0.beta2 → 5.0.0.beta3

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -5
  3. data/lib/abstract_controller.rb +6 -0
  4. data/lib/abstract_controller/caching.rb +62 -0
  5. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +3 -8
  6. data/lib/action_controller.rb +4 -6
  7. data/lib/action_controller/caching.rb +12 -55
  8. data/lib/action_controller/log_subscriber.rb +3 -1
  9. data/lib/action_controller/metal.rb +1 -4
  10. data/lib/action_controller/metal/instrumentation.rb +2 -2
  11. data/lib/action_controller/metal/live.rb +41 -25
  12. data/lib/action_controller/metal/request_forgery_protection.rb +3 -1
  13. data/lib/action_controller/metal/strong_parameters.rb +22 -22
  14. data/lib/action_controller/test_case.rb +14 -3
  15. data/lib/action_dispatch/http/mime_types.rb +3 -1
  16. data/lib/action_dispatch/http/parameters.rb +15 -6
  17. data/lib/action_dispatch/http/request.rb +4 -0
  18. data/lib/action_dispatch/http/response.rb +1 -0
  19. data/lib/action_dispatch/journey/route.rb +3 -2
  20. data/lib/action_dispatch/journey/router.rb +0 -3
  21. data/lib/action_dispatch/middleware/cookies.rb +6 -1
  22. data/lib/action_dispatch/middleware/debug_exceptions.rb +10 -5
  23. data/lib/action_dispatch/middleware/params_parser.rb +1 -0
  24. data/lib/action_dispatch/middleware/session/cookie_store.rb +1 -1
  25. data/lib/action_dispatch/request/session.rb +10 -16
  26. data/lib/action_dispatch/routing.rb +2 -3
  27. data/lib/action_dispatch/routing/inspector.rb +4 -3
  28. data/lib/action_dispatch/routing/mapper.rb +3 -1
  29. data/lib/action_dispatch/routing/route_set.rb +1 -1
  30. data/lib/action_dispatch/routing/url_for.rb +1 -1
  31. data/lib/action_dispatch/testing/assertions/routing.rb +1 -0
  32. data/lib/action_dispatch/testing/integration.rb +98 -5
  33. data/lib/action_dispatch/testing/test_response.rb +6 -0
  34. data/lib/action_pack/gem_version.rb +1 -1
  35. metadata +11 -12
  36. data/lib/action_dispatch/journey/backwards.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b471942b30689112172143f0c7f110a47bb07c1
4
- data.tar.gz: 96f4cb5ab8175de829b41313fca5068e8d37e081
3
+ metadata.gz: c2847271b11f9c0787c4d0468c83fac6b307cbce
4
+ data.tar.gz: b8df093bb286c2d9160a70cfd9d22a8343affcad
5
5
  SHA512:
6
- metadata.gz: dd1182095560e1b846a1fa4d793481ace31c98481efc8027f37815a0c1d98196e04b77466849bdcb13563e7c9345739461088cbb0d365dcfa945034619001f88
7
- data.tar.gz: 1932992f247727b865f236e20d8a286d1aeb8641c10e351386e976dad9f8a69f9cfb869d27b73cded695632de855be978c75de88be55a9abd8cbe36b8c87ee97
6
+ metadata.gz: 9d456ad1bbbd96908af0c0febd7922af482d88e315b83e3debba4aafe603fa3d531481c63b4e88a973b7a1910d93462e181a1cb780715aadc6d7e2677594a411
7
+ data.tar.gz: 27395600e033a142f00a7550bd97d96003af16a9c81e5c1e128759e50cc5c6ca21be046f5fa7e6c77234778eb670e810c3ee9d40c7d2d22e022b5e032a2a9a19
@@ -1,10 +1,75 @@
1
+ ## Rails 5.0.0.beta3 (February 24, 2016) ##
2
+
3
+ * Update session to have indifferent access across multiple requests.
4
+
5
+ session[:deep][:hash] = "Magic"
6
+
7
+ session[:deep][:hash] == "Magic"
8
+ session[:deep]["hash"] == "Magic"
9
+
10
+ *Tom Prats*
11
+
12
+ * Add application/gzip as a default mime type.
13
+
14
+ *Mehmet Emin İNAÇ*
15
+
16
+ * Add request encoding and response parsing to integration tests.
17
+
18
+ What previously was:
19
+
20
+ ```ruby
21
+ require 'test_helper'
22
+
23
+ class ApiTest < ActionDispatch::IntegrationTest
24
+ test 'creates articles' do
25
+ assert_difference -> { Article.count } do
26
+ post articles_path(format: :json),
27
+ params: { article: { title: 'Ahoy!' } }.to_json,
28
+ headers: { 'Content-Type' => 'application/json' }
29
+ end
30
+
31
+ assert_equal({ 'id' => Article.last.id, 'title' => 'Ahoy!' }, JSON.parse(response.body))
32
+ end
33
+ end
34
+ ```
35
+
36
+ Can now be written as:
37
+
38
+ ```ruby
39
+ require 'test_helper'
40
+
41
+ class ApiTest < ActionDispatch::IntegrationTest
42
+ test 'creates articles' do
43
+ assert_difference -> { Article.count } do
44
+ post articles_path, params: { article: { title: 'Ahoy!' } }, as: :json
45
+ end
46
+
47
+ assert_equal({ 'id' => Article.last.id, 'title' => 'Ahoy!' }, response.parsed_body)
48
+ end
49
+ end
50
+ ```
51
+
52
+ Passing `as: :json` to integration test request helpers will set the format,
53
+ content type and encode the parameters as JSON.
54
+
55
+ Then on the response side, `parsed_body` will parse the body according to the
56
+ content type the response has.
57
+
58
+ Currently JSON is the only supported MIME type. Add your own with
59
+ `ActionDispatch::IntegrationTest.register_encoder`.
60
+
61
+ *Kasper Timm Hansen*
62
+
63
+ * Add image/svg+xml as a default mime type.
64
+
65
+ *DHH*
66
+
1
67
  ## Rails 5.0.0.beta2 (February 01, 2016) ##
2
68
 
3
- * Add `-g` and `-c` (short for _grep_ and _controller_ respectively) options
4
- to `bin/rake routes`. These options return the url `name`, `verb` and
69
+ * Add `-g` and `-c` options to `bin/rails routes`. These options return the url `name`, `verb` and
5
70
  `path` field that match the pattern or match a specific controller.
6
71
 
7
- Deprecate `CONTROLLER` env variable in `bin/rake routes`.
72
+ Deprecate `CONTROLLER` env variable in `bin/rails routes`.
8
73
 
9
74
  See #18902.
10
75
 
@@ -183,11 +248,11 @@
183
248
  * Accessing mime types via constants like `Mime::HTML` is deprecated. Please
184
249
  change code like this:
185
250
 
186
- Mime::HTML
251
+ Mime::HTML
187
252
 
188
253
  To this:
189
254
 
190
- Mime[:html]
255
+ Mime[:html]
191
256
 
192
257
  This change is so that Rails will not manage a list of constants, and fixes
193
258
  an issue where if a type isn't registered you could possibly get the wrong
@@ -6,6 +6,7 @@ module AbstractController
6
6
  extend ActiveSupport::Autoload
7
7
 
8
8
  autoload :Base
9
+ autoload :Caching
9
10
  autoload :Callbacks
10
11
  autoload :Collector
11
12
  autoload :DoubleRenderError, "abstract_controller/rendering"
@@ -15,4 +16,9 @@ module AbstractController
15
16
  autoload :Translation
16
17
  autoload :AssetPaths
17
18
  autoload :UrlFor
19
+
20
+ def self.eager_load!
21
+ super
22
+ AbstractController::Caching.eager_load!
23
+ end
18
24
  end
@@ -0,0 +1,62 @@
1
+ module AbstractController
2
+ module Caching
3
+ extend ActiveSupport::Concern
4
+ extend ActiveSupport::Autoload
5
+
6
+ eager_autoload do
7
+ autoload :Fragments
8
+ end
9
+
10
+ module ConfigMethods
11
+ def cache_store
12
+ config.cache_store
13
+ end
14
+
15
+ def cache_store=(store)
16
+ config.cache_store = ActiveSupport::Cache.lookup_store(store)
17
+ end
18
+
19
+ private
20
+ def cache_configured?
21
+ perform_caching && cache_store
22
+ end
23
+ end
24
+
25
+ include ConfigMethods
26
+ include AbstractController::Caching::Fragments
27
+
28
+ included do
29
+ extend ConfigMethods
30
+
31
+ config_accessor :default_static_extension
32
+ self.default_static_extension ||= '.html'
33
+
34
+ config_accessor :perform_caching
35
+ self.perform_caching = true if perform_caching.nil?
36
+
37
+ class_attribute :_view_cache_dependencies
38
+ self._view_cache_dependencies = []
39
+ helper_method :view_cache_dependencies if respond_to?(:helper_method)
40
+ end
41
+
42
+ module ClassMethods
43
+ def view_cache_dependency(&dependency)
44
+ self._view_cache_dependencies += [dependency]
45
+ end
46
+ end
47
+
48
+ def view_cache_dependencies
49
+ self.class._view_cache_dependencies.map { |dep| instance_exec(&dep) }.compact
50
+ end
51
+
52
+ protected
53
+ # Convenience accessor.
54
+ def cache(key, options = {}, &block)
55
+ if cache_configured?
56
+ cache_store.fetch(ActiveSupport::Cache.expand_cache_key(key, :controller), options, &block)
57
+ else
58
+ yield
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,4 +1,4 @@
1
- module ActionController
1
+ module AbstractController
2
2
  module Caching
3
3
  # Fragment caching is used for caching various blocks within
4
4
  # views without caching the entire action as a whole. This is
@@ -135,13 +135,8 @@ module ActionController
135
135
  end
136
136
 
137
137
  def instrument_fragment_cache(name, key) # :nodoc:
138
- payload = {
139
- controller: controller_name,
140
- action: action_name,
141
- key: key
142
- }
143
-
144
- ActiveSupport::Notifications.instrument("#{name}.action_controller", payload) { yield }
138
+ payload = instrument_payload(key)
139
+ ActiveSupport::Notifications.instrument("#{name}.#{instrument_name}", payload) { yield }
145
140
  end
146
141
  end
147
142
  end
@@ -9,12 +9,15 @@ module ActionController
9
9
 
10
10
  autoload :API
11
11
  autoload :Base
12
- autoload :Caching
13
12
  autoload :Metal
14
13
  autoload :Middleware
15
14
  autoload :Renderer
16
15
  autoload :FormBuilder
17
16
 
17
+ eager_autoload do
18
+ autoload :Caching
19
+ end
20
+
18
21
  autoload_under "metal" do
19
22
  autoload :ConditionalGet
20
23
  autoload :Cookies
@@ -47,11 +50,6 @@ module ActionController
47
50
 
48
51
  autoload :TestCase, 'action_controller/test_case'
49
52
  autoload :TemplateAssertions, 'action_controller/test_case'
50
-
51
- def self.eager_load!
52
- super
53
- ActionController::Caching.eager_load!
54
- end
55
53
  end
56
54
 
57
55
  # Common Active Support usage in Action Controller
@@ -1,6 +1,3 @@
1
- require 'fileutils'
2
- require 'uri'
3
-
4
1
  module ActionController
5
2
  # \Caching is a cheap way of speeding up slow applications by keeping the result of
6
3
  # calculations, renderings, and database calls around for subsequent requests.
@@ -23,65 +20,25 @@ module ActionController
23
20
  # config.action_controller.cache_store = :mem_cache_store, Memcached::Rails.new('localhost:11211')
24
21
  # config.action_controller.cache_store = MyOwnStore.new('parameter')
25
22
  module Caching
26
- extend ActiveSupport::Concern
27
23
  extend ActiveSupport::Autoload
28
-
29
- eager_autoload do
30
- autoload :Fragments
31
- end
32
-
33
- module ConfigMethods
34
- def cache_store
35
- config.cache_store
36
- end
37
-
38
- def cache_store=(store)
39
- config.cache_store = ActiveSupport::Cache.lookup_store(store)
40
- end
41
-
42
- private
43
- def cache_configured?
44
- perform_caching && cache_store
45
- end
46
- end
47
-
48
- include AbstractController::Callbacks
49
-
50
- include ConfigMethods
51
- include Fragments
24
+ extend ActiveSupport::Concern
52
25
 
53
26
  included do
54
- extend ConfigMethods
55
-
56
- config_accessor :default_static_extension
57
- self.default_static_extension ||= '.html'
58
-
59
- config_accessor :perform_caching
60
- self.perform_caching = true if perform_caching.nil?
61
-
62
- class_attribute :_view_cache_dependencies
63
- self._view_cache_dependencies = []
64
- helper_method :view_cache_dependencies if respond_to?(:helper_method)
27
+ include AbstractController::Caching
65
28
  end
66
29
 
67
- module ClassMethods
68
- def view_cache_dependency(&dependency)
69
- self._view_cache_dependencies += [dependency]
70
- end
71
- end
30
+ private
72
31
 
73
- def view_cache_dependencies
74
- self.class._view_cache_dependencies.map { |dep| instance_exec(&dep) }.compact
75
- end
32
+ def instrument_payload(key)
33
+ {
34
+ controller: controller_name,
35
+ action: action_name,
36
+ key: key
37
+ }
38
+ end
76
39
 
77
- protected
78
- # Convenience accessor.
79
- def cache(key, options = {}, &block)
80
- if cache_configured?
81
- cache_store.fetch(ActiveSupport::Cache.expand_cache_key(key, :controller), options, &block)
82
- else
83
- yield
84
- end
40
+ def instrument_name
41
+ "action_controller"
85
42
  end
86
43
  end
87
44
  end
@@ -25,7 +25,9 @@ module ActionController
25
25
  status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
26
26
  end
27
27
  message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
28
- message << " (#{additions.join(" | ".freeze)})" unless additions.blank?
28
+ message << " (#{additions.join(" | ".freeze)})" unless additions.empty?
29
+ message << "\n\n" if defined?(Rails.env) && Rails.env.development?
30
+
29
31
  message
30
32
  end
31
33
  end
@@ -175,10 +175,7 @@ module ActionController
175
175
  body = [body] unless body.nil? || body.respond_to?(:each)
176
176
  response.reset_body!
177
177
  return unless body
178
- body.each { |part|
179
- next if part.empty?
180
- response.write part
181
- }
178
+ response.body = body
182
179
  super
183
180
  end
184
181
 
@@ -19,9 +19,9 @@ module ActionController
19
19
  :controller => self.class.name,
20
20
  :action => self.action_name,
21
21
  :params => request.filtered_parameters,
22
- :format => request.format.try(:ref),
22
+ :format => request.format.ref,
23
23
  :method => request.request_method,
24
- :path => (request.fullpath rescue "unknown")
24
+ :path => request.fullpath
25
25
  }
26
26
 
27
27
  ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)
@@ -237,39 +237,55 @@ module ActionController
237
237
  # This processes the action in a child thread. It lets us return the
238
238
  # response code and headers back up the rack stack, and still process
239
239
  # the body in parallel with sending data to the client
240
- Thread.new {
241
- t2 = Thread.current
242
- t2.abort_on_exception = true
243
-
244
- # Since we're processing the view in a different thread, copy the
245
- # thread locals from the main thread to the child thread. :'(
246
- locals.each { |k,v| t2[k] = v }
247
-
248
- begin
249
- super(name)
250
- rescue => e
251
- if @_response.committed?
252
- begin
253
- @_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html
254
- @_response.stream.call_on_error
255
- rescue => exception
256
- log_error(exception)
257
- ensure
258
- log_error(e)
259
- @_response.stream.close
240
+ new_controller_thread {
241
+ ActiveSupport::Dependencies.interlock.running do
242
+ t2 = Thread.current
243
+
244
+ # Since we're processing the view in a different thread, copy the
245
+ # thread locals from the main thread to the child thread. :'(
246
+ locals.each { |k,v| t2[k] = v }
247
+
248
+ begin
249
+ super(name)
250
+ rescue => e
251
+ if @_response.committed?
252
+ begin
253
+ @_response.stream.write(ActionView::Base.streaming_completion_on_exception) if request.format == :html
254
+ @_response.stream.call_on_error
255
+ rescue => exception
256
+ log_error(exception)
257
+ ensure
258
+ log_error(e)
259
+ @_response.stream.close
260
+ end
261
+ else
262
+ error = e
260
263
  end
261
- else
262
- error = e
264
+ ensure
265
+ @_response.commit!
263
266
  end
264
- ensure
265
- @_response.commit!
266
267
  end
267
268
  }
268
269
 
269
- @_response.await_commit
270
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
271
+ @_response.await_commit
272
+ end
273
+
270
274
  raise error if error
271
275
  end
272
276
 
277
+ # Spawn a new thread to serve up the controller in. This is to get
278
+ # around the fact that Rack isn't based around IOs and we need to use
279
+ # a thread to stream data from the response bodies. Nobody should call
280
+ # this method except in Rails internals. Seriously!
281
+ def new_controller_thread # :nodoc:
282
+ Thread.new {
283
+ t2 = Thread.current
284
+ t2.abort_on_exception = true
285
+ yield
286
+ }
287
+ end
288
+
273
289
  def log_error(exception)
274
290
  logger = ActionController::Base.logger
275
291
  return unless logger
@@ -378,7 +378,9 @@ module ActionController #:nodoc:
378
378
  end
379
379
 
380
380
  def xor_byte_strings(s1, s2)
381
- s1.bytes.zip(s2.bytes).map { |(c1,c2)| c1 ^ c2 }.pack('c*')
381
+ s2_bytes = s2.bytes
382
+ s1.each_byte.with_index { |c1, i| s2_bytes[i] ^= c1 }
383
+ s2_bytes.pack('C*')
382
384
  end
383
385
 
384
386
  # The form's authenticity parameter. Override to provide your own.
@@ -109,7 +109,7 @@ module ActionController
109
109
  cattr_accessor :permit_all_parameters, instance_accessor: false
110
110
  cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false
111
111
 
112
- delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?, :inspect,
112
+ delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?,
113
113
  :as_json, to: :@parameters
114
114
 
115
115
  # By default, never raise an UnpermittedParameters exception if these
@@ -122,16 +122,6 @@ module ActionController
122
122
  cattr_accessor :always_permitted_parameters
123
123
  self.always_permitted_parameters = %w( controller action )
124
124
 
125
- def self.const_missing(const_name)
126
- return super unless const_name == :NEVER_UNPERMITTED_PARAMS
127
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
128
- `ActionController::Parameters::NEVER_UNPERMITTED_PARAMS` has been deprecated.
129
- Use `ActionController::Parameters.always_permitted_parameters` instead.
130
- MSG
131
-
132
- always_permitted_parameters
133
- end
134
-
135
125
  # Returns a new instance of <tt>ActionController::Parameters</tt>.
136
126
  # Also, sets the +permitted+ attribute to the default value of
137
127
  # <tt>ActionController::Parameters.permit_all_parameters</tt>.
@@ -154,17 +144,21 @@ module ActionController
154
144
  end
155
145
 
156
146
  # Returns true if another +Parameters+ object contains the same content and
157
- # permitted flag, or other Hash-like object contains the same content. This
158
- # override is in place so you can perform a comparison with `Hash`.
159
- def ==(other_hash)
160
- if other_hash.respond_to?(:permitted?)
161
- super
147
+ # permitted flag.
148
+ def ==(other)
149
+ if other.respond_to?(:permitted?)
150
+ self.permitted? == other.permitted? && self.parameters == other.parameters
151
+ elsif other.is_a?(Hash)
152
+ ActiveSupport::Deprecation.warn <<-WARNING.squish
153
+ Comparing equality between `ActionController::Parameters` and a
154
+ `Hash` is deprecated and will be removed in Rails 5.1. Please only do
155
+ comparisons between instances of `ActionController::Parameters`. If
156
+ you need to compare to a hash, first convert it using
157
+ `ActionController::Parameters#new`.
158
+ WARNING
159
+ @parameters == other.with_indifferent_access
162
160
  else
163
- if other_hash.is_a?(Hash)
164
- @parameters == other_hash.with_indifferent_access
165
- else
166
- @parameters == other_hash
167
- end
161
+ @parameters == other
168
162
  end
169
163
  end
170
164
 
@@ -584,6 +578,10 @@ module ActionController
584
578
  dup
585
579
  end
586
580
 
581
+ def inspect
582
+ "<#{self.class} #{@parameters} permitted: #{@permitted}>"
583
+ end
584
+
587
585
  def method_missing(method_sym, *args, &block)
588
586
  if @parameters.respond_to?(method_sym)
589
587
  message = <<-DEPRECATE.squish
@@ -603,12 +601,14 @@ module ActionController
603
601
  end
604
602
 
605
603
  protected
604
+ attr_reader :parameters
605
+
606
606
  def permitted=(new_permitted)
607
607
  @permitted = new_permitted
608
608
  end
609
609
 
610
610
  def fields_for_style?
611
- @parameters.all? { |k, v| k =~ /\A-?\d+\z/ && v.is_a?(Hash) }
611
+ @parameters.all? { |k, v| k =~ /\A-?\d+\z/ && (v.is_a?(Hash) || v.is_a?(Parameters)) }
612
612
  end
613
613
 
614
614
  private
@@ -12,6 +12,17 @@ module ActionController
12
12
  include Testing::Functional
13
13
  end
14
14
 
15
+ module Live
16
+ # Disable controller / rendering threads in tests. User tests can access
17
+ # the database on the main thread, so they could open a txn, then the
18
+ # controller thread will open a new connection and try to access data
19
+ # that's only visible to the main thread's txn. This is the problem in #23483
20
+ remove_method :new_controller_thread
21
+ def new_controller_thread # :nodoc:
22
+ yield
23
+ end
24
+ end
25
+
15
26
  # ActionController::TestCase will be deprecated and moved to a gem in Rails 5.1.
16
27
  # Please use ActionDispatch::IntegrationTest going forward.
17
28
  class TestRequest < ActionDispatch::TestRequest #:nodoc:
@@ -41,7 +52,7 @@ module ActionController
41
52
  self.session = session
42
53
  self.session_options = TestSession::DEFAULT_OPTIONS
43
54
  @custom_param_parsers = {
44
- Mime[:xml] => lambda { |raw_post| Hash.from_xml(raw_post)['hash'] }
55
+ xml: lambda { |raw_post| Hash.from_xml(raw_post)['hash'] }
45
56
  }
46
57
  end
47
58
 
@@ -94,7 +105,7 @@ module ActionController
94
105
  when :url_encoded_form
95
106
  data = non_path_parameters.to_query
96
107
  else
97
- @custom_param_parsers[content_mime_type] = ->(_) { non_path_parameters }
108
+ @custom_param_parsers[content_mime_type.symbol] = ->(_) { non_path_parameters }
98
109
  data = non_path_parameters.to_query
99
110
  end
100
111
  end
@@ -165,7 +176,7 @@ module ActionController
165
176
  def initialize(session = {})
166
177
  super(nil, nil)
167
178
  @id = SecureRandom.hex(16)
168
- @data = stringify_keys(session)
179
+ @data = session.with_indifferent_access
169
180
  @loaded = true
170
181
  end
171
182
 
@@ -14,6 +14,7 @@ Mime::Type.register "image/jpeg", :jpeg, [], %w(jpg jpeg jpe pjpeg)
14
14
  Mime::Type.register "image/gif", :gif, [], %w(gif)
15
15
  Mime::Type.register "image/bmp", :bmp, [], %w(bmp)
16
16
  Mime::Type.register "image/tiff", :tiff, [], %w(tif tiff)
17
+ Mime::Type.register "image/svg+xml", :svg
17
18
 
18
19
  Mime::Type.register "video/mpeg", :mpeg, [], %w(mpg mpeg mpe)
19
20
 
@@ -27,7 +28,8 @@ Mime::Type.register "application/x-www-form-urlencoded", :url_encoded_form
27
28
 
28
29
  # http://www.ietf.org/rfc/rfc4627.txt
29
30
  # http://www.json.org/JSONRequest.html
30
- Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest application/vnd.api+json )
31
+ Mime::Type.register "application/json", :json, %w( text/x-json application/jsonrequest )
31
32
 
32
33
  Mime::Type.register "application/pdf", :pdf, [], %w(pdf)
33
34
  Mime::Type.register "application/zip", :zip, [], %w(zip)
35
+ Mime::Type.register "application/gzip", :gzip, %w(application/x-gzip), %w(gz)
@@ -1,22 +1,31 @@
1
1
  module ActionDispatch
2
2
  module Http
3
3
  module Parameters
4
+ extend ActiveSupport::Concern
5
+
4
6
  PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
5
7
 
6
8
  DEFAULT_PARSERS = {
7
- Mime[:json] => lambda { |raw_post|
9
+ Mime[:json].symbol => -> (raw_post) {
8
10
  data = ActiveSupport::JSON.decode(raw_post)
9
11
  data.is_a?(Hash) ? data : {:_json => data}
10
12
  }
11
13
  }
12
14
 
13
- def self.included(klass)
14
- class << klass
15
- attr_accessor :parameter_parsers
15
+ included do
16
+ class << self
17
+ attr_reader :parameter_parsers
16
18
  end
17
19
 
18
- klass.parameter_parsers = DEFAULT_PARSERS
20
+ self.parameter_parsers = DEFAULT_PARSERS
19
21
  end
22
+
23
+ module ClassMethods
24
+ def parameter_parsers=(parsers) # :nodoc:
25
+ @parameter_parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key }
26
+ end
27
+ end
28
+
20
29
  # Returns both GET and POST \parameters in a single hash.
21
30
  def parameters
22
31
  params = get_header("action_dispatch.request.parameters")
@@ -51,7 +60,7 @@ module ActionDispatch
51
60
  def parse_formatted_parameters(parsers)
52
61
  return yield if content_length.zero?
53
62
 
54
- strategy = parsers.fetch(content_mime_type) { return yield }
63
+ strategy = parsers.fetch(content_mime_type.symbol) { return yield }
55
64
 
56
65
  begin
57
66
  strategy.call(raw_post)
@@ -403,6 +403,10 @@ module ActionDispatch
403
403
  def commit_flash
404
404
  end
405
405
 
406
+ def ssl?
407
+ super || scheme == 'wss'.freeze
408
+ end
409
+
406
410
  private
407
411
  def check_method(name)
408
412
  HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS[0...-1].join(', ')}, and #{HTTP_METHODS[-1]}")
@@ -1,5 +1,6 @@
1
1
  require 'active_support/core_ext/module/attribute_accessors'
2
2
  require 'action_dispatch/http/filter_redirect'
3
+ require 'action_dispatch/http/cache'
3
4
  require 'monitor'
4
5
 
5
6
  module ActionDispatch # :nodoc:
@@ -3,7 +3,7 @@ module ActionDispatch
3
3
  class Route # :nodoc:
4
4
  attr_reader :app, :path, :defaults, :name, :precedence
5
5
 
6
- attr_reader :constraints
6
+ attr_reader :constraints, :internal
7
7
  alias :conditions :constraints
8
8
 
9
9
  module VerbMatchers
@@ -55,7 +55,7 @@ module ActionDispatch
55
55
  ##
56
56
  # +path+ is a path constraint.
57
57
  # +constraints+ is a hash of constraints to be applied to this route.
58
- def initialize(name, app, path, constraints, required_defaults, defaults, request_method_match, precedence)
58
+ def initialize(name, app, path, constraints, required_defaults, defaults, request_method_match, precedence, internal = false)
59
59
  @name = name
60
60
  @app = app
61
61
  @path = path
@@ -70,6 +70,7 @@ module ActionDispatch
70
70
  @decorated_ast = nil
71
71
  @precedence = precedence
72
72
  @path_formatter = @path.build_formatter
73
+ @internal = internal
73
74
  end
74
75
 
75
76
  def ast
@@ -16,9 +16,6 @@ module ActionDispatch
16
16
  class RoutingError < ::StandardError # :nodoc:
17
17
  end
18
18
 
19
- # :nodoc:
20
- VERSION = '2.0.0'
21
-
22
19
  attr_accessor :routes
23
20
 
24
21
  def initialize(routes)
@@ -2,6 +2,7 @@ require 'active_support/core_ext/hash/keys'
2
2
  require 'active_support/key_generator'
3
3
  require 'active_support/message_verifier'
4
4
  require 'active_support/json'
5
+ require 'rack/utils'
5
6
 
6
7
  module ActionDispatch
7
8
  class Request
@@ -337,7 +338,7 @@ module ActionDispatch
337
338
  end
338
339
 
339
340
  def to_header
340
- @cookies.map { |k,v| "#{k}=#{v}" }.join ';'
341
+ @cookies.map { |k,v| "#{escape(k)}=#{escape(v)}" }.join '; '
341
342
  end
342
343
 
343
344
  def handle_options(options) #:nodoc:
@@ -419,6 +420,10 @@ module ActionDispatch
419
420
 
420
421
  private
421
422
 
423
+ def escape(string)
424
+ ::Rack::Utils.escape(string)
425
+ end
426
+
422
427
  def make_set_cookie_header(header)
423
428
  header = @set_cookies.inject(header) { |m, (k, v)|
424
429
  if write_cookie?(v)
@@ -156,15 +156,20 @@ module ActionDispatch
156
156
  trace = wrapper.framework_trace if trace.empty?
157
157
 
158
158
  ActiveSupport::Deprecation.silence do
159
- message = "\n#{exception.class} (#{exception.message}):\n"
160
- message << exception.annoted_source_code.to_s if exception.respond_to?(:annoted_source_code)
161
- message << " " << trace.join("\n ")
162
- logger.fatal("#{message}\n\n")
159
+ logger.fatal " "
160
+ logger.fatal "#{exception.class} (#{exception.message}):"
161
+ log_array logger, exception.annoted_source_code if exception.respond_to?(:annoted_source_code)
162
+ logger.fatal " "
163
+ log_array logger, trace
163
164
  end
164
165
  end
165
166
 
167
+ def log_array(logger, array)
168
+ array.map { |line| logger.fatal line }
169
+ end
170
+
166
171
  def logger(request)
167
- request.logger || stderr_logger
172
+ request.logger || ActionView::Base.logger || stderr_logger
168
173
  end
169
174
 
170
175
  def stderr_logger
@@ -37,6 +37,7 @@ module ActionDispatch
37
37
  # The +parsers+ argument can take Hash of parsers where key is identifying
38
38
  # content mime type, and value is a lambda that is going to process data.
39
39
  def self.new(app, parsers = {})
40
+ parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key }
40
41
  ActionDispatch::Request.parameter_parsers = ActionDispatch::Request::DEFAULT_PARSERS.merge(parsers)
41
42
  app
42
43
  end
@@ -23,7 +23,7 @@ module ActionDispatch
23
23
  # goes a step further than signed cookies in that encrypted cookies cannot
24
24
  # be altered or read by users. This is the default starting in Rails 4.
25
25
  #
26
- # If you have both secret_token and secret_key base set, your cookies will
26
+ # If you have both secret_token and secret_key_base set, your cookies will
27
27
  # be encrypted, and signed cookies generated by Rails 3 will be
28
28
  # transparently read and encrypted to provide a smooth upgrade path.
29
29
  #
@@ -9,7 +9,7 @@ module ActionDispatch
9
9
 
10
10
  # Singleton object used to determine if an optional param wasn't specified
11
11
  Unspecified = Object.new
12
-
12
+
13
13
  # Creates a session hash, merging the properties of the previous session if any
14
14
  def self.create(store, req, default_options)
15
15
  session_was = find req
@@ -61,7 +61,7 @@ module ActionDispatch
61
61
  def initialize(by, req)
62
62
  @by = by
63
63
  @req = req
64
- @delegate = {}
64
+ @delegate = {}.with_indifferent_access
65
65
  @loaded = false
66
66
  @exists = nil # we haven't checked yet
67
67
  end
@@ -88,13 +88,13 @@ module ActionDispatch
88
88
  # nil if the given key is not found in the session.
89
89
  def [](key)
90
90
  load_for_read!
91
- @delegate[key.to_s]
91
+ @delegate[key]
92
92
  end
93
93
 
94
94
  # Returns true if the session has the given key or false.
95
95
  def has_key?(key)
96
96
  load_for_read!
97
- @delegate.key?(key.to_s)
97
+ @delegate.key?(key)
98
98
  end
99
99
  alias :key? :has_key?
100
100
  alias :include? :has_key?
@@ -112,7 +112,7 @@ module ActionDispatch
112
112
  # Writes given value to given key of the session.
113
113
  def []=(key, value)
114
114
  load_for_write!
115
- @delegate[key.to_s] = value
115
+ @delegate[key] = value
116
116
  end
117
117
 
118
118
  # Clears the session.
@@ -139,13 +139,13 @@ module ActionDispatch
139
139
  # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
140
140
  def update(hash)
141
141
  load_for_write!
142
- @delegate.update stringify_keys(hash)
142
+ @delegate.update hash
143
143
  end
144
144
 
145
145
  # Deletes given key from the session.
146
146
  def delete(key)
147
147
  load_for_write!
148
- @delegate.delete key.to_s
148
+ @delegate.delete key
149
149
  end
150
150
 
151
151
  # Returns value of the given key from the session, or raises +KeyError+
@@ -165,9 +165,9 @@ module ActionDispatch
165
165
  def fetch(key, default=Unspecified, &block)
166
166
  load_for_read!
167
167
  if default == Unspecified
168
- @delegate.fetch(key.to_s, &block)
168
+ @delegate.fetch(key, &block)
169
169
  else
170
- @delegate.fetch(key.to_s, default, &block)
170
+ @delegate.fetch(key, default, &block)
171
171
  end
172
172
  end
173
173
 
@@ -211,15 +211,9 @@ module ActionDispatch
211
211
  def load!
212
212
  id, session = @by.load_session @req
213
213
  options[:id] = id
214
- @delegate.replace(stringify_keys(session))
214
+ @delegate.replace(session)
215
215
  @loaded = true
216
216
  end
217
-
218
- def stringify_keys(other)
219
- other.each_with_object({}) { |(key, value), hash|
220
- hash[key.to_s] = value
221
- }
222
- end
223
217
  end
224
218
  end
225
219
  end
@@ -159,7 +159,7 @@ module ActionDispatch
159
159
  #
160
160
  # controller 'geocode' do
161
161
  # get 'geocode/:postalcode' => :show, constraints: {
162
- # postalcode: /# Postcode format
162
+ # postalcode: /# Postalcode format
163
163
  # \d{5} #Prefix
164
164
  # (-\d{4})? #Suffix
165
165
  # /x
@@ -239,8 +239,7 @@ module ActionDispatch
239
239
  #
240
240
  # rails routes
241
241
  #
242
- # Target specific controllers by prefixing the command with <tt>--controller</tt> option
243
- # - or its <tt>-c</tt> shorthand.
242
+ # Target specific controllers by prefixing the command with <tt>-c</tt> option.
244
243
  #
245
244
  module Routing
246
245
  extend ActiveSupport::Autoload
@@ -41,7 +41,7 @@ module ActionDispatch
41
41
  end
42
42
 
43
43
  def internal?
44
- controller.to_s =~ %r{\Arails/(info|mailers|welcome)}
44
+ internal
45
45
  end
46
46
 
47
47
  def engine?
@@ -84,14 +84,15 @@ module ActionDispatch
84
84
  if filter.is_a?(Hash) && filter[:controller]
85
85
  { controller: /#{filter[:controller].downcase.sub(/_?controller\z/, '').sub('::', '/')}/ }
86
86
  elsif filter
87
- { controller: /#{filter}/, action: /#{filter}/ }
87
+ { controller: /#{filter}/, action: /#{filter}/, verb: /#{filter}/, name: /#{filter}/, path: /#{filter}/ }
88
88
  end
89
89
  end
90
90
 
91
91
  def filter_routes(filter)
92
92
  if filter
93
93
  @routes.select do |route|
94
- filter.any? { |default, value| route.defaults[default] =~ value }
94
+ route_wrapper = RouteWrapper.new(route)
95
+ filter.any? { |default, value| route_wrapper.send(default) =~ value }
95
96
  end
96
97
  else
97
98
  @routes
@@ -107,6 +107,7 @@ module ActionDispatch
107
107
  @ast = ast
108
108
  @anchor = anchor
109
109
  @via = via
110
+ @internal = options[:internal]
110
111
 
111
112
  path_params = ast.find_all(&:symbol?).map(&:to_sym)
112
113
 
@@ -148,7 +149,8 @@ module ActionDispatch
148
149
  required_defaults,
149
150
  defaults,
150
151
  request_method,
151
- precedence)
152
+ precedence,
153
+ @internal)
152
154
 
153
155
  route
154
156
  end
@@ -289,7 +289,7 @@ module ActionDispatch
289
289
  if last.permitted?
290
290
  args.pop.to_h
291
291
  else
292
- raise ArgumentError, "Generating an URL from non sanitized request parameters is insecure!"
292
+ raise ArgumentError, "Generating a URL from non sanitized request parameters is insecure!"
293
293
  end
294
294
  end
295
295
  helper.call self, args, options
@@ -173,7 +173,7 @@ module ActionDispatch
173
173
  route_name)
174
174
  when ActionController::Parameters
175
175
  unless options.permitted?
176
- raise ArgumentError.new("Generating an URL from non sanitized request parameters is insecure!")
176
+ raise ArgumentError.new("Generating a URL from non sanitized request parameters is insecure!")
177
177
  end
178
178
  route_name = options.delete :use_route
179
179
  _routes.url_for(options.to_h.symbolize_keys.
@@ -86,6 +86,7 @@ module ActionDispatch
86
86
  end
87
87
  # Load routes.rb if it hasn't been loaded.
88
88
 
89
+ options = options.clone
89
90
  generated_path, query_string_keys = @routes.generate_extras(options, defaults)
90
91
  found_extras = options.reject { |k, _| ! query_string_keys.include? k }
91
92
 
@@ -71,7 +71,7 @@ module ActionDispatch
71
71
  end
72
72
 
73
73
  # Performs an XMLHttpRequest request with the given parameters, mirroring
74
- # a request from the Prototype library.
74
+ # an AJAX request made from JavaScript.
75
75
  #
76
76
  # The request_method is +:get+, +:post+, +:patch+, +:put+, +:delete+ or
77
77
  # +:head+; the parameters are +nil+, a hash, or a url-encoded or multipart
@@ -321,7 +321,9 @@ module ActionDispatch
321
321
  end
322
322
 
323
323
  # Performs the actual request.
324
- def process(method, path, params: nil, headers: nil, env: nil, xhr: false)
324
+ def process(method, path, params: nil, headers: nil, env: nil, xhr: false, as: nil)
325
+ request_encoder = RequestEncoder.encoder(as)
326
+
325
327
  if path =~ %r{://}
326
328
  location = URI.parse(path)
327
329
  https! URI::HTTPS === location if location.scheme
@@ -330,14 +332,17 @@ module ActionDispatch
330
332
  url_host += ":#{location.port}" if default != location.port
331
333
  host! url_host
332
334
  end
333
- path = location.query ? "#{location.path}?#{location.query}" : location.path
335
+ path = request_encoder.append_format_to location.path
336
+ path = location.query ? "#{path}?#{location.query}" : path
337
+ else
338
+ path = request_encoder.append_format_to path
334
339
  end
335
340
 
336
341
  hostname, port = host.split(':')
337
342
 
338
343
  request_env = {
339
344
  :method => method,
340
- :params => params,
345
+ :params => request_encoder.encode_params(params),
341
346
 
342
347
  "SERVER_NAME" => hostname,
343
348
  "SERVER_PORT" => port || (https? ? "443" : "80"),
@@ -347,7 +352,7 @@ module ActionDispatch
347
352
  "REQUEST_URI" => path,
348
353
  "HTTP_HOST" => host,
349
354
  "REMOTE_ADDR" => remote_addr,
350
- "CONTENT_TYPE" => "application/x-www-form-urlencoded",
355
+ "CONTENT_TYPE" => request_encoder.content_type,
351
356
  "HTTP_ACCEPT" => accept
352
357
  }
353
358
 
@@ -376,6 +381,7 @@ module ActionDispatch
376
381
  response = _mock_session.last_response
377
382
  @response = ActionDispatch::TestResponse.from_response(response)
378
383
  @response.request = @request
384
+ @response.response_parser = RequestEncoder.parser(@response.content_type)
379
385
  @html_document = nil
380
386
  @url_options = nil
381
387
 
@@ -387,6 +393,56 @@ module ActionDispatch
387
393
  def build_full_uri(path, env)
388
394
  "#{env['rack.url_scheme']}://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{path}"
389
395
  end
396
+
397
+ class RequestEncoder # :nodoc:
398
+ @encoders = {}
399
+
400
+ attr_reader :response_parser
401
+
402
+ def initialize(mime_name, param_encoder, response_parser, url_encoded_form = false)
403
+ @mime = Mime[mime_name]
404
+
405
+ unless @mime
406
+ raise ArgumentError, "Can't register a request encoder for " \
407
+ "unregistered MIME Type: #{mime_name}. See `Mime::Type.register`."
408
+ end
409
+
410
+ @url_encoded_form = url_encoded_form
411
+ @path_format = ".#{@mime.symbol}" unless @url_encoded_form
412
+ @response_parser = response_parser || -> body { body }
413
+ @param_encoder = param_encoder || :"to_#{@mime.symbol}".to_proc
414
+ end
415
+
416
+ def append_format_to(path)
417
+ path << @path_format unless @url_encoded_form
418
+ path
419
+ end
420
+
421
+ def content_type
422
+ @mime.to_s
423
+ end
424
+
425
+ def encode_params(params)
426
+ @param_encoder.call(params)
427
+ end
428
+
429
+ def self.parser(content_type)
430
+ mime = Mime::Type.lookup(content_type)
431
+ encoder(mime ? mime.ref : nil).response_parser
432
+ end
433
+
434
+ def self.encoder(name)
435
+ @encoders[name] || WWWFormEncoder
436
+ end
437
+
438
+ def self.register_encoder(mime_name, param_encoder: nil, response_parser: nil)
439
+ @encoders[mime_name] = new(mime_name, param_encoder, response_parser)
440
+ end
441
+
442
+ register_encoder :json, response_parser: -> body { JSON.parse(body) }
443
+
444
+ WWWFormEncoder = new(:url_encoded_form, -> params { params }, nil, true)
445
+ end
390
446
  end
391
447
 
392
448
  module Runner
@@ -643,6 +699,39 @@ module ActionDispatch
643
699
  # end
644
700
  # end
645
701
  #
702
+ # You can also test your JSON API easily by setting what the request should
703
+ # be encoded as:
704
+ #
705
+ # require 'test_helper'
706
+ #
707
+ # class ApiTest < ActionDispatch::IntegrationTest
708
+ # test 'creates articles' do
709
+ # assert_difference -> { Article.count } do
710
+ # post articles_path, params: { article: { title: 'Ahoy!' } }, as: :json
711
+ # end
712
+ #
713
+ # assert_response :success
714
+ # assert_equal({ id: Arcticle.last.id, title: 'Ahoy!' }, response.parsed_body)
715
+ # end
716
+ # end
717
+ #
718
+ # The `as` option sets the format to JSON, sets the content type to
719
+ # 'application/json' and encodes the parameters as JSON.
720
+ #
721
+ # Calling `parsed_body` on the response parses the response body as what
722
+ # the last request was encoded as. If the request wasn't encoded `as` something,
723
+ # it's the same as calling `body`.
724
+ #
725
+ # For any custom MIME Types you've registered, you can even add your own encoders with:
726
+ #
727
+ # ActionDispatch::IntegrationTest.register_encoder :wibble,
728
+ # param_encoder: -> params { params.to_wibble },
729
+ # response_parser: -> body { body }
730
+ #
731
+ # Where `param_encoder` defines how the params should be encoded and
732
+ # `response_parser` defines how the response body should be parsed through
733
+ # `parsed_body`.
734
+ #
646
735
  # Consult the Rails Testing Guide for more.
647
736
 
648
737
  class IntegrationTest < ActiveSupport::TestCase
@@ -671,5 +760,9 @@ module ActionDispatch
671
760
  def document_root_element
672
761
  html_document.root
673
762
  end
763
+
764
+ def self.register_encoder(*args)
765
+ Integration::Session::RequestEncoder.register_encoder(*args)
766
+ end
674
767
  end
675
768
  end
@@ -18,5 +18,11 @@ module ActionDispatch
18
18
 
19
19
  # Was there a server-side error?
20
20
  alias_method :error?, :server_error?
21
+
22
+ attr_writer :response_parser # :nodoc:
23
+
24
+ def parsed_body
25
+ @parsed_body ||= @response_parser.call(body)
26
+ end
21
27
  end
22
28
  end
@@ -8,7 +8,7 @@ module ActionPack
8
8
  MAJOR = 5
9
9
  MINOR = 0
10
10
  TINY = 0
11
- PRE = "beta2"
11
+ PRE = "beta3"
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
14
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.beta2
4
+ version: 5.0.0.beta3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-01 00:00:00.000000000 Z
11
+ date: 2016-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 5.0.0.beta2
19
+ version: 5.0.0.beta3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 5.0.0.beta2
26
+ version: 5.0.0.beta3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rack
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -98,28 +98,28 @@ dependencies:
98
98
  requirements:
99
99
  - - '='
100
100
  - !ruby/object:Gem::Version
101
- version: 5.0.0.beta2
101
+ version: 5.0.0.beta3
102
102
  type: :runtime
103
103
  prerelease: false
104
104
  version_requirements: !ruby/object:Gem::Requirement
105
105
  requirements:
106
106
  - - '='
107
107
  - !ruby/object:Gem::Version
108
- version: 5.0.0.beta2
108
+ version: 5.0.0.beta3
109
109
  - !ruby/object:Gem::Dependency
110
110
  name: activemodel
111
111
  requirement: !ruby/object:Gem::Requirement
112
112
  requirements:
113
113
  - - '='
114
114
  - !ruby/object:Gem::Version
115
- version: 5.0.0.beta2
115
+ version: 5.0.0.beta3
116
116
  type: :development
117
117
  prerelease: false
118
118
  version_requirements: !ruby/object:Gem::Requirement
119
119
  requirements:
120
120
  - - '='
121
121
  - !ruby/object:Gem::Version
122
- version: 5.0.0.beta2
122
+ version: 5.0.0.beta3
123
123
  description: Web apps on Rails. Simple, battle-tested conventions for building and
124
124
  testing MVC web applications. Works with any Rack-compatible server.
125
125
  email: david@loudthinking.com
@@ -133,6 +133,8 @@ files:
133
133
  - lib/abstract_controller.rb
134
134
  - lib/abstract_controller/asset_paths.rb
135
135
  - lib/abstract_controller/base.rb
136
+ - lib/abstract_controller/caching.rb
137
+ - lib/abstract_controller/caching/fragments.rb
136
138
  - lib/abstract_controller/callbacks.rb
137
139
  - lib/abstract_controller/collector.rb
138
140
  - lib/abstract_controller/helpers.rb
@@ -146,7 +148,6 @@ files:
146
148
  - lib/action_controller/api/api_rendering.rb
147
149
  - lib/action_controller/base.rb
148
150
  - lib/action_controller/caching.rb
149
- - lib/action_controller/caching/fragments.rb
150
151
  - lib/action_controller/form_builder.rb
151
152
  - lib/action_controller/log_subscriber.rb
152
153
  - lib/action_controller/metal.rb
@@ -196,7 +197,6 @@ files:
196
197
  - lib/action_dispatch/http/upload.rb
197
198
  - lib/action_dispatch/http/url.rb
198
199
  - lib/action_dispatch/journey.rb
199
- - lib/action_dispatch/journey/backwards.rb
200
200
  - lib/action_dispatch/journey/formatter.rb
201
201
  - lib/action_dispatch/journey/gtg/builder.rb
202
202
  - lib/action_dispatch/journey/gtg/simulator.rb
@@ -301,9 +301,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
301
301
  requirements:
302
302
  - none
303
303
  rubyforge_project:
304
- rubygems_version: 2.5.2
304
+ rubygems_version: 2.5.1
305
305
  signing_key:
306
306
  specification_version: 4
307
307
  summary: Web-flow and rendering framework putting the VC in MVC (part of Rails).
308
308
  test_files: []
309
- has_rdoc:
@@ -1,5 +0,0 @@
1
- module Rack # :nodoc:
2
- Mount = ActionDispatch::Journey::Router
3
- Mount::RouteSet = ActionDispatch::Journey::Router
4
- Mount::RegexpWithNamedGroups = ActionDispatch::Journey::Path::Pattern
5
- end