aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorKasper Timm Hansen <kaspth@gmail.com>2016-11-22 22:22:34 +0100
committerKasper Timm Hansen <kaspth@gmail.com>2016-11-23 22:02:19 +0100
commit86754a8f7b4986323aae3be172330fbc228c27ab (patch)
treedcfaf38a44dace30b40ce9a597eed3cc2c9d4937 /actionpack
parent49aa974ec8b15721d53b3b6abea88bd6ba433a68 (diff)
downloadrails-86754a8f7b4986323aae3be172330fbc228c27ab.tar.gz
rails-86754a8f7b4986323aae3be172330fbc228c27ab.tar.bz2
rails-86754a8f7b4986323aae3be172330fbc228c27ab.zip
Use accept header instead of mangling request path.
Instead of appending a format to the request, it's much better to just pass a more appropriate accept header. Rails will figure out the format from that instead. This allows devs to use `:as` on routes that don't have a format. Introduce an `IdentityEncoder` to avoid `if request_encoder`, essentially a better version of the purpose of the `WWWFormEncoder`. One that makes conceptual sense on GET requests too. Fixes #27144.
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb10
-rw-r--r--actionpack/lib/action_dispatch/testing/request_encoder.rb31
-rw-r--r--actionpack/test/controller/integration_test.rb27
3 files changed, 44 insertions, 24 deletions
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index a1c2a8858a..c60395acf9 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -211,7 +211,7 @@ module ActionDispatch
end
if path =~ %r{://}
- path = build_expanded_path(path, request_encoder) do |location|
+ path = build_expanded_path(path) do |location|
https! URI::HTTPS === location if location.scheme
if url_host = location.host
@@ -220,8 +220,6 @@ module ActionDispatch
host! url_host
end
end
- elsif as
- path = build_expanded_path(path, request_encoder)
end
hostname, port = host.split(":")
@@ -239,7 +237,7 @@ module ActionDispatch
"HTTP_HOST" => host,
"REMOTE_ADDR" => remote_addr,
"CONTENT_TYPE" => request_encoder.content_type,
- "HTTP_ACCEPT" => accept
+ "HTTP_ACCEPT" => request_encoder.accept_header || accept
}
wrapped_headers = Http::Headers.from_hash({})
@@ -291,10 +289,10 @@ module ActionDispatch
"#{env['rack.url_scheme']}://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{path}"
end
- def build_expanded_path(path, request_encoder)
+ def build_expanded_path(path)
location = URI.parse(path)
yield location if block_given?
- path = request_encoder.append_format_to location.path
+ path = location.path
location.query ? "#{path}?#{location.query}" : path
end
end
diff --git a/actionpack/lib/action_dispatch/testing/request_encoder.rb b/actionpack/lib/action_dispatch/testing/request_encoder.rb
index b0b994b2d0..734fc8cb54 100644
--- a/actionpack/lib/action_dispatch/testing/request_encoder.rb
+++ b/actionpack/lib/action_dispatch/testing/request_encoder.rb
@@ -1,10 +1,17 @@
module ActionDispatch
class RequestEncoder # :nodoc:
- @encoders = {}
+ class IdentityEncoder
+ def content_type; end
+ def accept_header; end
+ def encode_params(params); params; end
+ def response_parser; -> body { body }; end
+ end
+
+ @encoders = { identity: IdentityEncoder.new }
attr_reader :response_parser
- def initialize(mime_name, param_encoder, response_parser, url_encoded_form = false)
+ def initialize(mime_name, param_encoder, response_parser = nil)
@mime = Mime[mime_name]
unless @mime
@@ -12,21 +19,15 @@ module ActionDispatch
"unregistered MIME Type: #{mime_name}. See `Mime::Type.register`."
end
- @url_encoded_form = url_encoded_form
- @path_format = ".#{@mime.symbol}" unless @url_encoded_form
- @response_parser = response_parser || -> body { body }
- @param_encoder = param_encoder || :"to_#{@mime.symbol}".to_proc
+ @response_parser = response_parser || -> body { body }
+ @param_encoder = param_encoder || :"to_#{@mime.symbol}".to_proc
end
- def append_format_to(path)
- if @url_encoded_form
- path
- else
- path + @path_format
- end
+ def content_type
+ @mime.to_s
end
- def content_type
+ def accept_header
@mime.to_s
end
@@ -40,7 +41,7 @@ module ActionDispatch
end
def self.encoder(name)
- @encoders[name] || WWWFormEncoder
+ @encoders[name] || @encoders[:identity]
end
def self.register_encoder(mime_name, param_encoder: nil, response_parser: nil)
@@ -48,7 +49,5 @@ module ActionDispatch
end
register_encoder :json, response_parser: -> body { JSON.parse(body) }
-
- WWWFormEncoder = new(:url_encoded_form, -> params { params }, nil, true)
end
end
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index f89cfdb78c..d8be5d32e1 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -930,6 +930,10 @@ end
class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest
class FooController < ActionController::Base
+ def foos
+ render plain: "ok"
+ end
+
def foos_json
render json: params.permit(:foo)
end
@@ -958,13 +962,30 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest
def test_encoding_as_json
post_to_foos as: :json do
assert_response :success
- assert_match "foos_json.json", request.path
assert_equal "application/json", request.content_type
+ assert_equal "application/json", request.accepts.first.to_s
+ assert_equal :json, request.format.ref
assert_equal({ "foo" => "fighters" }, request.request_parameters)
assert_equal({ "foo" => "fighters" }, response.parsed_body)
end
end
+ def test_doesnt_mangle_request_path
+ with_routing do |routes|
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ post ":action" => FooController
+ end
+ end
+
+ post "/foos"
+ assert_equal "/foos", request.path
+
+ post "/foos_json", as: :json
+ assert_equal "/foos_json", request.path
+ end
+ end
+
def test_encoding_as_without_mime_registration
assert_raise ArgumentError do
ActionDispatch::IntegrationTest.register_encoder :wibble
@@ -979,8 +1000,10 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest
post_to_foos as: :wibble do
assert_response :success
- assert_match "foos_wibble.wibble", request.path
+ assert_equal "/foos_wibble", request.path
assert_equal "text/wibble", request.content_type
+ assert_equal "text/wibble", request.accepts.first.to_s
+ assert_equal :wibble, request.format.ref
assert_equal Hash.new, request.request_parameters # Unregistered MIME Type can't be parsed.
assert_equal "ok", response.parsed_body
end