actionpack 4.1.1 → 4.1.2.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.

@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e696e9aea917e1a7a0ce12cc8e365682a661c6d8
4
+ data.tar.gz: d259d80f6c29728ab611c9d01087415e19a82f46
5
+ SHA512:
6
+ metadata.gz: 631a18596b298cd0f1655d001994579bcc17297cdf47a2304474852fb4f43976116b47ffaf21fe6836c75148fcbb90c074bb85fa27ddfde4bf0bf76aeba58326
7
+ data.tar.gz: b794e4f3045572405883896d1bbe6aab5006cd376c057326aa7d8fef5d2bb083ecfd990bb851904f931df858e250ec217463358a7fd7ae09a8dced8ac6042965
@@ -1,3 +1,77 @@
1
+ ## Rails 4.1.2 (May 27, 2014) ##
2
+
3
+ * Fix URL generation with `:trailing_slash` such that it does not add
4
+ a trailing slash after `.:format`
5
+
6
+ *Dan Langevin*
7
+
8
+ * Fixed an issue with migrating legacy json cookies.
9
+
10
+ Previously, the `VerifyAndUpgradeLegacySignedMessage` assumes all incoming
11
+ cookies are marshal-encoded. This is not the case when `secret_token` is
12
+ used in conjunction with the `:json` or `:hybrid` serializer.
13
+
14
+ In those case, when upgrading to use `secret_key_base`, this would cause a
15
+ `TypeError: incompatible marshal file format` and a 500 error for the user.
16
+
17
+ Fixes #14774.
18
+
19
+ *Godfrey Chan*
20
+
21
+ * `http_basic_authenticate_with` only check the autentication if the schema is
22
+ `Basic`.
23
+
24
+ Fixes #10257.
25
+
26
+ *tomykaira*
27
+
28
+ * Fix `'Stack level too deep'` when rendering `head :ok` in an action method
29
+ called 'status' in a controller.
30
+
31
+ Fixes #13905.
32
+
33
+ *Christiaan Van den Poel*
34
+
35
+ * Always use the provided port if the protocol is relative.
36
+
37
+ Fixes #15043.
38
+
39
+ *Guilherme Cavalcanti*, *Andrew White*
40
+
41
+ * Append link to bad code to backtrace when exception is `SyntaxError`.
42
+
43
+ *Boris Kuznetsov*
44
+
45
+ * Make URL escaping more consistent:
46
+
47
+ 1. Escape '%' characters in URLs - only unescaped data should be passed to URL helpers
48
+ 2. Add an `escape_segment` helper to `Router::Utils` that escapes '/' characters
49
+ 3. Use `escape_segment` rather than `escape_fragment` in optimized URL generation
50
+ 4. Use `escape_segment` rather than `escape_path` in URL generation
51
+
52
+ For point 4 there are two exceptions. Firstly, when a route uses wildcard segments
53
+ (e.g. `*foo`) then we use `escape_path` as the value may contain '/' characters. This
54
+ means that wildcard routes can't be optimized. Secondly, if a `:controller` segment
55
+ is used in the path then this uses `escape_path` as the controller may be namespaced.
56
+
57
+ Fixes #14629, #14636 and #14070.
58
+
59
+ *Andrew White*, *Edho Arief*
60
+
61
+ * Returns null type format when format is not know and controller is using `any`
62
+ format block.
63
+
64
+ Fixes #14462.
65
+
66
+ *Rafael Mendonça França*
67
+
68
+ * Only make deeply nested routes shallow when parent is shallow.
69
+
70
+ Fixes #14684.
71
+
72
+ *Andrew White*, *James Coglan*
73
+
74
+
1
75
  ## Rails 4.1.1 (May 6, 2014) ##
2
76
 
3
77
  * Only accept actions without File::SEPARATOR in the name.
@@ -18,6 +92,17 @@
18
92
 
19
93
  *Vishal Lal*
20
94
 
95
+ * The method `shallow?` returns false if the parent resource is a singleton so
96
+ we need to check if we're not inside a nested scope before copying the :path
97
+ and :as options to their shallow equivalents.
98
+
99
+ Fixes #14388.
100
+
101
+ *Andrew White*
102
+
103
+
104
+ ## Rails 4.1.0 (April 8, 2014) ##
105
+
21
106
  * Fix URL generation in controller tests with request-dependent
22
107
  `default_url_options` methods.
23
108
 
@@ -106,7 +106,9 @@ module AbstractController
106
106
  def _normalize_render(*args, &block)
107
107
  options = _normalize_args(*args, &block)
108
108
  #TODO: remove defined? when we restore AP <=> AV dependency
109
- options[:variant] = request.variant if defined?(request) && request.variant.present?
109
+ if defined?(request) && request && request.variant.present?
110
+ options[:variant] = request.variant
111
+ end
110
112
  _normalize_options(options)
111
113
  options
112
114
  end
@@ -70,7 +70,8 @@ module ActionController
70
70
  # can do the following:
71
71
  #
72
72
  # class HelloController < ActionController::Metal
73
- # include ActionController::Rendering
73
+ # include AbstractController::Rendering
74
+ # include ActionView::Layouts
74
75
  # append_view_path "#{Rails.root}/app/views"
