actionpack 4.0.0.beta1 → 4.0.0.rc1

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.

Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +195 -11
  3. data/lib/abstract_controller/base.rb +1 -1
  4. data/lib/abstract_controller/helpers.rb +2 -2
  5. data/lib/abstract_controller/layouts.rb +10 -5
  6. data/lib/abstract_controller/rendering.rb +11 -3
  7. data/lib/abstract_controller/translation.rb +1 -1
  8. data/lib/action_controller/log_subscriber.rb +5 -0
  9. data/lib/action_controller/metal.rb +2 -3
  10. data/lib/action_controller/metal/force_ssl.rb +52 -17
  11. data/lib/action_controller/metal/helpers.rb +0 -1
  12. data/lib/action_controller/metal/hide_actions.rb +1 -1
  13. data/lib/action_controller/metal/http_authentication.rb +3 -2
  14. data/lib/action_controller/metal/live.rb +34 -0
  15. data/lib/action_controller/metal/rendering.rb +1 -1
  16. data/lib/action_controller/metal/strong_parameters.rb +7 -3
  17. data/lib/action_controller/test_case.rb +45 -11
  18. data/lib/action_dispatch.rb +4 -6
  19. data/lib/action_dispatch/http/cache.rb +2 -2
  20. data/lib/action_dispatch/http/headers.rb +39 -15
  21. data/lib/action_dispatch/http/mime_negotiation.rb +1 -1
  22. data/lib/action_dispatch/http/mime_type.rb +11 -3
  23. data/lib/action_dispatch/http/parameters.rb +17 -24
  24. data/lib/action_dispatch/http/request.rb +17 -2
  25. data/lib/action_dispatch/http/response.rb +2 -1
  26. data/lib/action_dispatch/http/upload.rb +5 -5
  27. data/lib/action_dispatch/http/url.rb +53 -12
  28. data/lib/action_dispatch/journey/formatter.rb +1 -1
  29. data/lib/action_dispatch/journey/path/pattern.rb +1 -1
  30. data/lib/action_dispatch/journey/route.rb +8 -0
  31. data/lib/action_dispatch/journey/router.rb +3 -1
  32. data/lib/action_dispatch/journey/visitors.rb +8 -0
  33. data/lib/action_dispatch/middleware/cookies.rb +169 -135
  34. data/lib/action_dispatch/middleware/exception_wrapper.rb +1 -0
  35. data/lib/action_dispatch/middleware/remote_ip.rb +2 -2
  36. data/lib/action_dispatch/middleware/request_id.rb +1 -1
  37. data/lib/action_dispatch/middleware/session/cookie_store.rb +38 -58
  38. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +1 -1
  39. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +4 -6
  40. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +1 -1
  41. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +1 -1
  42. data/lib/action_dispatch/routing.rb +28 -64
  43. data/lib/action_dispatch/routing/mapper.rb +61 -48
  44. data/lib/action_dispatch/routing/route_set.rb +17 -14
  45. data/lib/action_dispatch/testing/assertions/routing.rb +2 -2
  46. data/lib/action_dispatch/testing/assertions/selector.rb +2 -2
  47. data/lib/action_dispatch/testing/integration.rb +36 -35
  48. data/lib/action_dispatch/testing/test_process.rb +1 -1
  49. data/lib/action_pack/version.rb +7 -6
  50. data/lib/action_view/buffers.rb +6 -0
  51. data/lib/action_view/dependency_tracker.rb +3 -1
  52. data/lib/action_view/helpers/asset_tag_helper.rb +13 -8
  53. data/lib/action_view/helpers/capture_helper.rb +2 -2
  54. data/lib/action_view/helpers/date_helper.rb +1 -1
  55. data/lib/action_view/helpers/form_helper.rb +56 -19
  56. data/lib/action_view/helpers/form_options_helper.rb +3 -3
  57. data/lib/action_view/helpers/form_tag_helper.rb +1 -1
  58. data/lib/action_view/helpers/javascript_helper.rb +2 -2
  59. data/lib/action_view/helpers/number_helper.rb +25 -0
  60. data/lib/action_view/helpers/tags/base.rb +9 -10
  61. data/lib/action_view/helpers/tags/check_box.rb +1 -1
  62. data/lib/action_view/helpers/tags/checkable.rb +2 -2
  63. data/lib/action_view/helpers/tags/collection_check_boxes.rb +3 -3
  64. data/lib/action_view/helpers/tags/collection_helpers.rb +3 -3
  65. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +3 -3
  66. data/lib/action_view/helpers/tags/collection_select.rb +1 -1
  67. data/lib/action_view/helpers/tags/color_field.rb +2 -2
  68. data/lib/action_view/helpers/tags/date_field.rb +2 -2
  69. data/lib/action_view/helpers/tags/date_select.rb +2 -2
  70. data/lib/action_view/helpers/tags/datetime_field.rb +2 -2
  71. data/lib/action_view/helpers/tags/datetime_local_field.rb +2 -2
  72. data/lib/action_view/helpers/tags/datetime_select.rb +2 -2
  73. data/lib/action_view/helpers/tags/email_field.rb +2 -2
  74. data/lib/action_view/helpers/tags/file_field.rb +2 -2
  75. data/lib/action_view/helpers/tags/grouped_collection_select.rb +2 -2
  76. data/lib/action_view/helpers/tags/hidden_field.rb +2 -2
  77. data/lib/action_view/helpers/tags/label.rb +2 -2
  78. data/lib/action_view/helpers/tags/month_field.rb +2 -2
  79. data/lib/action_view/helpers/tags/number_field.rb +2 -2
  80. data/lib/action_view/helpers/tags/password_field.rb +2 -2
  81. data/lib/action_view/helpers/tags/radio_button.rb +2 -2
  82. data/lib/action_view/helpers/tags/range_field.rb +2 -2
  83. data/lib/action_view/helpers/tags/search_field.rb +2 -2
  84. data/lib/action_view/helpers/tags/select.rb +2 -3
  85. data/lib/action_view/helpers/tags/tel_field.rb +2 -2
  86. data/lib/action_view/helpers/tags/text_area.rb +2 -2
  87. data/lib/action_view/helpers/tags/text_field.rb +2 -2
  88. data/lib/action_view/helpers/tags/time_field.rb +2 -2
  89. data/lib/action_view/helpers/tags/time_select.rb +2 -2
  90. data/lib/action_view/helpers/tags/time_zone_select.rb +2 -2
  91. data/lib/action_view/helpers/tags/url_field.rb +2 -2
  92. data/lib/action_view/helpers/tags/week_field.rb +2 -2
  93. data/lib/action_view/helpers/text_helper.rb +8 -5
  94. data/lib/action_view/helpers/url_helper.rb +18 -6
  95. data/lib/action_view/lookup_context.rb +7 -1
  96. data/lib/action_view/path_set.rb +6 -0
  97. data/lib/action_view/renderer/abstract_renderer.rb +15 -0
  98. data/lib/action_view/renderer/partial_renderer.rb +14 -0
  99. data/lib/action_view/renderer/renderer.rb +6 -0
  100. data/lib/action_view/template.rb +3 -2
  101. data/lib/action_view/template/handlers/erb.rb +29 -3
  102. data/lib/action_view/template/resolver.rb +3 -3
  103. data/lib/action_view/test_case.rb +1 -0
  104. data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +5 -5
  105. data/lib/action_view/vendor/html-scanner/html/selector.rb +8 -8
  106. metadata +8 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b3463df116c388c7b2d15a3ac267fea12a100cf1
