actionpack 3.0.0.beta → 3.0.0.beta2

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 (118) hide show
  1. data/CHANGELOG +291 -260
  2. data/lib/abstract_controller.rb +5 -2
  3. data/lib/abstract_controller/assigns.rb +21 -0
  4. data/lib/abstract_controller/base.rb +13 -5
  5. data/lib/abstract_controller/collector.rb +2 -0
  6. data/lib/abstract_controller/helpers.rb +4 -14
  7. data/lib/abstract_controller/layouts.rb +50 -99
  8. data/lib/abstract_controller/logger.rb +2 -2
  9. data/lib/abstract_controller/rendering.rb +105 -173
  10. data/lib/abstract_controller/view_paths.rb +69 -0
  11. data/lib/action_controller.rb +1 -2
  12. data/lib/action_controller/base.rb +10 -32
  13. data/lib/action_controller/caching.rb +19 -18
  14. data/lib/action_controller/caching/actions.rb +17 -11
  15. data/lib/action_controller/caching/fragments.rb +5 -17
  16. data/lib/action_controller/caching/pages.rb +24 -24
  17. data/lib/action_controller/caching/sweeping.rb +1 -3
  18. data/lib/action_controller/deprecated.rb +0 -2
  19. data/lib/action_controller/deprecated/base.rb +143 -0
  20. data/lib/action_controller/metal.rb +29 -26
  21. data/lib/action_controller/metal/compatibility.rb +18 -87
  22. data/lib/action_controller/metal/cookies.rb +0 -1
  23. data/lib/action_controller/metal/head.rb +1 -0
  24. data/lib/action_controller/metal/helpers.rb +2 -2
  25. data/lib/action_controller/metal/hide_actions.rb +4 -6
  26. data/lib/action_controller/metal/http_authentication.rb +18 -33
  27. data/lib/action_controller/metal/implicit_render.rb +21 -0
  28. data/lib/action_controller/metal/instrumentation.rb +1 -1
  29. data/lib/action_controller/metal/mime_responds.rb +2 -1
  30. data/lib/action_controller/metal/rack_delegation.rb +3 -8
  31. data/lib/action_controller/metal/redirecting.rb +2 -1
  32. data/lib/action_controller/metal/renderers.rb +4 -2
  33. data/lib/action_controller/metal/rendering.rb +31 -44
  34. data/lib/action_controller/metal/request_forgery_protection.rb +41 -4
  35. data/lib/action_controller/metal/responder.rb +2 -0
  36. data/lib/action_controller/metal/session_management.rb +0 -36
  37. data/lib/action_controller/metal/streaming.rb +20 -47
  38. data/lib/action_controller/metal/testing.rb +0 -1
  39. data/lib/action_controller/metal/url_for.rb +11 -148
  40. data/lib/action_controller/middleware.rb +2 -1
  41. data/lib/action_controller/polymorphic_routes.rb +1 -2
  42. data/lib/action_controller/railtie.rb +63 -10
  43. data/lib/action_controller/railties/{subscriber.rb → log_subscriber.rb} +5 -12
  44. data/lib/action_controller/railties/url_helpers.rb +14 -0
  45. data/lib/action_controller/record_identifier.rb +20 -1
  46. data/lib/action_controller/test_case.rb +123 -12
  47. data/lib/action_dispatch.rb +1 -0
  48. data/lib/action_dispatch/http/cache.rb +20 -3
  49. data/lib/action_dispatch/http/filter_parameters.rb +40 -25
  50. data/lib/action_dispatch/http/mime_negotiation.rb +6 -17
  51. data/lib/action_dispatch/http/mime_type.rb +2 -7
  52. data/lib/action_dispatch/http/request.rb +12 -33
  53. data/lib/action_dispatch/http/response.rb +35 -15
  54. data/lib/action_dispatch/http/upload.rb +2 -0
  55. data/lib/action_dispatch/http/url.rb +5 -32
  56. data/lib/action_dispatch/middleware/callbacks.rb +1 -1
  57. data/lib/action_dispatch/middleware/cookies.rb +4 -3
  58. data/lib/action_dispatch/middleware/params_parser.rb +4 -3
  59. data/lib/action_dispatch/middleware/remote_ip.rb +51 -0
  60. data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -0
  61. data/lib/action_dispatch/middleware/session/cookie_store.rb +6 -8
  62. data/lib/action_dispatch/middleware/show_exceptions.rb +0 -14
  63. data/lib/action_dispatch/middleware/stack.rb +6 -2
  64. data/lib/action_dispatch/railtie.rb +3 -1
  65. data/lib/action_dispatch/routing.rb +2 -0
  66. data/lib/action_dispatch/routing/deprecated_mapper.rb +35 -7
  67. data/lib/action_dispatch/routing/mapper.rb +134 -48
  68. data/lib/action_dispatch/routing/route.rb +2 -2
  69. data/lib/action_dispatch/routing/route_set.rb +217 -158
  70. data/lib/action_dispatch/routing/url_for.rb +139 -0
  71. data/lib/action_dispatch/testing/assertions/response.rb +14 -61
  72. data/lib/action_dispatch/testing/assertions/routing.rb +25 -14
  73. data/lib/action_dispatch/testing/integration.rb +32 -50
  74. data/lib/action_dispatch/testing/performance_test.rb +3 -1
  75. data/lib/action_dispatch/testing/test_process.rb +2 -0
  76. data/lib/action_dispatch/testing/test_request.rb +2 -0
  77. data/lib/action_pack/version.rb +4 -3
  78. data/lib/action_view.rb +11 -6
  79. data/lib/action_view/base.rb +33 -121
  80. data/lib/action_view/context.rb +0 -2
  81. data/lib/action_view/helpers.rb +26 -23
  82. data/lib/action_view/helpers/active_model_helper.rb +28 -18
  83. data/lib/action_view/helpers/asset_tag_helper.rb +109 -54
  84. data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
  85. data/lib/action_view/helpers/cache_helper.rb +22 -1
  86. data/lib/action_view/helpers/capture_helper.rb +22 -22
  87. data/lib/action_view/helpers/date_helper.rb +6 -5
  88. data/lib/action_view/helpers/form_helper.rb +78 -63
  89. data/lib/action_view/helpers/form_options_helper.rb +6 -4
  90. data/lib/action_view/helpers/form_tag_helper.rb +26 -15
  91. data/lib/action_view/helpers/javascript_helper.rb +90 -10
  92. data/lib/action_view/helpers/number_helper.rb +315 -118
  93. data/lib/action_view/helpers/prototype_helper.rb +19 -46
  94. data/lib/action_view/helpers/record_tag_helper.rb +4 -4
  95. data/lib/action_view/helpers/tag_helper.rb +7 -24
  96. data/lib/action_view/helpers/text_helper.rb +8 -7
  97. data/lib/action_view/helpers/translation_helper.rb +7 -5
  98. data/lib/action_view/helpers/url_helper.rb +19 -16
  99. data/lib/action_view/locale/en.yml +45 -6
  100. data/lib/action_view/lookup_context.rb +190 -0
  101. data/lib/action_view/paths.rb +22 -63
  102. data/lib/action_view/railtie.rb +14 -4
  103. data/lib/action_view/railties/{subscriber.rb → log_subscriber.rb} +1 -1
  104. data/lib/action_view/render/layouts.rb +73 -0
  105. data/lib/action_view/render/partials.rb +15 -41
  106. data/lib/action_view/render/rendering.rb +27 -78
  107. data/lib/action_view/template.rb +20 -24
  108. data/lib/action_view/template/error.rb +22 -2
  109. data/lib/action_view/template/handlers/erb.rb +33 -9
  110. data/lib/action_view/template/handlers/rjs.rb +1 -2
  111. data/lib/action_view/template/resolver.rb +46 -104
  112. data/lib/action_view/template/text.rb +5 -12
  113. data/lib/action_view/test_case.rb +14 -23
  114. metadata +83 -40
  115. data/lib/abstract_controller/compatibility.rb +0 -18
  116. data/lib/abstract_controller/localized_cache.rb +0 -49
  117. data/lib/action_controller/metal/configuration.rb +0 -28
  118. data/lib/action_controller/url_rewriter.rb +0 -76