75
76
  #
76
77
  # def index
@@ -231,5 +232,9 @@ module ActionController
231
232
  new.dispatch(name, klass.new(env))
232
233
  end
233
234
  end
235
+
236
+ def _status_code
237
+ @_status
238
+ end
234
239
  end
235
240
  end
@@ -27,7 +27,7 @@ module ActionController
27
27
  self.status = status
28
28
  self.location = url_for(location) if location
29
29
 
30
- if include_content?(self.status)
30
+ if include_content?(self._status_code)
31
31
  self.content_type = content_type || (Mime[formats.first] if formats)
32
32
  self.response.charset = false if self.response
33
33
  self.response_body = " "
@@ -90,17 +90,29 @@ module ActionController
90
90
  end
91
91
 
92
92
  def authenticate(request, &login_procedure)
93
- unless request.authorization.blank?
93
+ if has_basic_credentials?(request)
94
94
  login_procedure.call(*user_name_and_password(request))
95
95
  end
96
96
  end
97
97
 
98
+ def has_basic_credentials?(request)
99
+ request.authorization.present? && (auth_scheme(request) == 'Basic')
100
+ end
101
+
98
102
  def user_name_and_password(request)
99
- decode_credentials(request).split(/:/, 2)
103
+ decode_credentials(request).split(':', 2)
100
104
  end
101
105
 
102
106
  def decode_credentials(request)
103
- ::Base64.decode64(request.authorization.split(' ', 2).last || '')
107
+ ::Base64.decode64(auth_param(request) || '')
108
+ end
109
+
110
+ def auth_scheme(request)
111
+ request.authorization.split(' ', 2).first
112
+ end
113
+
114
+ def auth_param(request)
115
+ request.authorization.split(' ', 2).second
104
116
  end
105
117
 
106
118
  def encode_credentials(user_name, password)
@@ -6,7 +6,7 @@ module ActionController
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  delegate :headers, :status=, :location=, :content_type=,
9
- :status, :location, :content_type, :to => "@_response"
9
+ :status, :location, :content_type, :_status_code, :to => "@_response"
10
10
 
11
11
  def dispatch(action, request)
12
12
  set_response!(request)
@@ -502,7 +502,7 @@ module ActionController
502
502
  # end
503
503
  # end
504
504
  #
505
- # In order to use <tt>accepts_nested_attribute_for</tt> with Strong \Parameters, you
505
+ # In order to use <tt>accepts_nested_attributes_for</tt> with Strong \Parameters, you
506
506
  # will need to specify which nested attributes should be whitelisted.
507
507
  #
508
508
  # class Person
@@ -26,7 +26,9 @@ module ActionDispatch
26
26
  @env[env_name(key)] = value
27
27
  end
28
28
 
29
- def key?(key); @env.key? key; end
29
+ def key?(key)
30
+ @env.key? env_name(key)
31
+ end
30
32
  alias :include? :key?
31
33
 
32
34
  def fetch(key, *args, &block)
@@ -129,7 +129,7 @@ module ActionDispatch
129
129
  end
130
130
  end
131
131
 
132
- order.include?(Mime::ALL) ? formats.first : nil
132
+ order.include?(Mime::ALL) ? format : nil
133
133
  end
134
134
 
135
135
  protected
@@ -174,7 +174,7 @@ module Mime
174
174
  end
175
175
 
176
176
  def parse(accept_header)
177
- if accept_header !~ /,/
177
+ if !accept_header.include?(',')
178
178
  accept_header = accept_header.split(PARAMETER_SEPARATOR_REGEXP).first
179
179
  parse_trailing_star(accept_header) || [Mime::Type.lookup(accept_header)].compact
180
180
  else
@@ -296,6 +296,9 @@ module ActionDispatch # :nodoc:
296
296
  cookies
297
297
  end
298
298
 
299
+ def _status_code
300
+ @status
301
+ end
299
302
  private
300
303
 
301
304
  def before_committed
@@ -34,19 +34,15 @@ module ActionDispatch
34
34
  path = options.delete(:script_name).to_s.chomp("/")
35
35
  path << options.delete(:path).to_s
36
36
 
37
+ add_trailing_slash(path) if options[:trailing_slash]
38
+
37
39
  params = options[:params].is_a?(Hash) ? options[:params] : options.slice(:params)
38
40
  params.reject! { |_,v| v.to_param.nil? }
39
41
 
40
42
  result = build_host_url(options)
41
- if options[:trailing_slash]
42
- if path.include?('?')
43
- result << path.sub(/\?/, '/\&')
44
- else
45
- result << path.sub(/[^\/]\z|\A\z/, '\&/')
46
- end
47
- else
48
- result << path
49
- end
43
+
44
+ result << path
45
+
50
46
  result << "?#{params.to_query}" unless params.empty?
51
47
  result << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor]
52
48
  result
@@ -54,6 +50,18 @@ module ActionDispatch
54
50
 
55
51
  private
56
52
 