4
- data.tar.gz: ad55681ebfbc24cbb11d1b06a5e31943a4515a96
3
+ metadata.gz: b2f9e896fa0aab306404dfec0ba34305704d5680
4
+ data.tar.gz: d36ac14f59dea1d6607b462c3df3c3103c19e3ad
5
5
  SHA512:
6
- metadata.gz: 83abc4ab5ba7fe34ad23f5f29bc7eee985ae62a7ea949fc84b942b9dbd3b3c8caebd692f5c52765a972c0e993edd1efb18b2a244ffb8917358f3743718ab90f9
7
- data.tar.gz: 91d22e18c2143a67a92fa61cf346adce168373835e7636de2a125de336958e3f528ba1a83807417dc7f541ce3156c08c88641273d05dacfc268f5ccea8cc05f5
6
+ metadata.gz: 61f6cfcae3aa384acba259c7185dc1f2cb4580973f525c4b98303c0bab0f5a9100fd7b73c2adbaa4fadf9f41defc525135306788e4859f40209bb80b92e315d4
7
+ data.tar.gz: 347a2469a9f69a56a36cf2d96059088b1f34ae3fb74c6d80f909b0cde9f165c647c1399535e794b5d5daebaa23d0fcabd82491caab5230e820fff03a05391fac
@@ -1,3 +1,187 @@
1
+ ## Rails 4.0.0 (unreleased) ##
2
+
3
+ * Add support for passing custom url options other than `:host` and custom
4
+ status and flash options to `force_ssl`.
5
+
6
+ *Andrew White*
7
+
8
+ * The `force_ssl` command now builds the redirect url from `request.fullpath`.
9
+ This ensures that the format is maintained and it doesn't redirect to a route
10
+ that has the same parameters but is defined earlier in `routes.rb`. Also any
11
+ optional segments are maintained.
12
+
13
+ Fixes #7528, #9061, #10305.
14
+
15
+ *Andrew White*
16
+
17
+ * Return a 405 Method Not Allowed response when a request contains an unknown
18
+ HTTP method.
19
+
20
+ *Lewis Marshall*
21
+
22
+ * Add support for extracting the port from the `:host` option passed to `url_for`.
23
+
24
+ *Andrew White*
25
+
26
+ * Add support for removing the subdomain from a url by passing `nil`, `false` or `''`.
27
+ Fixes #10180.
28
+
29
+ *Derek Watson + Andrew White*
30
+
31
+ * Element of the collection for `options_from_collection_for_select` helper can
32
+ optionally contain html attributes as the last element of the array as
33
+ `options_for_select` helper.
34
+
35
+ *Vasiliy Ermolovich*
36
+
37
+ * Fix explicit names on multiple file fields. If a file field tag has
38
+ the multiple option, it is turned into an array field (appending `[]`),
39
+ but if an explicit name is passed to `file_field` the `[]` is not
40
+ appended.
41
+ Fixes #9830.
42
+
43
+ *Ryan McGeary*
44
+
45
+ * Add block support for the `mail_to` helper, similar to the `link_to` helper.
46
+
47
+ *Sam Pohlenz*
48
+
49
+ * Automatically configure cookie-based sessions to be encrypted if
50
+ `secret_key_base` is set, falling back to signed if only `secret_token`
51
+ is set. Automatically upgrade existing signed cookie-based sessions from
52
+ Rails 3.x to be encrypted if both `secret_key_base` and `secret_token`
53
+ are set, or signed with the new key generator if only `secret_token` is
54
+ set. This leaves only the `config.session_store :cookie_store` option and
55
+ removes the two new options introduced in 4.0.0.beta1:
56
+ `encrypted_cookie_store` and `upgrade_signature_to_encryption_cookie_store`.
57
+
58
+ *Trevor Turk*
59
+
60
+ * Ensure consistent fallback to the default layout lookup for layouts set
61
+ using symbols or procs that return `nil`.
62
+
63
+ All of the following layouts will result in the default layout lookup:
64
+
65
+ layout nil
66
+
67
+ layout proc { nil }
68
+
69
+ layout :returns_nil
70
+ def returns_nil
71
+ nil
72
+ end
73
+
74
+ Previously symbols and procs which returned `nil` resulted in no layout which
75
+ differed from the `layout nil` behavior. To get the "no layout" behavior just
76
+ return `false` instead of `nil` for `layout`.
77
+
78
+ *Chris Nicola*
79
+
80
+ * Create `UpgradeLegacySignedCookieJar` to transparently upgrade existing signed
81
+ cookies generated by Rails 3.x to avoid invalidating them when upgrading to Rails 4.x.
82
+
83
+ *Trevor Turk + Neeraj Singh*
84
+
85
+ * Raise an `ArgumentError` when a clashing named route is defined.
86
+
87
+ *Trevor Turk*
88
+
89
+ * Allow default url options to accept host with protocol such as `http://`
90
+
91
+ config.action_mailer.default_url_options = { host: "http://mydomain.com" }
92
+
93
+ *Richard Schneeman*
94
+
95
+ * Ensure that digest authentication responds with a 401 status when a basic
96
+ header is received.
97
+
98
+ *Brad Dunbar*
99
+
100
+ * Include I18n locale fallbacks in view lookup.
101
+ Fixes #3512.
102
+
103
+ *Juan Barreneche*
104
+
105
+ * Integration and functional tests allow headers and rack env
106
+ variables to be passed when performing requests.
107
+ Fixes #6513.
108
+
109
+ Example:
110
+
111
+ # integration test
112
+ get "/success", {}, "HTTP_REFERER" => "http://test.com/",
113
+ "Accepts" => "text/plain, text/html"
114
+
115
+ # functional test
116
+ @request.headers["Accepts"] = "text/plain, text/html"
117
+
118
+ *Yves Senn*
119
+
120
+ * Http::Headers respects headers that are not prefixed with HTTP_
121
+
122
+ *Yves Senn*
123
+
124
+ * Fix incorrectly appended square brackets to a multiple select box
125
+ if an explicit name has been given and it already ends with "[]"
126
+
127
+ Before:
128
+
129
+ select(:category, [], {}, multiple: true, name: "post[category][]")
130
+ # => <select name="post[category][][]" ...>
131
+
132
+ After:
133
+
134
+ select(:category, [], {}, multiple: true, name: "post[category][]")
135
+ # => <select name="post[category][]" ...>
136
+
137
+ *Olek Janiszewski*
138
+
139
+ * Fixed regression when using `assert_template` to verify files sent using
140
+ `render file: 'README.md'`.
141
+ Fixes #9464.
142
+
143
+ *Justin Coyne*
144
+
145
+ * Fixed `ActionView::Helpers::CaptureHelper#content_for` regression when trying to use it in
146
+ a boolean statement.
147
+ Fixes #9360.
148
+
149
+ *Nikolay Shebanov*
150
+
151
+ * `format: true` does not override existing format constraints.
152
+ Fixes #9466.
153
+
154
+ Example:
155
+
156
+ # This will force the .json extension.
157
+ get '/json_only', to: ok, format: true, constraints: { format: /json/ }
158
+
159
+ *Yves Senn*
160
+
161
+ * Skip valid encoding checks for non-String parameters that come
162
+ from the matched route's defaults.
163
+ Fixes #9435.
164
+
165
+ Example:
166
+
167
+ root to: 'main#posts', page: 1
168
+
169
+ *Yves Senn*
170
+
171
+ * Don't verify Regexp requirements for non-Regexp `:constraints`.
172
+ Fixes #9432.
173
+
174
+ Example:
175
+
176
+ get '/photos.:format' => 'feeds#photos', constraints: {format: 'xml'}
177
+
178
+ *Yves Senn*
179
+
180
+ * Make `ActionDispatch::Journey::Path::Pattern#new` raise more meaningful exception message.
181
+
182
+ *Thierry Zires*
183
+
184
+
1
185
  ## Rails 4.0.0.beta1 (February 25, 2013) ##