@@ -20,7 +20,7 @@ module ActionController
20
20
  :params => request.filtered_parameters,
21
21
  :formats => request.formats.map(&:to_sym),
22
22
  :method => request.method,
23
- :path => (request.request_uri rescue "unknown")
23
+ :path => (request.fullpath rescue "unknown")
24
24
  }
25
25
 
26
26
  ActiveSupport::Notifications.instrument("action_controller.start_processing", raw_payload.dup)
@@ -261,7 +261,8 @@ module ActionController #:nodoc:
261
261
  block.call(collector) if block_given?
262
262
 
263
263
  if format = request.negotiate_mime(collector.order)
264
- self.formats = [format.to_sym]
264
+ self.content_type ||= format.to_s
265
+ lookup_context.freeze_formats([format.to_sym])
265
266
  collector.response_for(format)
266
267
  else
267
268
  head :not_acceptable
@@ -5,15 +5,10 @@ module ActionController
5
5
  module RackDelegation
6
6
  extend ActiveSupport::Concern
7
7
 
8
- included do
9
- delegate :session, :to => "@_request"
10
- delegate :headers, :status=, :location=, :content_type=,
11
- :status, :location, :content_type, :to => "@_response"
12
- attr_internal :request
13
- end
8
+ delegate :headers, :status=, :location=, :content_type=,
9
+ :status, :location, :content_type, :to => "@_response"
14
10
 