53
+ def add_trailing_slash(path)
54
+ # includes querysting
55
+ if path.include?('?')
56
+ path.sub!(/\?/, '/\&')
57
+ # does not have a .format
58
+ elsif !path.include?(".")
59
+ path.sub!(/[^\/]\z|\A\z/, '\&/')
60
+ end
61
+
62
+ path
63
+ end
64
+
57
65
  def build_host_url(options)
58
66
  if options[:host].blank? && options[:only_path].blank?
59
67
  raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true'
@@ -130,7 +138,7 @@ module ActionDispatch
130
138
 
131
139
  case options[:protocol]
132
140
  when "//"
133
- nil
141
+ options[:port]
134
142
  when "https://"
135
143
  options[:port].to_i == 443 ? nil : options[:port]
136
144
  else
@@ -101,6 +101,10 @@ module ActionDispatch
101
101
  end
102
102
  end
103
103
 
104
+ def glob?
105
+ !path.spec.grep(Nodes::Star).empty?
106
+ end
107
+
104
108
  def dispatcher?
105
109
  @dispatcher
106
110
  end
@@ -1,5 +1,3 @@
1
- require 'uri'
2
-
3
1
  module ActionDispatch
4
2
  module Journey # :nodoc:
5
3
  class Router # :nodoc:
@@ -25,31 +23,67 @@ module ActionDispatch
25
23
 
26
24
  # URI path and fragment escaping
27
25
  # http://tools.ietf.org/html/rfc3986
