diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2015-08-25 18:35:44 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2015-08-25 18:35:44 -0700 |
commit | 51c7ac142d31095d4c699f44cc44ddea627da1eb (patch) | |
tree | 920c40c749272ebec57be8b26164829660781dff /actionpack/lib | |
parent | 85a78d9358aa728298cd020cdc842b55c16f9549 (diff) | |
download | rails-51c7ac142d31095d4c699f44cc44ddea627da1eb.tar.gz rails-51c7ac142d31095d4c699f44cc44ddea627da1eb.tar.bz2 rails-51c7ac142d31095d4c699f44cc44ddea627da1eb.zip |
provide a request and response to all controllers
Controllers should always have a request and response when responding.
Since we make this The Rule(tm), then controllers don't need to be
somewhere in limbo between "asking a response object for a rack
response" or "I, myself contain a rack response". This duality leads to
conditionals spread through the codebase that we can delete:
* https://github.com/rails/rails/blob/85a78d9358aa728298cd020cdc842b55c16f9549/actionpack/lib/action_controller/metal.rb#L221-L223
Diffstat (limited to 'actionpack/lib')
-rw-r--r-- | actionpack/lib/action_controller/metal.rb | 37 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/head.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/rack_delegation.rb | 17 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/response.rb | 3 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 10 |
5 files changed, 37 insertions, 35 deletions
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 54980aa453..129e0bbd3c 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -132,6 +132,12 @@ module ActionController @controller_name ||= name.demodulize.sub(/Controller$/, '').underscore end + def self.make_response!(request) + ActionDispatch::Response.new.tap do |res| + res.request = request + end + end + # Delegates to the class' <tt>controller_name</tt> def controller_name self.class.controller_name @@ -143,11 +149,10 @@ module ActionController # and response object available. You might wish to control the # environment and response manually for performance reasons. - attr_internal :headers, :response, :request - delegate :session, :to => "@_request" + attr_internal :response, :request + delegate :session, :headers, :to => "@_request" def initialize - @_headers = {"Content-Type" => "text/html"} @_status = 200 @_request = nil @_response = nil @@ -168,7 +173,7 @@ module ActionController # in Renderer and Redirector. def content_type=(type) - headers["Content-Type"] = type.to_s + response.content_type = type end def content_type @@ -199,6 +204,7 @@ module ActionController def response_body=(body) body = [body] unless body.nil? || body.respond_to?(:each) + response.body = body super end @@ -207,12 +213,17 @@ module ActionController response_body || (response && response.committed?) end - def dispatch(name, request) #:nodoc: + def dispatch(name, request, response) #:nodoc: set_request!(request) + set_response!(response) process(name) to_a end + def set_response!(response) # :nodoc: + @_response = response + end + def set_request!(request) #:nodoc: @_request = request @_request.controller_instance = self @@ -253,20 +264,26 @@ module ActionController def self.action(name) if middleware_stack.any? middleware_stack.build(name) do |env| - new.dispatch(name, ActionDispatch::Request.new(env)) + req = ActionDispatch::Request.new(env) + res = make_response! req + new.dispatch(name, req, res) end else - lambda { |env| new.dispatch(name, ActionDispatch::Request.new(env)) } + lambda { |env| + req = ActionDispatch::Request.new(env) + res = make_response! req + new.dispatch(name, req, res) + } end end # Direct dispatch to the controller. Instantiates the controller, then # executes the action named +name+. - def self.dispatch(name, req) + def self.dispatch(name, req, res) if middleware_stack.any? - middleware_stack.build(name) { |env| new.dispatch(name, req) }.call req.env + middleware_stack.build(name) { |env| new.dispatch(name, req, res) }.call req.env else - new.dispatch(name, req) + new.dispatch(name, req, res) end end end diff --git a/actionpack/lib/action_controller/metal/head.rb b/actionpack/lib/action_controller/metal/head.rb index 056962b38c..7dbd5ef328 100644 --- a/actionpack/lib/action_controller/metal/head.rb +++ b/actionpack/lib/action_controller/metal/head.rb @@ -36,6 +36,8 @@ module ActionController headers[key.to_s.dasherize.split('-').each { |v| v[0] = v[0].chr.upcase }.join('-')] = value.to_s end + response.status = Rack::Utils.status_code(status) + self.status = status self.location = url_for(location) if location @@ -44,9 +46,6 @@ module ActionController if include_content?(self.response_code) self.content_type = content_type || (Mime[formats.first] if formats) self.response.charset = false if self.response - else - headers.delete('Content-Type') - headers.delete('Content-Length') end true diff --git a/actionpack/lib/action_controller/metal/rack_delegation.rb b/actionpack/lib/action_controller/metal/rack_delegation.rb index eb8bca1d92..5ba9a47d63 100644 --- a/actionpack/lib/action_controller/metal/rack_delegation.rb +++ b/actionpack/lib/action_controller/metal/rack_delegation.rb @@ -12,17 +12,6 @@ module ActionController def build_with_env(env = {}) #:nodoc: new.tap { |c| c.set_request! ActionDispatch::Request.new(env) } end - - def make_response!(request) - ActionDispatch::Response.new.tap do |res| - res.request = request - end - end - end - - def set_request!(request) #:nodoc: - super - set_response!(request) end def response_body=(body) @@ -33,11 +22,5 @@ module ActionController def reset_session @_request.reset_session end - - private - - def set_response!(request) - @_response = self.class.make_response! request - end end end diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index fd92e89231..c83b682f69 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -65,7 +65,7 @@ module ActionDispatch # :nodoc: CONTENT_TYPE = "Content-Type".freeze SET_COOKIE = "Set-Cookie".freeze LOCATION = "Location".freeze - NO_CONTENT_CODES = [204, 304] + NO_CONTENT_CODES = [100, 101, 102, 204, 205, 304] cattr_accessor(:default_charset) { "utf-8" } cattr_accessor(:default_headers) @@ -396,6 +396,7 @@ module ActionDispatch # :nodoc: if NO_CONTENT_CODES.include?(@status) header.delete CONTENT_TYPE + header.delete 'Content-Length' [status, header, []] else [status, header, RackBody.new(self)] diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 3e3a424df3..e4b8d5993e 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -27,8 +27,10 @@ module ActionDispatch def dispatcher?; true; end def serve(req) - params = req.path_parameters - dispatch(controller(req), params[:action], req) + params = req.path_parameters + controller = controller req + res = controller.make_response! req + dispatch(controller, params[:action], req, res) rescue NameError => e if @raise_on_name_error raise ActionController::RoutingError, e.message, e.backtrace @@ -43,8 +45,8 @@ module ActionDispatch req.controller_class end - def dispatch(controller, action, req) - controller.dispatch(action, req) + def dispatch(controller, action, req, res) + controller.dispatch(action, req, res) end end |