15
- def dispatch(action, env)
16
- @_request = ActionDispatch::Request.new(env)
11
+ def dispatch(action, request)
17
12
  @_response = ActionDispatch::Response.new
18
13
  @_response.request = request
19
14
  super
@@ -11,6 +11,7 @@ module ActionController
11
11
  extend ActiveSupport::Concern
12
12
 
13
13
  include AbstractController::Logger
14
+ include ActionController::RackDelegation
14
15
  include ActionController::UrlFor
15
16
 
16
17
  # Redirects the browser to the target specified in +options+. This parameter can take one of three forms:
@@ -75,7 +76,7 @@ module ActionController
75
76
  # The scheme name consist of a letter followed by any combination of
76
77
  # letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
77
78
  # characters; and is terminated by a colon (":").
78
- when %r{^\w[\w\d+.-]*:.*}
79
+ when %r{^\w[\w+.-]*:.*}
79
80
  options
80
81
  when String
81
82
  request.protocol + request.host_with_port + options
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/class/attribute'
2
+ require 'active_support/core_ext/object/blank'
2
3
 
3
4
  module ActionController
4
5
  def self.add_renderer(key, &block)
@@ -19,7 +20,7 @@ module ActionController
19
20
  <<-RUBY_EVAL
20
21
  if options.key?(:#{name})
21
22
  _process_options(options)
22
- return _render_option_#{name}(options[:#{name}], options)
23
+ return _render_option_#{name}(options.delete(:#{name}), options)
23
24
  end
24
25
  RUBY_EVAL
25
26
  end
@@ -87,8 +88,9 @@ module ActionController
87
88
  end
88
89
 
89
90
  add :update do |proc, options|
91
+ view_context = self.view_context
90
92
  generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc)
91
- self.content_type = Mime::JS
93
+ self.content_type = Mime::JS
92
94
  self.response_body = generator.to_s
93
95
  end
94
96
  end
@@ -2,68 +2,55 @@ module ActionController
2
2
  module Rendering
3
3
  extend ActiveSupport::Concern
4
4
 
5
- included do
6
- include AbstractController::Rendering
7
- include AbstractController::LocalizedCache
8
- end
5
+ include ActionController::RackDelegation
6
+ include AbstractController::Rendering
9
7
 
10
- def process_action(*)
11
- self.formats = request.formats.map {|x| x.to_sym}
8
+ # Before processing, set the request formats in current controller formats.
9
+ def process_action(*) #:nodoc:
10
+ self.formats = request.formats.map { |x| x.to_sym }
12
11
  super
