From fda62ecf707b4023b30303dd0baf303f1ef8d344 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Fri, 19 Dec 2008 17:15:22 -0600 Subject: Rename AbstractResponse to Response and inheirt from Rack::Response --- actionpack/lib/action_controller.rb | 3 +- actionpack/lib/action_controller/dispatcher.rb | 2 +- actionpack/lib/action_controller/integration.rb | 8 +- actionpack/lib/action_controller/rack_process.rb | 77 ------------------ actionpack/lib/action_controller/response.rb | 95 ++++++++++++++-------- actionpack/lib/action_controller/test_process.rb | 6 +- .../test/controller/action_pack_assertions_test.rb | 6 +- actionpack/test/controller/cookie_test.rb | 8 +- actionpack/test/controller/rack_test.rb | 8 +- actionpack/test/controller/render_test.rb | 10 +-- 10 files changed, 86 insertions(+), 137 deletions(-) diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index eaf7779f1e..ae947820b4 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -42,7 +42,6 @@ module ActionController end autoload :AbstractRequest, 'action_controller/request' - autoload :AbstractResponse, 'action_controller/response' autoload :Base, 'action_controller/base' autoload :Benchmarking, 'action_controller/benchmarking' autoload :Caching, 'action_controller/caching' @@ -61,8 +60,8 @@ module ActionController autoload :MimeResponds, 'action_controller/mime_responds' autoload :PolymorphicRoutes, 'action_controller/polymorphic_routes' autoload :RackRequest, 'action_controller/rack_process' - autoload :RackResponse, 'action_controller/rack_process' autoload :RecordIdentifier, 'action_controller/record_identifier' + autoload :Response, 'action_controller/response' autoload :RequestForgeryProtection, 'action_controller/request_forgery_protection' autoload :Rescue, 'action_controller/rescue' autoload :Resources, 'action_controller/resources' diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index 11c4f057d8..e1eaaf7cbb 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -98,7 +98,7 @@ module ActionController def _call(env) @request = RackRequest.new(env) - @response = RackResponse.new + @response = Response.new dispatch end diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb index 8c2e3197df..d952c3489b 100644 --- a/actionpack/lib/action_controller/integration.rb +++ b/actionpack/lib/action_controller/integration.rb @@ -181,7 +181,7 @@ module ActionController # - +headers+: Additional HTTP headers to pass, as a Hash. The keys will # automatically be upcased, with the prefix 'HTTP_' added if needed. # - # This method returns an AbstractResponse object, which one can use to + # This method returns an Response object, which one can use to # inspect the details of the response. Furthermore, if this method was # called from an ActionController::IntegrationTest object, then that # object's @response instance variable will point to the same @@ -331,10 +331,10 @@ module ActionController @response = @controller.response else # Decorate responses from Rack Middleware and Rails Metal - # as an AbstractResponse for the purposes of integration testing - @response = AbstractResponse.new + # as an Response for the purposes of integration testing + @response = Response.new @response.status = status.to_s - @response.headers = @headers + @response.headers.replace(@headers) @response.body = @body end diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index be189b421d..8c6db91dd0 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -70,81 +70,4 @@ module ActionController #:nodoc: @env['rack.session'] = {} end end - - class RackResponse < AbstractResponse #:nodoc: - def initialize - @writer = lambda { |x| @body << x } - @block = nil - super() - end - - def to_a(&block) - @block = block - if [204, 304].include?(status.to_i) - headers.delete("Content-Type") - [status, headers.to_hash, []] - else - [status, headers.to_hash, self] - end - end - - def each(&callback) - if @body.respond_to?(:call) - @writer = lambda { |x| callback.call(x) } - @body.call(self, self) - elsif @body.is_a?(String) - @body.each_line(&callback) - else - @body.each(&callback) - end - - @writer = callback - @block.call(self) if @block - end - - def write(str) - @writer.call str.to_s - str - end - - def close - @body.close if @body.respond_to?(:close) - end - - def empty? - @block == nil && @body.empty? - end - - def prepare! - super - - convert_language! - convert_expires! - set_status! - end - - private - def convert_language! - headers["Content-Language"] = headers.delete("language") if headers["language"] - end - - def convert_expires! - headers["Expires"] = headers.delete("") if headers["expires"] - end - - def convert_content_type! - super - headers['Content-Type'] = headers.delete('type') || "text/html" - headers['Content-Type'] += "; charset=" + headers.delete('charset') if headers['charset'] - end - - def set_content_length! - super - headers["Content-Length"] = headers["Content-Length"].to_s if headers["Content-Length"] - end - - def set_status! - self.status ||= "200 OK" - end - end end diff --git a/actionpack/lib/action_controller/response.rb b/actionpack/lib/action_controller/response.rb index f89861e5a5..866616bac3 100644 --- a/actionpack/lib/action_controller/response.rb +++ b/actionpack/lib/action_controller/response.rb @@ -1,24 +1,25 @@ require 'digest/md5' module ActionController # :nodoc: - # Represents an HTTP response generated by a controller action. One can use an - # ActionController::AbstractResponse object to retrieve the current state of the - # response, or customize the response. An AbstractResponse object can either - # represent a "real" HTTP response (i.e. one that is meant to be sent back to the - # web browser) or a test response (i.e. one that is generated from integration - # tests). See CgiResponse and TestResponse, respectively. + # Represents an HTTP response generated by a controller action. One can use + # an ActionController::Response object to retrieve the current state + # of the response, or customize the response. An Response object can + # either represent a "real" HTTP response (i.e. one that is meant to be sent + # back to the web browser) or a test response (i.e. one that is generated + # from integration tests). See CgiResponse and TestResponse, respectively. # - # AbstractResponse is mostly a Ruby on Rails framework implement detail, and should - # never be used directly in controllers. Controllers should use the methods defined - # in ActionController::Base instead. For example, if you want to set the HTTP - # response's content MIME type, then use ActionControllerBase#headers instead of - # AbstractResponse#headers. + # Response is mostly a Ruby on Rails framework implement detail, and + # should never be used directly in controllers. Controllers should use the + # methods defined in ActionController::Base instead. For example, if you want + # to set the HTTP response's content MIME type, then use + # ActionControllerBase#headers instead of Response#headers. # - # Nevertheless, integration tests may want to inspect controller responses in more - # detail, and that's when AbstractResponse can be useful for application developers. - # Integration test methods such as ActionController::Integration::Session#get and - # ActionController::Integration::Session#post return objects of type TestResponse - # (which are of course also of type AbstractResponse). + # Nevertheless, integration tests may want to inspect controller responses in + # more detail, and that's when Response can be useful for application + # developers. Integration test methods such as + # ActionController::Integration::Session#get and + # ActionController::Integration::Session#post return objects of type + # TestResponse (which are of course also of type Response). # # For example, the following demo integration "test" prints the body of the # controller response to the console: @@ -29,22 +30,24 @@ module ActionController # :nodoc: # puts @response.body # end # end - class AbstractResponse + class Response < Rack::Response DEFAULT_HEADERS = { "Cache-Control" => "no-cache" } attr_accessor :request - attr_accessor :status - # The body content (e.g. HTML) of the response, as a String. - attr_accessor :body - # The headers of the response, as a Hash. It maps header names to header values. - attr_accessor :headers attr_accessor :session, :cookies, :assigns, :template, :layout attr_accessor :redirected_to, :redirected_to_method_params delegate :default_charset, :to => 'ActionController::Base' def initialize - @body, @headers, @session, @assigns = "", DEFAULT_HEADERS.merge("cookie" => []), [], [] + @status = 200 + @header = DEFAULT_HEADERS.merge("cookie" => []) + + @writer = lambda { |x| @body << x } + @block = nil + + @body = "", + @session, @assigns = [], [] end def location; headers['Location'] end @@ -140,9 +143,31 @@ module ActionController # :nodoc: handle_conditional_get! set_content_length! convert_content_type! + + convert_language! + convert_expires! set_cookies! end + def each(&callback) + if @body.respond_to?(:call) + @writer = lambda { |x| callback.call(x) } + @body.call(self, self) + elsif @body.is_a?(String) + @body.each_line(&callback) + else + @body.each(&callback) + end + + @writer = callback + @block.call(self) if @block + end + + def write(str) + @writer.call str.to_s + str + end + private def handle_conditional_get! if etag? || last_modified? @@ -171,23 +196,25 @@ module ActionController # :nodoc: end def convert_content_type! - if content_type = headers.delete("Content-Type") - self.headers["type"] = content_type - end - if content_type = headers.delete("Content-type") - self.headers["type"] = content_type - end - if content_type = headers.delete("content-type") - self.headers["type"] = content_type - end + headers['Content-Type'] ||= "text/html" + headers['Content-Type'] += "; charset=" + headers.delete('charset') if headers['charset'] end - # Don't set the Content-Length for block-based bodies as that would mean reading it all into memory. Not nice - # for, say, a 2GB streaming file. + # Don't set the Content-Length for block-based bodies as that would mean + # reading it all into memory. Not nice for, say, a 2GB streaming file. def set_content_length! unless body.respond_to?(:call) || (status && status.to_s[0..2] == '304') self.headers["Content-Length"] ||= body.size end + headers["Content-Length"] = headers["Content-Length"].to_s if headers["Content-Length"] + end + + def convert_language! + headers["Content-Language"] = headers.delete("language") if headers["language"] + end + + def convert_expires! + headers["Expires"] = headers.delete("") if headers["expires"] end def set_cookies! diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb index 1597f637fc..c4d7d52951 100644 --- a/actionpack/lib/action_controller/test_process.rb +++ b/actionpack/lib/action_controller/test_process.rb @@ -290,8 +290,8 @@ module ActionController #:nodoc: # TestResponse, which represent the HTTP response results of the requested # controller actions. # - # See AbstractResponse for more information on controller response objects. - class TestResponse < AbstractResponse + # See Response for more information on controller response objects. + class TestResponse < Response include TestResponseBehavior def recycle! @@ -435,7 +435,7 @@ module ActionController #:nodoc: end def session - @response.session + @request.session end def flash diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb index 87c12ee4ee..cb7922efd2 100644 --- a/actionpack/test/controller/action_pack_assertions_test.rb +++ b/actionpack/test/controller/action_pack_assertions_test.rb @@ -500,17 +500,17 @@ class ActionPackHeaderTest < ActionController::TestCase def test_rendering_xml_sets_content_type process :hello_xml_world - assert_equal('application/xml; charset=utf-8', @response.headers['type']) + assert_equal('application/xml; charset=utf-8', @response.headers['Content-Type']) end def test_rendering_xml_respects_content_type @response.headers['type'] = 'application/pdf' process :hello_xml_world - assert_equal('application/pdf; charset=utf-8', @response.headers['type']) + assert_equal('application/pdf; charset=utf-8', @response.headers['Content-Type']) end def test_render_text_with_custom_content_type get :render_text_with_custom_content_type - assert_equal 'application/rss+xml; charset=utf-8', @response.headers['type'] + assert_equal 'application/rss+xml; charset=utf-8', @response.headers['Content-Type'] end end diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb index cfe5726253..4b969519c6 100644 --- a/actionpack/test/controller/cookie_test.rb +++ b/actionpack/test/controller/cookie_test.rb @@ -59,7 +59,7 @@ class CookieTest < Test::Unit::TestCase get :authenticate_for_fourteen_days assert_equal ["user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 GMT"], @response.headers["Set-Cookie"] assert_equal({"user_name" => ["david"]}, @response.cookies) - end + end def test_setting_cookie_for_fourteen_days_with_symbols get :authenticate_for_fourteen_days_with_symbols @@ -71,7 +71,7 @@ class CookieTest < Test::Unit::TestCase get :authenticate_with_http_only assert_equal ["user_name=david; path=/; HttpOnly"], @response.headers["Set-Cookie"] assert_equal({"user_name" => ["david"]}, @response.cookies) - end + end def test_multiple_cookies get :set_multiple_cookies @@ -79,7 +79,7 @@ class CookieTest < Test::Unit::TestCase assert_equal "user_name=david; path=/; expires=Mon, 10 Oct 2005 05:00:00 GMT", @response.headers["Set-Cookie"][0] assert_equal "login=XJ-122; path=/", @response.headers["Set-Cookie"][1] assert_equal({"login" => ["XJ-122"], "user_name" => ["david"]}, @response.cookies) - end + end def test_setting_test_cookie assert_nothing_raised { get :access_frozen_cookies } @@ -89,7 +89,7 @@ class CookieTest < Test::Unit::TestCase get :logout assert_equal ["user_name=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"], @response.headers["Set-Cookie"] assert_equal({"user_name" => []}, @response.cookies) - end + end def test_cookiejar_accessor @request.cookies["user_name"] = CGI::Cookie.new("name" => "user_name", "value" => "david", "expires" => Time.local(2025, 10, 10)) diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index 51f43290d2..81d103f0f9 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -229,7 +229,7 @@ end class RackResponseTest < BaseRackTest def setup super - @response = ActionController::RackResponse.new + @response = ActionController::Response.new end def test_simple_output @@ -237,7 +237,7 @@ class RackResponseTest < BaseRackTest @response.prepare! status, headers, body = @response.to_a - assert_equal "200 OK", status + assert_equal 200, status assert_equal({ "Content-Type" => "text/html; charset=utf-8", "Cache-Control" => "private, max-age=0, must-revalidate", @@ -258,7 +258,7 @@ class RackResponseTest < BaseRackTest @response.prepare! status, headers, body = @response.to_a - assert_equal "200 OK", status + assert_equal 200, status assert_equal({"Content-Type" => "text/html; charset=utf-8", "Cache-Control" => "no-cache", "Set-Cookie" => []}, headers) parts = [] @@ -270,7 +270,7 @@ end class RackResponseHeadersTest < BaseRackTest def setup super - @response = ActionController::RackResponse.new + @response = ActionController::Response.new @response.status = "200 OK" end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index e0f05d654c..8e08a5a8e9 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -208,7 +208,7 @@ class TestController < ActionController::Base def greeting # let's just rely on the template end - + def blank_response render :text => ' ' end @@ -1099,14 +1099,14 @@ class RenderTest < ActionController::TestCase def test_update_page get :update_page assert_template nil - assert_equal 'text/javascript; charset=utf-8', @response.headers['type'] + assert_equal 'text/javascript; charset=utf-8', @response.headers['Content-Type'] assert_equal 2, @response.body.split($/).length end def test_update_page_with_instance_variables get :update_page_with_instance_variables assert_template nil - assert_equal 'text/javascript; charset=utf-8', @response.headers['type'] + assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"] assert_match /balance/, @response.body assert_match /\$37/, @response.body end @@ -1114,7 +1114,7 @@ class RenderTest < ActionController::TestCase def test_update_page_with_view_method get :update_page_with_view_method assert_template nil - assert_equal 'text/javascript; charset=utf-8', @response.headers['type'] + assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"] assert_match /2 people/, @response.body end @@ -1384,7 +1384,7 @@ class EtagRenderTest < ActionController::TestCase @request.host = "www.nextangle.com" @expected_bang_etag = etag_for(expand_key([:foo, 123])) end - + def test_render_blank_body_shouldnt_set_etag get :blank_response assert !@response.etag? -- cgit v1.2.3