actionpack 5.0.7.2 → 5.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +189 -1002
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/abstract_controller.rb +3 -3
- data/lib/abstract_controller/base.rb +10 -12
- data/lib/abstract_controller/caching.rb +6 -3
- data/lib/abstract_controller/caching/fragments.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +2 -43
- data/lib/abstract_controller/collector.rb +2 -2
- data/lib/abstract_controller/helpers.rb +19 -19
- data/lib/abstract_controller/rendering.rb +9 -11
- data/lib/abstract_controller/translation.rb +3 -3
- data/lib/action_controller.rb +15 -13
- data/lib/action_controller/api.rb +3 -3
- data/lib/action_controller/base.rb +7 -12
- data/lib/action_controller/caching.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +2 -2
- data/lib/action_controller/metal.rb +34 -43
- data/lib/action_controller/metal/conditional_get.rb +10 -9
- data/lib/action_controller/metal/data_streaming.rb +8 -9
- data/lib/action_controller/metal/etag_with_flash.rb +16 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +15 -15
- data/lib/action_controller/metal/exceptions.rb +4 -14
- data/lib/action_controller/metal/flash.rb +1 -1
- data/lib/action_controller/metal/force_ssl.rb +6 -6
- data/lib/action_controller/metal/head.rb +13 -19
- data/lib/action_controller/metal/helpers.rb +6 -6
- data/lib/action_controller/metal/http_authentication.rb +22 -23
- data/lib/action_controller/metal/implicit_render.rb +2 -5
- data/lib/action_controller/metal/instrumentation.rb +14 -14
- data/lib/action_controller/metal/live.rb +15 -16
- data/lib/action_controller/metal/mime_responds.rb +3 -3
- data/lib/action_controller/metal/parameter_encoding.rb +49 -0
- data/lib/action_controller/metal/params_wrapper.rb +32 -32
- data/lib/action_controller/metal/redirecting.rb +8 -24
- data/lib/action_controller/metal/renderers.rb +2 -3
- data/lib/action_controller/metal/rendering.rb +50 -60
- data/lib/action_controller/metal/request_forgery_protection.rb +51 -49
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/streaming.rb +4 -4
- data/lib/action_controller/metal/strong_parameters.rb +117 -250
- data/lib/action_controller/metal/testing.rb +1 -1
- data/lib/action_controller/metal/url_for.rb +4 -4
- data/lib/action_controller/railtie.rb +9 -13
- data/lib/action_controller/renderer.rb +17 -16
- data/lib/action_controller/test_case.rb +75 -148
- data/lib/action_dispatch.rb +20 -19
- data/lib/action_dispatch/http/cache.rb +9 -10
- data/lib/action_dispatch/http/filter_parameters.rb +8 -8
- data/lib/action_dispatch/http/filter_redirect.rb +2 -4
- data/lib/action_dispatch/http/headers.rb +10 -10
- data/lib/action_dispatch/http/mime_negotiation.rb +17 -22
- data/lib/action_dispatch/http/mime_type.rb +27 -52
- data/lib/action_dispatch/http/parameter_filter.rb +8 -6
- data/lib/action_dispatch/http/parameters.rb +40 -17
- data/lib/action_dispatch/http/request.rb +38 -34
- data/lib/action_dispatch/http/response.rb +16 -16
- data/lib/action_dispatch/http/upload.rb +6 -10
- data/lib/action_dispatch/http/url.rb +48 -74
- data/lib/action_dispatch/journey.rb +5 -5
- data/lib/action_dispatch/journey/formatter.rb +8 -4
- data/lib/action_dispatch/journey/gtg/builder.rb +5 -5
- data/lib/action_dispatch/journey/gtg/simulator.rb +1 -1
- data/lib/action_dispatch/journey/gtg/transition_table.rb +15 -15
- data/lib/action_dispatch/journey/nfa/builder.rb +3 -3
- 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 +2 -2
- data/lib/action_dispatch/journey/nodes/node.rb +5 -5
- data/lib/action_dispatch/journey/parser.rb +23 -24
- data/lib/action_dispatch/journey/parser.y +3 -2
- data/lib/action_dispatch/journey/parser_extras.rb +2 -2
- data/lib/action_dispatch/journey/path/pattern.rb +10 -3
- data/lib/action_dispatch/journey/route.rb +19 -12
- data/lib/action_dispatch/journey/router.rb +19 -12
- data/lib/action_dispatch/journey/router/utils.rb +9 -9
- data/lib/action_dispatch/journey/scanner.rb +17 -15
- data/lib/action_dispatch/journey/visitors.rb +23 -23
- data/lib/action_dispatch/middleware/callbacks.rb +0 -12
- data/lib/action_dispatch/middleware/cookies.rb +39 -39
- data/lib/action_dispatch/middleware/debug_exceptions.rb +126 -112
- data/lib/action_dispatch/middleware/debug_locks.rb +8 -8
- data/lib/action_dispatch/middleware/exception_wrapper.rb +55 -55
- data/lib/action_dispatch/middleware/executor.rb +1 -1
- data/lib/action_dispatch/middleware/flash.rb +17 -16
- data/lib/action_dispatch/middleware/public_exceptions.rb +20 -20
- data/lib/action_dispatch/middleware/reloader.rb +3 -47
- data/lib/action_dispatch/middleware/remote_ip.rb +6 -8
- data/lib/action_dispatch/middleware/request_id.rb +6 -5
- data/lib/action_dispatch/middleware/session/abstract_store.rb +14 -26
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +35 -35
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +2 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +19 -19
- data/lib/action_dispatch/middleware/ssl.rb +9 -27
- data/lib/action_dispatch/middleware/stack.rb +7 -26
- data/lib/action_dispatch/middleware/static.rb +13 -24
- data/lib/action_dispatch/railtie.rb +9 -11
- data/lib/action_dispatch/request/session.rb +22 -22
- data/lib/action_dispatch/request/utils.rb +11 -2
- data/lib/action_dispatch/routing.rb +8 -6
- data/lib/action_dispatch/routing/inspector.rb +37 -37
- data/lib/action_dispatch/routing/mapper.rb +296 -203
- data/lib/action_dispatch/routing/polymorphic_routes.rb +160 -134
- data/lib/action_dispatch/routing/redirection.rb +27 -22
- data/lib/action_dispatch/routing/route_set.rb +206 -92
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -2
- data/lib/action_dispatch/routing/url_for.rb +14 -12
- data/lib/action_dispatch/system_test_case.rb +119 -0
- data/lib/action_dispatch/system_testing/browser.rb +28 -0
- data/lib/action_dispatch/system_testing/driver.rb +18 -0
- data/lib/action_dispatch/system_testing/server.rb +32 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +61 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +20 -0
- data/lib/action_dispatch/testing/assertion_response.rb +6 -6
- data/lib/action_dispatch/testing/assertions.rb +4 -4
- data/lib/action_dispatch/testing/assertions/response.rb +8 -3
- data/lib/action_dispatch/testing/assertions/routing.rb +11 -11
- data/lib/action_dispatch/testing/integration.rb +47 -138
- data/lib/action_dispatch/testing/test_process.rb +2 -2
- data/lib/action_dispatch/testing/test_request.rb +16 -16
- data/lib/action_dispatch/testing/test_response.rb +1 -1
- data/lib/action_pack.rb +2 -2
- data/lib/action_pack/gem_version.rb +3 -3
- data/lib/action_pack/version.rb +1 -1
- metadata +20 -12
- data/lib/action_dispatch/middleware/params_parser.rb +0 -46
@@ -1,7 +1,9 @@
|
|
1
|
+
require "active_support/core_ext/object/duplicable"
|
2
|
+
|
1
3
|
module ActionDispatch
|
2
4
|
module Http
|
3
5
|
class ParameterFilter
|
4
|
-
FILTERED =
|
6
|
+
FILTERED = "[FILTERED]".freeze # :nodoc:
|
5
7
|
|
6
8
|
def initialize(filters = [])
|
7
9
|
@filters = filters
|
@@ -37,8 +39,8 @@ module ActionDispatch
|
|
37
39
|
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.".freeze) }
|
38
40
|
deep_strings, strings = strings.partition { |s| s.include?("\\.".freeze) }
|
39
41
|
|
40
|
-
regexps << Regexp.new(strings.join(
|
41
|
-
deep_regexps << Regexp.new(deep_strings.join(
|
42
|
+
regexps << Regexp.new(strings.join("|".freeze), true) unless strings.empty?
|
43
|
+
deep_regexps << Regexp.new(deep_strings.join("|".freeze), true) unless deep_strings.empty?
|
42
44
|
|
43
45
|
new regexps, deep_regexps, blocks
|
44
46
|
end
|
@@ -48,17 +50,17 @@ module ActionDispatch
|
|
48
50
|
def initialize(regexps, deep_regexps, blocks)
|
49
51
|
@regexps = regexps
|
50
52
|
@deep_regexps = deep_regexps.any? ? deep_regexps : nil
|
51
|
-
@blocks
|
53
|
+
@blocks = blocks
|
52
54
|
end
|
53
55
|
|
54
56
|
def call(original_params, parents = [])
|
55
|
-
filtered_params =
|
57
|
+
filtered_params = {}
|
56
58
|
|
57
59
|
original_params.each do |key, value|
|
58
60
|
parents.push(key) if deep_regexps
|
59
61
|
if regexps.any? { |r| key =~ r }
|
60
62
|
value = FILTERED
|
61
|
-
elsif deep_regexps && (joined = parents.join(
|
63
|
+
elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| joined =~ r }
|
62
64
|
value = FILTERED
|
63
65
|
elsif value.is_a?(Hash)
|
64
66
|
value = call(value, parents)
|
@@ -3,15 +3,23 @@ module ActionDispatch
|
|
3
3
|
module Parameters
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
PARAMETERS_KEY =
|
6
|
+
PARAMETERS_KEY = "action_dispatch.request.path_parameters"
|
7
7
|
|
8
8
|
DEFAULT_PARSERS = {
|
9
9
|
Mime[:json].symbol => -> (raw_post) {
|
10
10
|
data = ActiveSupport::JSON.decode(raw_post)
|
11
|
-
data.is_a?(Hash) ? data : {:
|
11
|
+
data.is_a?(Hash) ? data : { _json: data }
|
12
12
|
}
|
13
13
|
}
|
14
14
|
|
15
|
+
# Raised when raw data from the request cannot be parsed by the parser
|
16
|
+
# defined for request's content mime type.
|
17
|
+
class ParseError < StandardError
|
18
|
+
def initialize
|
19
|
+
super($!.message)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
15
23
|
included do
|
16
24
|
class << self
|
17
25
|
# Returns the parameter parsers.
|
@@ -22,7 +30,7 @@ module ActionDispatch
|
|
22
30
|
end
|
23
31
|
|
24
32
|
module ClassMethods
|
25
|
-
# Configure the parameter parser for a
|
33
|
+
# Configure the parameter parser for a given mime type.
|
26
34
|
#
|
27
35
|
# It accepts a hash where the key is the symbol of the mime type
|
28
36
|
# and the value is a proc.
|
@@ -47,13 +55,14 @@ module ActionDispatch
|
|
47
55
|
query_parameters.dup
|
48
56
|
end
|
49
57
|
params.merge!(path_parameters)
|
58
|
+
params = set_binary_encoding(params)
|
50
59
|
set_header("action_dispatch.request.parameters", params)
|
51
60
|
params
|
52
61
|
end
|
53
62
|
alias :params :parameters
|
54
63
|
|
55
64
|
def path_parameters=(parameters) #:nodoc:
|
56
|
-
delete_header(
|
65
|
+
delete_header("action_dispatch.request.parameters")
|
57
66
|
|
58
67
|
# If any of the path parameters has an invalid encoding then
|
59
68
|
# raise since it's likely to trigger errors further on.
|
@@ -74,24 +83,38 @@ module ActionDispatch
|
|
74
83
|
|
75
84
|
private
|
76
85
|
|
77
|
-
|
78
|
-
|
86
|
+
def set_binary_encoding(params)
|
87
|
+
action = params[:action]
|
88
|
+
if controller_class.binary_params_for?(action)
|
89
|
+
ActionDispatch::Request::Utils.each_param_value(params) do |param|
|
90
|
+
param.force_encoding ::Encoding::ASCII_8BIT
|
91
|
+
end
|
92
|
+
end
|
93
|
+
params
|
94
|
+
end
|
95
|
+
|
96
|
+
def parse_formatted_parameters(parsers)
|
97
|
+
return yield if content_length.zero? || content_mime_type.nil?
|
79
98
|
|
80
|
-
|
99
|
+
strategy = parsers.fetch(content_mime_type.symbol) { return yield }
|
81
100
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
101
|
+
begin
|
102
|
+
strategy.call(raw_post)
|
103
|
+
rescue # JSON or Ruby code block errors
|
104
|
+
my_logger = logger || ActiveSupport::Logger.new($stderr)
|
105
|
+
my_logger.debug "Error occurred while parsing request parameters.\nContents:\n\n#{raw_post}"
|
87
106
|
|
88
|
-
|
107
|
+
raise ParseError
|
108
|
+
end
|
89
109
|
end
|
90
|
-
end
|
91
110
|
|
92
|
-
|
93
|
-
|
94
|
-
|
111
|
+
def params_parsers
|
112
|
+
ActionDispatch::Request.parameter_parsers
|
113
|
+
end
|
95
114
|
end
|
96
115
|
end
|
116
|
+
|
117
|
+
module ParamsParser
|
118
|
+
ParseError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new("ActionDispatch::ParamsParser::ParseError", "ActionDispatch::Http::Parameters::ParseError")
|
119
|
+
end
|
97
120
|
end
|
@@ -1,16 +1,16 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
1
|
+
require "stringio"
|
2
|
+
|
3
|
+
require "active_support/inflector"
|
4
|
+
require "action_dispatch/http/headers"
|
5
|
+
require "action_controller/metal/exceptions"
|
6
|
+
require "rack/request"
|
7
|
+
require "action_dispatch/http/cache"
|
8
|
+
require "action_dispatch/http/mime_negotiation"
|
9
|
+
require "action_dispatch/http/parameters"
|
10
|
+
require "action_dispatch/http/filter_parameters"
|
11
|
+
require "action_dispatch/http/upload"
|
12
|
+
require "action_dispatch/http/url"
|
13
|
+
require "active_support/core_ext/array/conversions"
|
14
14
|
|
15
15
|
module ActionDispatch
|
16
16
|
class Request
|
@@ -22,8 +22,8 @@ module ActionDispatch
|
|
22
22
|
include ActionDispatch::Http::URL
|
23
23
|
include Rack::Request::Env
|
24
24
|
|
25
|
-
autoload :Session,
|
26
|
-
autoload :Utils,
|
25
|
+
autoload :Session, "action_dispatch/request/session"
|
26
|
+
autoload :Utils, "action_dispatch/request/utils"
|
27
27
|
|
28
28
|
LOCALHOST = Regexp.union [/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]
|
29
29
|
|
@@ -68,7 +68,8 @@ module ActionDispatch
|
|
68
68
|
|
69
69
|
PASS_NOT_FOUND = Class.new { # :nodoc:
|
70
70
|
def self.action(_); self; end
|
71
|
-
def self.call(_); [404, {
|
71
|
+
def self.call(_); [404, { "X-Cascade" => "pass" }, []]; end
|
72
|
+
def self.binary_params_for?(action); false; end
|
72
73
|
}
|
73
74
|
|
74
75
|
def controller_class
|
@@ -76,7 +77,7 @@ module ActionDispatch
|
|
76
77
|
|
77
78
|
if params.key?(:controller)
|
78
79
|
controller_param = params[:controller].underscore
|
79
|
-
params[:action] ||=
|
80
|
+
params[:action] ||= "index"
|
80
81
|
const_name = "#{controller_param.camelize}Controller"
|
81
82
|
ActiveSupport::Dependencies.constantize(const_name)
|
82
83
|
else
|
@@ -84,6 +85,9 @@ module ActionDispatch
|
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
88
|
+
# Returns true if the request has a header matching the given key parameter.
|
89
|
+
#
|
90
|
+
# request.key? :ip_spoofing_check # => true
|
87
91
|
def key?(key)
|
88
92
|
has_header? key
|
89
93
|
end
|
@@ -148,11 +152,11 @@ module ActionDispatch
|
|
148
152
|
end
|
149
153
|
|
150
154
|
def controller_instance # :nodoc:
|
151
|
-
get_header(
|
155
|
+
get_header("action_controller.instance".freeze)
|
152
156
|
end
|
153
157
|
|
154
158
|
def controller_instance=(controller) # :nodoc:
|
155
|
-
set_header(
|
159
|
+
set_header("action_controller.instance".freeze, controller)
|
156
160
|
end
|
157
161
|
|
158
162
|
def http_auth_salt
|
@@ -163,7 +167,7 @@ module ActionDispatch
|
|
163
167
|
# We're treating `nil` as "unset", and we want the default setting to be
|
164
168
|
# `true`. This logic should be extracted to `env_config` and calculated
|
165
169
|
# once.
|
166
|
-
!(get_header(
|
170
|
+
!(get_header("action_dispatch.show_exceptions".freeze) == false)
|
167
171
|
end
|
168
172
|
|
169
173
|
# Returns a symbol form of the #request_method
|
@@ -175,7 +179,7 @@ module ActionDispatch
|
|
175
179
|
# even if it was overridden by middleware. See #request_method for
|
176
180
|
# more information.
|
177
181
|
def method
|
178
|
-
@method ||= check_method(get_header("rack.methodoverride.original_method") || get_header(
|
182
|
+
@method ||= check_method(get_header("rack.methodoverride.original_method") || get_header("REQUEST_METHOD"))
|
179
183
|
end
|
180
184
|
|
181
185
|
# Returns a symbol form of the #method
|
@@ -237,7 +241,7 @@ module ActionDispatch
|
|
237
241
|
# (case-insensitive), which may need to be manually added depending on the
|
238
242
|
# choice of JavaScript libraries and frameworks.
|
239
243
|
def xml_http_request?
|
240
|
-
get_header(
|
244
|
+
get_header("HTTP_X_REQUESTED_WITH") =~ /XMLHttpRequest/i
|
241
245
|
end
|
242
246
|
alias :xhr? :xml_http_request?
|
243
247
|
|
@@ -276,24 +280,24 @@ module ActionDispatch
|
|
276
280
|
|
277
281
|
# Returns the lowercase name of the HTTP server software.
|
278
282
|
def server_software
|
279
|
-
(get_header(
|
283
|
+
(get_header("SERVER_SOFTWARE") && /^([a-zA-Z]+)/ =~ get_header("SERVER_SOFTWARE")) ? $1.downcase : nil
|
280
284
|
end
|
281
285
|
|
282
286
|
# Read the request \body. This is useful for web services that need to
|
283
287
|
# work with raw requests directly.
|
284
288
|
def raw_post
|
285
|
-
unless has_header?
|
289
|
+
unless has_header? "RAW_POST_DATA"
|
286
290
|
raw_post_body = body
|
287
|
-
set_header(
|
291
|
+
set_header("RAW_POST_DATA", raw_post_body.read(content_length))
|
288
292
|
raw_post_body.rewind if raw_post_body.respond_to?(:rewind)
|
289
293
|
end
|
290
|
-
get_header
|
294
|
+
get_header "RAW_POST_DATA"
|
291
295
|
end
|
292
296
|
|
293
297
|
# The request body is an IO input stream. If the RAW_POST_DATA environment
|
294
298
|
# variable is already set, wrap it in a StringIO.
|
295
299
|
def body
|
296
|
-
if raw_post = get_header(
|
300
|
+
if raw_post = get_header("RAW_POST_DATA")
|
297
301
|
raw_post.force_encoding(Encoding::BINARY)
|
298
302
|
StringIO.new(raw_post)
|
299
303
|
else
|
@@ -314,7 +318,7 @@ module ActionDispatch
|
|
314
318
|
end
|
315
319
|
|
316
320
|
def body_stream #:nodoc:
|
317
|
-
get_header(
|
321
|
+
get_header("rack.input")
|
318
322
|
end
|
319
323
|
|
320
324
|
# TODO This should be broken apart into AD::Request::Session and probably
|
@@ -356,7 +360,7 @@ module ActionDispatch
|
|
356
360
|
end
|
357
361
|
self.request_parameters = Request::Utils.normalize_encode_params(pr)
|
358
362
|
end
|
359
|
-
rescue
|
363
|
+
rescue Http::Parameters::ParseError # one of the parse strategies blew up
|
360
364
|
self.request_parameters = Request::Utils.normalize_encode_params(super || {})
|
361
365
|
raise
|
362
366
|
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
|
@@ -367,10 +371,10 @@ module ActionDispatch
|
|
367
371
|
# Returns the authorization header regardless of whether it was specified directly or through one of the
|
368
372
|
# proxy alternatives.
|
369
373
|
def authorization
|
370
|
-
get_header(
|
371
|
-
get_header(
|
372
|
-
get_header(
|
373
|
-
get_header(
|
374
|
+
get_header("HTTP_AUTHORIZATION") ||
|
375
|
+
get_header("X-HTTP_AUTHORIZATION") ||
|
376
|
+
get_header("X_HTTP_AUTHORIZATION") ||
|
377
|
+
get_header("REDIRECT_X_HTTP_AUTHORIZATION")
|
374
378
|
end
|
375
379
|
|
376
380
|
# True if the request came from localhost, 127.0.0.1, or ::1.
|
@@ -391,7 +395,7 @@ module ActionDispatch
|
|
391
395
|
end
|
392
396
|
|
393
397
|
def ssl?
|
394
|
-
super || scheme ==
|
398
|
+
super || scheme == "wss".freeze
|
395
399
|
end
|
396
400
|
|
397
401
|
private
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "active_support/core_ext/module/attribute_accessors"
|
2
|
+
require "action_dispatch/http/filter_redirect"
|
3
|
+
require "action_dispatch/http/cache"
|
4
|
+
require "monitor"
|
5
5
|
|
6
6
|
module ActionDispatch # :nodoc:
|
7
7
|
# Represents an HTTP response generated by a controller action. Use it to
|
@@ -39,9 +39,9 @@ module ActionDispatch # :nodoc:
|
|
39
39
|
super(header)
|
40
40
|
end
|
41
41
|
|
42
|
-
def []=(k,v)
|
42
|
+
def []=(k, v)
|
43
43
|
if @response.sending? || @response.sent?
|
44
|
-
raise ActionDispatch::IllegalStateError,
|
44
|
+
raise ActionDispatch::IllegalStateError, "header already sent"
|
45
45
|
end
|
46
46
|
|
47
47
|
super
|
@@ -67,7 +67,7 @@ module ActionDispatch # :nodoc:
|
|
67
67
|
|
68
68
|
alias_method :headers, :header
|
69
69
|
|
70
|
-
delegate :[], :[]=, :
|
70
|
+
delegate :[], :[]=, to: :@header
|
71
71
|
|
72
72
|
def each(&block)
|
73
73
|
sending!
|
@@ -103,8 +103,8 @@ module ActionDispatch # :nodoc:
|
|
103
103
|
|
104
104
|
def body
|
105
105
|
@str_body ||= begin
|
106
|
-
buf =
|
107
|
-
|
106
|
+
buf = ""
|
107
|
+
each { |chunk| buf << chunk }
|
108
108
|
buf
|
109
109
|
end
|
110
110
|
end
|
@@ -251,7 +251,7 @@ module ActionDispatch # :nodoc:
|
|
251
251
|
end
|
252
252
|
end
|
253
253
|
|
254
|
-
# Sets the HTTP character set. In case of nil parameter
|
254
|
+
# Sets the HTTP character set. In case of +nil+ parameter
|
255
255
|
# it sets the charset to utf-8.
|
256
256
|
#
|
257
257
|
# response.charset = 'utf-16' # => 'utf-16'
|
@@ -333,7 +333,7 @@ module ActionDispatch # :nodoc:
|
|
333
333
|
|
334
334
|
# Stream the file's contents if Rack::Sendfile isn't present.
|
335
335
|
def each
|
336
|
-
File.open(to_path,
|
336
|
+
File.open(to_path, "rb") do |file|
|
337
337
|
while chunk = file.read(16384)
|
338
338
|
yield chunk
|
339
339
|
end
|
@@ -393,7 +393,7 @@ module ActionDispatch # :nodoc:
|
|
393
393
|
if header = get_header(SET_COOKIE)
|
394
394
|
header = header.split("\n") if header.respond_to?(:to_str)
|
395
395
|
header.each do |cookie|
|
396
|
-
if pair = cookie.split(
|
396
|
+
if pair = cookie.split(";").first
|
397
397
|
key, value = pair.split("=").map { |v| Rack::Utils.unescape(v) }
|
398
398
|
cookies[key] = value
|
399
399
|
end
|
@@ -424,8 +424,8 @@ module ActionDispatch # :nodoc:
|
|
424
424
|
end
|
425
425
|
|
426
426
|
def set_content_type(content_type, charset)
|
427
|
-
type = (content_type ||
|
428
|
-
type << "; charset=#{charset}" if charset
|
427
|
+
type = (content_type || "").dup
|
428
|
+
type << "; charset=#{charset.to_s.downcase}" if charset
|
429
429
|
set_header CONTENT_TYPE, type
|
430
430
|
end
|
431
431
|
|
@@ -484,7 +484,7 @@ module ActionDispatch # :nodoc:
|
|
484
484
|
end
|
485
485
|
|
486
486
|
def respond_to?(method, include_private = false)
|
487
|
-
if method.to_s ==
|
487
|
+
if method.to_s == "to_path"
|
488
488
|
@response.stream.respond_to?(method)
|
489
489
|
else
|
490
490
|
super
|
@@ -503,7 +503,7 @@ module ActionDispatch # :nodoc:
|
|
503
503
|
def handle_no_content!
|
504
504
|
if NO_CONTENT_CODES.include?(@status)
|
505
505
|
@header.delete CONTENT_TYPE
|
506
|
-
@header.delete
|
506
|
+
@header.delete "Content-Length"
|
507
507
|
end
|
508
508
|
end
|
509
509
|
|
@@ -24,27 +24,23 @@ module ActionDispatch
|
|
24
24
|
attr_accessor :headers
|
25
25
|
|
26
26
|
def initialize(hash) # :nodoc:
|
27
|
-
@tempfile
|
28
|
-
raise(ArgumentError,
|
29
|
-
|
30
|
-
if hash[:filename]
|
31
|
-
@original_filename = hash[:filename].dup
|
27
|
+
@tempfile = hash[:tempfile]
|
28
|
+
raise(ArgumentError, ":tempfile is required") unless @tempfile
|
32
29
|
|
30
|
+
@original_filename = hash[:filename]
|
31
|
+
if @original_filename
|
33
32
|
begin
|
34
33
|
@original_filename.encode!(Encoding::UTF_8)
|
35
34
|
rescue EncodingError
|
36
35
|
@original_filename.force_encoding(Encoding::UTF_8)
|
37
36
|
end
|
38
|
-
else
|
39
|
-
@original_filename = nil
|
40
37
|
end
|
41
|
-
|
42
38
|
@content_type = hash[:type]
|
43
39
|
@headers = hash[:head]
|
44
40
|
end
|
45
41
|
|
46
42
|
# Shortcut for +tempfile.read+.
|
47
|
-
def read(length=nil, buffer=nil)
|
43
|
+
def read(length = nil, buffer = nil)
|
48
44
|
@tempfile.read(length, buffer)
|
49
45
|
end
|
50
46
|
|
@@ -54,7 +50,7 @@ module ActionDispatch
|
|
54
50
|
end
|
55
51
|
|
56
52
|
# Shortcut for +tempfile.close+.
|
57
|
-
def close(unlink_now=false)
|
53
|
+
def close(unlink_now = false)
|
58
54
|
@tempfile.close(unlink_now)
|
59
55
|
end
|
60
56
|
|