13
12
  end
14
13
 
15
- def render(*args)
16
- if response_body
17
- raise ::AbstractController::DoubleRenderError
18
- end
19
-
20
- args << {} unless args.last.is_a?(Hash)
21
- super(*args)
22
- self.content_type ||= args.last[:_template].mime_type.to_s
23
- response_body
24
- end
25
-
26
- def render_to_body(options)
27
- _process_options(options)
14
+ # Check for double render errors and set the content_type after rendering.
15
+ def render(*args) #:nodoc:
16
+ raise ::AbstractController::DoubleRenderError if response_body
28
17
  super
18
+ self.content_type ||= Mime[formats.first].to_s
19
+ response_body
29
20
  end
30
21
 
31
22
  private
32
23
 
33
- def _render_partial(options)
34
- options[:partial] = action_name if options[:partial] == true
35
- options[:_details] = {:formats => formats}
36
- super
24
+ # Normalize arguments by catching blocks and setting them on :update.
25
+ def _normalize_args(action=nil, options={}, &blk) #:nodoc:
26
+ options = super
27
+ options[:update] = blk if block_given?
28
+ options
37
29
  end
38
30
 
39
- def format_for_text
40
- formats.first
31
+ # Normalize both text and status options.
32
+ def _normalize_options(options) #:nodoc:
33
+ if options.key?(:text) && options[:text].respond_to?(:to_text)
34
+ options[:text] = options[:text].to_text
35
+ end
36
+
37
+ if options[:status]
38
+ options[:status] = Rack::Utils.status_code(options[:status])
39
+ end
40
+
41
+ super
41
42
  end
42
43
 
43
- def _process_options(options)
44
+ # Process controller specific options, as status, content-type and location.
45
+ def _process_options(options) #:nodoc:
44
46
  status, content_type, location = options.values_at(:status, :content_type, :location)
47
+
45
48
  self.status = status if status
46
49
  self.content_type = content_type if content_type
47
50
  self.headers["Location"] = url_for(location) if location
48
- end
49
-
50
- def _normalize_options(action=nil, options={}, &blk)
51
- case action
52
- when NilClass
53
- when Hash
54
- options = super(action.delete(:action), action)
55
- when String, Symbol
56
- options = super
57
- else
58
- options.merge! :partial => action
59
- end
60
-
61
- if options[:status]
62
- options[:status] = Rack::Utils.status_code(options[:status])
63
- end
64
51
 
65
- options[:update] = blk if block_given?
66
- options
52
+ super
67
53
  end
54
+
68
55
  end
69
56
  end
@@ -12,11 +12,10 @@ module ActionController #:nodoc:
12
12
  included do
13
13
  # Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+
14
14
  # sets it to <tt>:authenticity_token</tt> by default.
15
- cattr_accessor :request_forgery_protection_token
15
+ config.request_forgery_protection_token ||= :authenticity_token
16
16
 
17
17
  # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode.
18
- class_attribute :allow_forgery_protection
19
- self.allow_forgery_protection = true
18
+ config.allow_forgery_protection ||= true
20
19
 
21
20
  helper_method :form_authenticity_token
22
21
  helper_method :protect_against_forgery?
@@ -80,9 +79,47 @@ module ActionController #:nodoc:
80
79
  self.request_forgery_protection_token ||= :authenticity_token
81
80
  before_filter :verify_authenticity_token, options
82
81
  end
82
+
83
+ def request_forgery_protection_token
84
+ config.request_forgery_protection_token
85
+ end
86
+
87
+ def request_forgery_protection_token=(val)
88
+ config.request_forgery_protection_token = val
89
+ end
90
+
91
+ def allow_forgery_protection
92
+ config.allow_forgery_protection
93
+ end
94
+
95
+ def allow_forgery_protection=(val)
96
+ config.allow_forgery_protection = val
97
+ end
83
98
  end
84
99
 
85
100
  protected