28
- module UriEscape # :nodoc:
29
- # Symbol captures can generate multiple path segments, so include /.
30
- reserved_segment = '/'
31
- reserved_fragment = '/?'
32
- reserved_pchar = ':@&=+$,;%'
33
-
34
- safe_pchar = "#{URI::REGEXP::PATTERN::UNRESERVED}#{reserved_pchar}"
35
- safe_segment = "#{safe_pchar}#{reserved_segment}"
36
- safe_fragment = "#{safe_pchar}#{reserved_fragment}"
37
- UNSAFE_SEGMENT = Regexp.new("[^#{safe_segment}]", false).freeze
38
- UNSAFE_FRAGMENT = Regexp.new("[^#{safe_fragment}]", false).freeze
26
+ class UriEncoder # :nodoc:
27
+ ENCODE = "%%%02X".freeze
28
+ ENCODING = Encoding::US_ASCII
29
+ EMPTY = "".force_encoding(ENCODING).freeze
30
+ DEC2HEX = (0..255).to_a.map{ |i| ENCODE % i }.map{ |s| s.force_encoding(ENCODING) }
31
+
32
+ ALPHA = "a-zA-Z".freeze
33
+ DIGIT = "0-9".freeze
34
+ UNRESERVED = "#{ALPHA}#{DIGIT}\\-\\._~".freeze
35
+ SUB_DELIMS = "!\\$&'\\(\\)\\*\\+,;=".freeze
36
+
37
+ ESCAPED = /%[a-zA-Z0-9]{2}/.freeze
38
+
39
+ FRAGMENT = /[^#{UNRESERVED}#{SUB_DELIMS}:@\/\?]/.freeze
40
+ SEGMENT = /[^#{UNRESERVED}#{SUB_DELIMS}:@]/.freeze
41
+ PATH = /[^#{UNRESERVED}#{SUB_DELIMS}:@\/]/.freeze
42
+
43
+ def escape_fragment(fragment)
44
+ escape(fragment, FRAGMENT)
45
+ end
46
+
47
+ def escape_path(path)
48
+ escape(path, PATH)
49
+ end
50
+
51
+ def escape_segment(segment)
52
+ escape(segment, SEGMENT)
53
+ end
54
+
55
+ def unescape_uri(uri)
56
+ uri.gsub(ESCAPED) { [$&[1, 2].hex].pack('C') }.force_encoding(uri.encoding)
57
+ end
58
+
59
+ protected
60
+ def escape(component, pattern)
61
+ component.gsub(pattern){ |unsafe| percent_encode(unsafe) }.force_encoding(ENCODING)
62
+ end
63
+
64
+ def percent_encode(unsafe)
65
+ safe = EMPTY.dup
66
+ unsafe.each_byte { |b| safe << DEC2HEX[b] }
67
+ safe
68
+ end
39
69
  end
40
70
 
41
- Parser = URI::Parser.new
71
+ ENCODER = UriEncoder.new
42
72
 
43
73
  def self.escape_path(path)
44
- Parser.escape(path.to_s, UriEscape::UNSAFE_SEGMENT)
74
+ ENCODER.escape_path(path.to_s)
75
+ end
76
+
77
+ def self.escape_segment(segment)
78
+ ENCODER.escape_segment(segment.to_s)
45
79
  end
46
80
 
47
81
  def self.escape_fragment(fragment)
48
- Parser.escape(fragment.to_s, UriEscape::UNSAFE_FRAGMENT)
82
+ ENCODER.escape_fragment(fragment.to_s)
49
83
  end
50
84
 
51
85
  def self.unescape_uri(uri)
52
- Parser.unescape(uri)
86
+ ENCODER.unescape_uri(uri)
53
87
  end
54
88
  end
55
89
  end
@@ -114,19 +114,26 @@ module ActionDispatch
114
114
  end
115
115
 
116
116
  private
117
+ def escape_path(value)
118
+ Router::Utils.escape_path(value)
119
+ end
120
+
121
+ def escape_segment(value)
122
+ Router::Utils.escape_segment(value)
123
+ end
117
124
 
118
125
  def visit(node, optional = false)
119
126
  case node.type
120
127
  when :LITERAL, :SLASH, :DOT
121
128
  node.left
122
129
  when :STAR
123
- visit(node.left)
130
+ visit_STAR(node.left)
124
131
  when :GROUP
125
132
  visit(node.left, true)
126
133
  when :CAT
127
134
  visit_CAT(node, optional)
128
135
  when :SYMBOL
129
- visit_SYMBOL(node)
136
+ visit_SYMBOL(node, node.to_sym)
130
137
  end
131
138
  end
132
139
 
@@ -141,9 +148,15 @@ module ActionDispatch
141
148
  end
142
149
  end
143
150
 
144
- def visit_SYMBOL(node)
151
+ def visit_STAR(node)
145
152
  if value = options[node.to_sym]
146
- Router::Utils.escape_path(value)
153
+ escape_path(value)
154
+ end
155
+ end
156
+
157
+ def visit_SYMBOL(node, name)
158
+ if value = options[name]
159
+ name == :controller ? escape_path(value) : escape_segment(value)
147
160
  end
148
161
  end
149
162
  end
@@ -176,11 +176,11 @@ module ActionDispatch
176
176
  module VerifyAndUpgradeLegacySignedMessage
177
177
  def initialize(*args)
178
178
  super
179
- @legacy_verifier = ActiveSupport::MessageVerifier.new(@options[:secret_token])
179
+ @legacy_verifier = ActiveSupport::MessageVerifier.new(@options[:secret_token], serializer: NullSerializer)
180
180
  end
181
181
 
182
182
  def verify_and_upgrade_legacy_signed_message(name, signed_message)
183
- @legacy_verifier.verify(signed_message).tap do |value|
183
+ deserialize(name, @legacy_verifier.verify(signed_message)).tap do |value|
184
184
  self[name] = { value: value }
185
185
  end
186
186
  rescue ActiveSupport::MessageVerifier::InvalidSignature
@@ -32,6 +32,8 @@ module ActionDispatch
32
32
  def initialize(env, exception)
33
33
  @env = env
34
34
  @exception = original_exception(exception)
35
+
36
+ expand_backtrace if exception.is_a?(SyntaxError) || exception.try(:original_exception).try(:is_a?, SyntaxError)
35
37
  end
36
38
 
37
39
  def rescue_template
@@ -104,5 +106,11 @@ module ActionDispatch
104
106
  end
105
107
  end
106
108
  end
109
+
110
+ def expand_backtrace
111
+ @exception.backtrace.unshift(
112
+ @exception.to_s.split("\n")
113
+ ).flatten!
114
+ end
107
115
  end
108
116
  end
@@ -32,11 +32,14 @@ module ActionDispatch
32
32
 
33
33
  private
34
34
  def redirect_to_https(request)
35
- url = URI(request.url)
36
- url.scheme = "https"
37
- url.host = @host if @host
38
- url.port = @port if @port
39
- headers = { 'Content-Type' => 'text/html', 'Location' => url.to_s }
35
+ host = @host || request.host
36
+ port = @port || request.port
37
+
38
+ location = "https://#{host}"
39
+ location << ":#{port}" if port != 80
40
+ location << request.fullpath
41
+
42
+ headers = { 'Content-Type' => 'text/html', 'Location' => location }
40
43
 
41
44
  [301, headers, []]
42
45
  end
@@ -122,7 +122,7 @@
122
122
  // On key press perform a search for matching paths
123
123
  pathElem.onkeyup = function(e){
124
124
  var path = sanitizePath(pathElem.value),
125
- defaultText = '<tr><th colspan="4">Paths Matching (' + path + '):</th></tr>';
125
+ defaultText = '<tr><th colspan="4">Paths Matching (' + escape(path) + '):</th></tr>';
126
126
 
127
127
  // Clear out results section
128
128
  selectedSection.innerHTML= defaultText;
@@ -1,6 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  require 'active_support/core_ext/object/to_param'
3
3
  require 'active_support/core_ext/regexp'
4
+ require 'active_support/dependencies/autoload'
4
5
 
5
6
  module ActionDispatch
6
7
  # The routing module provides URL rewriting in native Ruby. It's a way to
@@ -340,18 +340,35 @@ module ActionDispatch
340
340
  match '/', { :as => :root, :via => :get }.merge!(options)
341
341
  end
342
342
 
343
- # Matches a url pattern to one or more routes. Any symbols in a pattern
344
- # are interpreted as url query parameters and thus available as +params+
345
- # in an action:
343
+ # Matches a url pattern to one or more routes.
346
344
  #
345
+ # You should not use the `match` method in your router
346
+ # without specifying an HTTP method.
347
+ #
348
+ # If you want to expose your action to both GET and POST, use:
349
+ #
347
350
  # # sets :controller, :action and :id in params
348
- # match ':controller/:action/:id'
351
+ # match ':controller/:action/:id', via: [:get, :post]
352
+ #
353
+ # Note that +:controller+, +:action+, +:id+ are interpreted as url query
354
+ # parameters and thus available as +params+
355
+ # in an action.
356
+ #
357
+ # If you want to expose your action to GET, use `get` in the router:
358
+ #
359
+ # Instead of:
360
+ #
361
+ # match ":controller/:action/:id"
362
+ #
363
+ # Do:
364
+ #
365
+ # get ":controller/:action/:id"
349
366
  #
350
367
  # Two of these symbols are special, +:controller+ maps to the controller
351
368
  # and +:action+ to the controller's action. A pattern can also map
352
369
  # wildcard segments (globs) to params:
353
370
  #
354
- # match 'songs/*category/:title', to: 'songs#show'
371
+ # get 'songs/*category/:title', to: 'songs#show'
355
372
  #
356
373
  # # 'songs/rock/classic/stairway-to-heaven' sets
357
374
  # # params[:category] = 'rock/classic'
@@ -360,17 +377,17 @@ module ActionDispatch
360
377
  # When a pattern points to an internal route, the route's +:action+ and
361
378
  # +:controller+ should be set in options or hash shorthand. Examples:
362
379
  #
363
- # match 'photos/:id' => 'photos#show'
364
- # match 'photos/:id', to: 'photos#show'
365
- # match 'photos/:id', controller: 'photos', action: 'show'
380
+ # match 'photos/:id' => 'photos#show', via: [:get]
381
+ # match 'photos/:id', to: 'photos#show', via: [:get]
382
+ # match 'photos/:id', controller: 'photos', action: 'show', via: [:get]
366
383
  #
367
384
  # A pattern can also point to a +Rack+ endpoint i.e. anything that
368
385
  # responds to +call+:
369
386
  #
370
- # match 'photos/:id', to: lambda {|hash| [200, {}, ["Coming soon"]] }
371
- # match 'photos/:id', to: PhotoRackApp
387
+ # match 'photos/:id', to: lambda {|hash| [200, {}, ["Coming soon"]] }, via: [:get]
388
+ # match 'photos/:id', to: PhotoRackApp, via: [:get]
372
389
  # # Yes, controller actions are just rack endpoints
373
- # match 'photos/:id', to: PhotosController.action(:show)
390
+ # match 'photos/:id', to: PhotosController.action(:show), via: [:get]
374
391
  #
375
392
  # Because requesting various HTTP verbs with a single action has security
376
393
  # implications, you must either specify the actions in
@@ -393,7 +410,7 @@ module ActionDispatch
393
410
  # [:module]
394
411
  # The namespace for :controller.
395
412
  #
396
- # match 'path', to: 'c#a', module: 'sekret', controller: 'posts'
413
+ # match 'path', to: 'c#a', module: 'sekret', controller: 'posts', via: [:get]
397
414
  # # => Sekret::PostsController
398
415
  #
399
416
  # See <tt>Scoping#namespace</tt> for its scope equivalent.
@@ -412,9 +429,9 @@ module ActionDispatch
412
429
  # Points to a +Rack+ endpoint. Can be an object that responds to
413
430
  # +call+ or a string representing a controller's action.
414
431
  #
415
- # match 'path', to: 'controller#action'
416
- # match 'path', to: lambda { |env| [200, {}, ["Success!"]] }
417
- # match 'path', to: RackApp
432
+ # match 'path', to: 'controller#action', via: [:get]
433
+ # match 'path', to: lambda { |env| [200, {}, ["Success!"]] }, via: [:get]
434
+ # match 'path', to: RackApp, via: [:get]
418
435
  #
419
436
  # [:on]
420
437
  # Shorthand for wrapping routes in a specific RESTful context. Valid
@@ -439,14 +456,14 @@ module ActionDispatch
439
456
  # other than path can also be specified with any object
440
457
  # that responds to <tt>===</tt> (eg. String, Array, Range, etc.).
441
458
  #
442
- # match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }
459
+ # match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }, via: [:get]
443
460
  #
444
- # match 'json_only', constraints: { format: 'json' }
461
+ # match 'json_only', constraints: { format: 'json' }, via: [:get]
445
462
  #
446
463
  # class Whitelist
447
464
  # def matches?(request) request.remote_ip == '1.2.3.4' end
448
465
  # end
449
- # match 'path', to: 'c#a', constraints: Whitelist.new
466
+ # match 'path', to: 'c#a', constraints: Whitelist.new, via: [:get]
450
467
  #
451
468
  # See <tt>Scoping#constraints</tt> for more examples with its scope
452
469
  # equivalent.
@@ -455,7 +472,7 @@ module ActionDispatch
455
472
  # Sets defaults for parameters
456
473
  #
457
474
  # # Sets params[:format] to 'jpg' by default
458
- # match 'path', to: 'c#a', defaults: { format: 'jpg' }
475
+ # match 'path', to: 'c#a', defaults: { format: 'jpg' }, via: [:get]
459
476
  #
460
477
  # See <tt>Scoping#defaults</tt> for its scope equivalent.
461
478
  #
@@ -464,7 +481,7 @@ module ActionDispatch
464
481
  # false, the pattern matches any request prefixed with the given path.
465
482
  #
466
483
  # # Matches any request starting with 'path'
467
- # match 'path', to: 'c#a', anchor: false
484
+ # match 'path', to: 'c#a', anchor: false, via: [:get]
468
485
  #
469
486
  # [:format]
470
487
  # Allows you to specify the default value for optional +format+
@@ -707,7 +724,7 @@ module ActionDispatch
707
724
  options[:path] = args.flatten.join('/') if args.any?
708
725
  options[:constraints] ||= {}
709
726
 
710
- unless shallow?
727
+ unless nested_scope?
711
728
  options[:shallow_path] ||= options[:path] if options.key?(:path)
712
729
  options[:shallow_prefix] ||= options[:as] if options.key?(:as)
713
730
  end
@@ -991,6 +1008,7 @@ module ActionDispatch
991
1008
  @as = options[:as]
992
1009
  @param = (options[:param] || :id).to_sym
993
1010
  @options = options
1011
+ @shallow = false
994
1012
  end
995
1013
 
996
1014
  def default_actions
@@ -1051,6 +1069,13 @@ module ActionDispatch
1051
1069
  "#{path}/:#{nested_param}"
1052
1070
  end
1053
1071
 
1072
+ def shallow=(value)
1073
+ @shallow = value
1074
+ end
1075
+
1076
+ def shallow?
1077
+ @shallow
1078
+ end
1054
1079
  end
1055
1080
 
1056
1081
  class SingletonResource < Resource #:nodoc:
@@ -1357,7 +1382,7 @@ module ActionDispatch
1357
1382
  end
1358
1383
 
1359
1384
  with_scope_level(:nested) do
1360
- if shallow? && nesting_depth > 1
1385
+ if shallow? && shallow_nesting_depth > 1
1361
1386
  shallow_scope(parent_resource.nested_scope, nested_options) { yield }
1362
1387
  else
1363
1388
  scope(parent_resource.nested_scope, nested_options) { yield }
@@ -1547,6 +1572,10 @@ module ActionDispatch
1547
1572
  RESOURCE_METHOD_SCOPES.include? @scope[:scope_level]
1548
1573
  end
1549
1574
 
1575
+ def nested_scope? #:nodoc:
1576
+ @scope[:scope_level] == :nested
1577
+ end
1578
+
1550
1579
  def with_exclusive_scope
1551
1580
  begin
1552
1581
  old_name_prefix, old_path = @scope[:as], @scope[:path]
@@ -1568,6 +1597,7 @@ module ActionDispatch
1568
1597
  end
1569
1598
 
1570
1599
  def resource_scope(kind, resource) #:nodoc:
1600
+ resource.shallow = @scope[:shallow]
1571
1601
  old_resource, @scope[:scope_level_resource] = @scope[:scope_level_resource], resource
1572
1602
  @nesting.push(resource)
1573
1603
 
@@ -1592,6 +1622,10 @@ module ActionDispatch
1592
1622
  @nesting.size
1593
1623
  end
1594
1624
 
1625
+ def shallow_nesting_depth #:nodoc:
1626
+ @nesting.select(&:shallow?).size
1627
+ end
1628
+
1595
1629
  def param_constraint? #:nodoc:
1596
1630
  @scope[:constraints] && @scope[:constraints][parent_resource.param].is_a?(Regexp)
1597
1631
  end
@@ -1,11 +1,13 @@
1
1
  require 'action_dispatch/journey'
2
2
  require 'forwardable'
3
3
  require 'thread_safe'
4
+ require 'active_support/concern'
4
5
  require 'active_support/core_ext/object/to_query'
5
6
  require 'active_support/core_ext/hash/slice'
6
7
  require 'active_support/core_ext/module/remove_method'
7
8
  require 'active_support/core_ext/array/extract_options'
8
9
  require 'action_controller/metal/exceptions'
10
+ require 'action_dispatch/http/request'
9
11
 
10
12
  module ActionDispatch
11
13
  module Routing
@@ -155,7 +157,7 @@ module ActionDispatch
155
157
  end
156
158
 
157
159
  def self.optimize_helper?(route)
158
- route.requirements.except(:controller, :action).empty?
160
+ !route.glob? && route.requirements.except(:controller, :action).empty?
159
161
  end
160
162
 
161
163
  class OptimizedUrlHelper < UrlHelper # :nodoc:
@@ -194,7 +196,7 @@ module ActionDispatch
194
196
  end
195
197
 
196
198
  def replace_segment(params, segment)
197
- Symbol === segment ? @klass.escape_fragment(params[segment]) : segment
199
+ Symbol === segment ? @klass.escape_segment(params[segment]) : segment
198
200
  end
199
201
 
200
202
  def optimize_routes_generation?(t)
@@ -73,7 +73,13 @@ module ActionDispatch
73
73
  if Regexp === fragment
74
74
  fragment
75
75
  else
76
- @controller._compute_redirect_to_location(fragment)
76
+ handle = @controller || Class.new(ActionController::Metal) do
77
+ include ActionController::Redirecting
78
+ def initialize(request)
79
+ @_request = request
80
+ end
81
+ end.new(@request)
82
+ handle._compute_redirect_to_location(fragment)
77
83
  end
78
84
  end
79
85
  end
@@ -267,7 +267,7 @@ module ActionDispatch
267
267
  text.strip! unless NO_STRIP.include?(match.name)
268
268
  text.sub!(/\A\n/, '') if match.name == "textarea"
269
269
  unless match_with.is_a?(Regexp) ? (text =~ match_with) : (text == match_with.to_s)
270
- content_mismatch ||= sprintf("<%s> expected but was\n<%s>.", match_with, text)
270
+ content_mismatch ||= sprintf("<%s> expected but was\n<%s>", match_with, text)
271
271
  true
272
272
  end
273
273
  end
@@ -276,7 +276,7 @@ module ActionDispatch
276
276
  html = match.children.map(&:to_s).join
277
277
  html.strip! unless NO_STRIP.include?(match.name)
278
278
  unless match_with.is_a?(Regexp) ? (html =~ match_with) : (html == match_with.to_s)
279
- content_mismatch ||= sprintf("<%s> expected but was\n<%s>.", match_with, html)
279
+ content_mismatch ||= sprintf("<%s> expected but was\n<%s>", match_with, html)
280
280
  true
281
281
  end
282
282
  end
@@ -289,7 +289,7 @@ module ActionDispatch
289
289
 
290
290
  # FIXME: minitest provides messaging when we use assert_operator,
291
291
  # so is this custom message really needed?
292
- message = message || %(Expected #{count_description(min, max, count)} matching "#{selector.to_s}", found #{matches.size}.)
292
+ message = message || %(Expected #{count_description(min, max, count)} matching "#{selector.to_s}", found #{matches.size})
293
293
  if count
294
294
  assert_equal count, matches.size, message
295
295
  else
@@ -7,8 +7,8 @@ module ActionPack
7
7
  module VERSION
8
8
  MAJOR = 4
9
9
  MINOR = 1
10
- TINY = 1
11
- PRE = nil
10
+ TINY = 2
11
+ PRE = "rc1"
12
12
 
13
13
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
14
14
  end
metadata CHANGED
@@ -1,96 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
5
- prerelease:
4
+ version: 4.1.2.rc1
6
5
  platform: ruby
7
6
  authors:
8
7
  - David Heinemeier Hansson
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2014-05-06 00:00:00.000000000 Z
11
+ date: 2014-05-27 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activesupport
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - '='
20
18
  - !ruby/object:Gem::Version
21
- version: 4.1.1
19
+ version: 4.1.2.rc1
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - '='
28
25
  - !ruby/object:Gem::Version
29
- version: 4.1.1
26
+ version: 4.1.2.rc1
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rack
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
33
  version: 1.5.2
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
40
  version: 1.5.2
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rack-test
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
47
  version: 0.6.2
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ~>
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
54
  version: 0.6.2
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: actionview
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - '='
68
60
  - !ruby/object:Gem::Version
69
- version: 4.1.1
61
+ version: 4.1.2.rc1
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - '='
76
67
  - !ruby/object:Gem::Version
77
- version: 4.1.1
68
+ version: 4.1.2.rc1
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: activemodel
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - '='
84
74
  - !ruby/object:Gem::Version
85
- version: 4.1.1
75
+ version: 4.1.2.rc1
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - '='
92
81
  - !ruby/object:Gem::Version
93
- version: 4.1.1
82
+ version: 4.1.2.rc1
94
83
  description: Web apps on Rails. Simple, battle-tested conventions for building and
95
84
  testing MVC web applications. Works with any Rack-compatible server.
96
85
  email: david@loudthinking.com
@@ -99,8 +88,9 @@ extensions: []
99
88
  extra_rdoc_files: []
100
89
  files:
101
90
  - CHANGELOG.md
102
- - README.rdoc
103
91
  - MIT-LICENSE
92
+ - README.rdoc
93
+ - lib/abstract_controller.rb
104
94
  - lib/abstract_controller/asset_paths.rb
105
95
  - lib/abstract_controller/base.rb
106
96
  - lib/abstract_controller/callbacks.rb
@@ -111,11 +101,12 @@ files:
111
101
  - lib/abstract_controller/rendering.rb
112
102
  - lib/abstract_controller/translation.rb
113
103
  - lib/abstract_controller/url_for.rb
114
- - lib/abstract_controller.rb
104
+ - lib/action_controller.rb
115
105
  - lib/action_controller/base.rb
116
- - lib/action_controller/caching/fragments.rb
117
106
  - lib/action_controller/caching.rb
107
+ - lib/action_controller/caching/fragments.rb
118
108
  - lib/action_controller/log_subscriber.rb
109
+ - lib/action_controller/metal.rb
119
110
  - lib/action_controller/metal/conditional_get.rb
120
111
  - lib/action_controller/metal/cookies.rb
121
112
  - lib/action_controller/metal/data_streaming.rb
@@ -142,13 +133,12 @@ files:
142
133
  - lib/action_controller/metal/strong_parameters.rb
143
134
  - lib/action_controller/metal/testing.rb
144
135
  - lib/action_controller/metal/url_for.rb
145
- - lib/action_controller/metal.rb
146
136
  - lib/action_controller/middleware.rb
147
137
  - lib/action_controller/model_naming.rb
148
138
  - lib/action_controller/railtie.rb
149
139
  - lib/action_controller/railties/helpers.rb
150
140
  - lib/action_controller/test_case.rb
151
- - lib/action_controller.rb
141
+ - lib/action_dispatch.rb
152
142
  - lib/action_dispatch/http/cache.rb
153
143
  - lib/action_dispatch/http/filter_parameters.rb
154
144
  - lib/action_dispatch/http/filter_redirect.rb
@@ -163,6 +153,7 @@ files:
163
153
  - lib/action_dispatch/http/response.rb
164
154
  - lib/action_dispatch/http/upload.rb
165
155
  - lib/action_dispatch/http/url.rb
156
+ - lib/action_dispatch/journey.rb
166
157
  - lib/action_dispatch/journey/backwards.rb
167
158
  - lib/action_dispatch/journey/formatter.rb
168
159
  - lib/action_dispatch/journey/gtg/builder.rb
@@ -178,16 +169,15 @@ files:
178
169
  - lib/action_dispatch/journey/parser_extras.rb
179
170
  - lib/action_dispatch/journey/path/pattern.rb
180
171
  - lib/action_dispatch/journey/route.rb
172
+ - lib/action_dispatch/journey/router.rb
181
173
  - lib/action_dispatch/journey/router/strexp.rb
182
174
  - lib/action_dispatch/journey/router/utils.rb
183
- - lib/action_dispatch/journey/router.rb
184
175
  - lib/action_dispatch/journey/routes.rb
185
176
  - lib/action_dispatch/journey/scanner.rb
186
177
  - lib/action_dispatch/journey/visitors.rb
187
178
  - lib/action_dispatch/journey/visualizer/fsm.css
188
179
  - lib/action_dispatch/journey/visualizer/fsm.js
189
180
  - lib/action_dispatch/journey/visualizer/index.html.erb
190
- - lib/action_dispatch/journey.rb
191
181
  - lib/action_dispatch/middleware/callbacks.rb
192
182
  - lib/action_dispatch/middleware/cookies.rb
193
183
  - lib/action_dispatch/middleware/debug_exceptions.rb
@@ -226,6 +216,7 @@ files:
226
216
  - lib/action_dispatch/railtie.rb
227
217
  - lib/action_dispatch/request/session.rb
228
218
  - lib/action_dispatch/request/utils.rb
219
+ - lib/action_dispatch/routing.rb
229
220
  - lib/action_dispatch/routing/inspector.rb
230
221
  - lib/action_dispatch/routing/mapper.rb
231
222
  - lib/action_dispatch/routing/polymorphic_routes.rb
@@ -233,45 +224,42 @@ files:
233
224
  - lib/action_dispatch/routing/route_set.rb
234
225
  - lib/action_dispatch/routing/routes_proxy.rb
235
226
  - lib/action_dispatch/routing/url_for.rb
236
- - lib/action_dispatch/routing.rb
227
+ - lib/action_dispatch/testing/assertions.rb
237
228
  - lib/action_dispatch/testing/assertions/dom.rb
238
229
  - lib/action_dispatch/testing/assertions/response.rb
239
230
  - lib/action_dispatch/testing/assertions/routing.rb
240
231
  - lib/action_dispatch/testing/assertions/selector.rb
241
232
  - lib/action_dispatch/testing/assertions/tag.rb
242
- - lib/action_dispatch/testing/assertions.rb
243
233
  - lib/action_dispatch/testing/integration.rb
244
234
  - lib/action_dispatch/testing/test_process.rb
245
235
  - lib/action_dispatch/testing/test_request.rb
246
236
  - lib/action_dispatch/testing/test_response.rb
247
- - lib/action_dispatch.rb
237
+ - lib/action_pack.rb
248
238
  - lib/action_pack/gem_version.rb
249
239
  - lib/action_pack/version.rb
250
- - lib/action_pack.rb
251
240
  homepage: http://www.rubyonrails.org
252
241
  licenses:
253
242
  - MIT
243
+ metadata: {}
254
244
  post_install_message:
255
245
  rdoc_options: []
256
246
  require_paths:
257
247
  - lib
258
248
  required_ruby_version: !ruby/object:Gem::Requirement
259
- none: false
260
249
  requirements:
261
- - - ! '>='
250
+ - - ">="
262
251
  - !ruby/object:Gem::Version
263
252
  version: 1.9.3
264
253
  required_rubygems_version: !ruby/object:Gem::Requirement
265
- none: false
266
254
  requirements:
267
- - - ! '>='
255
+ - - ">"
268
256
  - !ruby/object:Gem::Version
269
- version: '0'
257
+ version: 1.3.1
270
258
  requirements:
271
259
  - none
272
260
  rubyforge_project:
273
- rubygems_version: 1.8.23.2
261
+ rubygems_version: 2.2.2
274
262
  signing_key:
275
- specification_version: 3
263
+ specification_version: 4
276
264
  summary: Web-flow and rendering framework putting the VC in MVC (part of Rails).
277
265
  test_files: []