提交 6bbe965c 编写于 作者: Y Yehuda Katz

Reduce the cost of using ActionController::Http significantly by:

  * Removing the dependency on AD::Request and AD::Response
  * Moving the logic for the request and response object
    into a new module that is included by default.
  * Changing Renderer and Redirector to use self.headers,
    self.content_type, and self.status, which have very basic
    default implementations on AC::Http. When RackConvenience
    is included (which it is by default on AC::Base), the full
    Request/Response logic is used instead of the simple logic.
上级 311d686d
......@@ -4,6 +4,7 @@ module ActionController
autoload :HideActions, "action_controller/new_base/hide_actions"
autoload :Http, "action_controller/new_base/http"
autoload :Layouts, "action_controller/new_base/layouts"
autoload :RackConvenience, "action_controller/new_base/rack_convenience"
autoload :Rails2Compatibility, "action_controller/new_base/compatibility"
autoload :Redirector, "action_controller/new_base/redirector"
autoload :Renderer, "action_controller/new_base/renderer"
......
......@@ -14,6 +14,7 @@ class Base < Http
include ActionController::Renderers::All
include ActionController::Layouts
include ActionController::ConditionalGet
include ActionController::RackConvenience
# Legacy modules
include SessionManagement
......
module ActionController
module ConditionalGet
extend ActiveSupport::DependencyModule
depends_on RackConvenience
# Sets the etag, last_modified, or both on the response and renders a
# "304 Not Modified" response if the request is already fresh.
......
......@@ -6,7 +6,7 @@ class Http < AbstractController::Base
abstract!
# :api: public
attr_internal :request, :response, :params
attr_internal :params, :env
# :api: public
def self.controller_name
......@@ -36,32 +36,48 @@ def self.call(env)
controller.call(env).to_rack
end
delegate :headers, :to => "@_response"
# The details below can be overridden to support a specific
# Request and Response object. The default ActionController::Base
# implementation includes RackConvenience, which makes a request
# and response object available. You might wish to control the
# environment and response manually for performance reasons.
def params
@_params ||= @_request.parameters
attr_internal :status, :headers, :content_type
def initialize(*)
@_headers = {}
super
end
# Basic implements for content_type=, location=, and headers are
# provided to reduce the dependency on the RackConvenience module
# in Renderer and Redirector.
def content_type=(type)
headers["Content-Type"] = type.to_s
end
def location=(url)
headers["Location"] = url
end
# :api: private
def call(name, env)
@_request = ActionDispatch::Request.new(env)
@_response = ActionDispatch::Response.new
@_response.request = request
@_env = env
process(name)
to_rack
end
# :api: private
def to_rack
[status, headers, response_body]
end
def self.action(name)
@actions ||= {}
@actions[name.to_s] ||= proc do |env|
new.call(name, env)
end
end
# :api: private
def to_rack
@_response.prepare!
@_response.to_a
end
end
end
module ActionController
module RackConvenience
extend ActiveSupport::DependencyModule
included do
delegate :headers, :status=, :location=,
:status, :location, :content_type, :to => "@_response"
attr_internal :request, :response
end
def call(name, env)
@_request = ActionDispatch::Request.new(env)
@_response = ActionDispatch::Response.new
@_response.request = request
super
end
def params
@_params ||= @_request.parameters
end
# :api: private
def to_rack
@_response.prepare!
@_response.to_a
end
def response_body=(body)
response.body = body if response
super
end
end
end
\ No newline at end of file
......@@ -11,8 +11,8 @@ module Redirector
def redirect_to(url, status) #:doc:
raise AbstractController::DoubleRenderError if response_body
logger.info("Redirected to #{url}") if logger && logger.info?
response.status = status
response.location = url.gsub(/[\r\n]/, '')
self.status = status
self.location = url.gsub(/[\r\n]/, '')
self.response_body = "<html><body>You are being <a href=\"#{CGI.escapeHTML(url)}\">redirected</a>.</body></html>"
end
end
......
......@@ -57,7 +57,7 @@ module Json
def _render_json(json, options)
json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
response.content_type ||= Mime::JSON
self.content_type ||= Mime::JSON
self.response_body = json
end
end
......@@ -67,7 +67,7 @@ module Js
register_renderer :js
def _render_js(js, options)
response.content_type ||= Mime::JS
self.content_type ||= Mime::JS
self.response_body = js
end
end
......@@ -77,7 +77,7 @@ module Xml
register_renderer :xml
def _render_xml(xml, options)
response.content_type ||= Mime::XML
self.content_type ||= Mime::XML
self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml : xml
end
end
......@@ -88,7 +88,7 @@ module Rjs
def _render_update(proc, options)
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(_action_view, &proc)
response.content_type = Mime::JS
self.content_type = Mime::JS
self.response_body = generator.to_s
end
end
......
......@@ -8,16 +8,11 @@ def process_action(*)
self.formats = request.formats.map {|x| x.to_sym}
super
end
def response_body=(body)
response.body = body if response
super
end
def render(options)
super
options[:_template] ||= _action_view._partial
response.content_type ||= begin
self.content_type ||= begin
mime = options[:_template].mime_type
formats.include?(mime && mime.to_sym) || formats.include?(:all) ? mime : Mime::Type.lookup_by_extension(formats.first)
end
......@@ -76,9 +71,9 @@ def _render_partial(partial, options)
def _process_options(options)
status, content_type, location = options.values_at(:status, :content_type, :location)
response.status = status if status
response.content_type = content_type if content_type
response.headers["Location"] = url_for(location) if location
self.status = status if status
self.content_type = content_type if content_type
self.headers["Location"] = url_for(location) if location
end
end
end
module ActionController
module Session
extend ActiveSupport::DependencyModule
depends_on RackConvenience
def session
@_request.session
end
......
......@@ -2,6 +2,8 @@ module ActionController
module Testing
extend ActiveSupport::DependencyModule
depends_on RackConvenience
# OMG MEGA HAX
def process_with_new_base_test(request, response)
@_request = request
......
module ActionController
module UrlFor
extend ActiveSupport::DependencyModule
depends_on RackConvenience
def process_action(*)
initialize_current_url
super
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册