101
+
102
+ def protect_from_forgery(options = {})
103
+ self.request_forgery_protection_token ||= :authenticity_token
104
+ before_filter :verify_authenticity_token, options
105
+ end
106
+
107
+ def request_forgery_protection_token
108
+ config.request_forgery_protection_token
109
+ end
110
+
111
+ def request_forgery_protection_token=(val)
112
+ config.request_forgery_protection_token = val
113
+ end
114
+
115
+ def allow_forgery_protection
116
+ config.allow_forgery_protection
117
+ end
118
+
119
+ def allow_forgery_protection=(val)
120
+ config.allow_forgery_protection = val
121
+ end
122
+
86
123
  # The actual before_filter that is used. Modify this to change how you handle unverified requests.
87
124
  def verify_authenticity_token
88
125
  verified_request? || raise(ActionController::InvalidAuthenticityToken)
@@ -109,7 +146,7 @@ module ActionController #:nodoc:
109
146
  end
110
147
 
111
148
  def protect_against_forgery?
112
- self.class.allow_forgery_protection
149
+ config.allow_forgery_protection
113
150
  end
114
151
  end
115
152
  end
@@ -1,3 +1,5 @@
1
+ require 'active_support/json'
2
+
1
3
  module ActionController #:nodoc:
2
4
  # Responder is responsible for exposing a resource to different mime requests,
3
5
  # usually depending on the HTTP verb. The responder is triggered when
@@ -2,44 +2,8 @@ module ActionController #:nodoc:
2
2
  module SessionManagement #:nodoc:
3
3
  extend ActiveSupport::Concern
4
4
 
5
- include ActionController::Configuration
6
-
7
5
  module ClassMethods
8
- # Set the session store to be used for keeping the session data between requests.
9
- # By default, sessions are stored in browser cookies (<tt>:cookie_store</tt>),
10
- # but you can also specify one of the other included stores (<tt>:active_record_store</tt>,
11
- # <tt>:mem_cache_store</tt>, or your own custom class.
12
- def session_store=(store)
13
- if store == :active_record_store
14
- self.session_store = ActiveRecord::SessionStore
15
- else
16
- @@session_store = store.is_a?(Symbol) ?
17
- ActionDispatch::Session.const_get(store.to_s.camelize) :
18
- store
19
- end
20
- end
21
-
22
- # Returns the session store class currently used.
23
- def session_store
24
- if defined? @@session_store
25
- @@session_store
26
- else
27
- ActionDispatch::Session::CookieStore
28
- end
29
- end
30
-
31
- def session=(options = {})
32
- self.session_store = nil if options.delete(:disabled)
33
- session_options.merge!(options)
34
- end
35
6
 
36
- def session(*args)
37
- ActiveSupport::Deprecation.warn(
38
- "Disabling sessions for a single controller has been deprecated. " +
39
- "Sessions are now lazy loaded. So if you don't access them, " +
40
- "consider them off. You can still modify the session cookie " +
41
- "options with request.session_options.", caller)
42
- end
43
7
  end
44
8
  end
45
9
  end
@@ -9,18 +9,13 @@ module ActionController #:nodoc:
9
9
  DEFAULT_SEND_FILE_OPTIONS = {
10
10
  :type => 'application/octet-stream'.freeze,
11
11
  :disposition => 'attachment'.freeze,
12
- :stream => true,
13
- :buffer_size => 4096,
14
- :x_sendfile => false
15
12
  }.freeze
16
13
 
17
- X_SENDFILE_HEADER = 'X-Sendfile'.freeze
18
-
19
14
  protected
20
- # Sends the file, by default streaming it 4096 bytes at a time. This way the
21
- # whole file doesn't need to be read into memory at once. This makes it
22
- # feasible to send even large files. You can optionally turn off streaming
23
- # and send the whole file at once.
15
+ # Sends the file. This uses a server-appropriate method (such as X-Sendfile)
16
+ # via the Rack::Sendfile middleware. The header to use is set via
17
+ # config.action_dispatch.x_sendfile_header, and defaults to "X-Sendfile".
18
+ # Your server can also configure this for you by setting the X-Sendfile-Type header.
24
19
  #
25
20
  # Be careful to sanitize the path parameter if it is coming from a web
26
21
  # page. <tt>send_file(params[:path])</tt> allows a malicious user to
