aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionpack/lib/action_controller/metal.rb40
-rw-r--r--actionpack/lib/action_controller/metal/compatibility.rb6
-rw-r--r--actionpack/lib/action_controller/metal/rack_convenience.rb8
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb5
-rw-r--r--actionpack/lib/action_dispatch/middleware/params_parser.rb12
-rw-r--r--actionpack/test/controller/webservice_test.rb129
-rw-r--r--actionpack/test/new_base/metal_test.rb45
-rwxr-xr-xactiverecord/examples/performance.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb3
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>&lt;foo &quot;bar&apos;s&quot; &amp; friends&gt;</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