2
186
 
3
187
  * Fix `respond_to` not using formats that have no block if all is present. *Michael Grosser*
@@ -190,12 +374,12 @@
190
374
  Client-IP and Remote-Addr headers, in that order. Document the rationale
191
375
  for that decision, and describe the options that can be passed to the
192
376
  RemoteIp middleware to change it.
193
- Fix #7979
377
+ Fixes #7979.
194
378
 
195
379
  *André Arko*, *Steve Klabnik*, *Alexey Gaziev*
196
380
 
197
381
  * Do not append second slash to `root_url` when using `trailing_slash: true`
198
- Fix #8700
382
+ Fixes #8700.
199
383
 
200
384
  Before:
201
385
 
@@ -223,7 +407,7 @@
223
407
 
224
408
  * Do not append `charset=` parameter when `head` is called with a
225
409
  `:content_type` option.
226
- Fix #8661.
410
+ Fixes #8661.
227
411
 
228
412
  *Yves Senn*
229
413
 
@@ -381,7 +565,7 @@
381
565
 
382
566
  * Render every partial with a new `ActionView::PartialRenderer`. This resolves
383
567
  issues when rendering nested partials.
384
- Fix #8197.
568
+ Fixes #8197.
385
569
 
386
570
  *Yves Senn*
387
571
 