@@ -31,24 +26,12 @@ module ActionController #:nodoc:
31
26
  # Defaults to <tt>File.basename(path)</tt>.
32
27
  # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify
33
28
  # either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json
34
- # * <tt>:length</tt> - used to manually override the length (in bytes) of the content that
35
- # is going to be sent to the client. Defaults to <tt>File.size(path)</tt>.
36
29
  # * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
37
30
  # Valid values are 'inline' and 'attachment' (default).
38
- # * <tt>:stream</tt> - whether to send the file to the user agent as it is read (+true+)
39
- # or to read the entire file before sending (+false+). Defaults to +true+.
40
- # * <tt>:buffer_size</tt> - specifies size (in bytes) of the buffer used to stream the file.
41
- # Defaults to 4096.
42
31
  # * <tt>:status</tt> - specifies the status code to send with the response. Defaults to '200 OK'.
43
32
  # * <tt>:url_based_filename</tt> - set to +true+ if you want the browser guess the filename from
44
33
  # the URL, which is necessary for i18n filenames on certain browsers
45
34
  # (setting <tt>:filename</tt> overrides this option).
46
- # * <tt>:x_sendfile</tt> - uses X-Sendfile to send the file when set to +true+. This is currently
47
- # only available with Lighttpd/Apache2 and specific modules installed and activated. Since this
48
- # uses the web server to send the file, this may lower memory consumption on your server and
49
- # it will not block your application for further requests.
50
- # See http://blog.lighttpd.net/articles/2006/07/02/x-sendfile and
51
- # http://tn123.ath.cx/mod_xsendfile/ for details. Defaults to +false+.
52
35
  #
53
36
  # The default Content-Type and Content-Disposition headers are
54
37
  # set to download arbitrary binary files in as many browsers as
@@ -81,29 +64,16 @@ module ActionController #:nodoc:
81
64
  def send_file(path, options = {}) #:doc:
82
65
  raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
83
66
 
84
- options[:length] ||= File.size(path)
85
67
  options[:filename] ||= File.basename(path) unless options[:url_based_filename]
86
68
  send_file_headers! options
87
69
 
88
- @performed_render = false
89
-
90
70
  if options[:x_sendfile]
91
- head options[:status], X_SENDFILE_HEADER => path
92
- else
93
- if options[:stream]
94
- # TODO : Make render :text => proc {} work with the new base
95
- render :status => options[:status], :text => Proc.new { |response, output|
96
- len = options[:buffer_size] || 4096
97
- File.open(path, 'rb') do |file|
98
- while buf = file.read(len)
99
- output.write(buf)
100
- end
101
- end
102
- }
103
- else
104
- File.open(path, 'rb') { |file| render :status => options[:status], :text => file.read }
105
- end
71
+ ActiveSupport::Deprecation.warn(":x_sendfile is no longer needed in send_file", caller)
106
72
  end
73
+
74
+ self.status = options[:status] || 200
75
+ self.content_type = options[:content_type] if options.key?(:content_type)
76
+ self.response_body = File.open(path, "rb")
107
77
  end
108
78
 
109
79
  # Sends the given binary data to the browser. This method is similar to
@@ -138,32 +108,35 @@ module ActionController #:nodoc:
138
108
  # data to the browser, then use <tt>render :text => proc { ... }</tt>
139
109
  # instead. See ActionController::Base#render for more information.
140
110
  def send_data(data, options = {}) #:doc:
141
- send_file_headers! options.merge(:length => data.bytesize)
142
- render :status => options[:status], :text => data
111
+ send_file_headers! options.dup
112
+ render options.slice(:status, :content_type).merge(:text => data)
143
113
  end
144
114
 
145
115
  private
146
116
  def send_file_headers!(options)
147
117
  options.update(DEFAULT_SEND_FILE_OPTIONS.merge(options))
148
- [:length, :type, :disposition].each do |arg|
118
+ [:type, :disposition].each do |arg|
149
119
  raise ArgumentError, ":#{arg} option required" if options[arg].nil?
150
120
  end
151
121
 
