From b43158afba7fb4de6a3530d4f4e940f0c89bd057 Mon Sep 17 00:00:00 2001 From: "Ryan T. Hosford" Date: Thu, 3 Mar 2016 00:43:18 -0600 Subject: Fixes #23964 - Adds #each_chunk to ActionDispatch::Response. it's a method which will be called by ActionDispatch::Response#each. - Make Response#each a proper method instead of delegating to @stream - In Live, instead of overriding #each, override #each_chunk. - `#each` should just spit out @str_body if it's already set - Adds #test_set_header_after_read_body_during_action to prove this fixes #23964 - Adds #test_each_isnt_called_if_str_body_is_written to ensure #each_chunk is not called when @str_body is available - Call `@response.sent!` in AC::TestCase's #perform so a test response acts a bit more like a real response. Makes test that call `#assert_stream_closed` pass again. - Additionally assert `#committed?` in `#assert_stream_closed` - Make test that was calling @response.stream.each pass again by calling @response.each instead. --- actionpack/lib/action_controller/metal/live.rb | 16 ++++++------ actionpack/lib/action_controller/test_case.rb | 2 ++ actionpack/lib/action_dispatch/http/response.rb | 33 ++++++++++++++++++------- actionpack/test/controller/live_stream_test.rb | 3 ++- actionpack/test/dispatch/live_response_test.rb | 2 +- actionpack/test/dispatch/response_test.rb | 33 +++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 19 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/live.rb b/actionpack/lib/action_controller/metal/live.rb index fc20e7a421..84a15d51a8 100644 --- a/actionpack/lib/action_controller/metal/live.rb +++ b/actionpack/lib/action_controller/metal/live.rb @@ -163,14 +163,6 @@ module ActionController end end - def each - @response.sending! - while str = @buf.pop - yield str - end - @response.sent! - end - # Write a 'close' event to the buffer; the producer/writing thread # uses this to notify us that it's finished supplying content. # @@ -210,6 +202,14 @@ module ActionController def call_on_error @error_callback.call end + + private + + def each_chunk(&block) + while str = @buf.pop + yield str + end + end end class Response < ActionDispatch::Response #:nodoc: all diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index ecd21f29ce..ed2edcbe06 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -554,6 +554,8 @@ module ActionController end @request.query_string = '' + @response.sent! + @response end diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index fa4c54701a..1515d59df3 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -68,7 +68,13 @@ module ActionDispatch # :nodoc: alias_method :headers, :header delegate :[], :[]=, :to => :@header - delegate :each, :to => :@stream + + def each(&block) + sending! + x = @stream.each(&block) + sent! + x + end CONTENT_TYPE = "Content-Type".freeze SET_COOKIE = "Set-Cookie".freeze @@ -97,10 +103,10 @@ module ActionDispatch # :nodoc: def body @str_body ||= begin - buf = '' - each { |chunk| buf << chunk } - buf - end + buf = '' + each { |chunk| buf << chunk } + buf + end end def write(string) @@ -112,10 +118,13 @@ module ActionDispatch # :nodoc: end def each(&block) - @response.sending! - x = @buf.each(&block) - @response.sent! - x + if @str_body + return enum_for(:each) unless block_given? + + yield @str_body + else + each_chunk(&block) + end end def abort @@ -129,6 +138,12 @@ module ActionDispatch # :nodoc: def closed? @closed end + + private + + def each_chunk(&block) + @buf.each(&block) # extract into own method + end end def self.create(status = 200, header = {}, body = [], default_headers: self.default_headers) diff --git a/actionpack/test/controller/live_stream_test.rb b/actionpack/test/controller/live_stream_test.rb index 0c3884cd38..298e12722b 100644 --- a/actionpack/test/controller/live_stream_test.rb +++ b/actionpack/test/controller/live_stream_test.rb @@ -246,7 +246,8 @@ module ActionController def assert_stream_closed assert response.stream.closed?, 'stream should be closed' - assert response.sent?, 'stream should be sent' + assert response.committed?, 'response should be committed' + assert response.sent?, 'response should be sent' end def capture_log_output diff --git a/actionpack/test/dispatch/live_response_test.rb b/actionpack/test/dispatch/live_response_test.rb index e4475f4233..de57c4be1d 100644 --- a/actionpack/test/dispatch/live_response_test.rb +++ b/actionpack/test/dispatch/live_response_test.rb @@ -65,7 +65,7 @@ module ActionController latch = Concurrent::CountDownLatch.new t = Thread.new { - @response.stream.each do + @response.each do latch.count_down end } diff --git a/actionpack/test/dispatch/response_test.rb b/actionpack/test/dispatch/response_test.rb index cd385982d9..b03791e499 100644 --- a/actionpack/test/dispatch/response_test.rb +++ b/actionpack/test/dispatch/response_test.rb @@ -37,6 +37,39 @@ class ResponseTest < ActiveSupport::TestCase assert_equal "closed stream", e.message end + def test_each_isnt_called_if_str_body_is_written + # Controller writes and reads response body + each_counter = 0 + @response.body = Object.new.tap {|o| o.singleton_class.send(:define_method, :each) { |&block| each_counter += 1; block.call 'foo' } } + @response['X-Foo'] = @response.body + + assert_equal 1, each_counter, "#each was not called once" + + # Build response + status, headers, body = @response.to_a + + assert_equal 200, status + assert_equal "foo", headers['X-Foo'] + assert_equal "foo", body.each.to_a.join + + # Show that #each was not called twice + assert_equal 1, each_counter, "#each was not called once" + end + + def test_set_header_after_read_body_during_action + @response.body + + # set header after the action reads back @response.body + @response['x-header'] = "Best of all possible worlds." + + # the response can be built. + status, headers, body = @response.to_a + assert_equal 200, status + assert_equal "", body.body + + assert_equal "Best of all possible worlds.", headers['x-header'] + end + def test_read_body_during_action @response.body = "Hello, World!" -- cgit v1.2.3 From f7a986012a6099445e20b6414d253ee0fc039118 Mon Sep 17 00:00:00 2001 From: eileencodes Date: Wed, 27 Apr 2016 15:47:22 -0500 Subject: Prep Rails 5 beta 4 --- actionpack/CHANGELOG.md | 2 ++ actionpack/lib/action_pack/gem_version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 5c856f1b36..85d2b14285 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,5 @@ +## Rails 5.0.0.beta4 (April 27, 2016) ## + * Routing: Refactor `:action` default handling to ensure that path parameters are not mutated during route generation. diff --git a/actionpack/lib/action_pack/gem_version.rb b/actionpack/lib/action_pack/gem_version.rb index 157f401f54..0fa51fa0fe 100644 --- a/actionpack/lib/action_pack/gem_version.rb +++ b/actionpack/lib/action_pack/gem_version.rb @@ -8,7 +8,7 @@ module ActionPack MAJOR = 5 MINOR = 0 TINY = 0 - PRE = "beta3" + PRE = "beta4" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end -- cgit v1.2.3 From e0b5a773ccb9c31a3fb76ba88813b6e41ca41466 Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Thu, 28 Apr 2016 20:26:58 -0400 Subject: Remove last uses of `@env[]` and `@env[]=` Last August (2015), @tenderlove worked to remove all `@env[]` and `@env[]=`, in favor of using `set_header`, `get_header`, etc. (Here's an [example commit](https://github.com/rails/rails/commit/f16a33b68efc3dc57cfafa27651b9a765e363fbf)). This PR should remove the last uses of these methods, and fully convert them to the newly standardized API. --- .../lib/action_dispatch/http/mime_negotiation.rb | 2 +- .../lib/action_dispatch/testing/test_request.rb | 22 +++++++++--------- actionpack/test/dispatch/test_request_test.rb | 27 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb index e9b25339dc..0a58ce2b96 100644 --- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb +++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb @@ -164,7 +164,7 @@ module ActionDispatch end def format_from_path_extension - path = @env['action_dispatch.original_path'] || @env['PATH_INFO'] + path = get_header('action_dispatch.original_path') || get_header('PATH_INFO') if match = path && path.match(/\.(\w+)\z/) Mime[match.captures.first] end diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb index ad1a7f7109..46523a8600 100644 --- a/actionpack/lib/action_dispatch/testing/test_request.rb +++ b/actionpack/lib/action_dispatch/testing/test_request.rb @@ -22,23 +22,23 @@ module ActionDispatch private_class_method :default_env def request_method=(method) - @env['REQUEST_METHOD'] = method.to_s.upcase + set_header('REQUEST_METHOD', method.to_s.upcase) end def host=(host) - @env['HTTP_HOST'] = host + set_header('HTTP_HOST', host) end def port=(number) - @env['SERVER_PORT'] = number.to_i + set_header('SERVER_PORT', number.to_i) end def request_uri=(uri) - @env['REQUEST_URI'] = uri + set_header('REQUEST_URI', uri) end def path=(path) - @env['PATH_INFO'] = path + set_header('PATH_INFO', path) end def action=(action_name) @@ -46,24 +46,24 @@ module ActionDispatch end def if_modified_since=(last_modified) - @env['HTTP_IF_MODIFIED_SINCE'] = last_modified + set_header('HTTP_IF_MODIFIED_SINCE', last_modified) end def if_none_match=(etag) - @env['HTTP_IF_NONE_MATCH'] = etag + set_header('HTTP_IF_NONE_MATCH', etag) end def remote_addr=(addr) - @env['REMOTE_ADDR'] = addr + set_header('REMOTE_ADDR', addr) end def user_agent=(user_agent) - @env['HTTP_USER_AGENT'] = user_agent + set_header('HTTP_USER_AGENT', user_agent) end def accept=(mime_types) - @env.delete('action_dispatch.request.accepts') - @env['HTTP_ACCEPT'] = Array(mime_types).collect(&:to_s).join(",") + delete_header('action_dispatch.request.accepts') + set_header('HTTP_ACCEPT', Array(mime_types).collect(&:to_s).join(",")) end end end diff --git a/actionpack/test/dispatch/test_request_test.rb b/actionpack/test/dispatch/test_request_test.rb index 51c469a61a..3c19cbd68a 100644 --- a/actionpack/test/dispatch/test_request_test.rb +++ b/actionpack/test/dispatch/test_request_test.rb @@ -88,6 +88,33 @@ class TestRequestTest < ActiveSupport::TestCase assert_equal 'GoogleBot', req.user_agent end + test "setter methods" do + req = ActionDispatch::TestRequest.create({}) + get = 'GET' + + [ + 'request_method=', 'host=', 'request_uri=', 'path=', 'if_modified_since=', 'if_none_match=', + 'remote_addr=', 'user_agent=', 'accept=' + ].each do |method| + req.send(method, get) + end + + req.port = 8080 + req.accept = 'hello goodbye' + + assert_equal(get, req.get_header('REQUEST_METHOD')) + assert_equal(get, req.get_header('HTTP_HOST')) + assert_equal(8080, req.get_header('SERVER_PORT')) + assert_equal(get, req.get_header('REQUEST_URI')) + assert_equal(get, req.get_header('PATH_INFO')) + assert_equal(get, req.get_header('HTTP_IF_MODIFIED_SINCE')) + assert_equal(get, req.get_header('HTTP_IF_NONE_MATCH')) + assert_equal(get, req.get_header('REMOTE_ADDR')) + assert_equal(get, req.get_header('HTTP_USER_AGENT')) + assert_nil(req.get_header('action_dispatch.request.accepts')) + assert_equal('hello goodbye', req.get_header('HTTP_ACCEPT')) + end + private def assert_cookies(expected, cookie_jar) assert_equal(expected, cookie_jar.instance_variable_get("@cookies")) -- cgit v1.2.3 From 41b7b8216c11736e0651a6b78a653458c1c40690 Mon Sep 17 00:00:00 2001 From: Tom Kadwill Date: Thu, 28 Apr 2016 20:18:05 +0100 Subject: Fix actionpack typos [ci skip] --- actionpack/lib/action_controller/metal/rescue.rb | 4 ++-- actionpack/lib/action_controller/metal/strong_parameters.rb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/rescue.rb b/actionpack/lib/action_controller/metal/rescue.rb index 0621a7368c..f1c967b982 100644 --- a/actionpack/lib/action_controller/metal/rescue.rb +++ b/actionpack/lib/action_controller/metal/rescue.rb @@ -1,6 +1,6 @@ module ActionController #:nodoc: - # This module is responsible to provide `rescue_from` helpers - # to controllers and configure when detailed exceptions must be + # This module is responsible for providing `rescue_from` helpers + # to controllers and configuring when detailed exceptions must be # shown. module Rescue extend ActiveSupport::Concern diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index f9b80dd805..08049d7af8 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -43,7 +43,7 @@ module ActionController # == Action Controller \Parameters # - # Allows to choose which attributes should be whitelisted for mass updating + # Allows you to choose which attributes should be whitelisted for mass updating # and thus prevent accidentally exposing that which shouldn't be exposed. # Provides two methods for this purpose: #require and #permit. The former is # used to mark parameters as required. The latter is used to set the parameter @@ -196,7 +196,7 @@ module ActionController end alias_method :to_unsafe_hash, :to_unsafe_h - # Convert all hashes in values into parameters, then yield each pair like + # Convert all hashes in values into parameters, then yield each pair in # the same way as Hash#each_pair def each_pair(&block) @parameters.each_pair do |key, value| @@ -278,7 +278,7 @@ module ActionController # params = ActionController::Parameters.new(user: { ... }, profile: { ... }) # user_params, profile_params = params.require(:user, :profile) # - # Otherwise, the method reraises the first exception found: + # Otherwise, the method re-raises the first exception found: # # params = ActionController::Parameters.new(user: {}, profile: {}) # user_params, profile_params = params.require(:user, :profile) -- cgit v1.2.3 From 6cb854f70717071529b293e4a3f4dc577fe89006 Mon Sep 17 00:00:00 2001 From: Tom Kadwill Date: Wed, 4 May 2016 07:00:47 +0100 Subject: Fix actionpack typos [ci skip] --- actionpack/lib/action_controller/base.rb | 2 +- actionpack/lib/action_controller/renderer.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 04e5922ce8..56a8d2e5f4 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -229,7 +229,7 @@ module ActionController HttpAuthentication::Digest::ControllerMethods, HttpAuthentication::Token::ControllerMethods, - # Before callbacks should also be executed the earliest as possible, so + # Before callbacks should also be executed as early as possible, so # also include them at the bottom. AbstractController::Callbacks, diff --git a/actionpack/lib/action_controller/renderer.rb b/actionpack/lib/action_controller/renderer.rb index e4d19e9dba..90e5a9afda 100644 --- a/actionpack/lib/action_controller/renderer.rb +++ b/actionpack/lib/action_controller/renderer.rb @@ -13,11 +13,11 @@ module ActionController # # ApplicationController.renderer.render template: '...' # - # You can use a shortcut on controller to replace previous example with: + # You can use this shortcut in a controller, instead of the previous example: # # ApplicationController.render template: '...' # - # #render method allows you to use any options as when rendering in controller. + # #render allows you to use the same options that you can use when rendering in a controller. # For example, # # FooController.render :action, locals: { ... }, assigns: { ... } -- cgit v1.2.3 From d2660c8cadd973b7a7c8b09fa03888631f9eea4b Mon Sep 17 00:00:00 2001 From: Joe Rafaniello Date: Wed, 4 May 2016 12:22:23 -0400 Subject: Fix some typos in comments. [ci skip] --- actionpack/lib/action_controller/metal/renderers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb index 90fb34e386..1735609cd9 100644 --- a/actionpack/lib/action_controller/metal/renderers.rb +++ b/actionpack/lib/action_controller/metal/renderers.rb @@ -103,7 +103,7 @@ module ActionController # # Both ActionController::Base and ActionController::API # include ActionController::Renderers::All, making all renderers - # avaialable in the controller. See Renderers::RENDERERS and Renderers.add. + # available in the controller. See Renderers::RENDERERS and Renderers.add. # # Since ActionController::Metal controllers cannot render, the controller # must include AbstractController::Rendering, ActionController::Rendering, -- cgit v1.2.3 From 09159d8530069ded68d1d5455dbe5009fb44c1c7 Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Mon, 2 May 2016 17:56:57 -0400 Subject: Ensure compatibility between ActionDispatch::Request::Session and Rack Adding the `each` method is required for ensuring compatibility between Rails, and other Rack frameworks (like Sinatra, etc.), that are mounted within Rails, and wish to use its session tooling. Prior to this, there was an inconsistency between ActionDispatch::Request::Session and Rack::Session::Cookie, due to the absence of the `each` method. This should hopefully fix that error. :) For a full integration test with Sinatra and a standalone Rack application, you can check out the gist for that here: https://gist.github.com/maclover7/08cd95b0bfe259465314311941326470. Solves #15843. --- actionpack/lib/action_dispatch/request/session.rb | 6 +++++- actionpack/test/dispatch/request/session_test.rb | 26 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/request/session.rb b/actionpack/lib/action_dispatch/request/session.rb index 42890225fa..47568f6ad0 100644 --- a/actionpack/lib/action_dispatch/request/session.rb +++ b/actionpack/lib/action_dispatch/request/session.rb @@ -9,7 +9,7 @@ module ActionDispatch # Singleton object used to determine if an optional param wasn't specified Unspecified = Object.new - + # Creates a session hash, merging the properties of the previous session if any def self.create(store, req, default_options) session_was = find req @@ -198,6 +198,10 @@ module ActionDispatch @delegate.merge!(other) end + def each(&block) + to_hash.each(&block) + end + private def load_for_read! diff --git a/actionpack/test/dispatch/request/session_test.rb b/actionpack/test/dispatch/request/session_test.rb index 7dcbcc5c21..e022e7e21e 100644 --- a/actionpack/test/dispatch/request/session_test.rb +++ b/actionpack/test/dispatch/request/session_test.rb @@ -114,5 +114,31 @@ module ActionDispatch }.new end end + + class SessionIntegrationTest < ActionDispatch::IntegrationTest + class MySessionApp + def call(env) + request = Rack::Request.new(env) + request.session['hello'] = 'Hello from MySessionApp!' + [ 200, {}, ['Hello from MySessionApp!'] ] + end + end + + Router = ActionDispatch::Routing::RouteSet.new + Router.draw do + get '/mysessionapp' => MySessionApp.new + end + + def app + @app ||= RoutedRackApp.new(Router) + end + + def test_session_follows_rack_api_contract_1 + get '/mysessionapp' + assert_response :ok + assert_equal 'Hello from MySessionApp!', @response.body + assert_equal 'Hello from MySessionApp!', session['hello'] + end + end end end -- cgit v1.2.3 From cece50d3a6b432f848ca04a92da331f8b032d51f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Thu, 5 May 2016 11:18:10 -0500 Subject: Move protected instance variable to the right place There were a lot of protected instance variables in AbsctractController::Rendering that were related to Action Controller and Action View. Moving to ActionController::Base's protected instance list we make it closer to where they are really defined. --- actionpack/lib/abstract_controller/rendering.rb | 4 +--- actionpack/lib/action_controller/base.rb | 7 ++++--- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 9f192c54f7..a6fb0dbe1d 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -60,9 +60,7 @@ module AbstractController end DEFAULT_PROTECTED_INSTANCE_VARIABLES = Set.new %i( - @_action_name @_response_body @_formats @_prefixes @_config - @_view_context_class @_view_renderer @_lookup_context - @_routes @_db_runtime + @_action_name @_response_body @_formats @_prefixes ) # This method should return a hash with assigns. diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 56a8d2e5f4..54dc6f48c5 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -251,9 +251,10 @@ module ActionController setup_renderer! # Define some internal variables that should not be propagated to the view. - PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + [ - :@_params, :@_response, :@_request, - :@_view_runtime, :@_stream, :@_url_options, :@_action_has_layout ] + PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + %i( + @_params @_response @_request @_config @_url_options @_action_has_layout @_view_context_class + @_view_renderer @_lookup_context @_routes @_view_runtime @_db_runtime + ) def _protected_ivars # :nodoc: PROTECTED_IVARS -- cgit v1.2.3 From 541a51ecf8ee04f956b7d8efb13935640aa831ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Thu, 5 May 2016 12:02:28 -0500 Subject: Implement helpers proxy in controller instance level It is a common pattern in the Rails community that when people want to :xa use any kind of helper that is defined inside app/helpers they includes the helper module inside the controller like: module UserHelper def my_user_helper # ... end end class UsersController < ApplicationController include UserHelper def index render inline: my_user_helper end end This has problem because the helper can't access anything that is defined in the view level context class. Also all public methods of the helper become available in the controller what can lead to undesirable methods being routed and behaving as actions. Also if you helper depends on other helpers or even Action View helpers you need to include each one of these dependencies in your controller otherwise your helper is not going to work. We already have a helpers proxy at controller class level but that proxy doesn't have access to the instance variables defined in the controller. With this new instance level helper proxy users can reuse helpers in the controller without having to include the modules and with access to instance variables defined in the controller. class UsersController < ApplicationController def index render inline: helpers.my_user_helper end end --- actionpack/CHANGELOG.md | 6 ++++++ actionpack/lib/action_controller/base.rb | 2 +- actionpack/lib/action_controller/metal/helpers.rb | 7 ++++++- actionpack/test/controller/helper_test.rb | 16 ++++++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 85d2b14285..9b902b46a2 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,9 @@ +* Add `ActionController#helpers` to get access to the view context in the controller + level. + + *Rafael Mendonça França* + + ## Rails 5.0.0.beta4 (April 27, 2016) ## * Routing: Refactor `:action` default handling to ensure that path diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 54dc6f48c5..d546d7260c 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -253,7 +253,7 @@ module ActionController # Define some internal variables that should not be propagated to the view. PROTECTED_IVARS = AbstractController::Rendering::DEFAULT_PROTECTED_INSTANCE_VARIABLES + %i( @_params @_response @_request @_config @_url_options @_action_has_layout @_view_context_class - @_view_renderer @_lookup_context @_routes @_view_runtime @_db_runtime + @_view_renderer @_lookup_context @_routes @_view_runtime @_db_runtime @_helper_proxy ) def _protected_ivars # :nodoc: diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index d3853e2e83..22493dea50 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -5,7 +5,7 @@ module ActionController # # In addition to using the standard template helpers provided, creating custom helpers to # extract complicated logic or reusable functionality is strongly encouraged. By default, each controller - # will include all helpers. These helpers are only accessible on the controller through .helpers + # will include all helpers. These helpers are only accessible on the controller through #helpers # # In previous versions of \Rails the controller will include a helper which # matches the name of the controller, e.g., MyController will automatically @@ -113,5 +113,10 @@ module ActionController all_helpers_from_path(helpers_path) end end + + # Provides a proxy to access helpers methods from outside the view. + def helpers + @_helper_proxy ||= view_context + end end end diff --git a/actionpack/test/controller/helper_test.rb b/actionpack/test/controller/helper_test.rb index feb882a2b3..ef85e141a0 100644 --- a/actionpack/test/controller/helper_test.rb +++ b/actionpack/test/controller/helper_test.rb @@ -207,6 +207,22 @@ class HelperTest < ActiveSupport::TestCase assert methods.include?(:foobar) end + def test_helper_proxy_in_instance + methods = AllHelpersController.new.helpers.methods + + # Action View + assert_includes methods, :pluralize + + # abc_helper.rb + assert_includes methods, :bare_a + + # fun/games_helper.rb + assert_includes methods, :stratego + + # fun/pdf_helper.rb + assert_includes methods, :foobar + end + def test_helper_proxy_config AllHelpersController.config.my_var = 'smth' -- cgit v1.2.3 From bf79bc039570df2e75a6d53a07a08268edf99b4e Mon Sep 17 00:00:00 2001 From: Prathamesh Sonpatki Date: Thu, 5 May 2016 23:02:38 -0500 Subject: Release notes: Add PR #24866 to release notes --- actionpack/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 9b902b46a2..49866d0d03 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,4 +1,4 @@ -* Add `ActionController#helpers` to get access to the view context in the controller +* Add `ActionController#helpers` to get access to the view context at the controller level. *Rafael Mendonça França* -- cgit v1.2.3 From 6e189a2e3b69d8b5858e789e4524f604bfeaaca4 Mon Sep 17 00:00:00 2001 From: Prathamesh Sonpatki Date: Fri, 6 May 2016 14:33:31 -0500 Subject: BoomerAPI is not used anywhere, so removed it! - It was originally added in 83b4e9073f0852afc065 and partially removed in 05d89410bf97d0778e7. --- actionpack/test/dispatch/debug_exceptions_test.rb | 7 ------- 1 file changed, 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/dispatch/debug_exceptions_test.rb b/actionpack/test/dispatch/debug_exceptions_test.rb index 159bf10545..f6e0076a6a 100644 --- a/actionpack/test/dispatch/debug_exceptions_test.rb +++ b/actionpack/test/dispatch/debug_exceptions_test.rb @@ -75,13 +75,6 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest end end - class BoomerAPI < Boomer - def call(env) - env['action_dispatch.show_detailed_exceptions'] = @detailed - raise "puke!" - end - end - RoutesApp = Struct.new(:routes).new(SharedTestRoutes) ProductionApp = ActionDispatch::DebugExceptions.new(Boomer.new(false), RoutesApp) DevelopmentApp = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp) -- cgit v1.2.3 From bf876aa0b61995f1be9b0146df7db74bd34d46af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 6 May 2016 15:05:25 -0500 Subject: Make flash messages cookie compatible with Rails 4 In #18721 we removed the discard key from the session hash used to flash messages and that broke compatibility with Rails 4 applications because they try to map in the discarded flash messages and it returns nil. Fixes #24726. --- actionpack/lib/action_dispatch/middleware/flash.rb | 2 +- actionpack/test/controller/flash_hash_test.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb index 06038af571..80703940ed 100644 --- a/actionpack/lib/action_dispatch/middleware/flash.rb +++ b/actionpack/lib/action_dispatch/middleware/flash.rb @@ -133,7 +133,7 @@ module ActionDispatch def to_session_value #:nodoc: flashes_to_keep = @flashes.except(*@discard) return nil if flashes_to_keep.empty? - {'flashes' => flashes_to_keep} + { 'discard' => [], 'flashes' => flashes_to_keep } end def initialize(flashes = {}, discard = []) #:nodoc: diff --git a/actionpack/test/controller/flash_hash_test.rb b/actionpack/test/controller/flash_hash_test.rb index 081288ef21..f87077dd86 100644 --- a/actionpack/test/controller/flash_hash_test.rb +++ b/actionpack/test/controller/flash_hash_test.rb @@ -57,10 +57,10 @@ module ActionDispatch def test_to_session_value @hash['foo'] = 'bar' - assert_equal({'flashes' => {'foo' => 'bar'}}, @hash.to_session_value) + assert_equal({ 'discard' => [], 'flashes' => { 'foo' => 'bar' } }, @hash.to_session_value) @hash.now['qux'] = 1 - assert_equal({'flashes' => {'foo' => 'bar'}}, @hash.to_session_value) + assert_equal({ 'flashes' => { 'foo' => 'bar' }, 'discard' => [] }, @hash.to_session_value) @hash.discard('foo') assert_equal(nil, @hash.to_session_value) -- cgit v1.2.3 From fbdcf5221ad7ea3d40ad09651962fc85d101dd67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 6 May 2016 16:54:40 -0500 Subject: Preparing for 5.0.0.rc1 release --- actionpack/CHANGELOG.md | 2 ++ actionpack/lib/action_pack/gem_version.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index 49866d0d03..f753c44029 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,5 @@ +## Rails 5.0.0.rc1 (May 06, 2016) ## + * Add `ActionController#helpers` to get access to the view context at the controller level. diff --git a/actionpack/lib/action_pack/gem_version.rb b/actionpack/lib/action_pack/gem_version.rb index 0fa51fa0fe..bbb637166e 100644 --- a/actionpack/lib/action_pack/gem_version.rb +++ b/actionpack/lib/action_pack/gem_version.rb @@ -8,7 +8,7 @@ module ActionPack MAJOR = 5 MINOR = 0 TINY = 0 - PRE = "beta4" + PRE = "rc1" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end -- cgit v1.2.3 From 0c3012991a188c28ede4262fc2721f269d07f0ee Mon Sep 17 00:00:00 2001 From: Jon Atack Date: Sat, 7 May 2016 17:15:23 +0200 Subject: Helpers doc grammar fix [skip ci] --- actionpack/lib/action_controller/metal/helpers.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index 22493dea50..295f0cb66f 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -71,7 +71,7 @@ module ActionController attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") } end - # Provides a proxy to access helpers methods from outside the view. + # Provides a proxy to access helper methods from outside the view. def helpers @helper_proxy ||= begin proxy = ActionView::Base.new @@ -114,7 +114,7 @@ module ActionController end end - # Provides a proxy to access helpers methods from outside the view. + # Provides a proxy to access helper methods from outside the view. def helpers @_helper_proxy ||= view_context end -- cgit v1.2.3 From 95e2d35bb8421b80e177d82470bcac3b3a63b7e6 Mon Sep 17 00:00:00 2001 From: Molchanov Andrey Date: Sat, 7 May 2016 20:52:56 +0300 Subject: Replace `loop` to `until` --- actionpack/lib/action_dispatch/routing/mapper.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index faa93ecc17..4c2a4cfeb0 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -2088,8 +2088,7 @@ to this: def each node = self - loop do - break if node.equal? NULL + until node.equal? NULL yield node node = node.parent end -- cgit v1.2.3 From 31bc9f27c8c689a19d0013ad92e088b80642ce64 Mon Sep 17 00:00:00 2001 From: Jordan Owens Date: Mon, 9 May 2016 14:04:45 -0400 Subject: use Rack::Utils.valid_path? to check path This commit uses the new method in Rack to check if a path is valid. --- actionpack/lib/action_dispatch/middleware/static.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb index 41c220236a..2c5721dc22 100644 --- a/actionpack/lib/action_dispatch/middleware/static.rb +++ b/actionpack/lib/action_dispatch/middleware/static.rb @@ -27,8 +27,8 @@ module ActionDispatch # in the server's `public/` directory (see Static#call). def match?(path) path = ::Rack::Utils.unescape_path path - return false unless valid_path?(path) - path = Rack::Utils.clean_path_info path + return false unless ::Rack::Utils.valid_path? path + path = ::Rack::Utils.clean_path_info path paths = [path, "#{path}#{ext}", "#{path}/#{@index}#{ext}"] @@ -94,10 +94,6 @@ module ActionDispatch false end end - - def valid_path?(path) - path.valid_encoding? && !path.include?("\0") - end end # This middleware will attempt to return the contents of a file's body from -- cgit v1.2.3 From 86c860ff0c36f66e131aaeaa85cab7a6e885f02e Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Mon, 9 May 2016 20:21:55 -0600 Subject: Update rails-dom-testing gem to 2.0 Resolves #24924. --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 66300754e3..965fafff5f 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -24,7 +24,7 @@ Gem::Specification.new do |s| s.add_dependency 'rack', '~> 2.x' s.add_dependency 'rack-test', '~> 0.6.3' s.add_dependency 'rails-html-sanitizer', '~> 1.0', '>= 1.0.2' - s.add_dependency 'rails-dom-testing', '~> 1.0', '>= 1.0.5' + s.add_dependency 'rails-dom-testing', '~> 2.0' s.add_dependency 'actionview', version s.add_development_dependency 'activemodel', version -- cgit v1.2.3 From 8ecc5ab1d88532a239f17c7520ed922c7579b01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 10 May 2016 01:07:09 -0300 Subject: Start Rails 5.1 development :tada: --- actionpack/CHANGELOG.md | 823 +----------------------------- actionpack/lib/action_pack/gem_version.rb | 4 +- 2 files changed, 3 insertions(+), 824 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index f753c44029..be911b147c 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,823 +1,2 @@ -## Rails 5.0.0.rc1 (May 06, 2016) ## -* Add `ActionController#helpers` to get access to the view context at the controller - level. - - *Rafael Mendonça França* - - -## Rails 5.0.0.beta4 (April 27, 2016) ## - -* Routing: Refactor `:action` default handling to ensure that path - parameters are not mutated during route generation. - - *Andrew White* - -* Add extension synonyms `yml` and `yaml` for MIME type `application/x-yaml`. - - *bogdanvlviv* - -* Adds support for including ActionController::Cookies in API controllers. - Previously, including the module would raise when trying to define - a `cookies` helper method. Skip calling #helper_method if it is not - defined -- if we don't have helpers, we needn't define one. - - Fixes #24304 - - *Ryan T. Hosford* - -* ETags: Introduce `Response#strong_etag=` and `#weak_etag=` and analogous - options for `fresh_when` and `stale?`. `Response#etag=` sets a weak ETag. - - Strong ETags are desirable when you're serving byte-for-byte identical - responses that support Range requests, like PDFs or videos (typically - done by reproxying the response from a backend storage service). - Also desirable when fronted by some CDNs that support strong ETags - only, like Akamai. - - *Jeremy Daer* - -* ETags: No longer strips quotes (") from ETag values before comparing them. - Quotes are significant, part of the ETag. A quoted ETag and an unquoted - one are not the same entity. - - *Jeremy Daer* - -* ETags: Support `If-None-Match: *`. Rarely useful for GET requests; meant - to provide some optimistic concurrency control for PUT requests. - - *Jeremy Daer* - -* `ActionDispatch::ParamsParser` is deprecated and was removed from the middleware - stack. To configure the parameter parsers use `ActionDispatch::Request.parameter_parsers=`. - - *tenderlove* - -* When a `respond_to` collector with a block doesn't have a response, then - a `:no_content` response should be rendered. This brings the default - rendering behavior introduced by https://github.com/rails/rails/issues/19036 - to controller methods employing `respond_to`. - - *Justin Coyne* - -* Add `ActionController::Parameters#dig` on Ruby 2.3 and greater, which - behaves the same as `Hash#dig`. - - *Sean Griffin* - -* Add request headers in the payload of the `start_processing.action_controller` - and `process_action.action_controller` notifications. - - *Gareth du Plooy* - -* Add `action_dispatch_integration_test` load hook. The hook can be used to - extend `ActionDispatch::IntegrationTest` once it has been loaded. - - *Yuichiro Kaneko* - -* Update default rendering policies when the controller action did - not explicitly indicate a response. - - For API controllers, the implicit render always renders "204 No Content" - and does not account for any templates. - - For other controllers, the following conditions are checked: - - First, if a template exists for the controller action, it is rendered. - This template lookup takes into account the action name, locales, format, - variant, template handlers, etc. (see `render` for details). - - Second, if other templates exist for the controller action but is not in - the right format (or variant, etc.), an `ActionController::UnknownFormat` - is raised. The list of available templates is assumed to be a complete - enumeration of all the possible formats (or variants, etc.); that is, - having only HTML and JSON templates indicate that the controller action is - not meant to handle XML requests. - - Third, if the current request is an "interactive" browser request (the user - navigated here by entering the URL in the address bar, submitting a form, - clicking on a link, etc. as opposed to an XHR or non-browser API request), - `ActionView::UnknownFormat` is raised to display a helpful error - message. - - Finally, it falls back to the same "204 No Content" behavior as API controllers. - - *Godfrey Chan*, *Jon Moss*, *Kasper Timm Hansen*, *Mike Clark*, *Matthew Draper* - -## Rails 5.0.0.beta3 (February 24, 2016) ## - -* Add "application/gzip" as a default mime type. - - *Mehmet Emin İNAÇ* - -* Add request encoding and response parsing to integration tests. - - What previously was: - - ```ruby - require 'test_helper' - - class ApiTest < ActionDispatch::IntegrationTest - test 'creates articles' do - assert_difference -> { Article.count } do - post articles_path(format: :json), - params: { article: { title: 'Ahoy!' } }.to_json, - headers: { 'Content-Type' => 'application/json' } - end - - assert_equal({ 'id' => Article.last.id, 'title' => 'Ahoy!' }, JSON.parse(response.body)) - end - end - ``` - - Can now be written as: - - ```ruby - require 'test_helper' - - class ApiTest < ActionDispatch::IntegrationTest - test 'creates articles' do - assert_difference -> { Article.count } do - post articles_path, params: { article: { title: 'Ahoy!' } }, as: :json - end - - assert_equal({ 'id' => Article.last.id, 'title' => 'Ahoy!' }, response.parsed_body) - end - end - ``` - - Passing `as: :json` to integration test request helpers will set the format, - content type and encode the parameters as JSON. - - Then on the response side, `parsed_body` will parse the body according to the - content type the response has. - - Currently JSON is the only supported MIME type. Add your own with - `ActionDispatch::IntegrationTest.register_encoder`. - - *Kasper Timm Hansen* - -* Add "image/svg+xml" as a default mime type. - - *DHH* - -## Rails 5.0.0.beta2 (February 01, 2016) ## - -* Add `-g` and `-c` options to `bin/rails routes`. These options return the url `name`, `verb` and - `path` field that match the pattern or match a specific controller. - - Deprecate `CONTROLLER` env variable in `bin/rails routes`. - - See #18902. - - *Anton Davydov*, *Vipul A M* - -* Response etags to always be weak: Prefixes 'W/' to value returned by - `ActionDispatch::Http::Cache::Response#etag=`, such that etags set in - `fresh_when` and `stale?` are weak. - - Fixes #17556. - - *Abhishek Yadav* - -* Provide the name of HTTP Status code in assertions. - - *Sean Collins* - -* More explicit error message when running `rake routes`. `CONTROLLER` argument - can now be supplied in different ways: - `Rails::WelcomeController`, `Rails::Welcome`, `rails/welcome`. - - Fixes #22918. - - *Edouard Chin* - -* Allow `ActionController::Parameters` instances as an argument to URL - helper methods. An `ArgumentError` will be raised if the passed parameters - are not secure. - - Fixes #22832. - - *Prathamesh Sonpatki* - -* Add option for per-form CSRF tokens. - - *Greg Ose*, *Ben Toews* - -* Fix `ActionController::Parameters#convert_parameters_to_hashes` to return filtered - or unfiltered values based on from where it is called, `to_h` or `to_unsafe_h` - respectively. - - Fixes #22841. - - *Prathamesh Sonpatki* - -* Add `ActionController::Parameters#include?` - - *Justin Coyne* - -## Rails 5.0.0.beta1 (December 18, 2015) ## - -* Deprecate `redirect_to :back` in favor of `redirect_back`, which accepts a - required `fallback_location` argument, thus eliminating the possibility of a - `RedirectBackError`. - - *Derek Prior* - -* Add `redirect_back` method to `ActionController::Redirecting` to provide a - way to safely redirect to the `HTTP_REFERER` if it is present, falling back - to a provided redirect otherwise. - - *Derek Prior* - -* `ActionController::TestCase` will be moved to its own gem in Rails 5.1. - - With the speed improvements made to `ActionDispatch::IntegrationTest` we no - longer need to keep two separate code bases for testing controllers. In - Rails 5.1 `ActionController::TestCase` will be deprecated and moved into a - gem outside of Rails source. - - This is a documentation deprecation so that going forward new tests will use - `ActionDispatch::IntegrationTest` instead of `ActionController::TestCase`. - - *Eileen M. Uchitelle* - -* Add a `response_format` option to `ActionDispatch::DebugExceptions` - to configure the format of the response when errors occur in - development mode. - - If `response_format` is `:default` the debug info will be rendered - in an HTML page. In the other hand, if the provided value is `:api` - the debug info will be rendered in the original response format. - - *Jorge Bejar* - -* Change the `protect_from_forgery` prepend default to `false`. - - Per this comment - https://github.com/rails/rails/pull/18334#issuecomment-69234050 we want - `protect_from_forgery` to default to `prepend: false`. - - `protect_from_forgery` will now be inserted into the callback chain at the - point it is called in your application. This is useful for cases where you - want to `protect_from_forgery` after you perform required authentication - callbacks or other callbacks that are required to run after forgery protection. - - If you want `protect_from_forgery` callbacks to always run first, regardless of - position they are called in your application then you can add `prepend: true` - to your `protect_from_forgery` call. - - Example: - - ```ruby - protect_from_forgery prepend: true - ``` - - *Eileen M. Uchitelle* - -* In url_for, never append a question mark to the URL when the query string - is empty anyway. (It used to do that when called like `url_for(controller: - 'x', action: 'y', q: {})`.) - - *Paul Grayson* - -* Catch invalid UTF-8 querystring values and respond with BadRequest - - Check querystring params for invalid UTF-8 characters, and raise an - ActionController::BadRequest error if present. Previously these strings - would typically trigger errors further down the stack. - - *Grey Baker* - -* Parse RSS/ATOM responses as XML, not HTML. - - *Alexander Kaupanin* - -* Show helpful message in `BadRequest` exceptions due to invalid path - parameter encodings. - - Fixes #21923. - - *Agis Anastasopoulos* - -* Add the ability of returning arbitrary headers to `ActionDispatch::Static`. - - Now ActionDispatch::Static can accept HTTP headers so that developers - will have control of returning arbitrary headers like - 'Access-Control-Allow-Origin' when a response is delivered. They can be - configured with `#config`: - - Example: - - config.public_file_server.headers = { - "Cache-Control" => "public, max-age=60", - "Access-Control-Allow-Origin" => "http://rubyonrails.org" - } - - *Yuki Nishijima* - -* Allow multiple `root` routes in same scope level. Example: - - Example: - - root 'blog#show', constraints: ->(req) { Hostname.blog_site?(req.host) } - root 'landing#show' - - *Rafael Sales* - -* Fix regression in mounted engine named routes generation for app deployed to - a subdirectory. `relative_url_root` was prepended to the path twice (e.g. - "/subdir/subdir/engine_path" instead of "/subdir/engine_path") - - Fixes #20920. Fixes #21459. - - *Matthew Erhard* - -* `ActionDispatch::Response#new` no longer applies default headers. If you want - default headers applied to the response object, then call - `ActionDispatch::Response.create`. This change only impacts people who are - directly constructing an `ActionDispatch::Response` object. - -* Accessing mime types via constants like `Mime::HTML` is deprecated. Please - change code like this: - - Mime::HTML - - To this: - - Mime[:html] - - This change is so that Rails will not manage a list of constants, and fixes - an issue where if a type isn't registered you could possibly get the wrong - object. - - `Mime[:html]` is available in older versions of Rails, too, so you can - safely change libraries and plugins and maintain compatibility with - multiple versions of Rails. - -* `url_for` does not modify its arguments when generating polymorphic URLs. - - *Bernerd Schaefer* - -* Make it easier to opt in to `config.force_ssl` and `config.ssl_options` by - making them less dangerous to try and easier to disable. - - SSL redirect: - * Move `:host` and `:port` options within `redirect: { … }`. Deprecate. - * Introduce `:status` and `:body` to customize the redirect response. - The 301 permanent default makes it difficult to test the redirect and - back out of it since browsers remember the 301. Test with a 302 or 307 - instead, then switch to 301 once you're confident that all is well. - - HTTP Strict Transport Security (HSTS): - * Shorter max-age. Shorten the default max-age from 1 year to 180 days, - the low end for https://www.ssllabs.com/ssltest/ grading and greater - than the 18-week minimum to qualify for browser preload lists. - * Disabling HSTS. Setting `hsts: false` now sets `hsts { expires: 0 }` - instead of omitting the header. Omitting does nothing to disable HSTS - since browsers hang on to your previous settings until they expire. - Sending `{ hsts: { expires: 0 }}` flushes out old browser settings and - actually disables HSTS: - http://tools.ietf.org/html/rfc6797#section-6.1.1 - * HSTS Preload. Introduce `preload: true` to set the `preload` flag, - indicating that your site may be included in browser preload lists, - including Chrome, Firefox, Safari, IE11, and Edge. Submit your site: - https://hstspreload.appspot.com - - *Jeremy Daer* - -* Update `ActionController::TestSession#fetch` to behave more like - `ActionDispatch::Request::Session#fetch` when using non-string keys. - - *Jeremy Friesen* - -* Using strings or symbols for middleware class names is deprecated. Convert - things like this: - - middleware.use "Foo::Bar" - - to this: - - middleware.use Foo::Bar - -* `ActionController::TestSession` now accepts a default value as well as - a block for generating a default value based off the key provided. - - This fixes calls to `session#fetch` in `ApplicationController` instances that - take more two arguments or a block from raising `ArgumentError: wrong - number of arguments (2 for 1)` when performing controller tests. - - *Matthew Gerrior* - -* Fix `ActionController::Parameters#fetch` overwriting `KeyError` returned by - default block. - - *Jonas Schuber Erlandsson*, *Roque Pinel* - -* `ActionController::Parameters` no longer inherits from - `HashWithIndifferentAccess` - - Inheriting from `HashWithIndifferentAccess` allowed users to call any - enumerable methods on `Parameters` object, resulting in a risk of losing the - `permitted?` status or even getting back a pure `Hash` object instead of - a `Parameters` object with proper sanitization. - - By not inheriting from `HashWithIndifferentAccess`, we are able to make - sure that all methods that are defined in `Parameters` object will return - a proper `Parameters` object with a correct `permitted?` flag. - - *Prem Sichanugrist* - -* Replaced `ActiveSupport::Concurrency::Latch` with `Concurrent::CountDownLatch` - from the concurrent-ruby gem. - - *Jerry D'Antonio* - -* Add ability to filter parameters based on parent keys. - - # matches {credit_card: {code: "xxxx"}} - # doesn't match {file: { code: "xxxx"}} - config.filter_parameters += [ "credit_card.code" ] - - See #13897. - - *Guillaume Malette* - -* Deprecate passing first parameter as `Hash` and default status code for `head` method. - - *Mehmet Emin İNAÇ* - -* Adds`Rack::Utils::ParameterTypeError` and `Rack::Utils::InvalidParameterError` - to the rescue_responses hash in `ExceptionWrapper` (Rack recommends - integrators serve 400s for both of these). - - *Grey Baker* - -* Add support for API only apps. - `ActionController::API` is added as a replacement of - `ActionController::Base` for this kind of applications. - - *Santiago Pastorino*, *Jorge Bejar* - -* Remove `assigns` and `assert_template`. Both methods have been extracted - into a gem at https://github.com/rails/rails-controller-testing. - - See #18950. - - *Alan Guo Xiang Tan* - -* `FileHandler` and `Static` middleware initializers accept `index` argument - to configure the directory index file name. Defaults to `index` (as in - `index.html`). - - See #20017. - - *Eliot Sykes* - -* Deprecate `:nothing` option for `render` method. - - *Mehmet Emin İNAÇ* - -* Fix `rake routes` not showing the right format when - nesting multiple routes. - - See #18373. - - *Ravil Bayramgalin* - -* Add ability to override default form builder for a controller. - - class AdminController < ApplicationController - default_form_builder AdminFormBuilder - end - - *Kevin McPhillips* - -* For actions with no corresponding templates, render `head :no_content` - instead of raising an error. This allows for slimmer API controller - methods that simply work, without needing further instructions. - - See #19036. - - *Stephen Bussey* - -* Provide friendlier access to request variants. - - request.variant = :phone - request.variant.phone? # true - request.variant.tablet? # false - - request.variant = [:phone, :tablet] - request.variant.phone? # true - request.variant.desktop? # false - request.variant.any?(:phone, :desktop) # true - request.variant.any?(:desktop, :watch) # false - - *George Claghorn* - -* Fix regression where a gzip file response would have a Content-type, - even when it was a 304 status code. - - See #19271. - - *Kohei Suzuki* - -* Fix handling of empty `X_FORWARDED_HOST` header in `raw_host_with_port`. - - Previously, an empty `X_FORWARDED_HOST` header would cause - `Actiondispatch::Http:URL.raw_host_with_port` to return `nil`, causing - `Actiondispatch::Http:URL.host` to raise a `NoMethodError`. - - *Adam Forsyth* - -* Allow `Bearer` as token-keyword in `Authorization-Header`. - - Additionally to `Token`, the keyword `Bearer` is acceptable as a keyword - for the auth-token. The `Bearer` keyword is described in the original - OAuth RFC and used in libraries like Angular-JWT. - - See #19094. - - *Peter Schröder* - -* Drop request class from `RouteSet` constructor. - - If you would like to use a custom request class, please subclass and implement - the `request_class` method. - - *tenderlove@ruby-lang.org* - -* Fallback to `ENV['RAILS_RELATIVE_URL_ROOT']` in `url_for`. - - Fixed an issue where the `RAILS_RELATIVE_URL_ROOT` environment variable is not - prepended to the path when `url_for` is called. If `SCRIPT_NAME` (used by Rack) - is set, it takes precedence. - - Fixes #5122. - - *Yasyf Mohamedali* - -* Partitioning of routes is now done when the routes are being drawn. This - helps to decrease the time spent filtering the routes during the first request. - - *Guo Xiang Tan* - -* Fix regression in functional tests. Responses should have default headers - assigned. - - See #18423. - - *Jeremy Kemper*, *Yves Senn* - -* Deprecate `AbstractController#skip_action_callback` in favor of individual skip_callback methods - (which can be made to raise an error if no callback was removed). - - *Iain Beeston* - -* Alias the `ActionDispatch::Request#uuid` method to `ActionDispatch::Request#request_id`. - Due to implementation, `config.log_tags = [:request_id]` also works in substitute - for `config.log_tags = [:uuid]`. - - *David Ilizarov* - -* Change filter on /rails/info/routes to use an actual path regexp from rails - and not approximate javascript version. Oniguruma supports much more - extensive list of features than javascript regexp engine. - - Fixes #18402. - - *Ravil Bayramgalin* - -* Non-string authenticity tokens do not raise NoMethodError when decoding - the masked token. - - *Ville Lautanala* - -* Add `http_cache_forever` to Action Controller, so we can cache a response - that never gets expired. - - *arthurnn* - -* `ActionController#translate` supports symbols as shortcuts. - When a shortcut is given it also performs the lookup without the action - name. - - *Max Melentiev* - -* Expand `ActionController::ConditionalGet#fresh_when` and `stale?` to also - accept a collection of records as the first argument, so that the - following code can be written in a shorter form. - - # Before - def index - @articles = Article.all - fresh_when(etag: @articles, last_modified: @articles.maximum(:updated_at)) - end - - # After - def index - @articles = Article.all - fresh_when(@articles) - end - - *claudiob* - -* Explicitly ignored wildcard verbs when searching for HEAD routes before fallback - - Fixes an issue where a mounted rack app at root would intercept the HEAD - request causing an incorrect behavior during the fall back to GET requests. - - Example: - - draw do - get '/home' => 'test#index' - mount rack_app, at: '/' - end - head '/home' - assert_response :success - - In this case, a HEAD request runs through the routes the first time and fails - to match anything. Then, it runs through the list with the fallback and matches - `get '/home'`. The original behavior would match the rack app in the first pass. - - *Terence Sun* - -* Migrating xhr methods to keyword arguments syntax - in `ActionController::TestCase` and `ActionDispatch::Integration` - - Old syntax: - - xhr :get, :create, params: { id: 1 } - - New syntax example: - - get :create, params: { id: 1 }, xhr: true - - *Kir Shatrov* - -* Migrating to keyword arguments syntax in `ActionController::TestCase` and - `ActionDispatch::Integration` HTTP request methods. - - Example: - - post :create, params: { y: x }, session: { a: 'b' } - get :view, params: { id: 1 } - get :view, params: { id: 1 }, format: :json - - *Kir Shatrov* - -* Preserve default url options when generating URLs. - - Fixes an issue that would cause `default_url_options` to be lost when - generating URLs with fewer positional arguments than parameters in the - route definition. - - *Tekin Suleyman* - -* Deprecate `*_via_redirect` integration test methods. - - Use `follow_redirect!` manually after the request call for the same behavior. - - *Aditya Kapoor* - -* Add `ActionController::Renderer` to render arbitrary templates - outside controller actions. - - Its functionality is accessible through class methods `render` and - `renderer` of `ActionController::Base`. - - *Ravil Bayramgalin* - -* Support `:assigns` option when rendering with controllers/mailers. - - *Ravil Bayramgalin* - -* Default headers, removed in controller actions, are no longer reapplied on - the test response. - - *Jonas Baumann* - -* Deprecate all `*_filter` callbacks in favor of `*_action` callbacks. - - *Rafael Mendonça França* - -* Allow you to pass `prepend: false` to `protect_from_forgery` to have the - verification callback appended instead of prepended to the chain. - This allows you to let the verification step depend on prior callbacks. - - Example: - - class ApplicationController < ActionController::Base - before_action :authenticate - protect_from_forgery prepend: false, unless: -> { @authenticated_by.oauth? } - - private - def authenticate - if oauth_request? - # authenticate with oauth - @authenticated_by = 'oauth'.inquiry - else - # authenticate with cookies - @authenticated_by = 'cookie'.inquiry - end - end - end - - *Josef Šimánek* - -* Remove `ActionController::HideActions`. - - *Ravil Bayramgalin* - -* Remove `respond_to`/`respond_with` placeholder methods, this functionality - has been extracted to the `responders` gem. - - *Carlos Antonio da Silva* - -* Remove deprecated assertion files. - - *Rafael Mendonça França* - -* Remove deprecated usage of string keys in URL helpers. - - *Rafael Mendonça França* - -* Remove deprecated `only_path` option on `*_path` helpers. - - *Rafael Mendonça França* - -* Remove deprecated `NamedRouteCollection#helpers`. - - *Rafael Mendonça França* - -* Remove deprecated support to define routes with `:to` option that doesn't contain `#`. - - *Rafael Mendonça França* - -* Remove deprecated `ActionDispatch::Response#to_ary`. - - *Rafael Mendonça França* - -* Remove deprecated `ActionDispatch::Request#deep_munge`. - - *Rafael Mendonça França* - -* Remove deprecated `ActionDispatch::Http::Parameters#symbolized_path_parameters`. - - *Rafael Mendonça França* - -* Remove deprecated option `use_route` in controller tests. - - *Rafael Mendonça França* - -* Ensure `append_info_to_payload` is called even if an exception is raised. - - Fixes an issue where when an exception is raised in the request the additional - payload data is not available. - - See #14903. - - *Dieter Komendera*, *Margus Pärt* - -* Correctly rely on the response's status code to handle calls to `head`. - - *Robin Dupret* - -* Using `head` method returns empty response_body instead - of returning a single space " ". - - The old behavior was added as a workaround for a bug in an early - version of Safari, where the HTTP headers are not returned correctly - if the response body has a 0-length. This is been fixed since and - the workaround is no longer necessary. - - Fixes #18253. - - *Prathamesh Sonpatki* - -* Fix how polymorphic routes works with objects that implement `to_model`. - - *Travis Grathwell* - -* Stop converting empty arrays in `params` to `nil`. - - This behavior was introduced in response to CVE-2012-2660, CVE-2012-2694 - and CVE-2013-0155 - - ActiveRecord now issues a safe query when passing an empty array into - a where clause, so there is no longer a need to defend against this type - of input (any nils are still stripped from the array). - - *Chris Sinjakli* - -* Fixed usage of optional scopes in url helpers. - - *Alex Robbin* - -* Fixed handling of positional url helper arguments when `format: false`. - - Fixes #17819. - - *Andrew White*, *Tatiana Soukiassian* - -Please check [4-2-stable](https://github.com/rails/rails/blob/4-2-stable/actionpack/CHANGELOG.md) for previous changes. +Please check [5-0-stable](https://github.com/rails/rails/blob/5-0-stable/actionpack/CHANGELOG.md) for previous changes. diff --git a/actionpack/lib/action_pack/gem_version.rb b/actionpack/lib/action_pack/gem_version.rb index bbb637166e..d8f86630b1 100644 --- a/actionpack/lib/action_pack/gem_version.rb +++ b/actionpack/lib/action_pack/gem_version.rb @@ -6,9 +6,9 @@ module ActionPack module VERSION MAJOR = 5 - MINOR = 0 + MINOR = 1 TINY = 0 - PRE = "rc1" + PRE = "alpha" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end -- cgit v1.2.3 From c33bda875e562561292eafc7c99362f23cf8150a Mon Sep 17 00:00:00 2001 From: Prathamesh Sonpatki Date: Sat, 7 May 2016 20:44:38 -0500 Subject: API only apps: Preserve request format for HTML requests too - Earlier we were responding with JSON format for HTML requests in a API app. - Now we will respond with HTML format for such requests in API apps. - Also earlier we were not testing the API app's JSON requests properly. We were actually sending HTML requests. Now we send correct JSON requests. Also added more test coverage. - Based on the discussion from this commit - https://github.com/rails/rails/commit/05d89410bf97d0778e78558db3c9fed275f8a614. [Prathamesh Sonpatki, Jorge Bejar] --- .../action_dispatch/middleware/debug_exceptions.rb | 20 +++--- actionpack/test/dispatch/debug_exceptions_test.rb | 82 +++++++++++++--------- 2 files changed, 62 insertions(+), 40 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb index 51a471fb23..5f758d641a 100644 --- a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb @@ -67,18 +67,19 @@ module ActionDispatch log_error(request, wrapper) if request.get_header('action_dispatch.show_detailed_exceptions') - case @response_format - when :api - render_for_api_application(request, wrapper) - when :default - render_for_default_application(request, wrapper) + content_type = request.formats.first + + if api_request?(content_type) + render_for_api_request(content_type, wrapper) + else + render_for_browser_request(request, wrapper) end else raise exception end end - def render_for_default_application(request, wrapper) + def render_for_browser_request(request, wrapper) template = create_template(request, wrapper) file = "rescues/#{wrapper.rescue_template}" @@ -92,7 +93,7 @@ module ActionDispatch render(wrapper.status_code, body, format) end - def render_for_api_application(request, wrapper) + def render_for_api_request(content_type, wrapper) body = { status: wrapper.status_code, error: Rack::Utils::HTTP_STATUS_CODES.fetch( @@ -103,7 +104,6 @@ module ActionDispatch traces: wrapper.traces } - content_type = request.formats.first to_format = "to_#{content_type.to_sym}" if content_type && body.respond_to?(to_format) @@ -181,5 +181,9 @@ module ActionDispatch ActionDispatch::Routing::RoutesInspector.new(@routes_app.routes.routes) end end + + def api_request?(content_type) + @response_format == :api && !content_type.html? + end end end diff --git a/actionpack/test/dispatch/debug_exceptions_test.rb b/actionpack/test/dispatch/debug_exceptions_test.rb index 159bf10545..8feb8607f5 100644 --- a/actionpack/test/dispatch/debug_exceptions_test.rb +++ b/actionpack/test/dispatch/debug_exceptions_test.rb @@ -27,37 +27,37 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest env['action_dispatch.show_detailed_exceptions'] = @detailed req = ActionDispatch::Request.new(env) case req.path - when "/pass" + when %r{/pass} [404, { "X-Cascade" => "pass" }, self] - when "/not_found" + when %r{/not_found} raise AbstractController::ActionNotFound - when "/runtime_error" + when %r{/runtime_error} raise RuntimeError - when "/method_not_allowed" + when %r{/method_not_allowed} raise ActionController::MethodNotAllowed - when "/unknown_http_method" + when %r{/unknown_http_method} raise ActionController::UnknownHttpMethod - when "/not_implemented" + when %r{/not_implemented} raise ActionController::NotImplemented - when "/unprocessable_entity" + when %r{/unprocessable_entity} raise ActionController::InvalidAuthenticityToken - when "/not_found_original_exception" + when %r{/not_found_original_exception} begin raise AbstractController::ActionNotFound.new rescue raise ActionView::Template::Error.new('template') end - when "/missing_template" + when %r{/missing_template} raise ActionView::MissingTemplate.new(%w(foo), 'foo/index', %w(foo), false, 'mailer') - when "/bad_request" + when %r{/bad_request} raise ActionController::BadRequest - when "/missing_keys" + when %r{/missing_keys} raise ActionController::UrlGenerationError, "No route matches" - when "/parameter_missing" + when %r{/parameter_missing} raise ActionController::ParameterMissing, :missing_param_key - when "/original_syntax_error" + when %r{/original_syntax_error} eval 'broke_syntax =' # `eval` need for raise native SyntaxError at runtime - when "/syntax_error_into_view" + when %r{/syntax_error_into_view} begin eval 'broke_syntax =' rescue Exception @@ -67,7 +67,7 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest {}) raise ActionView::Template::Error.new(template) end - when "/framework_raises" + when %r{/framework_raises} method_that_raises else raise "puke!" @@ -212,61 +212,60 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest assert_match(/ActionController::ParameterMissing/, body) end - test "rescue with json error for API request" do + test "rescue with JSON error for JSON API request" do @app = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp, :api) - get "/", headers: { 'action_dispatch.show_exceptions' => true } + get "/", headers: { 'action_dispatch.show_exceptions' => true }, as: :json assert_response 500 assert_no_match(/
/, body) assert_no_match(//, body) assert_equal "application/json", response.content_type assert_match(/RuntimeError: puke/, body) - get "/not_found", headers: { 'action_dispatch.show_exceptions' => true } + get "/not_found", headers: { 'action_dispatch.show_exceptions' => true }, as: :json assert_response 404 assert_no_match(//, body) assert_equal "application/json", response.content_type assert_match(/#{AbstractController::ActionNotFound.name}/, body) - get "/method_not_allowed", headers: { 'action_dispatch.show_exceptions' => true } + get "/method_not_allowed", headers: { 'action_dispatch.show_exceptions' => true }, as: :json assert_response 405 assert_no_match(//, body) assert_equal "application/json", response.content_type assert_match(/ActionController::MethodNotAllowed/, body) - get "/unknown_http_method", headers: { 'action_dispatch.show_exceptions' => true } + get "/unknown_http_method", headers: { 'action_dispatch.show_exceptions' => true }, as: :json assert_response 405 assert_no_match(//, body) assert_equal "application/json", response.content_type assert_match(/ActionController::UnknownHttpMethod/, body) - get "/bad_request", headers: { 'action_dispatch.show_exceptions' => true } + get "/bad_request", headers: { 'action_dispatch.show_exceptions' => true }, as: :json assert_response 400 assert_no_match(//, body) assert_equal "application/json", response.content_type assert_match(/ActionController::BadRequest/, body) - get "/parameter_missing", headers: { 'action_dispatch.show_exceptions' => true } + get "/parameter_missing", headers: { 'action_dispatch.show_exceptions' => true }, as: :json assert_response 400 assert_no_match(//, body) assert_equal "application/json", response.content_type assert_match(/ActionController::ParameterMissing/, body) end - test "rescue with json on API request returns only allowed formats or json as a fallback" do + test "rescue with HTML format for HTML API request" do @app = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp, :api) - get "/index.json", headers: { 'action_dispatch.show_exceptions' => true } - assert_response 500 - assert_equal "application/json", response.content_type - assert_match(/RuntimeError: puke/, body) - get "/index.html", headers: { 'action_dispatch.show_exceptions' => true } assert_response 500 - assert_no_match(/
/, body) - assert_no_match(//, body) - assert_equal "application/json", response.content_type - assert_match(/RuntimeError: puke/, body) + assert_match(/
/, body) + assert_match(//, body) + assert_equal "text/html", response.content_type + assert_match(/puke/, body) + end + + test "rescue with XML format for XML API requests" do + @app = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp, :api) get "/index.xml", headers: { 'action_dispatch.show_exceptions' => true } assert_response 500 @@ -274,6 +273,25 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest assert_match(/RuntimeError: puke/, body) end + test "rescue with JSON format as fallback if API request format is not supported" do + begin + Mime::Type.register 'text/wibble', :wibble + + ActionDispatch::IntegrationTest.register_encoder(:wibble, + param_encoder: -> params { params }) + + @app = ActionDispatch::DebugExceptions.new(Boomer.new(true), RoutesApp, :api) + + get "/index", headers: { 'action_dispatch.show_exceptions' => true }, as: :wibble + assert_response 500 + assert_equal "application/json", response.content_type + assert_match(/RuntimeError: puke/, body) + + ensure + Mime::Type.unregister :wibble + end + end + test "does not show filtered parameters" do @app = DevelopmentApp -- cgit v1.2.3 From 6b9bd2e3b08538cd74e497eb35193c51385f411e Mon Sep 17 00:00:00 2001 From: Tom Kadwill Date: Wed, 11 May 2016 19:06:10 +0100 Subject: Improve documentation and tests for raw_host_with_port and host_with_port --- actionpack/lib/action_dispatch/http/url.rb | 13 ++++++++++--- actionpack/test/dispatch/request_test.rb | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 37f41ae988..b7a6aeee7d 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -217,7 +217,7 @@ module ActionDispatch @protocol ||= ssl? ? 'https://' : 'http://' end - # Returns the \host for this request, such as "example.com". + # Returns the \host and port for this request, such as "example.com:8080". # # class Request < Rack::Request # include ActionDispatch::Http::URL @@ -226,6 +226,9 @@ module ActionDispatch # req = Request.new 'HTTP_HOST' => 'example.com' # req.raw_host_with_port # => "example.com" # + # req = Request.new 'HTTP_HOST' => 'example.com:80' + # req.raw_host_with_port # => "example.com:80" + # # req = Request.new 'HTTP_HOST' => 'example.com:8080' # req.raw_host_with_port # => "example.com:8080" def raw_host_with_port @@ -236,7 +239,7 @@ module ActionDispatch end end - # Returns the host for this request, such as example.com. + # Returns the host for this request, such as "example.com". # # class Request < Rack::Request # include ActionDispatch::Http::URL @@ -249,12 +252,16 @@ module ActionDispatch end # Returns a \host:\port string for this request, such as "example.com" or - # "example.com:8080". + # "example.com:8080". Port is only included if it is not a default port + # (80 or 443) # # class Request < Rack::Request # include ActionDispatch::Http::URL # end # + # req = Request.new 'HTTP_HOST' => 'example.com' + # req.host_with_port # => "example.com" + # # req = Request.new 'HTTP_HOST' => 'example.com:80' # req.host_with_port # => "example.com" # diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index a4cb8ce449..781f852633 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -417,6 +417,11 @@ class RequestPath < BaseRequestTest end class RequestHost < BaseRequestTest + test "host without specifying port" do + request = stub_request 'HTTP_HOST' => 'rubyonrails.org' + assert_equal "rubyonrails.org", request.host_with_port + end + test "host with default port" do request = stub_request 'HTTP_HOST' => 'rubyonrails.org:80' assert_equal "rubyonrails.org", request.host_with_port @@ -427,6 +432,21 @@ class RequestHost < BaseRequestTest assert_equal "rubyonrails.org:81", request.host_with_port end + test "raw without specifying port" do + request = stub_request 'HTTP_HOST' => 'rubyonrails.org' + assert_equal "rubyonrails.org", request.raw_host_with_port + end + + test "raw host with default port" do + request = stub_request 'HTTP_HOST' => 'rubyonrails.org:80' + assert_equal "rubyonrails.org:80", request.raw_host_with_port + end + + test "raw host with non default port" do + request = stub_request 'HTTP_HOST' => 'rubyonrails.org:81' + assert_equal "rubyonrails.org:81", request.raw_host_with_port + end + test "proxy request" do request = stub_request 'HTTP_HOST' => 'glu.ttono.us:80' assert_equal "glu.ttono.us", request.host_with_port -- cgit v1.2.3 From 775703e1f9b99500ecc362fd0eef5212b3580619 Mon Sep 17 00:00:00 2001 From: Tom Kadwill Date: Thu, 12 May 2016 07:05:41 +0100 Subject: Document and test ActionDispatch server_port --- actionpack/lib/action_dispatch/http/url.rb | 11 +++++++++++ actionpack/test/dispatch/request_test.rb | 11 +++++++++++ 2 files changed, 22 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index b7a6aeee7d..7a1350a46d 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -354,6 +354,17 @@ module ActionDispatch standard_port? ? '' : ":#{port}" end + # Returns the requested port, such as 8080, based on SERVER_PORT + # + # class Request < Rack::Request + # include ActionDispatch::Http::URL + # end + # + # req = Request.new 'SERVER_PORT' => '80' + # req.server_port # => 80 + # + # req = Request.new 'SERVER_PORT' => '8080' + # req.server_port # => 8080 def server_port get_header('SERVER_PORT').to_i end diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 781f852633..8a5d85ab84 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -358,6 +358,17 @@ class RequestPort < BaseRequestTest request = stub_request 'HTTP_HOST' => 'www.example.org:8080' assert_equal ':8080', request.port_string end + + test "server port" do + request = stub_request 'SERVER_PORT' => '8080' + assert_equal 8080, request.server_port + + request = stub_request 'SERVER_PORT' => '80' + assert_equal 80, request.server_port + + request = stub_request 'SERVER_PORT' => '' + assert_equal 0, request.server_port + end end class RequestPath < BaseRequestTest -- cgit v1.2.3 From e35b98e6f5c54330245645f2ed40d56c74538902 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Fri, 13 May 2016 17:43:48 -0700 Subject: Action Mailer: Declarative exception handling with `rescue_from`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follows the same pattern as controllers and jobs. Exceptions raised in delivery jobs (enqueued by `#deliver_later`) are also delegated to the mailer's rescue_from handlers, so you can handle the DeserializationError raised by delivery jobs: ```ruby class MyMailer < ApplicationMailer rescue_from ActiveJob::DeserializationError do … end ``` ActiveSupport::Rescuable polish: * Add the `rescue_with_handler` class method so exceptions may be handled at the class level without requiring an instance. * Rationalize `exception.cause` handling. If no handler matches the exception, fall back to the handler that matches its cause. * Handle exceptions raised elsewhere. Pass `object: …` to execute the `rescue_from` handler (e.g. a method call or a block to instance_exec) against a different object. Defaults to `self`. --- actionpack/lib/action_controller/metal/rescue.rb | 13 +--------- actionpack/test/controller/rescue_test.rb | 31 +----------------------- 2 files changed, 2 insertions(+), 42 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/rescue.rb b/actionpack/lib/action_controller/metal/rescue.rb index f1c967b982..17f4030f25 100644 --- a/actionpack/lib/action_controller/metal/rescue.rb +++ b/actionpack/lib/action_controller/metal/rescue.rb @@ -6,17 +6,6 @@ module ActionController #:nodoc: extend ActiveSupport::Concern include ActiveSupport::Rescuable - def rescue_with_handler(exception) - if exception.cause - handler_index = index_of_handler_for_rescue(exception) || Float::INFINITY - cause_handler_index = index_of_handler_for_rescue(exception.cause) - if cause_handler_index && cause_handler_index <= handler_index - exception = exception.cause - end - end - super(exception) - end - # Override this method if you want to customize when detailed # exceptions must be shown. This method is only called when # consider_all_requests_local is false. By default, it returns @@ -31,7 +20,7 @@ module ActionController #:nodoc: super rescue Exception => exception request.env['action_dispatch.show_detailed_exceptions'] ||= show_detailed_exceptions? - rescue_with_handler(exception) || raise(exception) + rescue_with_handler(exception) || raise end end end diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb index ed78f859ce..c088e5a043 100644 --- a/actionpack/test/controller/rescue_test.rb +++ b/actionpack/test/controller/rescue_test.rb @@ -131,22 +131,6 @@ class RescueController < ActionController::Base def missing_template end - def io_error_in_view - begin - raise IOError.new('this is io error') - rescue - raise ActionView::TemplateError.new(nil) - end - end - - def zero_division_error_in_view - begin - raise ZeroDivisionError.new('this is zero division error') - rescue - raise ActionView::TemplateError.new(nil) - end - end - def exception_with_more_specific_handler_for_wrapper raise RecordInvalid rescue @@ -251,17 +235,6 @@ class ControllerInheritanceRescueControllerTest < ActionController::TestCase end class RescueControllerTest < ActionController::TestCase - - def test_io_error_in_view - get :io_error_in_view - assert_equal 'io error', @response.body - end - - def test_zero_division_error_in_view - get :zero_division_error_in_view - assert_equal 'action_view templater error', @response.body - end - def test_rescue_handler get :not_authorized assert_response :forbidden @@ -276,7 +249,6 @@ class RescueControllerTest < ActionController::TestCase get :record_invalid end end - def test_rescue_handler_with_argument_as_string assert_called_with @controller, :show_errors, [Exception] do get :record_invalid_raise_as_string @@ -314,7 +286,6 @@ class RescueControllerTest < ActionController::TestCase get :resource_unavailable assert_equal "RescueController::ResourceUnavailable", @response.body end - def test_block_rescue_handler_with_argument_as_string get :resource_unavailable_raise_as_string assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body @@ -322,7 +293,7 @@ class RescueControllerTest < ActionController::TestCase test 'rescue when wrapper has more specific handler than cause' do get :exception_with_more_specific_handler_for_wrapper - assert_response :unprocessable_entity + assert_response :forbidden end test 'rescue when cause has more specific handler than wrapper' do -- cgit v1.2.3 From 89e2f7e722e06f900bdb1c14db33073c90d7cdea Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Tue, 17 May 2016 07:56:08 -0700 Subject: Support for unified Integer class in Ruby 2.4+ Ruby 2.4 unifies Fixnum and Bignum into Integer: https://bugs.ruby-lang.org/issues/12005 * Forward compat with new unified Integer class in Ruby 2.4+. * Backward compat with separate Fixnum/Bignum in Ruby 2.2 & 2.3. * Drops needless Fixnum distinction in docs, preferring Integer. --- actionpack/lib/action_dispatch/routing/mapper.rb | 4 ++-- .../lib/action_dispatch/testing/assertion_response.rb | 16 ++++++---------- actionpack/test/assertions/response_assertions_test.rb | 2 +- actionpack/test/controller/routing_test.rb | 2 +- actionpack/test/controller/test_case_test.rb | 4 ++-- 5 files changed, 12 insertions(+), 16 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 4c2a4cfeb0..8ff3b42a40 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -120,7 +120,7 @@ module ActionDispatch if options_constraints.is_a?(Hash) @defaults = Hash[options_constraints.find_all { |key, default| - URL_OPTIONS.include?(key) && (String === default || Fixnum === default) + URL_OPTIONS.include?(key) && (String === default || Integer === default) }].merge @defaults @blocks = blocks constraints.merge! options_constraints @@ -824,7 +824,7 @@ module ActionDispatch if options[:constraints].is_a?(Hash) defaults = options[:constraints].select do |k, v| - URL_OPTIONS.include?(k) && (v.is_a?(String) || v.is_a?(Fixnum)) + URL_OPTIONS.include?(k) && (v.is_a?(String) || v.is_a?(Integer)) end options[:defaults] = defaults.merge(options[:defaults] || {}) diff --git a/actionpack/lib/action_dispatch/testing/assertion_response.rb b/actionpack/lib/action_dispatch/testing/assertion_response.rb index 3fb81ff083..404b96bbcd 100644 --- a/actionpack/lib/action_dispatch/testing/assertion_response.rb +++ b/actionpack/lib/action_dispatch/testing/assertion_response.rb @@ -1,14 +1,7 @@ module ActionDispatch - # This is a class that abstracts away an asserted response. - # It purposely does not inherit from Response, because it doesn't need it. - # That means it does not have headers or a body. - # - # As an input to the initializer, we take a Fixnum, a String, or a Symbol. - # If it's a Fixnum or String, we figure out what its symbolized name. - # If it's a Symbol, we figure out what its corresponding code is. - # The resulting code will be a Fixnum, for real HTTP codes, and it will - # be a String for the pseudo-HTTP codes, such as: - # :success, :missing, :redirect and :error + # This is a class that abstracts away an asserted response. It purposely + # does not inherit from Response because it doesn't need it. That means it + # does not have headers or a body. class AssertionResponse attr_reader :code, :name @@ -19,6 +12,9 @@ module ActionDispatch error: "5XX" } + # Accepts a specific response status code as an Integer (404) or String + # ('404') or a response status range as a Symbol pseudo-code (:success, + # indicating any 200-299 status code). def initialize(code_or_name) if code_or_name.is_a?(Symbol) @name = code_or_name diff --git a/actionpack/test/assertions/response_assertions_test.rb b/actionpack/test/assertions/response_assertions_test.rb index 579ce0ed29..57a67a48b5 100644 --- a/actionpack/test/assertions/response_assertions_test.rb +++ b/actionpack/test/assertions/response_assertions_test.rb @@ -35,7 +35,7 @@ module ActionDispatch end end - def test_assert_response_fixnum + def test_assert_response_integer @response = FakeResponse.new 400 assert_response 400 diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb index 168677829a..03bf8f8295 100644 --- a/actionpack/test/controller/routing_test.rb +++ b/actionpack/test/controller/routing_test.rb @@ -626,7 +626,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase assert_equal '/pages/boo', url_for(rs, { :controller => 'pages', :action => 'boo' }) end - def test_route_with_fixnum_default + def test_route_with_integer_default rs.draw do get 'page(/:id)' => 'content#show_page', :id => 1 diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb index ebcdda6074..6160b3395a 100644 --- a/actionpack/test/controller/test_case_test.rb +++ b/actionpack/test/controller/test_case_test.rb @@ -553,7 +553,7 @@ XML assert_equal 'created', flash[:notice] end - def test_params_passing_with_fixnums + def test_params_passing_with_integer get :test_params, params: { page: { name: "Page name", month: 4, year: 2004, day: 6 } } @@ -565,7 +565,7 @@ XML ) end - def test_params_passing_with_fixnums_when_not_html_request + def test_params_passing_with_integers_when_not_html_request get :test_params, params: { format: 'json', count: 999 } parsed_params = ::JSON.parse(@response.body) assert_equal( -- cgit v1.2.3 From e73f9bed62a138dc0f2a78dfa4eda7d3292ba1aa Mon Sep 17 00:00:00 2001 From: Jose Donizetti Date: Thu, 19 May 2016 00:06:48 -0400 Subject: fix named route example [ci skip] --- actionpack/lib/action_dispatch/routing.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index 67f441dfec..64f8636c52 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -118,11 +118,11 @@ module ActionDispatch # controller :blog do # get 'blog/show' => :list # get 'blog/delete' => :delete - # get 'blog/edit/:id' => :edit + # get 'blog/edit' => :edit # end # - # # provides named routes for show, delete, and edit - # link_to @article.title, show_path(id: @article.id) + # # provides named routes for show, delete and edit + # link_to @article.title, blog_show_path(id: @article.id) # # == Pretty URLs # -- cgit v1.2.3 From f58bd6ed22b0fea1cfe07eaf8b62940fcb104d7a Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Thu, 19 May 2016 15:41:59 -0400 Subject: Add back in Oxford Comma per [API documentation guidelines](http://edgeguides.rubyonrails.org/api_documentation_guidelines.html#oxford-comma) [ci skip] --- actionpack/lib/action_dispatch/routing.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb index 64f8636c52..dd6ac9db9c 100644 --- a/actionpack/lib/action_dispatch/routing.rb +++ b/actionpack/lib/action_dispatch/routing.rb @@ -121,7 +121,7 @@ module ActionDispatch # get 'blog/edit' => :edit # end # - # # provides named routes for show, delete and edit + # # provides named routes for show, delete, and edit # link_to @article.title, blog_show_path(id: @article.id) # # == Pretty URLs -- cgit v1.2.3 From 0ce7eae7418f1b9bb06b351c1f26d50c3674c0d0 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Tue, 17 May 2016 16:53:20 -0700 Subject: Make sure the cache is always populated This way we don't have to make multiple calls on anonymous controllers --- actionpack/lib/abstract_controller/base.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index d4317399ed..e90886775e 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -94,7 +94,11 @@ module AbstractController # ==== Returns # * String def controller_path - @controller_path ||= name.sub(/Controller$/, ''.freeze).underscore unless anonymous? + @controller_path ||= if anonymous? + superclass.controller_path + else + name.sub(/Controller$/, ''.freeze).underscore + end end # Refresh the cached action_methods when a new action_method is added. -- cgit v1.2.3 From e3b239cc1a8626c24f4a642e9261bad4a97c6cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 20 May 2016 23:28:00 -0300 Subject: Revert "Make sure the cache is always populated" This reverts commit 0ce7eae7418f1b9bb06b351c1f26d50c3674c0d0. Tests were broken https://travis-ci.org/rails/rails/jobs/131850726#L520 --- actionpack/lib/abstract_controller/base.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index e90886775e..d4317399ed 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -94,11 +94,7 @@ module AbstractController # ==== Returns # * String def controller_path - @controller_path ||= if anonymous? - superclass.controller_path - else - name.sub(/Controller$/, ''.freeze).underscore - end + @controller_path ||= name.sub(/Controller$/, ''.freeze).underscore unless anonymous? end # Refresh the cached action_methods when a new action_method is added. -- cgit v1.2.3 From 683b9627b3ad51f14457b580d0d988715b202f96 Mon Sep 17 00:00:00 2001 From: Matthew Caruana Galizia Date: Fri, 20 May 2016 16:25:02 +0200 Subject: Respect `log_warning_on_csrf_failure` setting for all CSRF failures CSRF verification for non-XHR GET requests (cross-origin `