@@ -389,7 +573,7 @@
389
573
  of mime types where template text is not html escaped by default. It prevents `Jack & Joe`
390
574
  from rendering as `Jack &amp; Joe` for the whitelisted mime types. The default whitelist
391
575
  contains `text/plain`.
392
- Fix #7976.
576
+ Fixes #7976.
393
577
 
394
578
  *Joost Baaij*
395
579
 
@@ -405,7 +589,7 @@
405
589
  check_box("post", "comment_ids", { multiple: true, index: "foo" }, 1)
406
590
  # => <input name=\"post[foo][comment_ids][]\" type=\"hidden\" value=\"0\" /><input id=\"post_foo_comment_ids_1\" name=\"post[foo][comment_ids][]\" type=\"checkbox\" value=\"1\" />
407
591
 
408
- Fix #8108.
592
+ Fixes #8108.
409
593
 
410
594
  *Daniel Fox, Grant Hutchins & Trace Wax*
411
595
 
@@ -428,7 +612,7 @@
428
612
  *Josh Peek*
429
613
 
430
614
  * `assert_template` can be used to assert on the same template with different locals
431
- Fix #3675.
615
+ Fixes #3675.
432
616
 
433
617
  *Yves Senn*
434
618
 
@@ -439,7 +623,7 @@
439
623
  * Accept `:remote` as symbolic option for `link_to` helper. *Riley Lynch*
