diff options
-rw-r--r-- | actionpack/lib/action_controller/metal.rb | 40 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/compatibility.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/rack_convenience.rb | 8 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/response.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/params_parser.rb | 12 | ||||
-rw-r--r-- | actionpack/test/controller/webservice_test.rb | 129 | ||||
-rw-r--r-- | actionpack/test/new_base/metal_test.rb | 45 | ||||
-rwxr-xr-x | activerecord/examples/performance.rb | 6 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/time/calculations.rb | 3 |
9 files changed, 164 insertions, 90 deletions
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 5333ca497c..aad9570237 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -47,7 +47,7 @@ module ActionController # and response object available. You might wish to control the # environment and response manually for performance reasons. - attr_internal :status, :headers, :content_type + attr_internal :status, :headers, :content_type, :app, :response def initialize(*) @_headers = {} @@ -75,7 +75,34 @@ module ActionController # :api: private def to_a - [status, headers, response_body] + response ? response.to_a : [status, headers, response_body] + end + + class ActionEndpoint + def initialize(controller, action) + @controller, @action = controller, action + end + + def call(env) + controller = @controller.new.call(@action, env) + end + end + + class ActionMiddleware + def initialize(controller, action) + @controller, @action = controller, action + end + + def call(env) + controller = @controller.new + controller.app = @app + controller.call(@action, env) + end + + def new(app) + @app = app + self + end end # Return a rack endpoint for the given action. Memoize the endpoint, so @@ -89,9 +116,12 @@ module ActionController # Proc:: A rack application def self.action(name) @actions ||= {} - @actions[name.to_s] ||= proc do |env| - new.call(name, env) - end + @actions[name.to_s] ||= ActionEndpoint.new(self, name) + end + + def self.middleware(name) + @middlewares ||= {} + @middlewares[name.to_s] ||= ActionMiddleware.new(self, name) end end end diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 5b0165f0e7..22f9ab219c 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -16,12 +16,6 @@ module ActionController cattr_accessor :allow_concurrency self.allow_concurrency = false - cattr_accessor :param_parsers - self.param_parsers = { Mime::MULTIPART_FORM => :multipart_form, - Mime::URL_ENCODED_FORM => :url_encoded_form, - Mime::XML => :xml_simple, - Mime::JSON => :json } - cattr_accessor :relative_url_root self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] diff --git a/actionpack/lib/action_controller/metal/rack_convenience.rb b/actionpack/lib/action_controller/metal/rack_convenience.rb index 5fac445dab..a80569c530 100644 --- a/actionpack/lib/action_controller/metal/rack_convenience.rb +++ b/actionpack/lib/action_controller/metal/rack_convenience.rb @@ -5,7 +5,7 @@ module ActionController included do delegate :headers, :status=, :location=, :content_type=, :status, :location, :content_type, :to => "@_response" - attr_internal :request, :response + attr_internal :request end def call(name, env) @@ -19,12 +19,6 @@ module ActionController @_params ||= @_request.parameters end - # :api: private - def to_a - @_response.prepare! - @_response.to_a - end - def response_body=(body) response.body = body if response super diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 055f29a972..e457450059 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -161,13 +161,16 @@ module ActionDispatch # :nodoc: headers[CONTENT_TYPE] = type end - def prepare! + def to_a assign_default_content_type_and_charset! handle_conditional_get! self["Set-Cookie"] = @cookie.join("\n") self["ETag"] = @etag if @etag + super end + alias prepare! to_a + def each(&callback) if @body.respond_to?(:call) @writer = lambda { |x| callback.call(x) } diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index ff2b2fe74b..32ccb5c931 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -2,11 +2,13 @@ require 'active_support/json' module ActionDispatch class ParamsParser - ActionController::Base.param_parsers[Mime::XML] = :xml_simple - ActionController::Base.param_parsers[Mime::JSON] = :json + DEFAULT_PARSERS = { + Mime::XML => :xml_simple, + Mime::JSON => :json + } - def initialize(app) - @app = app + def initialize(app, parsers = {}) + @app, @parsers = app, DEFAULT_PARSERS.merge(parsers) end def call(env) @@ -24,7 +26,7 @@ module ActionDispatch return false if request.content_length.zero? mime_type = content_type_from_legacy_post_data_format_header(env) || request.content_type - strategy = ActionController::Base.param_parsers[mime_type] + strategy = @parsers[mime_type] return false unless strategy diff --git a/actionpack/test/controller/webservice_test.rb b/actionpack/test/controller/webservice_test.rb index 9bf8da7276..3fded34d78 100644 --- a/actionpack/test/controller/webservice_test.rb +++ b/actionpack/test/controller/webservice_test.rb @@ -24,11 +24,6 @@ class WebServiceTest < ActionController::IntegrationTest def setup @controller = TestController.new - @default_param_parsers = ActionController::Base.param_parsers.dup - end - - def teardown - ActionController::Base.param_parsers = @default_param_parsers end def test_check_parameters @@ -110,58 +105,61 @@ class WebServiceTest < ActionController::IntegrationTest def test_post_xml_using_an_attributted_node_named_type with_test_route_set do - ActionController::Base.param_parsers[Mime::XML] = Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access } - post "/", '<request><type type="string">Arial,12</type><z>3</z></request>', - {'CONTENT_TYPE' => 'application/xml'} - - assert_equal 'type, z', @controller.response.body - assert @controller.params.has_key?(:type) - assert_equal 'Arial,12', @controller.params['type'], @controller.params.inspect - assert_equal '3', @controller.params['z'], @controller.params.inspect + with_params_parsers Mime::XML => Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access } do + post "/", '<request><type type="string">Arial,12</type><z>3</z></request>', + {'CONTENT_TYPE' => 'application/xml'} + + assert_equal 'type, z', @controller.response.body + assert @controller.params.has_key?(:type) + assert_equal 'Arial,12', @controller.params['type'], @controller.params.inspect + assert_equal '3', @controller.params['z'], @controller.params.inspect + end end end def test_register_and_use_yaml with_test_route_set do - ActionController::Base.param_parsers[Mime::YAML] = Proc.new { |d| YAML.load(d) } - post "/", {"entry" => "loaded from yaml"}.to_yaml, - {'CONTENT_TYPE' => 'application/x-yaml'} + with_params_parsers Mime::YAML => Proc.new { |d| YAML.load(d) } do + post "/", {"entry" => "loaded from yaml"}.to_yaml, + {'CONTENT_TYPE' => 'application/x-yaml'} - assert_equal 'entry', @controller.response.body - assert @controller.params.has_key?(:entry) - assert_equal 'loaded from yaml', @controller.params["entry"] + assert_equal 'entry', @controller.response.body + assert @controller.params.has_key?(:entry) + assert_equal 'loaded from yaml', @controller.params["entry"] + end end end def test_register_and_use_yaml_as_symbol with_test_route_set do - ActionController::Base.param_parsers[Mime::YAML] = :yaml - post "/", {"entry" => "loaded from yaml"}.to_yaml, - {'CONTENT_TYPE' => 'application/x-yaml'} + with_params_parsers Mime::YAML => :yaml do + post "/", {"entry" => "loaded from yaml"}.to_yaml, + {'CONTENT_TYPE' => 'application/x-yaml'} - assert_equal 'entry', @controller.response.body - assert @controller.params.has_key?(:entry) - assert_equal 'loaded from yaml', @controller.params["entry"] + assert_equal 'entry', @controller.response.body + assert @controller.params.has_key?(:entry) + assert_equal 'loaded from yaml', @controller.params["entry"] + end end end def test_register_and_use_xml_simple with_test_route_set do - ActionController::Base.param_parsers[Mime::XML] = Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access } - post "/", '<request><summary>content...</summary><title>SimpleXml</title></request>', - {'CONTENT_TYPE' => 'application/xml'} - - assert_equal 'summary, title', @controller.response.body - assert @controller.params.has_key?(:summary) - assert @controller.params.has_key?(:title) - assert_equal 'content...', @controller.params["summary"] - assert_equal 'SimpleXml', @controller.params["title"] + with_params_parsers Mime::XML => Proc.new { |data| Hash.from_xml(data)['request'].with_indifferent_access } do + post "/", '<request><summary>content...</summary><title>SimpleXml</title></request>', + {'CONTENT_TYPE' => 'application/xml'} + + assert_equal 'summary, title', @controller.response.body + assert @controller.params.has_key?(:summary) + assert @controller.params.has_key?(:title) + assert_equal 'content...', @controller.params["summary"] + assert_equal 'SimpleXml', @controller.params["title"] + end end end def test_use_xml_ximple_with_empty_request with_test_route_set do - ActionController::Base.param_parsers[Mime::XML] = :xml_simple assert_nothing_raised { post "/", "", {'CONTENT_TYPE' => 'application/xml'} } assert @controller.response.body.blank? end @@ -169,7 +167,6 @@ class WebServiceTest < ActionController::IntegrationTest def test_dasherized_keys_as_xml with_test_route_set do - ActionController::Base.param_parsers[Mime::XML] = :xml_simple post "/?full=1", "<first-key>\n<sub-key>...</sub-key>\n</first-key>", {'CONTENT_TYPE' => 'application/xml'} assert_equal 'action, controller, first_key(sub_key), full', @controller.response.body @@ -179,7 +176,6 @@ class WebServiceTest < ActionController::IntegrationTest def test_typecast_as_xml with_test_route_set do - ActionController::Base.param_parsers[Mime::XML] = :xml_simple xml = <<-XML <data> <a type="integer">15</a> @@ -208,7 +204,6 @@ class WebServiceTest < ActionController::IntegrationTest def test_entities_unescaped_as_xml_simple with_test_route_set do - ActionController::Base.param_parsers[Mime::XML] = :xml_simple xml = <<-XML <data><foo "bar's" & friends></data> XML @@ -219,34 +214,44 @@ class WebServiceTest < ActionController::IntegrationTest def test_typecast_as_yaml with_test_route_set do - ActionController::Base.param_parsers[Mime::YAML] = :yaml - yaml = <<-YAML - --- - data: - a: 15 - b: false - c: true - d: 2005-03-17 - e: 2005-03-17T21:41:07Z - f: unparsed - g: - - 1 - - hello - - 1974-07-25 - YAML - post "/", yaml, {'CONTENT_TYPE' => 'application/x-yaml'} - params = @controller.params - assert_equal 15, params[:data][:a] - assert_equal false, params[:data][:b] - assert_equal true, params[:data][:c] - assert_equal Date.new(2005,3,17), params[:data][:d] - assert_equal Time.utc(2005,3,17,21,41,7), params[:data][:e] - assert_equal "unparsed", params[:data][:f] - assert_equal [1, "hello", Date.new(1974,7,25)], params[:data][:g] + with_params_parsers Mime::YAML => :yaml do + yaml = <<-YAML + --- + data: + a: 15 + b: false + c: true + d: 2005-03-17 + e: 2005-03-17T21:41:07Z + f: unparsed + g: + - 1 + - hello + - 1974-07-25 + YAML + post "/", yaml, {'CONTENT_TYPE' => 'application/x-yaml'} + params = @controller.params + assert_equal 15, params[:data][:a] + assert_equal false, params[:data][:b] + assert_equal true, params[:data][:c] + assert_equal Date.new(2005,3,17), params[:data][:d] + assert_equal Time.utc(2005,3,17,21,41,7), params[:data][:e] + assert_equal "unparsed", params[:data][:f] + assert_equal [1, "hello", Date.new(1974,7,25)], params[:data][:g] + end end end private + def with_params_parsers(parsers = {}) + old_session = @integration_session + app = ActionDispatch::ParamsParser.new(ActionController::Routing::Routes, parsers) + @integration_session = open_session(app) + yield + ensure + @integration_session = old_session + end + def with_test_route_set with_routing do |set| set.draw do |map| diff --git a/actionpack/test/new_base/metal_test.rb b/actionpack/test/new_base/metal_test.rb new file mode 100644 index 0000000000..c7c45b5cc9 --- /dev/null +++ b/actionpack/test/new_base/metal_test.rb @@ -0,0 +1,45 @@ +require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper") + +module MetalTest + class MetalMiddleware < ActionController::Metal + def index + if env["PATH_INFO"] =~ /authed/ + self.response = app.call(env) + else + self.response_body = "Not authed!" + self.status = 401 + end + end + end + + class Endpoint + def call(env) + [200, {}, "Hello World"] + end + end + + class TestMiddleware < ActiveSupport::TestCase + def setup + @app = Rack::Builder.new do + use MetalMiddleware.middleware(:index) + run Endpoint.new + end.to_app + end + + test "it can call the next app by using @app" do + env = Rack::MockRequest.env_for("/authed") + response = @app.call(env) + + assert_equal "Hello World", response[2] + end + + test "it can return a response using the normal AC::Metal techniques" do + env = Rack::MockRequest.env_for("/") + response = @app.call(env) + + assert_equal "Not authed!", response[2] + assert_equal 401, response[0] + end + end +end + diff --git a/activerecord/examples/performance.rb b/activerecord/examples/performance.rb index 12153b490a..53acd62f47 100755 --- a/activerecord/examples/performance.rb +++ b/activerecord/examples/performance.rb @@ -75,13 +75,13 @@ else puts 'Inserting 10,000 users and exhibits...' 10_000.times do user = User.create( - :created_on => today, + :created_at => today, :name => Faker::Name.name, :email => Faker::Internet.email ) Exhibit.create( - :created_on => today, + :created_at => today, :name => Faker::Company.name, :user => user, :notes => notes @@ -130,7 +130,7 @@ RBench.run(TIMES) do exhibit = { :name => Faker::Company.name, :notes => Faker::Lorem.paragraphs.join($/), - :created_on => Date.today + :created_at => Date.today } report 'Model.create' do diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 4f3b869f50..4f4492f0fd 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -172,7 +172,8 @@ class Time # Returns a new Time representing the start of the day (0:00) def beginning_of_day - (self - seconds_since_midnight).change(:usec => 0) + #(self - seconds_since_midnight).change(:usec => 0) + change(:hour => 0, :min => 0, :sec => 0, :usec => 0) end alias :midnight :beginning_of_day alias :at_midnight :beginning_of_day |