152
- disposition = options[:disposition].dup || 'attachment'
122
+ if options.key?(:length)
123
+ ActiveSupport::Deprecation.warn("You do not need to provide the file's length", caller)
124
+ end
153
125
 
154
- disposition <<= %(; filename="#{options[:filename]}") if options[:filename]
126
+ disposition = options[:disposition]
127
+ disposition += %(; filename="#{options[:filename]}") if options[:filename]
155
128
 
156
129
  content_type = options[:type]
157
130
 
158
131
  if content_type.is_a?(Symbol)
159
- raise ArgumentError, "Unknown MIME type #{options[:type]}" unless Mime::EXTENSION_LOOKUP.key?(content_type.to_s)
160
- self.content_type = Mime::Type.lookup_by_extension(content_type.to_s)
132
+ extension = Mime[content_type]
133
+ raise ArgumentError, "Unknown MIME type #{options[:type]}" unless extension
134
+ self.content_type = extension
161
135
  else
162
136
  self.content_type = content_type
163
137
  end
164
138
 
165
139
  headers.merge!(
166
- 'Content-Length' => options[:length].to_s,
167
140
  'Content-Disposition' => disposition,
168
141
  'Content-Transfer-Encoding' => 'binary'
169
142
  )
@@ -13,7 +13,6 @@ module ActionController
13
13
  if cookies = @_request.env['action_dispatch.cookies']
14
14
  cookies.write(@_response)
15
15
  end
16
- @_response.body ||= self.response_body
17
16
  @_response.prepare!
18
17
  set_test_assigns
19
18
  ret
@@ -1,157 +1,20 @@
1
- require 'active_support/core_ext/class/attribute'
2
-
3
1
  module ActionController
4
- # In <b>routes.rb</b> one defines URL-to-controller mappings, but the reverse
5
- # is also possible: an URL can be generated from one of your routing definitions.
6
- # URL generation functionality is centralized in this module.
7
- #
8
- # See ActionController::Routing and ActionController::Resources for general
9
- # information about routing and routes.rb.
10
- #
11
- # <b>Tip:</b> If you need to generate URLs from your models or some other place,
12
- # then ActionController::UrlFor is what you're looking for. Read on for
13
- # an introduction.
14
- #
15
- # == URL generation from parameters
16
- #
17
- # As you may know, some functions - such as ActionController::Base#url_for
18
- # and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set
19
- # of parameters. For example, you've probably had the chance to write code
20
- # like this in one of your views:
21
- #
22
- # <%= link_to('Click here', :controller => 'users',
23
- # :action => 'new', :message => 'Welcome!') %>
24
- #
25
- # #=> Generates a link to: /users/new?message=Welcome%21
26
- #
27
- # link_to, and all other functions that require URL generation functionality,
28
- # actually use ActionController::UrlFor under the hood. And in particular,
29
- # they use the ActionController::UrlFor#url_for method. One can generate
30
- # the same path as the above example by using the following code:
31
- #
32
- # include UrlFor
33
- # url_for(:controller => 'users',
34
- # :action => 'new',
35
- # :message => 'Welcome!',
36
- # :only_path => true)
37
- # # => "/users/new?message=Welcome%21"
38
- #
39
- # Notice the <tt>:only_path => true</tt> part. This is because UrlFor has no
40
- # information about the website hostname that your Rails app is serving. So if you
41
- # want to include the hostname as well, then you must also pass the <tt>:host</tt>
42
- # argument:
43
- #
44
- # include UrlFor
45
- # url_for(:controller => 'users',
46
- # :action => 'new',
47
- # :message => 'Welcome!',
48
- # :host => 'www.example.com') # Changed this.
49
- # # => "http://www.example.com/users/new?message=Welcome%21"
50
- #
51
- # By default, all controllers and views have access to a special version of url_for,
52
- # that already knows what the current hostname is. So if you use url_for in your
53
- # controllers or your views, then you don't need to explicitly pass the <tt>:host</tt>
54
- # argument.
55
- #
56
- # For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for.
57
- # So within mailers, you only have to type 'url_for' instead of 'ActionController::UrlFor#url_for'
58
- # in full. However, mailers don't have hostname information, and what's why you'll still
59
- # have to specify the <tt>:host</tt> argument when generating URLs in mailers.
60
- #
61
- #
62
- # == URL generation for named routes
63
- #
64
- # UrlFor also allows one to access methods that have been auto-generated from
65
- # named routes. For example, suppose that you have a 'users' resource in your
66
- # <b>routes.rb</b>:
67
- #
68
- # map.resources :users
69
- #
70
- # This generates, among other things, the method <tt>users_path</tt>. By default,
71
- # this method is accessible from your controllers, views and mailers. If you need
72
- # to access this auto-generated method from other places (such as a model), then
73
- # you can do that by including ActionController::UrlFor in your class:
74
- #
75
- # class User < ActiveRecord::Base
76
- # include ActionController::UrlFor
77
- #
78
- # def base_uri
79
- # user_path(self)
80
- # end
81
- # end
82
- #
83
- # User.find(1).base_uri # => "/users/1"
84
- #
85
2
  module UrlFor