440
624
 
441
625
  * Warn when the `:locals` option is passed to `assert_template` outside of a view test case
442
- Fix #3415.
626
+ Fixes #3415.
443
627
 
444
628
  *Yves Senn*
445
629
 
@@ -463,12 +647,12 @@
463
647
 
464
648
  * Rename internal variables on `ActionController::TemplateAssertions` to prevent
465
649
  naming collisions. `@partials`, `@templates` and `@layouts` are now prefixed with an underscore.
466
- Fix #7459.
650
+ Fixes #7459.
467
651
 
468
652
  *Yves Senn*
469
653
 
470
654
  * `resource` and `resources` don't modify the passed options hash.
471
- Fix #7777.
655
+ Fixes #7777.
472
656
 
473
657
  *Yves Senn*
474
658
 
@@ -532,7 +716,7 @@
532
716
  *Guillermo Iguaran*
533
717
 
534
718
  * Log now displays the correct status code when an exception is raised.
535
- Fix #7646.
719
+ Fixes #7646.
536
720
 
537
721
  *Yves Senn*
538
722
 
@@ -35,7 +35,7 @@ module AbstractController
35
35
  end
36
36
 
37
37
  def inherited(klass) # :nodoc:
38
- # define the abstract ivar on subclasses so that we don't get
38
+ # Define the abstract ivar on subclasses so that we don't get
39
39
  # uninitialized ivar warnings
40
40
  unless klass.instance_variable_defined?(:@abstract)
41
41
  klass.instance_variable_set(:@abstract, false)
@@ -29,7 +29,7 @@ module AbstractController
29
29
  # helper_method :current_user, :logged_in?
30
30
  #
31
31
  # def current_user
32
- # @current_user ||= User.find_by_id(session[:user])
32
+ # @current_user ||= User.find_by(id: session[:user])
33
33
  # end
34
34
  #
35
35
  # def logged_in?
@@ -59,7 +59,7 @@ module AbstractController
59
59
  # The +helper+ class method can take a series of helper module names, a block, or both.
60
60
  #
61
61
  # ==== Options
62
- # * <tt>*args</tt> - Module, Symbol, String, :all
62
+ # * <tt>*args</tt> - Module, Symbol, String
63
63
  # * <tt>block</tt> - A block defining helper methods
64
64
  #
65
65
  # When the argument is a module it will be included directly in the template class.
@@ -285,10 +285,9 @@ module AbstractController
285
285
  remove_possible_method(:_layout)
286
286
 
287
287
  prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
288
+ default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}).first || super"
288
289
  name_clause = if name
