actionpack 3.2.19 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +850 -401
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -288
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +39 -37
- data/lib/abstract_controller/callbacks.rb +101 -82
- data/lib/abstract_controller/collector.rb +7 -3
- data/lib/abstract_controller/helpers.rb +25 -13
- data/lib/abstract_controller/layouts.rb +74 -74
- data/lib/abstract_controller/logger.rb +1 -2
- data/lib/abstract_controller/rendering.rb +30 -13
- data/lib/abstract_controller/translation.rb +16 -1
- data/lib/abstract_controller/url_for.rb +6 -6
- data/lib/abstract_controller/view_paths.rb +1 -1
- data/lib/abstract_controller.rb +1 -8
- data/lib/action_controller/base.rb +46 -22
- data/lib/action_controller/caching/fragments.rb +23 -53
- data/lib/action_controller/caching.rb +46 -33
- data/lib/action_controller/deprecated/integration_test.rb +3 -0
- data/lib/action_controller/deprecated.rb +5 -1
- data/lib/action_controller/log_subscriber.rb +16 -8
- data/lib/action_controller/metal/conditional_get.rb +76 -32
- data/lib/action_controller/metal/data_streaming.rb +20 -26
- data/lib/action_controller/metal/exceptions.rb +19 -6
- data/lib/action_controller/metal/flash.rb +24 -9
- data/lib/action_controller/metal/force_ssl.rb +70 -12
- data/lib/action_controller/metal/head.rb +25 -4
- data/lib/action_controller/metal/helpers.rb +5 -9
- data/lib/action_controller/metal/hide_actions.rb +0 -1
- data/lib/action_controller/metal/http_authentication.rb +107 -83
- data/lib/action_controller/metal/implicit_render.rb +1 -1
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/live.rb +175 -0
- data/lib/action_controller/metal/mime_responds.rb +161 -47
- data/lib/action_controller/metal/params_wrapper.rb +112 -74
- data/lib/action_controller/metal/rack_delegation.rb +9 -3
- data/lib/action_controller/metal/redirecting.rb +15 -20
- data/lib/action_controller/metal/renderers.rb +11 -9
- data/lib/action_controller/metal/rendering.rb +9 -1
- data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
- data/lib/action_controller/metal/responder.rb +20 -19
- data/lib/action_controller/metal/streaming.rb +12 -18
- data/lib/action_controller/metal/strong_parameters.rb +520 -0
- data/lib/action_controller/metal/testing.rb +13 -18
- data/lib/action_controller/metal/url_for.rb +28 -25
- data/lib/action_controller/metal.rb +17 -32
- data/lib/action_controller/model_naming.rb +12 -0
- data/lib/action_controller/railtie.rb +33 -17
- data/lib/action_controller/railties/helpers.rb +22 -0
- data/lib/action_controller/record_identifier.rb +18 -72
- data/lib/action_controller/test_case.rb +251 -131
- data/lib/action_controller/vendor/html-scanner.rb +4 -19
- data/lib/action_controller.rb +15 -6
- data/lib/action_dispatch/http/cache.rb +63 -11
- data/lib/action_dispatch/http/filter_parameters.rb +18 -8
- data/lib/action_dispatch/http/filter_redirect.rb +37 -0
- data/lib/action_dispatch/http/headers.rb +49 -17
- data/lib/action_dispatch/http/mime_negotiation.rb +24 -1
- data/lib/action_dispatch/http/mime_type.rb +154 -100
- data/lib/action_dispatch/http/mime_types.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +44 -46
- data/lib/action_dispatch/http/parameters.rb +28 -28
- data/lib/action_dispatch/http/rack_cache.rb +2 -3
- data/lib/action_dispatch/http/request.rb +64 -18
- data/lib/action_dispatch/http/response.rb +130 -35
- data/lib/action_dispatch/http/upload.rb +63 -20
- data/lib/action_dispatch/http/url.rb +98 -35
- data/lib/action_dispatch/journey/backwards.rb +5 -0
- data/lib/action_dispatch/journey/formatter.rb +146 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
- data/lib/action_dispatch/journey/nodes/node.rb +124 -0
- data/lib/action_dispatch/journey/parser.rb +206 -0
- data/lib/action_dispatch/journey/parser.y +47 -0
- data/lib/action_dispatch/journey/parser_extras.rb +23 -0
- data/lib/action_dispatch/journey/path/pattern.rb +196 -0
- data/lib/action_dispatch/journey/route.rb +124 -0
- data/lib/action_dispatch/journey/router/strexp.rb +24 -0
- data/lib/action_dispatch/journey/router/utils.rb +54 -0
- data/lib/action_dispatch/journey/router.rb +166 -0
- data/lib/action_dispatch/journey/routes.rb +75 -0
- data/lib/action_dispatch/journey/scanner.rb +61 -0
- data/lib/action_dispatch/journey/visitors.rb +197 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/journey.rb +5 -0
- data/lib/action_dispatch/middleware/callbacks.rb +9 -4
- data/lib/action_dispatch/middleware/cookies.rb +259 -114
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
- data/lib/action_dispatch/middleware/exception_wrapper.rb +29 -3
- data/lib/action_dispatch/middleware/flash.rb +58 -58
- data/lib/action_dispatch/middleware/params_parser.rb +14 -29
- data/lib/action_dispatch/middleware/public_exceptions.rb +30 -14
- data/lib/action_dispatch/middleware/reloader.rb +6 -6
- data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
- data/lib/action_dispatch/middleware/request_id.rb +2 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
- data/lib/action_dispatch/middleware/session/cookie_store.rb +82 -28
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
- data/lib/action_dispatch/middleware/ssl.rb +70 -0
- data/lib/action_dispatch/middleware/stack.rb +6 -1
- data/lib/action_dispatch/middleware/static.rb +2 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +7 -9
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +127 -5
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
- data/lib/action_dispatch/railtie.rb +16 -6
- data/lib/action_dispatch/request/session.rb +181 -0
- data/lib/action_dispatch/routing/inspector.rb +240 -0
- data/lib/action_dispatch/routing/mapper.rb +540 -291
- data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
- data/lib/action_dispatch/routing/redirection.rb +46 -29
- data/lib/action_dispatch/routing/route_set.rb +207 -164
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
- data/lib/action_dispatch/routing/url_for.rb +48 -33
- data/lib/action_dispatch/routing.rb +48 -83
- data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
- data/lib/action_dispatch/testing/assertions/response.rb +32 -40
- data/lib/action_dispatch/testing/assertions/routing.rb +42 -41
- data/lib/action_dispatch/testing/assertions/selector.rb +17 -22
- data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
- data/lib/action_dispatch/testing/integration.rb +65 -51
- data/lib/action_dispatch/testing/test_process.rb +9 -6
- data/lib/action_dispatch/testing/test_request.rb +7 -3
- data/lib/action_dispatch.rb +21 -15
- data/lib/action_pack/version.rb +7 -6
- data/lib/action_pack.rb +1 -1
- data/lib/action_view/base.rb +15 -34
- data/lib/action_view/buffers.rb +7 -1
- data/lib/action_view/context.rb +4 -4
- data/lib/action_view/dependency_tracker.rb +93 -0
- data/lib/action_view/digestor.rb +85 -0
- data/lib/action_view/flows.rb +1 -4
- data/lib/action_view/helpers/active_model_helper.rb +3 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +215 -352
- data/lib/action_view/helpers/asset_url_helper.rb +355 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
- data/lib/action_view/helpers/cache_helper.rb +150 -18
- data/lib/action_view/helpers/capture_helper.rb +44 -31
- data/lib/action_view/helpers/csrf_helper.rb +0 -2
- data/lib/action_view/helpers/date_helper.rb +269 -248
- data/lib/action_view/helpers/debug_helper.rb +10 -11
- data/lib/action_view/helpers/form_helper.rb +931 -537
- data/lib/action_view/helpers/form_options_helper.rb +341 -166
- data/lib/action_view/helpers/form_tag_helper.rb +190 -90
- data/lib/action_view/helpers/javascript_helper.rb +23 -16
- data/lib/action_view/helpers/number_helper.rb +148 -329
- data/lib/action_view/helpers/output_safety_helper.rb +3 -3
- data/lib/action_view/helpers/record_tag_helper.rb +17 -22
- data/lib/action_view/helpers/rendering_helper.rb +2 -2
- data/lib/action_view/helpers/sanitize_helper.rb +3 -6
- data/lib/action_view/helpers/tag_helper.rb +46 -33
- data/lib/action_view/helpers/tags/base.rb +147 -0
- data/lib/action_view/helpers/tags/check_box.rb +64 -0
- data/lib/action_view/helpers/tags/checkable.rb +16 -0
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
- data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
- data/lib/action_view/helpers/tags/collection_select.rb +28 -0
- data/lib/action_view/helpers/tags/color_field.rb +25 -0
- data/lib/action_view/helpers/tags/date_field.rb +13 -0
- data/lib/action_view/helpers/tags/date_select.rb +72 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
- data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
- data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
- data/lib/action_view/helpers/tags/email_field.rb +8 -0
- data/lib/action_view/helpers/tags/file_field.rb +8 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
- data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
- data/lib/action_view/helpers/tags/label.rb +65 -0
- data/lib/action_view/helpers/tags/month_field.rb +13 -0
- data/lib/action_view/helpers/tags/number_field.rb +18 -0
- data/lib/action_view/helpers/tags/password_field.rb +12 -0
- data/lib/action_view/helpers/tags/radio_button.rb +31 -0
- data/lib/action_view/helpers/tags/range_field.rb +8 -0
- data/lib/action_view/helpers/tags/search_field.rb +24 -0
- data/lib/action_view/helpers/tags/select.rb +40 -0
- data/lib/action_view/helpers/tags/tel_field.rb +8 -0
- data/lib/action_view/helpers/tags/text_area.rb +18 -0
- data/lib/action_view/helpers/tags/text_field.rb +29 -0
- data/lib/action_view/helpers/tags/time_field.rb +13 -0
- data/lib/action_view/helpers/tags/time_select.rb +8 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
- data/lib/action_view/helpers/tags/url_field.rb +8 -0
- data/lib/action_view/helpers/tags/week_field.rb +13 -0
- data/lib/action_view/helpers/tags.rb +39 -0
- data/lib/action_view/helpers/text_helper.rb +130 -114
- data/lib/action_view/helpers/translation_helper.rb +32 -16
- data/lib/action_view/helpers/url_helper.rb +211 -270
- data/lib/action_view/helpers.rb +2 -4
- data/lib/action_view/locale/en.yml +1 -105
- data/lib/action_view/log_subscriber.rb +6 -4
- data/lib/action_view/lookup_context.rb +15 -28
- data/lib/action_view/model_naming.rb +12 -0
- data/lib/action_view/path_set.rb +8 -20
- data/lib/action_view/railtie.rb +6 -22
- data/lib/action_view/record_identifier.rb +84 -0
- data/lib/action_view/renderer/abstract_renderer.rb +25 -19
- data/lib/action_view/renderer/partial_renderer.rb +158 -81
- data/lib/action_view/renderer/renderer.rb +8 -12
- data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
- data/lib/action_view/renderer/template_renderer.rb +12 -10
- data/lib/action_view/routing_url_for.rb +107 -0
- data/lib/action_view/template/error.rb +22 -12
- data/lib/action_view/template/handlers/builder.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +40 -19
- data/lib/action_view/template/handlers/raw.rb +11 -0
- data/lib/action_view/template/handlers.rb +12 -9
- data/lib/action_view/template/resolver.rb +107 -53
- data/lib/action_view/template/text.rb +12 -8
- data/lib/action_view/template/types.rb +57 -0
- data/lib/action_view/template.rb +25 -23
- data/lib/action_view/test_case.rb +67 -42
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +13 -2
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +9 -9
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
- data/lib/action_view/vendor/html-scanner.rb +20 -0
- data/lib/action_view.rb +17 -8
- metadata +184 -214
- data/lib/action_controller/caching/actions.rb +0 -185
- data/lib/action_controller/caching/pages.rb +0 -187
- data/lib/action_controller/caching/sweeping.rb +0 -97
- data/lib/action_controller/deprecated/performance_test.rb +0 -1
- data/lib/action_controller/metal/compatibility.rb +0 -65
- data/lib/action_controller/metal/session_management.rb +0 -14
- data/lib/action_controller/railties/paths.rb +0 -25
- data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
- data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
- data/lib/action_dispatch/middleware/head.rb +0 -18
- data/lib/action_dispatch/middleware/rescue.rb +0 -26
- data/lib/action_dispatch/testing/performance_test.rb +0 -10
- data/lib/action_view/asset_paths.rb +0 -142
- data/lib/action_view/helpers/asset_paths.rb +0 -7
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
- data/lib/sprockets/assets.rake +0 -99
- data/lib/sprockets/bootstrap.rb +0 -37
- data/lib/sprockets/compressors.rb +0 -83
- data/lib/sprockets/helpers/isolated_helper.rb +0 -13
- data/lib/sprockets/helpers/rails_helper.rb +0 -182
- data/lib/sprockets/helpers.rb +0 -6
- data/lib/sprockets/railtie.rb +0 -62
- data/lib/sprockets/static_compiler.rb +0 -56
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
require 'tempfile'
|
|
2
1
|
require 'stringio'
|
|
3
|
-
require 'strscan'
|
|
4
2
|
|
|
5
|
-
require 'active_support/core_ext/hash/indifferent_access'
|
|
6
|
-
require 'active_support/core_ext/string/access'
|
|
7
3
|
require 'active_support/inflector'
|
|
8
4
|
require 'action_dispatch/http/headers'
|
|
9
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'
|
|
10
14
|
|
|
11
15
|
module ActionDispatch
|
|
12
16
|
class Request < Rack::Request
|
|
@@ -17,7 +21,10 @@ module ActionDispatch
|
|
|
17
21
|
include ActionDispatch::Http::Upload
|
|
18
22
|
include ActionDispatch::Http::URL
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
autoload :Session, 'action_dispatch/request/session'
|
|
25
|
+
|
|
26
|
+
LOCALHOST = Regexp.union [/^127\.0\.0\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]
|
|
27
|
+
|
|
21
28
|
ENV_METHODS = %w[ AUTH_TYPE GATEWAY_INTERFACE
|
|
22
29
|
PATH_TRANSLATED REMOTE_HOST
|
|
23
30
|
REMOTE_IDENT REMOTE_USER REMOTE_ADDR
|
|
@@ -35,6 +42,17 @@ module ActionDispatch
|
|
|
35
42
|
METHOD
|
|
36
43
|
end
|
|
37
44
|
|
|
45
|
+
def initialize(env)
|
|
46
|
+
super
|
|
47
|
+
@method = nil
|
|
48
|
+
@request_method = nil
|
|
49
|
+
@remote_ip = nil
|
|
50
|
+
@original_fullpath = nil
|
|
51
|
+
@fullpath = nil
|
|
52
|
+
@ip = nil
|
|
53
|
+
@uuid = nil
|
|
54
|
+
end
|
|
55
|
+
|
|
38
56
|
def key?(key)
|
|
39
57
|
@env.key?(key)
|
|
40
58
|
end
|
|
@@ -56,12 +74,13 @@ module ActionDispatch
|
|
|
56
74
|
RFC5789 = %w(PATCH)
|
|
57
75
|
|
|
58
76
|
HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789
|
|
77
|
+
|
|
59
78
|
HTTP_METHOD_LOOKUP = {}
|
|
60
79
|
|
|
61
80
|
# Populate the HTTP method lookup cache
|
|
62
|
-
HTTP_METHODS.each
|
|
81
|
+
HTTP_METHODS.each { |method|
|
|
63
82
|
HTTP_METHOD_LOOKUP[method] = method.underscore.to_sym
|
|
64
|
-
|
|
83
|
+
}
|
|
65
84
|
|
|
66
85
|
# Returns the HTTP \method that the application should see.
|
|
67
86
|
# In the case where the \method was overridden by a middleware
|
|
@@ -102,6 +121,12 @@ module ActionDispatch
|
|
|
102
121
|
HTTP_METHOD_LOOKUP[request_method] == :post
|
|
103
122
|
end
|
|
104
123
|
|
|
124
|
+
# Is this a PATCH request?
|
|
125
|
+
# Equivalent to <tt>request.request_method == :patch</tt>.
|
|
126
|
+
def patch?
|
|
127
|
+
HTTP_METHOD_LOOKUP[request_method] == :patch
|
|
128
|
+
end
|
|
129
|
+
|
|
105
130
|
# Is this a PUT request?
|
|
106
131
|
# Equivalent to <tt>request.request_method_symbol == :put</tt>.
|
|
107
132
|
def put?
|
|
@@ -115,9 +140,9 @@ module ActionDispatch
|
|
|
115
140
|
end
|
|
116
141
|
|
|
117
142
|
# Is this a HEAD request?
|
|
118
|
-
# Equivalent to <tt>request.
|
|
143
|
+
# Equivalent to <tt>request.request_method_symbol == :head</tt>.
|
|
119
144
|
def head?
|
|
120
|
-
HTTP_METHOD_LOOKUP[
|
|
145
|
+
HTTP_METHOD_LOOKUP[request_method] == :head
|
|
121
146
|
end
|
|
122
147
|
|
|
123
148
|
# Provides access to the request's HTTP headers, for example:
|
|
@@ -131,14 +156,29 @@ module ActionDispatch
|
|
|
131
156
|
@original_fullpath ||= (env["ORIGINAL_FULLPATH"] || fullpath)
|
|
132
157
|
end
|
|
133
158
|
|
|
159
|
+
# Returns the +String+ full path including params of the last URL requested.
|
|
160
|
+
#
|
|
161
|
+
# # get "/articles"
|
|
162
|
+
# request.fullpath # => "/articles"
|
|
163
|
+
#
|
|
164
|
+
# # get "/articles?page=2"
|
|
165
|
+
# request.fullpath # => "/articles?page=2"
|
|
134
166
|
def fullpath
|
|
135
167
|
@fullpath ||= super
|
|
136
168
|
end
|
|
137
169
|
|
|
170
|
+
# Returns the original request URL as a +String+.
|
|
171
|
+
#
|
|
172
|
+
# # get "/articles?page=2"
|
|
173
|
+
# request.original_url # => "http://www.example.com/articles?page=2"
|
|
138
174
|
def original_url
|
|
139
175
|
base_url + original_fullpath
|
|
140
176
|
end
|
|
141
177
|
|
|
178
|
+
# The +String+ MIME type of the request.
|
|
179
|
+
#
|
|
180
|
+
# # get "/articles"
|
|
181
|
+
# request.media_type # => "application/x-www-form-urlencoded"
|
|
142
182
|
def media_type
|
|
143
183
|
content_mime_type.to_s
|
|
144
184
|
end
|
|
@@ -195,7 +235,7 @@ module ActionDispatch
|
|
|
195
235
|
# variable is already set, wrap it in a StringIO.
|
|
196
236
|
def body
|
|
197
237
|
if raw_post = @env['RAW_POST_DATA']
|
|
198
|
-
raw_post.force_encoding(Encoding::BINARY)
|
|
238
|
+
raw_post.force_encoding(Encoding::BINARY)
|
|
199
239
|
StringIO.new(raw_post)
|
|
200
240
|
else
|
|
201
241
|
@env['rack.input']
|
|
@@ -213,32 +253,38 @@ module ActionDispatch
|
|
|
213
253
|
# TODO This should be broken apart into AD::Request::Session and probably
|
|
214
254
|
# be included by the session middleware.
|
|
215
255
|
def reset_session
|
|
216
|
-
|
|
217
|
-
|
|
256
|
+
if session && session.respond_to?(:destroy)
|
|
257
|
+
session.destroy
|
|
258
|
+
else
|
|
259
|
+
self.session = {}
|
|
260
|
+
end
|
|
218
261
|
@env['action_dispatch.request.flash_hash'] = nil
|
|
219
262
|
end
|
|
220
263
|
|
|
221
264
|
def session=(session) #:nodoc:
|
|
222
|
-
@env
|
|
265
|
+
Session.set @env, session
|
|
223
266
|
end
|
|
224
267
|
|
|
225
268
|
def session_options=(options)
|
|
226
|
-
@env
|
|
269
|
+
Session::Options.set @env, options
|
|
227
270
|
end
|
|
228
271
|
|
|
229
272
|
# Override Rack's GET method to support indifferent access
|
|
230
273
|
def GET
|
|
231
|
-
@env["action_dispatch.request.query_parameters"] ||=
|
|
274
|
+
@env["action_dispatch.request.query_parameters"] ||= (normalize_encode_params(super) || {})
|
|
275
|
+
rescue TypeError => e
|
|
276
|
+
raise ActionController::BadRequest.new(:query, e)
|
|
232
277
|
end
|
|
233
278
|
alias :query_parameters :GET
|
|
234
279
|
|
|
235
280
|
# Override Rack's POST method to support indifferent access
|
|
236
281
|
def POST
|
|
237
|
-
@env["action_dispatch.request.request_parameters"] ||=
|
|
282
|
+
@env["action_dispatch.request.request_parameters"] ||= (normalize_encode_params(super) || {})
|
|
283
|
+
rescue TypeError => e
|
|
284
|
+
raise ActionController::BadRequest.new(:request, e)
|
|
238
285
|
end
|
|
239
286
|
alias :request_parameters :POST
|
|
240
287
|
|
|
241
|
-
|
|
242
288
|
# Returns the authorization header regardless of whether it was specified directly or through one of the
|
|
243
289
|
# proxy alternatives.
|
|
244
290
|
def authorization
|
|
@@ -250,7 +296,7 @@ module ActionDispatch
|
|
|
250
296
|
|
|
251
297
|
# True if the request came from localhost, 127.0.0.1.
|
|
252
298
|
def local?
|
|
253
|
-
LOCALHOST
|
|
299
|
+
LOCALHOST =~ remote_addr && LOCALHOST =~ remote_ip
|
|
254
300
|
end
|
|
255
301
|
|
|
256
302
|
# Remove nils from the params hash
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
require 'digest/md5'
|
|
2
|
-
require 'active_support/core_ext/module/delegation'
|
|
3
|
-
require 'active_support/core_ext/object/blank'
|
|
4
1
|
require 'active_support/core_ext/class/attribute_accessors'
|
|
2
|
+
require 'monitor'
|
|
5
3
|
|
|
6
4
|
module ActionDispatch # :nodoc:
|
|
7
5
|
# Represents an HTTP response generated by a controller action. Use it to
|
|
@@ -29,7 +27,7 @@ module ActionDispatch # :nodoc:
|
|
|
29
27
|
# class DemoControllerTest < ActionDispatch::IntegrationTest
|
|
30
28
|
# def test_print_root_path_to_console
|
|
31
29
|
# get('/')
|
|
32
|
-
# puts
|
|
30
|
+
# puts response.body
|
|
33
31
|
# end
|
|
34
32
|
# end
|
|
35
33
|
class Response
|
|
@@ -41,7 +39,7 @@ module ActionDispatch # :nodoc:
|
|
|
41
39
|
alias_method :headers, :header
|
|
42
40
|
|
|
43
41
|
delegate :[], :[]=, :to => :@header
|
|
44
|
-
delegate :each, :to => :@
|
|
42
|
+
delegate :each, :to => :@stream
|
|
45
43
|
|
|
46
44
|
# Sets the HTTP response's content MIME type. For example, in the controller
|
|
47
45
|
# you could write this:
|
|
@@ -51,22 +49,65 @@ module ActionDispatch # :nodoc:
|
|
|
51
49
|
# If a character set has been defined for this response (see charset=) then
|
|
52
50
|
# the character set information will also be included in the content type
|
|
53
51
|
# information.
|
|
54
|
-
attr_accessor :charset
|
|
52
|
+
attr_accessor :charset
|
|
53
|
+
attr_reader :content_type
|
|
55
54
|
|
|
56
55
|
CONTENT_TYPE = "Content-Type".freeze
|
|
57
56
|
SET_COOKIE = "Set-Cookie".freeze
|
|
58
57
|
LOCATION = "Location".freeze
|
|
59
|
-
|
|
58
|
+
NO_CONTENT_CODES = [204, 304]
|
|
59
|
+
|
|
60
60
|
cattr_accessor(:default_charset) { "utf-8" }
|
|
61
|
+
cattr_accessor(:default_headers)
|
|
61
62
|
|
|
62
63
|
include Rack::Response::Helpers
|
|
64
|
+
include ActionDispatch::Http::FilterRedirect
|
|
63
65
|
include ActionDispatch::Http::Cache::Response
|
|
66
|
+
include MonitorMixin
|
|
67
|
+
|
|
68
|
+
class Buffer # :nodoc:
|
|
69
|
+
def initialize(response, buf)
|
|
70
|
+
@response = response
|
|
71
|
+
@buf = buf
|
|
72
|
+
@closed = false
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def write(string)
|
|
76
|
+
raise IOError, "closed stream" if closed?
|
|
77
|
+
|
|
78
|
+
@response.commit!
|
|
79
|
+
@buf.push string
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def each(&block)
|
|
83
|
+
@buf.each(&block)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def close
|
|
87
|
+
@response.commit!
|
|
88
|
+
@closed = true
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def closed?
|
|
92
|
+
@closed
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
attr_reader :stream
|
|
64
97
|
|
|
65
98
|
def initialize(status = 200, header = {}, body = [])
|
|
99
|
+
super()
|
|
100
|
+
|
|
101
|
+
header = merge_default_headers(header, self.class.default_headers)
|
|
102
|
+
|
|
66
103
|
self.body, self.header, self.status = body, header, status
|
|
67
104
|
|
|
68
105
|
@sending_file = false
|
|
69
|
-
@blank
|
|
106
|
+
@blank = false
|
|
107
|
+
@cv = new_cond
|
|
108
|
+
@committed = false
|
|
109
|
+
@content_type = nil
|
|
110
|
+
@charset = nil
|
|
70
111
|
|
|
71
112
|
if content_type = self[CONTENT_TYPE]
|
|
72
113
|
type, charset = content_type.split(/;\s*charset=/)
|
|
@@ -79,37 +120,69 @@ module ActionDispatch # :nodoc:
|
|
|
79
120
|
yield self if block_given?
|
|
80
121
|
end
|
|
81
122
|
|
|
123
|
+
def await_commit
|
|
124
|
+
synchronize do
|
|
125
|
+
@cv.wait_until { @committed }
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def commit!
|
|
130
|
+
synchronize do
|
|
131
|
+
@committed = true
|
|
132
|
+
@cv.broadcast
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def committed?
|
|
137
|
+
@committed
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Sets the HTTP status code.
|
|
82
141
|
def status=(status)
|
|
83
142
|
@status = Rack::Utils.status_code(status)
|
|
84
143
|
end
|
|
85
144
|
|
|
86
|
-
|
|
145
|
+
def content_type=(content_type)
|
|
146
|
+
@content_type = content_type.to_s
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# The response code of the request.
|
|
87
150
|
def response_code
|
|
88
151
|
@status
|
|
89
152
|
end
|
|
90
153
|
|
|
91
|
-
# Returns a
|
|
154
|
+
# Returns a string to ensure compatibility with <tt>Net::HTTPResponse</tt>.
|
|
92
155
|
def code
|
|
93
156
|
@status.to_s
|
|
94
157
|
end
|
|
95
158
|
|
|
159
|
+
# Returns the corresponding message for the current HTTP status code:
|
|
160
|
+
#
|
|
161
|
+
# response.status = 200
|
|
162
|
+
# response.message # => "OK"
|
|
163
|
+
#
|
|
164
|
+
# response.status = 404
|
|
165
|
+
# response.message # => "Not Found"
|
|
166
|
+
#
|
|
96
167
|
def message
|
|
97
168
|
Rack::Utils::HTTP_STATUS_CODES[@status]
|
|
98
169
|
end
|
|
99
170
|
alias_method :status_message, :message
|
|
100
171
|
|
|
101
172
|
def respond_to?(method)
|
|
102
|
-
if method.
|
|
103
|
-
|
|
173
|
+
if method.to_s == 'to_path'
|
|
174
|
+
stream.respond_to?(:to_path)
|
|
104
175
|
else
|
|
105
176
|
super
|
|
106
177
|
end
|
|
107
178
|
end
|
|
108
179
|
|
|
109
180
|
def to_path
|
|
110
|
-
|
|
181
|
+
stream.to_path
|
|
111
182
|
end
|
|
112
183
|
|
|
184
|
+
# Returns the content of the response as a string. This contains the contents
|
|
185
|
+
# of any calls to <tt>render</tt>.
|
|
113
186
|
def body
|
|
114
187
|
strings = []
|
|
115
188
|
each { |part| strings << part.to_s }
|
|
@@ -118,21 +191,21 @@ module ActionDispatch # :nodoc:
|
|
|
118
191
|
|
|
119
192
|
EMPTY = " "
|
|
120
193
|
|
|
194
|
+
# Allows you to manually set or override the response body.
|
|
121
195
|
def body=(body)
|
|
122
196
|
@blank = true if body == EMPTY
|
|
123
197
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
# is bad on Ruby 1.8 (because strings responds to each then).
|
|
127
|
-
@body = if body.respond_to?(:to_str) || !body.respond_to?(:each)
|
|
128
|
-
[body]
|
|
198
|
+
if body.respond_to?(:to_path)
|
|
199
|
+
@stream = body
|
|
129
200
|
else
|
|
130
|
-
body
|
|
201
|
+
@stream = build_buffer self, munge_body_object(body)
|
|
131
202
|
end
|
|
132
203
|
end
|
|
133
204
|
|
|
134
205
|
def body_parts
|
|
135
|
-
|
|
206
|
+
parts = []
|
|
207
|
+
@stream.each { |x| parts << x }
|
|
208
|
+
parts
|
|
136
209
|
end
|
|
137
210
|
|
|
138
211
|
def set_cookie(key, value)
|
|
@@ -153,21 +226,11 @@ module ActionDispatch # :nodoc:
|
|
|
153
226
|
end
|
|
154
227
|
|
|
155
228
|
def close
|
|
156
|
-
|
|
229
|
+
stream.close if stream.respond_to?(:close)
|
|
157
230
|
end
|
|
158
231
|
|
|
159
232
|
def to_a
|
|
160
|
-
|
|
161
|
-
handle_conditional_get!
|
|
162
|
-
|
|
163
|
-
@header[SET_COOKIE] = @header[SET_COOKIE].join("\n") if @header[SET_COOKIE].respond_to?(:join)
|
|
164
|
-
|
|
165
|
-
if [204, 304].include?(@status)
|
|
166
|
-
@header.delete CONTENT_TYPE
|
|
167
|
-
[@status, @header, []]
|
|
168
|
-
else
|
|
169
|
-
[@status, @header, self]
|
|
170
|
-
end
|
|
233
|
+
rack_response @status, @header.to_hash
|
|
171
234
|
end
|
|
172
235
|
alias prepare! to_a
|
|
173
236
|
alias to_ary to_a # For implicit splat on 1.9.2
|
|
@@ -191,16 +254,48 @@ module ActionDispatch # :nodoc:
|
|
|
191
254
|
|
|
192
255
|
private
|
|
193
256
|
|
|
194
|
-
def
|
|
257
|
+
def merge_default_headers(original, default)
|
|
258
|
+
return original unless default.respond_to?(:merge)
|
|
259
|
+
|
|
260
|
+
default.merge(original)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def build_buffer(response, body)
|
|
264
|
+
Buffer.new response, body
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def munge_body_object(body)
|
|
268
|
+
body.respond_to?(:each) ? body : [body]
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def assign_default_content_type_and_charset!(headers)
|
|
195
272
|
return if headers[CONTENT_TYPE].present?
|
|
196
273
|
|
|
197
274
|
@content_type ||= Mime::HTML
|
|
198
|
-
@charset ||= self.class.default_charset
|
|
275
|
+
@charset ||= self.class.default_charset unless @charset == false
|
|
199
276
|
|
|
200
277
|
type = @content_type.to_s.dup
|
|
201
|
-
type << "; charset=#{@charset}"
|
|
278
|
+
type << "; charset=#{@charset}" if append_charset?
|
|
202
279
|
|
|
203
280
|
headers[CONTENT_TYPE] = type
|
|
204
281
|
end
|
|
282
|
+
|
|
283
|
+
def append_charset?
|
|
284
|
+
!@sending_file && @charset != false
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def rack_response(status, header)
|
|
288
|
+
assign_default_content_type_and_charset!(header)
|
|
289
|
+
handle_conditional_get!
|
|
290
|
+
|
|
291
|
+
header[SET_COOKIE] = header[SET_COOKIE].join("\n") if header[SET_COOKIE].respond_to?(:join)
|
|
292
|
+
|
|
293
|
+
if NO_CONTENT_CODES.include?(@status)
|
|
294
|
+
header.delete CONTENT_TYPE
|
|
295
|
+
[status, header, []]
|
|
296
|
+
else
|
|
297
|
+
[status, header, self]
|
|
298
|
+
end
|
|
299
|
+
end
|
|
205
300
|
end
|
|
206
301
|
end
|
|
@@ -1,47 +1,90 @@
|
|
|
1
1
|
module ActionDispatch
|
|
2
2
|
module Http
|
|
3
|
+
# Models uploaded files.
|
|
4
|
+
#
|
|
5
|
+
# The actual file is accessible via the +tempfile+ accessor, though some
|
|
6
|
+
# of its interface is available directly for convenience.
|
|
7
|
+
#
|
|
8
|
+
# Uploaded files are temporary files whose lifespan is one request. When
|
|
9
|
+
# the object is finalized Ruby unlinks the file, so there is no need to
|
|
10
|
+
# clean them with a separate maintenance task.
|
|
3
11
|
class UploadedFile
|
|
4
|
-
|
|
12
|
+
# The basename of the file in the client.
|
|
13
|
+
attr_accessor :original_filename
|
|
14
|
+
|
|
15
|
+
# A string with the MIME type of the file.
|
|
16
|
+
attr_accessor :content_type
|
|
17
|
+
|
|
18
|
+
# A +Tempfile+ object with the actual uploaded file. Note that some of
|
|
19
|
+
# its interface is available directly.
|
|
20
|
+
attr_accessor :tempfile
|
|
21
|
+
|
|
22
|
+
# A string with the headers of the multipart request.
|
|
23
|
+
attr_accessor :headers
|
|
24
|
+
|
|
25
|
+
def initialize(hash) # :nodoc:
|
|
26
|
+
@tempfile = hash[:tempfile]
|
|
27
|
+
raise(ArgumentError, ':tempfile is required') unless @tempfile
|
|
5
28
|
|
|
6
|
-
def initialize(hash)
|
|
7
29
|
@original_filename = encode_filename(hash[:filename])
|
|
8
30
|
@content_type = hash[:type]
|
|
9
31
|
@headers = hash[:head]
|
|
10
|
-
@tempfile = hash[:tempfile]
|
|
11
|
-
raise(ArgumentError, ':tempfile is required') unless @tempfile
|
|
12
32
|
end
|
|
13
33
|
|
|
14
|
-
|
|
15
|
-
|
|
34
|
+
# Shortcut for +tempfile.read+.
|
|
35
|
+
def read(length=nil, buffer=nil)
|
|
36
|
+
@tempfile.read(length, buffer)
|
|
16
37
|
end
|
|
17
38
|
|
|
18
|
-
#
|
|
19
|
-
|
|
20
|
-
|
|
39
|
+
# Shortcut for +tempfile.open+.
|
|
40
|
+
def open
|
|
41
|
+
@tempfile.open
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Shortcut for +tempfile.close+.
|
|
45
|
+
def close(unlink_now=false)
|
|
46
|
+
@tempfile.close(unlink_now)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Shortcut for +tempfile.path+.
|
|
50
|
+
def path
|
|
51
|
+
@tempfile.path
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Shortcut for +tempfile.rewind+.
|
|
55
|
+
def rewind
|
|
56
|
+
@tempfile.rewind
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Shortcut for +tempfile.size+.
|
|
60
|
+
def size
|
|
61
|
+
@tempfile.size
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Shortcut for +tempfile.eof?+.
|
|
65
|
+
def eof?
|
|
66
|
+
@tempfile.eof?
|
|
21
67
|
end
|
|
22
68
|
|
|
23
69
|
private
|
|
70
|
+
|
|
24
71
|
def encode_filename(filename)
|
|
25
|
-
# Encode the filename in the utf8 encoding, unless it is nil
|
|
26
|
-
|
|
27
|
-
filename.force_encoding("UTF-8").encode!
|
|
28
|
-
else
|
|
29
|
-
filename
|
|
30
|
-
end
|
|
72
|
+
# Encode the filename in the utf8 encoding, unless it is nil
|
|
73
|
+
filename.force_encoding(Encoding::UTF_8).encode! if filename
|
|
31
74
|
end
|
|
32
75
|
end
|
|
33
76
|
|
|
34
|
-
module Upload
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
def
|
|
77
|
+
module Upload # :nodoc:
|
|
78
|
+
# Replace file upload hash with UploadedFile objects
|
|
79
|
+
# when normalize and encode parameters.
|
|
80
|
+
def normalize_encode_params(value)
|
|
38
81
|
if Hash === value && value.has_key?(:tempfile)
|
|
39
82
|
UploadedFile.new(value)
|
|
40
83
|
else
|
|
41
84
|
super
|
|
42
85
|
end
|
|
43
86
|
end
|
|
44
|
-
private :
|
|
87
|
+
private :normalize_encode_params
|
|
45
88
|
end
|
|
46
89
|
end
|
|
47
90
|
end
|