actionpack 4.1.7 → 4.2.11
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +404 -451
- data/README.rdoc +7 -2
- data/lib/abstract_controller/base.rb +16 -6
- data/lib/abstract_controller/callbacks.rb +28 -51
- data/lib/abstract_controller/helpers.rb +11 -4
- data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
- data/lib/abstract_controller/rendering.rb +7 -1
- data/lib/abstract_controller/url_for.rb +1 -1
- data/lib/action_controller/base.rb +3 -2
- data/lib/action_controller/caching/fragments.rb +7 -1
- data/lib/action_controller/caching.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +26 -26
- data/lib/action_controller/metal/conditional_get.rb +37 -12
- data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
- data/lib/action_controller/metal/exceptions.rb +1 -1
- data/lib/action_controller/metal/force_ssl.rb +1 -1
- data/lib/action_controller/metal/head.rb +7 -3
- data/lib/action_controller/metal/http_authentication.rb +20 -10
- data/lib/action_controller/metal/instrumentation.rb +8 -5
- data/lib/action_controller/metal/live.rb +57 -6
- data/lib/action_controller/metal/mime_responds.rb +25 -246
- data/lib/action_controller/metal/params_wrapper.rb +5 -5
- data/lib/action_controller/metal/rack_delegation.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +14 -8
- data/lib/action_controller/metal/renderers.rb +29 -11
- data/lib/action_controller/metal/rendering.rb +2 -6
- data/lib/action_controller/metal/request_forgery_protection.rb +78 -7
- data/lib/action_controller/metal/streaming.rb +1 -1
- data/lib/action_controller/metal/strong_parameters.rb +129 -14
- data/lib/action_controller/metal/url_for.rb +11 -12
- data/lib/action_controller/metal.rb +12 -11
- data/lib/action_controller/model_naming.rb +1 -1
- data/lib/action_controller/railtie.rb +4 -0
- data/lib/action_controller/test_case.rb +119 -75
- data/lib/action_controller.rb +1 -1
- data/lib/action_dispatch/http/cache.rb +5 -4
- data/lib/action_dispatch/http/filter_parameters.rb +2 -2
- data/lib/action_dispatch/http/headers.rb +43 -9
- data/lib/action_dispatch/http/mime_negotiation.rb +10 -3
- data/lib/action_dispatch/http/mime_type.rb +18 -4
- data/lib/action_dispatch/http/parameter_filter.rb +1 -1
- data/lib/action_dispatch/http/parameters.rb +11 -26
- data/lib/action_dispatch/http/request.rb +37 -11
- data/lib/action_dispatch/http/response.rb +74 -23
- data/lib/action_dispatch/http/upload.rb +9 -8
- data/lib/action_dispatch/http/url.rb +89 -70
- data/lib/action_dispatch/journey/formatter.rb +34 -18
- data/lib/action_dispatch/journey/gtg/builder.rb +3 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -7
- data/lib/action_dispatch/journey/gtg/transition_table.rb +20 -28
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
- data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
- data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -5
- data/lib/action_dispatch/journey/nodes/node.rb +4 -0
- data/lib/action_dispatch/journey/parser.rb +52 -60
- data/lib/action_dispatch/journey/parser.y +11 -10
- data/lib/action_dispatch/journey/path/pattern.rb +16 -19
- data/lib/action_dispatch/journey/route.rb +4 -19
- data/lib/action_dispatch/journey/router/strexp.rb +9 -6
- data/lib/action_dispatch/journey/router/utils.rb +1 -1
- data/lib/action_dispatch/journey/router.rb +53 -77
- data/lib/action_dispatch/journey/routes.rb +4 -0
- data/lib/action_dispatch/journey/scanner.rb +5 -5
- data/lib/action_dispatch/journey/visitors.rb +81 -92
- data/lib/action_dispatch/journey/visualizer/fsm.css +0 -4
- data/lib/action_dispatch/journey/visualizer/index.html.erb +2 -2
- data/lib/action_dispatch/middleware/callbacks.rb +1 -1
- data/lib/action_dispatch/middleware/cookies.rb +34 -34
- data/lib/action_dispatch/middleware/debug_exceptions.rb +15 -4
- data/lib/action_dispatch/middleware/exception_wrapper.rb +50 -18
- data/lib/action_dispatch/middleware/flash.rb +13 -7
- data/lib/action_dispatch/middleware/params_parser.rb +1 -1
- data/lib/action_dispatch/middleware/public_exceptions.rb +12 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +40 -54
- data/lib/action_dispatch/middleware/request_id.rb +1 -1
- data/lib/action_dispatch/middleware/session/cookie_store.rb +1 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +1 -0
- data/lib/action_dispatch/middleware/ssl.rb +1 -1
- data/lib/action_dispatch/middleware/static.rb +75 -39
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +21 -19
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +37 -9
- data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +2 -8
- data/lib/action_dispatch/middleware/templates/rescues/{diagnostics.erb → diagnostics.html.erb} +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +6 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +4 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +2 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -24
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +0 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +120 -64
- data/lib/action_dispatch/railtie.rb +2 -0
- data/lib/action_dispatch/routing/endpoint.rb +10 -0
- data/lib/action_dispatch/routing/inspector.rb +5 -12
- data/lib/action_dispatch/routing/mapper.rb +414 -283
- data/lib/action_dispatch/routing/polymorphic_routes.rb +191 -79
- data/lib/action_dispatch/routing/redirection.rb +10 -12
- data/lib/action_dispatch/routing/route_set.rb +300 -173
- data/lib/action_dispatch/routing/routes_proxy.rb +5 -4
- data/lib/action_dispatch/routing/url_for.rb +17 -5
- data/lib/action_dispatch/testing/assertions/dom.rb +2 -26
- data/lib/action_dispatch/testing/assertions/response.rb +2 -7
- data/lib/action_dispatch/testing/assertions/routing.rb +22 -22
- data/lib/action_dispatch/testing/assertions/selector.rb +2 -429
- data/lib/action_dispatch/testing/assertions/tag.rb +2 -134
- data/lib/action_dispatch/testing/assertions.rb +11 -7
- data/lib/action_dispatch/testing/integration.rb +28 -20
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +1 -5
- data/lib/action_pack/gem_version.rb +3 -3
- metadata +55 -13
- data/lib/action_controller/metal/responder.rb +0 -297
data/lib/action_controller.rb
CHANGED
@@ -17,6 +17,7 @@ module ActionController
|
|
17
17
|
autoload :ConditionalGet
|
18
18
|
autoload :Cookies
|
19
19
|
autoload :DataStreaming
|
20
|
+
autoload :EtagWithTemplateDigest
|
20
21
|
autoload :Flash
|
21
22
|
autoload :ForceSSL
|
22
23
|
autoload :Head
|
@@ -33,7 +34,6 @@ module ActionController
|
|
33
34
|
autoload :Rendering
|
34
35
|
autoload :RequestForgeryProtection
|
35
36
|
autoload :Rescue
|
36
|
-
autoload :Responder
|
37
37
|
autoload :Streaming
|
38
38
|
autoload :StrongParameters
|
39
39
|
autoload :Testing
|
@@ -69,17 +69,17 @@ module ActionDispatch
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def date
|
72
|
-
if date_header = headers[
|
72
|
+
if date_header = headers[DATE]
|
73
73
|
Time.httpdate(date_header)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
77
|
def date?
|
78
|
-
headers.include?(
|
78
|
+
headers.include?(DATE)
|
79
79
|
end
|
80
80
|
|
81
81
|
def date=(utc_time)
|
82
|
-
headers[
|
82
|
+
headers[DATE] = utc_time.httpdate
|
83
83
|
end
|
84
84
|
|
85
85
|
def etag=(etag)
|
@@ -89,10 +89,11 @@ module ActionDispatch
|
|
89
89
|
|
90
90
|
private
|
91
91
|
|
92
|
+
DATE = 'Date'.freeze
|
92
93
|
LAST_MODIFIED = "Last-Modified".freeze
|
93
94
|
ETAG = "ETag".freeze
|
94
95
|
CACHE_CONTROL = "Cache-Control".freeze
|
95
|
-
SPECIAL_KEYS = %w[extras no-cache max-age public must-revalidate]
|
96
|
+
SPECIAL_KEYS = Set.new(%w[extras no-cache max-age public must-revalidate])
|
96
97
|
|
97
98
|
def cache_control_segments
|
98
99
|
if cache_control = self[CACHE_CONTROL]
|
@@ -6,8 +6,8 @@ module ActionDispatch
|
|
6
6
|
module Http
|
7
7
|
# Allows you to specify sensitive parameters which will be replaced from
|
8
8
|
# the request log by looking in the query string of the request and all
|
9
|
-
#
|
10
|
-
# value of the params hash and all
|
9
|
+
# sub-hashes of the params hash to filter. If a block is given, each key and
|
10
|
+
# value of the params hash and all sub-hashes is passed to it, the value
|
11
11
|
# or key can be replaced using String#replace or similar method.
|
12
12
|
#
|
13
13
|
# env["action_dispatch.parameter_filter"] = [:password]
|
@@ -1,27 +1,47 @@
|
|
1
1
|
module ActionDispatch
|
2
2
|
module Http
|
3
|
+
# Provides access to the request's HTTP headers from the environment.
|
4
|
+
#
|
5
|
+
# env = { "CONTENT_TYPE" => "text/plain" }
|
6
|
+
# headers = ActionDispatch::Http::Headers.new(env)
|
7
|
+
# headers["Content-Type"] # => "text/plain"
|
3
8
|
class Headers
|
4
|
-
CGI_VARIABLES = %
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
CGI_VARIABLES = Set.new(%W[
|
10
|
+
AUTH_TYPE
|
11
|
+
CONTENT_LENGTH
|
12
|
+
CONTENT_TYPE
|
13
|
+
GATEWAY_INTERFACE
|
14
|
+
HTTPS
|
15
|
+
PATH_INFO
|
16
|
+
PATH_TRANSLATED
|
17
|
+
QUERY_STRING
|
18
|
+
REMOTE_ADDR
|
19
|
+
REMOTE_HOST
|
20
|
+
REMOTE_IDENT
|
21
|
+
REMOTE_USER
|
22
|
+
REQUEST_METHOD
|
23
|
+
SCRIPT_NAME
|
24
|
+
SERVER_NAME
|
25
|
+
SERVER_PORT
|
26
|
+
SERVER_PROTOCOL
|
27
|
+
SERVER_SOFTWARE
|
28
|
+
]).freeze
|
29
|
+
|
12
30
|
HTTP_HEADER = /\A[A-Za-z0-9-]+\z/
|
13
31
|
|
14
32
|
include Enumerable
|
15
33
|
attr_reader :env
|
16
34
|
|
17
|
-
def initialize(env = {})
|
35
|
+
def initialize(env = {}) # :nodoc:
|
18
36
|
@env = env
|
19
37
|
end
|
20
38
|
|
39
|
+
# Returns the value for the given key mapped to @env.
|
21
40
|
def [](key)
|
22
41
|
@env[env_name(key)]
|
23
42
|
end
|
24
43
|
|
44
|
+
# Sets the given value for the key mapped to @env.
|
25
45
|
def []=(key, value)
|
26
46
|
@env[env_name(key)] = value
|
27
47
|
end
|
@@ -31,6 +51,13 @@ module ActionDispatch
|
|
31
51
|
end
|
32
52
|
alias :include? :key?
|
33
53
|
|
54
|
+
# Returns the value for the given key mapped to @env.
|
55
|
+
#
|
56
|
+
# If the key is not found and an optional code block is not provided,
|
57
|
+
# raises a <tt>KeyError</tt> exception.
|
58
|
+
#
|
59
|
+
# If the code block is provided, then it will be run and
|
60
|
+
# its result returned.
|
34
61
|
def fetch(key, *args, &block)
|
35
62
|
@env.fetch env_name(key), *args, &block
|
36
63
|
end
|
@@ -39,12 +66,17 @@ module ActionDispatch
|
|
39
66
|
@env.each(&block)
|
40
67
|
end
|
41
68
|
|
69
|
+
# Returns a new Http::Headers instance containing the contents of
|
70
|
+
# <tt>headers_or_env</tt> and the original instance.
|
42
71
|
def merge(headers_or_env)
|
43
72
|
headers = Http::Headers.new(env.dup)
|
44
73
|
headers.merge!(headers_or_env)
|
45
74
|
headers
|
46
75
|
end
|
47
76
|
|
77
|
+
# Adds the contents of <tt>headers_or_env</tt> to original instance
|
78
|
+
# entries; duplicate keys are overwritten with the values from
|
79
|
+
# <tt>headers_or_env</tt>.
|
48
80
|
def merge!(headers_or_env)
|
49
81
|
headers_or_env.each do |key, value|
|
50
82
|
self[env_name(key)] = value
|
@@ -52,6 +84,8 @@ module ActionDispatch
|
|
52
84
|
end
|
53
85
|
|
54
86
|
private
|
87
|
+
# Converts a HTTP header name to an environment variable name if it is
|
88
|
+
# not contained within the headers hash.
|
55
89
|
def env_name(key)
|
56
90
|
key = key.to_s
|
57
91
|
if key =~ HTTP_HEADER
|
@@ -54,8 +54,14 @@ module ActionDispatch
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def formats
|
57
|
-
@env["action_dispatch.request.formats"] ||=
|
58
|
-
|
57
|
+
@env["action_dispatch.request.formats"] ||= begin
|
58
|
+
params_readable = begin
|
59
|
+
parameters[:format]
|
60
|
+
rescue ActionController::BadRequest
|
61
|
+
false
|
62
|
+
end
|
63
|
+
|
64
|
+
if params_readable
|
59
65
|
Array(Mime[parameters[:format]])
|
60
66
|
elsif use_accept_header && valid_accept_header
|
61
67
|
accepts
|
@@ -64,13 +70,14 @@ module ActionDispatch
|
|
64
70
|
else
|
65
71
|
[Mime::HTML]
|
66
72
|
end
|
73
|
+
end
|
67
74
|
end
|
68
75
|
|
69
76
|
# Sets the \variant for template.
|
70
77
|
def variant=(variant)
|
71
78
|
if variant.is_a?(Symbol)
|
72
79
|
@variant = [variant]
|
73
|
-
elsif variant.is_a?(Array) && variant.any? && variant.all?{ |v| v.is_a?(Symbol) }
|
80
|
+
elsif variant.nil? || variant.is_a?(Array) && variant.any? && variant.all?{ |v| v.is_a?(Symbol) }
|
74
81
|
@variant = variant
|
75
82
|
else
|
76
83
|
raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols, not a #{variant.class}. " \
|
@@ -23,7 +23,7 @@ module Mime
|
|
23
23
|
|
24
24
|
SET = Mimes.new
|
25
25
|
EXTENSION_LOOKUP = {}
|
26
|
-
LOOKUP =
|
26
|
+
LOOKUP = {}
|
27
27
|
|
28
28
|
class << self
|
29
29
|
def [](type)
|
@@ -45,8 +45,8 @@ module Mime
|
|
45
45
|
#
|
46
46
|
# respond_to do |format|
|
47
47
|
# format.html
|
48
|
-
# format.ics { render text: post.to_ics, mime_type: Mime::Type["text/calendar"] }
|
49
|
-
# format.xml { render xml: @
|
48
|
+
# format.ics { render text: @post.to_ics, mime_type: Mime::Type["text/calendar"] }
|
49
|
+
# format.xml { render xml: @post }
|
50
50
|
# end
|
51
51
|
# end
|
52
52
|
# end
|
@@ -146,7 +146,7 @@ module Mime
|
|
146
146
|
end
|
147
147
|
|
148
148
|
def lookup(string)
|
149
|
-
LOOKUP[string]
|
149
|
+
LOOKUP[string] || Type.new(string)
|
150
150
|
end
|
151
151
|
|
152
152
|
def lookup_by_extension(extension)
|
@@ -225,9 +225,12 @@ module Mime
|
|
225
225
|
end
|
226
226
|
end
|
227
227
|
|
228
|
+
attr_reader :hash
|
229
|
+
|
228
230
|
def initialize(string, symbol = nil, synonyms = [])
|
229
231
|
@symbol, @synonyms = symbol, synonyms
|
230
232
|
@string = string
|
233
|
+
@hash = [@string, @synonyms, @symbol].hash
|
231
234
|
end
|
232
235
|
|
233
236
|
def to_s
|
@@ -261,6 +264,13 @@ module Mime
|
|
261
264
|
end
|
262
265
|
end
|
263
266
|
|
267
|
+
def eql?(other)
|
268
|
+
super || (self.class == other.class &&
|
269
|
+
@string == other.string &&
|
270
|
+
@synonyms == other.synonyms &&
|
271
|
+
@symbol == other.symbol)
|
272
|
+
end
|
273
|
+
|
264
274
|
def =~(mime_type)
|
265
275
|
return false if mime_type.blank?
|
266
276
|
regexp = Regexp.new(Regexp.quote(mime_type.to_s))
|
@@ -274,6 +284,10 @@ module Mime
|
|
274
284
|
end
|
275
285
|
|
276
286
|
|
287
|
+
protected
|
288
|
+
|
289
|
+
attr_reader :string, :synonyms
|
290
|
+
|
277
291
|
private
|
278
292
|
|
279
293
|
def to_ary; end
|
@@ -56,7 +56,7 @@ module ActionDispatch
|
|
56
56
|
elsif value.is_a?(Array)
|
57
57
|
value = value.map { |v| v.is_a?(Hash) ? call(v) : v }
|
58
58
|
elsif blocks.any?
|
59
|
-
key = key.dup
|
59
|
+
key = key.dup if key.duplicable?
|
60
60
|
value = value.dup if value.duplicable?
|
61
61
|
blocks.each { |b| b.call(key, value) }
|
62
62
|
end
|
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'active_support/core_ext/hash/keys'
|
2
2
|
require 'active_support/core_ext/hash/indifferent_access'
|
3
|
+
require 'active_support/deprecation'
|
3
4
|
|
4
5
|
module ActionDispatch
|
5
6
|
module Http
|
6
7
|
module Parameters
|
7
|
-
|
8
|
-
super
|
9
|
-
@symbolized_path_params = nil
|
10
|
-
end
|
8
|
+
PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
|
11
9
|
|
12
10
|
# Returns both GET and POST \parameters in a single hash.
|
13
11
|
def parameters
|
@@ -18,55 +16,42 @@ module ActionDispatch
|
|
18
16
|
query_parameters.dup
|
19
17
|
end
|
20
18
|
params.merge!(path_parameters)
|
21
|
-
params.with_indifferent_access
|
22
19
|
end
|
23
20
|
end
|
24
21
|
alias :params :parameters
|
25
22
|
|
26
23
|
def path_parameters=(parameters) #:nodoc:
|
27
|
-
@
|
28
|
-
@env
|
29
|
-
@env["action_dispatch.request.path_parameters"] = parameters
|
24
|
+
@env.delete('action_dispatch.request.parameters')
|
25
|
+
@env[PARAMETERS_KEY] = parameters
|
30
26
|
end
|
31
27
|
|
32
|
-
# The same as <tt>path_parameters</tt> with explicitly symbolized keys.
|
33
28
|
def symbolized_path_parameters
|
34
|
-
|
29
|
+
ActiveSupport::Deprecation.warn(
|
30
|
+
'`symbolized_path_parameters` is deprecated. Please use `path_parameters`.'
|
31
|
+
)
|
32
|
+
path_parameters
|
35
33
|
end
|
36
34
|
|
37
35
|
# Returns a hash with the \parameters used to form the \path of the request.
|
38
36
|
# Returned hash keys are strings:
|
39
37
|
#
|
40
38
|
# {'action' => 'my_action', 'controller' => 'my_controller'}
|
41
|
-
#
|
42
|
-
# See <tt>symbolized_path_parameters</tt> for symbolized keys.
|
43
39
|
def path_parameters
|
44
|
-
@env[
|
45
|
-
end
|
46
|
-
|
47
|
-
def reset_parameters #:nodoc:
|
48
|
-
@env.delete("action_dispatch.request.parameters")
|
40
|
+
@env[PARAMETERS_KEY] ||= {}
|
49
41
|
end
|
50
42
|
|
51
43
|
private
|
52
44
|
|
53
|
-
# Convert nested Hash to HashWithIndifferentAccess
|
54
|
-
# and UTF-8 encode both keys and values in nested Hash.
|
45
|
+
# Convert nested Hash to HashWithIndifferentAccess.
|
55
46
|
#
|
56
|
-
# TODO: Validate that the characters are UTF-8. If they aren't,
|
57
|
-
# you'll get a weird error down the road, but our form handling
|
58
|
-
# should really prevent that from happening
|
59
47
|
def normalize_encode_params(params)
|
60
48
|
case params
|
61
|
-
when String
|
62
|
-
params.force_encoding(Encoding::UTF_8).encode!
|
63
49
|
when Hash
|
64
50
|
if params.has_key?(:tempfile)
|
65
51
|
UploadedFile.new(params)
|
66
52
|
else
|
67
53
|
params.each_with_object({}) do |(key, val), new_hash|
|
68
|
-
|
69
|
-
new_hash[new_key] = if val.is_a?(Array)
|
54
|
+
new_hash[key] = if val.is_a?(Array)
|
70
55
|
val.map! { |el| normalize_encode_params(el) }
|
71
56
|
else
|
72
57
|
normalize_encode_params(val)
|
@@ -23,7 +23,7 @@ module ActionDispatch
|
|
23
23
|
autoload :Session, 'action_dispatch/request/session'
|
24
24
|
autoload :Utils, 'action_dispatch/request/utils'
|
25
25
|
|
26
|
-
LOCALHOST = Regexp.union [/^127
|
26
|
+
LOCALHOST = Regexp.union [/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]
|
27
27
|
|
28
28
|
ENV_METHODS = %w[ AUTH_TYPE GATEWAY_INTERFACE
|
29
29
|
PATH_TRANSLATED REMOTE_HOST
|
@@ -53,6 +53,17 @@ module ActionDispatch
|
|
53
53
|
@uuid = nil
|
54
54
|
end
|
55
55
|
|
56
|
+
def check_path_parameters!
|
57
|
+
# If any of the path parameters has an invalid encoding then
|
58
|
+
# raise since it's likely to trigger errors further on.
|
59
|
+
path_parameters.each do |key, value|
|
60
|
+
next unless value.respond_to?(:valid_encoding?)
|
61
|
+
unless value.valid_encoding?
|
62
|
+
raise ActionController::BadRequest, "Invalid parameter: #{key} => #{value}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
56
67
|
def key?(key)
|
57
68
|
@env.key?(key)
|
58
69
|
end
|
@@ -64,6 +75,7 @@ module ActionDispatch
|
|
64
75
|
# Ordered Collections Protocol (WebDAV) (http://www.ietf.org/rfc/rfc3648.txt)
|
65
76
|
# Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol (http://www.ietf.org/rfc/rfc3744.txt)
|
66
77
|
# Web Distributed Authoring and Versioning (WebDAV) SEARCH (http://www.ietf.org/rfc/rfc5323.txt)
|
78
|
+
# Calendar Extensions to WebDAV (http://www.ietf.org/rfc/rfc4791.txt)
|
67
79
|
# PATCH Method for HTTP (http://www.ietf.org/rfc/rfc5789.txt)
|
68
80
|
RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
|
69
81
|
RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
|
@@ -71,9 +83,10 @@ module ActionDispatch
|
|
71
83
|
RFC3648 = %w(ORDERPATCH)
|
72
84
|
RFC3744 = %w(ACL)
|
73
85
|
RFC5323 = %w(SEARCH)
|
86
|
+
RFC4791 = %w(MKCALENDAR)
|
74
87
|
RFC5789 = %w(PATCH)
|
75
88
|
|
76
|
-
HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789
|
89
|
+
HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC4791 + RFC5789
|
77
90
|
|
78
91
|
HTTP_METHOD_LOOKUP = {}
|
79
92
|
|
@@ -92,6 +105,12 @@ module ActionDispatch
|
|
92
105
|
@request_method ||= check_method(env["REQUEST_METHOD"])
|
93
106
|
end
|
94
107
|
|
108
|
+
def request_method=(request_method) #:nodoc:
|
109
|
+
if check_method(request_method)
|
110
|
+
@request_method = env["REQUEST_METHOD"] = request_method
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
95
114
|
# Returns a symbol form of the #request_method
|
96
115
|
def request_method_symbol
|
97
116
|
HTTP_METHOD_LOOKUP[request_method]
|
@@ -152,6 +171,13 @@ module ActionDispatch
|
|
152
171
|
Http::Headers.new(@env)
|
153
172
|
end
|
154
173
|
|
174
|
+
# Returns a +String+ with the last requested path including their params.
|
175
|
+
#
|
176
|
+
# # get '/foo'
|
177
|
+
# request.original_fullpath # => '/foo'
|
178
|
+
#
|
179
|
+
# # get '/foo?bar'
|
180
|
+
# request.original_fullpath # => '/foo?bar'
|
155
181
|
def original_fullpath
|
156
182
|
@original_fullpath ||= (env["ORIGINAL_FULLPATH"] || fullpath)
|
157
183
|
end
|
@@ -189,8 +215,8 @@ module ActionDispatch
|
|
189
215
|
end
|
190
216
|
|
191
217
|
# Returns true if the "X-Requested-With" header contains "XMLHttpRequest"
|
192
|
-
# (case-insensitive)
|
193
|
-
#
|
218
|
+
# (case-insensitive), which may need to be manually added depending on the
|
219
|
+
# choice of JavaScript libraries and frameworks.
|
194
220
|
def xml_http_request?
|
195
221
|
@env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/i
|
196
222
|
end
|
@@ -205,7 +231,7 @@ module ActionDispatch
|
|
205
231
|
@remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s
|
206
232
|
end
|
207
233
|
|
208
|
-
# Returns the unique request id, which is based
|
234
|
+
# Returns the unique request id, which is based on either the X-Request-Id header that can
|
209
235
|
# be generated by a firewall, load balancer, or web server or by the RequestId middleware
|
210
236
|
# (which sets the action_dispatch.request_id environment variable).
|
211
237
|
#
|
@@ -271,16 +297,16 @@ module ActionDispatch
|
|
271
297
|
|
272
298
|
# Override Rack's GET method to support indifferent access
|
273
299
|
def GET
|
274
|
-
@env["action_dispatch.request.query_parameters"] ||= Utils.deep_munge(
|
275
|
-
rescue
|
300
|
+
@env["action_dispatch.request.query_parameters"] ||= Utils.deep_munge(normalize_encode_params(super || {}))
|
301
|
+
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
|
276
302
|
raise ActionController::BadRequest.new(:query, e)
|
277
303
|
end
|
278
304
|
alias :query_parameters :GET
|
279
305
|
|
280
306
|
# Override Rack's POST method to support indifferent access
|
281
307
|
def POST
|
282
|
-
@env["action_dispatch.request.request_parameters"] ||= Utils.deep_munge(
|
283
|
-
rescue
|
308
|
+
@env["action_dispatch.request.request_parameters"] ||= Utils.deep_munge(normalize_encode_params(super || {}))
|
309
|
+
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
|
284
310
|
raise ActionController::BadRequest.new(:request, e)
|
285
311
|
end
|
286
312
|
alias :request_parameters :POST
|
@@ -302,7 +328,7 @@ module ActionDispatch
|
|
302
328
|
# Extracted into ActionDispatch::Request::Utils.deep_munge, but kept here for backwards compatibility.
|
303
329
|
def deep_munge(hash)
|
304
330
|
ActiveSupport::Deprecation.warn(
|
305
|
-
|
331
|
+
'This method has been extracted into `ActionDispatch::Request::Utils.deep_munge`. Please start using that instead.'
|
306
332
|
)
|
307
333
|
|
308
334
|
Utils.deep_munge(hash)
|
@@ -315,7 +341,7 @@ module ActionDispatch
|
|
315
341
|
|
316
342
|
private
|
317
343
|
def check_method(name)
|
318
|
-
HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS.
|
344
|
+
HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS[0...-1].join(', ')}, and #{HTTP_METHODS[-1]}")
|
319
345
|
name
|
320
346
|
end
|
321
347
|
end
|