289
- <<-RUBY
290
- lookup_context.find_all("#{_implied_layout_name}", #{prefixes.inspect}).first || super
291
- RUBY
290
+ default_behavior
292
291
  else
293
292
  <<-RUBY
294
293
  super
@@ -301,6 +300,7 @@ module AbstractController
301
300
  when Symbol
302
301
  <<-RUBY
303
302
  #{_layout}.tap do |layout|
303
+ return #{default_behavior} if layout.nil?
304
304
  unless layout.is_a?(String) || !layout
305
305
  raise ArgumentError, "Your layout method :#{_layout} returned \#{layout}. It " \
306
306
  "should have returned a String, false, or nil"
@@ -308,8 +308,13 @@ module AbstractController
308
308
  end
309
309
  RUBY
310
310
  when Proc
311
- define_method :_layout_from_proc, &_layout
312
- _layout.arity == 0 ? "_layout_from_proc" : "_layout_from_proc(self)"
311
+ define_method :_layout_from_proc, &_layout
312
+ protected :_layout_from_proc
313
+ <<-RUBY
314
+ result = _layout_from_proc(#{_layout.arity == 0 ? '' : 'self'})
315
+ return #{default_behavior} if result.nil?
316
+ result
317
+ RUBY
313
318
  when false
314
319
  nil
315
320
  when true
@@ -97,15 +97,23 @@ module AbstractController
97
97
  self.response_body = render_to_body(options)
98
98
  end
99
99
 
100
- # Raw rendering of a template to a string. Just convert the results of
101
- # render_response into a String.
100
+ # Raw rendering of a template to a string.
101
+ #
102
+ # It is similar to render, except that it does not
103
+ # set the response_body and it should be guaranteed
104
+ # to always return a string.
105
+ #
106
+ # If a component extends the semantics of response_body
107
+ # (as Action Controller extends it to be anything that
108
+ # responds to the method each), this method needs to be
109
+ # overridden in order to still return a string.
102
110
  # :api: plugin
103
111
  def render_to_string(*args, &block)
104
112
  options = _normalize_render(*args, &block)
105
113
  render_to_body(options)
106
114
  end
107
115
 
108
- # Raw rendering of a template to a Rack-compatible body.
116
+ # Raw rendering of a template.
109
117
  # :api: plugin
110
118
  def render_to_body(options = {})
111
119
  _process_options(options)
@@ -11,7 +11,7 @@ module AbstractController
11
11
  def translate(*args)
12
12
  key = args.first
13
13
  if key.is_a?(String) && (key[0] == '.')
14
- key = "#{ controller_path.gsub('/', '.') }.#{ action_name }#{ key }"
14
+ key = "#{ controller_path.tr('/', '.') }.#{ action_name }#{ key }"
15
15
  args[0] = key
16
16
  end
17
17
 
@@ -48,6 +48,11 @@ module ActionController
48
48
  info("Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)")
49
49
  end
50
50
 
51
+ def unpermitted_parameters(event)
52
+ unpermitted_keys = event.payload[:keys]
53
+ debug("Unpermitted parameters: #{unpermitted_keys.join(", ")}")
54
+ end
55
+
51
56
  %w(write_fragment read_fragment exist_fragment?
52
57
  expire_fragment expire_page write_page).each do |method|
53
58
  class_eval <<-METHOD, __FILE__, __LINE__ + 1
@@ -36,8 +36,7 @@ module ActionController
36
36
  raise "MiddlewareStack#build requires an app" unless app
37
37
 
38
38
  middlewares.reverse.inject(app) do |a, middleware|
39
- middleware.valid?(action) ?
40
- middleware.build(a) : a
39
+ middleware.valid?(action) ? middleware.build(a) : a
41
40
  end
42
41
  end
43
42
  end
@@ -57,7 +56,7 @@ module ActionController
57
56
  # And then to route requests to your metal controller, you would add
58
57
  # something like this to <tt>config/routes.rb</tt>:
59
58
  #
60
- # match 'hello', to: HelloController.action(:index)
59
+ # get 'hello', to: HelloController.action(:index)
61
60
  #
62
61
  # The +action+ method returns a valid Rack application for the \Rails
63
62
  # router to dispatch to.
@@ -1,3 +1,6 @@
1
+ require 'active_support/core_ext/hash/except'
2
+ require 'active_support/core_ext/hash/slice'
3
+
1
4
  module ActionController
2
5
  # This module provides a method which will redirect browser to use HTTPS
3
6
  # protocol. This will ensure that user's sensitive information will be
@@ -14,6 +17,10 @@ module ActionController
14
17
  extend ActiveSupport::Concern
15
18
  include AbstractController::Callbacks
16
19
 
20
+ ACTION_OPTIONS = [:only, :except, :if, :unless]
21
+ URL_OPTIONS = [:protocol, :host, :domain, :subdomain, :port, :path]
22
+ REDIRECT_OPTIONS = [:status, :flash, :alert, :notice]
23
+
17
24
  module ClassMethods
18
25
  # Force the request to this particular controller or specified actions to be
19
26
  # under HTTPS protocol.
@@ -29,18 +36,34 @@ module ActionController
29
36
  # end
30
37
  # end
31
38
  #
32
- # ==== Options
33
- # * <tt>host</tt> - Redirect to a different host name
34
- # * <tt>only</tt> - The callback should be run only for this action
35
- # * <tt>except</tt> - The callback should be run for all actions except this action
36
- # * <tt>if</tt> - A symbol naming an instance method or a proc; the callback
37
- # will be called only when it returns a true value.
38
- # * <tt>unless</tt> - A symbol naming an instance method or a proc; the callback
39
- # will be called only when it returns a false value.
39
+ # ==== URL Options
40
+ # You can pass any of the following options to affect the redirect url
41
+ # * <tt>host</tt> - Redirect to a different host name
42
+ # * <tt>subdomain</tt> - Redirect to a different subdomain
43
+ # * <tt>domain</tt> - Redirect to a different domain
44
+ # * <tt>port</tt> - Redirect to a non-standard port
45
+ # * <tt>path</tt> - Redirect to a different path
46
+ #
47
+ # ==== Redirect Options
48
+ # You can pass any of the following options to affect the redirect status and response
49
+ # * <tt>status</tt> - Redirect with a custom status (default is 301 Moved Permanently)
50
+ # * <tt>flash</tt> - Set a flash message when redirecting
51
+ # * <tt>alert</tt> - Set a alert message when redirecting
52
+ # * <tt>notice</tt> - Set a notice message when redirecting
53
+ #
54
+ # ==== Action Options
55
+ # You can pass any of the following options to affect the before_action callback
56
+ # * <tt>only</tt> - The callback should be run only for this action
57
+ # * <tt>except</tt> - The callback should be run for all actions except this action
58
+ # * <tt>if</tt> - A symbol naming an instance method or a proc; the callback
59
+ # will be called only when it returns a true value.
60
+ # * <tt>unless</tt> - A symbol naming an instance method or a proc; the callback
61
+ # will be called only when it returns a false value.
40
62
  def force_ssl(options = {})
41
- host = options.delete(:host)
42
- before_action(options) do
43
- force_ssl_redirect(host)
63
+ action_options = options.slice(*ACTION_OPTIONS)
64
+ redirect_options = options.except(*ACTION_OPTIONS)
65
+ before_action(action_options) do
66
+ force_ssl_redirect(redirect_options)
44
67
  end
45
68
  end
46
69
  end
@@ -48,14 +71,26 @@ module ActionController
48
71
  # Redirect the existing request to use the HTTPS protocol.
49
72
  #
50
73
  # ==== Parameters
51
- # * <tt>host</tt> - Redirect to a different host name
52
- def force_ssl_redirect(host = nil)
74
+ # * <tt>host_or_options</tt> - Either a host name or any of the url & redirect options
75
+ # available to the <tt>force_ssl</tt> method.
76
+ def force_ssl_redirect(host_or_options = nil)
53
77
  unless request.ssl?
54
- redirect_options = {:protocol => 'https://', :status => :moved_permanently}
55
- redirect_options.merge!(:host => host) if host
56
- redirect_options.merge!(:params => request.query_parameters)
78
+ options = {
79
+ :protocol => 'https://',
80
+ :host => request.host,
81
+ :path => request.fullpath,
82
+ :status => :moved_permanently
83
+ }
84
+
85
+ if host_or_options.is_a?(Hash)
86
+ options.merge!(host_or_options)
87
+ elsif host_or_options
88
+ options.merge!(:host => host_or_options)
89
+ end
90
+
91
+ secure_url = ActionDispatch::Http::URL.url_for(options.slice(*URL_OPTIONS))
57
92
  flash.keep if respond_to?(:flash)
58
- redirect_to redirect_options
93
+ redirect_to secure_url, options.slice(*REDIRECT_OPTIONS)
59
94
  end
60
95
  end
61
96
  end