86
3
  extend ActiveSupport::Concern
87
4
 
88
- included do
89
- ActionController::Routing::Routes.install_helpers(self)
90
- class_attribute :default_url_options
91
- self.default_url_options = {}
92
- end
93
-
94
- # Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in
95
- # the form of a hash, just like the one you would use for url_for directly. Example:
96
- #
97
- # def default_url_options(options)
98
- # { :project => @project.active? ? @project.url_name : "unknown" }
99
- # end
100
- #
101
- # As you can infer from the example, this is mostly useful for situations where you want to centralize dynamic decisions about the
102
- # urls as they stem from the business domain. Please note that any individual url_for call can always override the defaults set
103
- # by this method.
104
- def default_url_options(options = nil)
105
- self.class.default_url_options
106
- end
5
+ include ActionDispatch::Routing::UrlFor
107
6
 
108
- def rewrite_options(options) #:nodoc:
109
- if options.delete(:use_defaults) != false && (defaults = default_url_options(options))
110
- defaults.merge(options)
111
- else
112
- options
113
- end
7
+ def url_options
8
+ super.reverse_merge(
9
+ :host => request.host_with_port,
10
+ :protocol => request.protocol,
11
+ :_path_segments => request.symbolized_path_parameters
12
+ ).merge(:script_name => request.script_name)
114
13
  end
115
14
 
116
- # Generate a url based on the options provided, default_url_options and the
117
- # routes defined in routes.rb. The following options are supported:
118
- #
119
- # * <tt>:only_path</tt> - If true, the relative url is returned. Defaults to +false+.
120
- # * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'.
121
- # * <tt>:host</tt> - Specifies the host the link should be targeted at.
122
- # If <tt>:only_path</tt> is false, this option must be
123
- # provided either explicitly, or via +default_url_options+.
124
- # * <tt>:port</tt> - Optionally specify the port to connect to.
125
- # * <tt>:anchor</tt> - An anchor name to be appended to the path.
126
- # * <tt>:skip_relative_url_root</tt> - If true, the url is not constructed using the
127
- # +relative_url_root+ set in ActionController::Base.relative_url_root.
128
- # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
129
- #
130
- # Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
131
- # +url_for+ is forwarded to the Routes module.
132
- #
133
- # Examples:
134
- #
135
- # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :port=>'8080' # => 'http://somehost.org:8080/tasks/testing'
136
- # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok'
137
- # url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/'
138
- # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33'
139
- def url_for(options = {})
140
- options ||= {}
141
- case options
142
- when String
143
- options
144
- when Hash
145
- _url_rewriter.rewrite(rewrite_options(options))
146
- else
147
- polymorphic_url(options)
148
- end
149
- end
150
-
151
- protected
152
-
153
- def _url_rewriter
154
- ActionController::UrlRewriter
15
+ def _router
16
+ raise "In order to use #url_for, you must include the helpers of a particular " \
17
+ "router. For instance, `include Rails.application.routes.url_helpers"
155
18
  end
156
19
  end
157
- end
20
+ end