From 319ae4628f4e0058de3e40e4ca7791b17e45e70c Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 27 Jan 2009 18:54:01 -0600 Subject: [PATCH] Move HTTP libs and middleware into ActionDispatch component --- actionpack/lib/action_controller.rb | 32 +- actionpack/lib/action_controller/base/base.rb | 6 +- .../action_controller/dispatch/dispatcher.rb | 4 +- .../dispatch/{rack => }/middlewares.rb | 10 +- .../action_controller/dispatch/rack/lock.rb | 16 - .../dispatch/request_parser.rb | 315 ------------------ .../lib/action_controller/dispatch/rescue.rb | 4 +- actionpack/lib/action_controller/rack_ext.rb | 3 - .../action_controller/routing/route_set.rb | 2 +- .../action_controller/session/management.rb | 2 +- .../testing/assertions/response.rb | 4 +- .../action_controller/testing/integration.rb | 6 +- .../lib/action_controller/testing/process.rb | 4 +- actionpack/lib/action_dispatch.rb | 64 ++++ .../base => action_dispatch/http}/headers.rb | 2 +- .../http/mime_type.rb} | 2 +- .../http/mime_types.rb} | 0 .../http}/request.rb | 12 +- .../http}/response.rb | 2 +- .../http}/status_codes.rb | 2 +- .../middleware}/failsafe.rb | 2 +- .../middleware}/params_parser.rb | 2 +- .../middleware}/rewindable_input.rb | 2 +- .../middleware}/session/abstract_store.rb | 2 +- .../middleware}/session/cookie_store.rb | 2 +- .../middleware}/session/mem_cache_store.rb | 2 +- actionpack/lib/action_dispatch/rack.rb | 3 + .../rack_ext => action_dispatch/rack}/lock.rb | 0 .../rack}/multipart.rb | 0 .../rack}/parse_query.rb | 0 .../utils}/middleware_stack.rb | 2 +- .../utils}/uploaded_file.rb | 2 +- .../utils}/url_encoded_pair_parser.rb | 2 +- actionpack/test/controller/dispatcher_test.rb | 2 +- actionpack/test/controller/header_test.rb | 2 +- .../test/controller/middleware_stack_test.rb | 2 +- actionpack/test/controller/rack_test.rb | 10 +- actionpack/test/controller/render_test.rb | 4 +- .../request/multipart_params_parsing_test.rb | 2 +- .../url_encoded_params_parsing_test.rb | 2 +- actionpack/test/controller/rescue_test.rb | 2 +- .../controller/session/cookie_store_test.rb | 18 +- .../session/mem_cache_store_test.rb | 2 +- .../lib/active_record/session_store.rb | 2 +- 44 files changed, 134 insertions(+), 427 deletions(-) rename actionpack/lib/action_controller/dispatch/{rack => }/middlewares.rb (64%) delete mode 100644 actionpack/lib/action_controller/dispatch/rack/lock.rb delete mode 100644 actionpack/lib/action_controller/dispatch/request_parser.rb delete mode 100644 actionpack/lib/action_controller/rack_ext.rb create mode 100644 actionpack/lib/action_dispatch.rb rename actionpack/lib/{action_controller/base => action_dispatch/http}/headers.rb (96%) rename actionpack/lib/{action_controller/mime/type.rb => action_dispatch/http/mime_type.rb} (99%) rename actionpack/lib/{action_controller/mime/default_types.rb => action_dispatch/http/mime_types.rb} (100%) rename actionpack/lib/{action_controller/dispatch => action_dispatch/http}/request.rb (97%) rename actionpack/lib/{action_controller/dispatch => action_dispatch/http}/response.rb (99%) rename actionpack/lib/{action_controller/dispatch => action_dispatch/http}/status_codes.rb (99%) rename actionpack/lib/{action_controller/dispatch/rack => action_dispatch/middleware}/failsafe.rb (98%) rename actionpack/lib/{action_controller/dispatch => action_dispatch/middleware}/params_parser.rb (98%) rename actionpack/lib/{action_controller/dispatch => action_dispatch/middleware}/rewindable_input.rb (95%) rename actionpack/lib/{action_controller => action_dispatch/middleware}/session/abstract_store.rb (99%) rename actionpack/lib/{action_controller => action_dispatch/middleware}/session/cookie_store.rb (99%) rename actionpack/lib/{action_controller => action_dispatch/middleware}/session/mem_cache_store.rb (98%) create mode 100644 actionpack/lib/action_dispatch/rack.rb rename actionpack/lib/{action_controller/rack_ext => action_dispatch/rack}/lock.rb (100%) rename actionpack/lib/{action_controller/rack_ext => action_dispatch/rack}/multipart.rb (100%) rename actionpack/lib/{action_controller/rack_ext => action_dispatch/rack}/parse_query.rb (100%) rename actionpack/lib/{action_controller/dispatch/rack => action_dispatch/utils}/middleware_stack.rb (98%) rename actionpack/lib/{action_controller/dispatch => action_dispatch/utils}/uploaded_file.rb (97%) rename actionpack/lib/{action_controller/dispatch => action_dispatch/utils}/url_encoded_pair_parser.rb (99%) diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index d973cbb382..eb596ba40e 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -31,17 +31,14 @@ rescue LoadError end end -gem 'rack', '>= 0.9.0' -require 'rack' -require 'action_controller/rack_ext' - require File.join(File.dirname(__FILE__), "action_pack") module ActionController # TODO: Review explicit to see if they will automatically be handled by # the initilizer if they are really needed. def self.load_all! - [Base, CGIHandler, CgiRequest, Request, Response, Http::Headers, UrlRewriter, UrlWriter] + [Base, Request, Response, UrlRewriter, UrlWriter] + [ActionDispatch::Http::Headers] end autoload :Base, 'action_controller/base/base' @@ -49,7 +46,6 @@ module ActionController autoload :Caching, 'action_controller/caching' autoload :Cookies, 'action_controller/base/cookies' autoload :Dispatcher, 'action_controller/dispatch/dispatcher' - autoload :Failsafe, 'action_controller/dispatch/rack/failsafe' autoload :Filters, 'action_controller/base/chained/filters' autoload :Flash, 'action_controller/base/chained/flash' autoload :Helpers, 'action_controller/base/helpers' @@ -57,32 +53,21 @@ module ActionController autoload :Integration, 'action_controller/testing/integration' autoload :IntegrationTest, 'action_controller/testing/integration' autoload :Layout, 'action_controller/base/layout' - autoload :Lock, 'action_controller/dispatch/rack/lock' - autoload :MiddlewareStack, 'action_controller/dispatch/rack/middleware_stack' autoload :MimeResponds, 'action_controller/mime/responds' - autoload :ParamsParser, 'action_controller/dispatch/params_parser' autoload :PolymorphicRoutes, 'action_controller/routing/generation/polymorphic_routes' autoload :RecordIdentifier, 'action_controller/record_identifier' autoload :Redirector, 'action_controller/base/redirect' autoload :Renderer, 'action_controller/base/render' - autoload :Request, 'action_controller/dispatch/request' autoload :RequestForgeryProtection, 'action_controller/base/request_forgery_protection' - autoload :RequestParser, 'action_controller/dispatch/request_parser' autoload :Rescue, 'action_controller/dispatch/rescue' autoload :Resources, 'action_controller/routing/resources' autoload :Responder, 'action_controller/base/responder' - autoload :Response, 'action_controller/dispatch/response' - autoload :RewindableInput, 'action_controller/dispatch/rewindable_input' autoload :Routing, 'action_controller/routing' autoload :SessionManagement, 'action_controller/session/management' - autoload :StatusCodes, 'action_controller/dispatch/status_codes' autoload :Streaming, 'action_controller/base/streaming' autoload :TestCase, 'action_controller/testing/test_case' autoload :TestProcess, 'action_controller/testing/process' autoload :Translation, 'action_controller/translation' - autoload :UploadedFile, 'action_controller/dispatch/uploaded_file' - autoload :UploadedStringIO, 'action_controller/dispatch/uploaded_file' - autoload :UploadedTempfile, 'action_controller/dispatch/uploaded_file' autoload :UrlEncodedPairParser, 'action_controller/dispatch/url_encoded_pair_parser' autoload :UrlRewriter, 'action_controller/routing/generation/url_rewriter' autoload :UrlWriter, 'action_controller/routing/generation/url_rewriter' @@ -96,20 +81,9 @@ module ActionController autoload :SelectorAssertions, 'action_controller/testing/assertions/selector' autoload :TagAssertions, 'action_controller/testing/assertions/tag' end - - module Http - autoload :Headers, 'action_controller/base/headers' - end - - module Session - autoload :AbstractStore, 'action_controller/session/abstract_store' - autoload :CookieStore, 'action_controller/session/cookie_store' - autoload :MemCacheStore, 'action_controller/session/mem_cache_store' - end end -autoload :Mime, 'action_controller/mime/type' - autoload :HTML, 'action_controller/vendor/html-scanner' +require 'action_dispatch' require 'action_view' diff --git a/actionpack/lib/action_controller/base/base.rb b/actionpack/lib/action_controller/base/base.rb index 84371643d7..c9c23008cd 100644 --- a/actionpack/lib/action_controller/base/base.rb +++ b/actionpack/lib/action_controller/base/base.rb @@ -232,7 +232,7 @@ module ActionController #:nodoc: # class Base - include StatusCodes + include ActionDispatch::StatusCodes cattr_reader :protected_instance_variables # Controller specific instance variables which will not be accessible inside views. @@ -367,8 +367,8 @@ module ActionController #:nodoc: class << self def call(env) # HACK: For global rescue to have access to the original request and response - request = env["action_controller.rescue.request"] ||= Request.new(env) - response = env["action_controller.rescue.response"] ||= Response.new + request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env) + response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new process(request, response) end diff --git a/actionpack/lib/action_controller/dispatch/dispatcher.rb b/actionpack/lib/action_controller/dispatch/dispatcher.rb index 714e270781..e205245f13 100644 --- a/actionpack/lib/action_controller/dispatch/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatch/dispatcher.rb @@ -45,8 +45,8 @@ module ActionController end cattr_accessor :middleware - self.middleware = MiddlewareStack.new do |middleware| - middlewares = File.join(File.dirname(__FILE__), "rack", "middlewares.rb") + self.middleware = ActionDispatch::MiddlewareStack.new do |middleware| + middlewares = File.join(File.dirname(__FILE__), "middlewares.rb") middleware.instance_eval(File.read(middlewares)) end diff --git a/actionpack/lib/action_controller/dispatch/rack/middlewares.rb b/actionpack/lib/action_controller/dispatch/middlewares.rb similarity index 64% rename from actionpack/lib/action_controller/dispatch/rack/middlewares.rb rename to actionpack/lib/action_controller/dispatch/middlewares.rb index f9cfc2b18e..3bf3dbebab 100644 --- a/actionpack/lib/action_controller/dispatch/rack/middlewares.rb +++ b/actionpack/lib/action_controller/dispatch/middlewares.rb @@ -2,10 +2,10 @@ use "Rack::Lock", :if => lambda { !ActionController::Base.allow_concurrency } -use "ActionController::Failsafe" +use "ActionDispatch::Failsafe" -["ActionController::Session::CookieStore", - "ActionController::Session::MemCacheStore", +["ActionDispatch::Session::CookieStore", + "ActionDispatch::Session::MemCacheStore", "ActiveRecord::SessionStore"].each do |store| use(store, ActionController::Base.session_options, :if => lambda { @@ -16,6 +16,6 @@ use "ActionController::Failsafe" ) end -use "ActionController::RewindableInput" -use "ActionController::ParamsParser" +use "ActionDispatch::RewindableInput" +use "ActionDispatch::ParamsParser" use "Rack::MethodOverride" diff --git a/actionpack/lib/action_controller/dispatch/rack/lock.rb b/actionpack/lib/action_controller/dispatch/rack/lock.rb deleted file mode 100644 index c50762216e..0000000000 --- a/actionpack/lib/action_controller/dispatch/rack/lock.rb +++ /dev/null @@ -1,16 +0,0 @@ -module ActionController - class Lock - FLAG = 'rack.multithread'.freeze - - def initialize(app, lock = Mutex.new) - @app, @lock = app, lock - end - - def call(env) - old, env[FLAG] = env[FLAG], false - @lock.synchronize { @app.call(env) } - ensure - env[FLAG] = old - end - end -end diff --git a/actionpack/lib/action_controller/dispatch/request_parser.rb b/actionpack/lib/action_controller/dispatch/request_parser.rb deleted file mode 100644 index d1739ef4d0..0000000000 --- a/actionpack/lib/action_controller/dispatch/request_parser.rb +++ /dev/null @@ -1,315 +0,0 @@ -module ActionController - class RequestParser - def initialize(env) - @env = env - freeze - end - - def request_parameters - @env["action_controller.request_parser.request_parameters"] ||= parse_formatted_request_parameters - end - - def query_parameters - @env["action_controller.request_parser.query_parameters"] ||= self.class.parse_query_parameters(query_string) - end - - # Returns the query string, accounting for server idiosyncrasies. - def query_string - @env['QUERY_STRING'].present? ? @env['QUERY_STRING'] : (@env['REQUEST_URI'].split('?', 2)[1] || '') - end - - # The request body is an IO input stream. If the RAW_POST_DATA environment - # variable is already set, wrap it in a StringIO. - def body - if raw_post = @env['RAW_POST_DATA'] - raw_post.force_encoding(Encoding::BINARY) if raw_post.respond_to?(:force_encoding) - StringIO.new(raw_post) - else - @env['rack.input'] - end - end - - # The raw content type string with its parameters stripped off. - def content_type_without_parameters - self.class.extract_content_type_without_parameters(content_type_with_parameters) - end - - def raw_post - unless @env.include? 'RAW_POST_DATA' - @env['RAW_POST_DATA'] = body.read(content_length) - body.rewind if body.respond_to?(:rewind) - end - @env['RAW_POST_DATA'] - end - - private - - def parse_formatted_request_parameters - return {} if content_length.zero? - - content_type, boundary = self.class.extract_multipart_boundary(content_type_with_parameters) - - # Don't parse params for unknown requests. - return {} if content_type.blank? - - mime_type = Mime::Type.lookup(content_type) - strategy = ActionController::Base.param_parsers[mime_type] - - # Only multipart form parsing expects a stream. - body = (strategy && strategy != :multipart_form) ? raw_post : self.body - - case strategy - when Proc - strategy.call(body) - when :url_encoded_form - self.class.clean_up_ajax_request_body! body - self.class.parse_query_parameters(body) - when :multipart_form - self.class.parse_multipart_form_parameters(body, boundary, content_length, @env) - when :xml_simple, :xml_node - body.blank? ? {} : Hash.from_xml(body).with_indifferent_access - when :yaml - YAML.load(body) - when :json - if body.blank? - {} - else - data = ActiveSupport::JSON.decode(body) - data = {:_json => data} unless data.is_a?(Hash) - data.with_indifferent_access - end - else - {} - end - rescue Exception => e # YAML, XML or Ruby code block errors - raise - { "body" => body, - "content_type" => content_type_with_parameters, - "content_length" => content_length, - "exception" => "#{e.message} (#{e.class})", - "backtrace" => e.backtrace } - end - - def content_length - @env['CONTENT_LENGTH'].to_i - end - - # The raw content type string. Use when you need parameters such as - # charset or boundary which aren't included in the content_type MIME type. - # Overridden by the X-POST_DATA_FORMAT header for backward compatibility. - def content_type_with_parameters - content_type_from_legacy_post_data_format_header || @env['CONTENT_TYPE'].to_s - end - - def content_type_from_legacy_post_data_format_header - if x_post_format = @env['HTTP_X_POST_DATA_FORMAT'] - case x_post_format.to_s.downcase - when 'yaml'; 'application/x-yaml' - when 'xml'; 'application/xml' - end - end - end - - class << self - def parse_query_parameters(query_string) - return {} if query_string.blank? - - pairs = query_string.split('&').collect do |chunk| - next if chunk.empty? - key, value = chunk.split('=', 2) - next if key.empty? - value = value.nil? ? nil : CGI.unescape(value) - [ CGI.unescape(key), value ] - end.compact - - UrlEncodedPairParser.new(pairs).result - end - - def parse_request_parameters(params) - parser = UrlEncodedPairParser.new - - params = params.dup - until params.empty? - for key, value in params - if key.blank? - params.delete key - elsif !key.include?('[') - # much faster to test for the most common case first (GET) - # and avoid the call to build_deep_hash - parser.result[key] = get_typed_value(value[0]) - params.delete key - elsif value.is_a?(Array) - parser.parse(key, get_typed_value(value.shift)) - params.delete key if value.empty? - else - raise TypeError, "Expected array, found #{value.inspect}" - end - end - end - - parser.result - end - - def parse_multipart_form_parameters(body, boundary, body_size, env) - parse_request_parameters(read_multipart(body, boundary, body_size, env)) - end - - def extract_multipart_boundary(content_type_with_parameters) - if content_type_with_parameters =~ MULTIPART_BOUNDARY - ['multipart/form-data', $1.dup] - else - extract_content_type_without_parameters(content_type_with_parameters) - end - end - - def extract_content_type_without_parameters(content_type_with_parameters) - $1.strip.downcase if content_type_with_parameters =~ /^([^,\;]*)/ - end - - def clean_up_ajax_request_body!(body) - body.chop! if body[-1] == 0 - body.gsub!(/&_=$/, '') - end - - - private - def get_typed_value(value) - case value - when String - value - when NilClass - '' - when Array - value.map { |v| get_typed_value(v) } - else - if value.respond_to? :original_filename - # Uploaded file - if value.original_filename - value - # Multipart param - else - result = value.read - value.rewind - result - end - # Unknown value, neither string nor multipart. - else - raise "Unknown form value: #{value.inspect}" - end - end - end - - MULTIPART_BOUNDARY = %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n - - EOL = "\015\012" - - def read_multipart(body, boundary, body_size, env) - params = Hash.new([]) - boundary = "--" + boundary - quoted_boundary = Regexp.quote(boundary) - buf = "" - bufsize = 10 * 1024 - boundary_end="" - - # start multipart/form-data - body.binmode if defined? body.binmode - case body - when File - body.set_encoding(Encoding::BINARY) if body.respond_to?(:set_encoding) - when StringIO - body.string.force_encoding(Encoding::BINARY) if body.string.respond_to?(:force_encoding) - end - boundary_size = boundary.size + EOL.size - body_size -= boundary_size - status = body.read(boundary_size) - if nil == status - raise EOFError, "no content body" - elsif boundary + EOL != status - raise EOFError, "bad content body" - end - - loop do - head = nil - content = - if 10240 < body_size - UploadedTempfile.new("CGI") - else - UploadedStringIO.new - end - content.binmode if defined? content.binmode - - until head and /#{quoted_boundary}(?:#{EOL}|--)/n.match(buf) - - if (not head) and /#{EOL}#{EOL}/n.match(buf) - buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do - head = $1.dup - "" - end - next - end - - if head and ( (EOL + boundary + EOL).size < buf.size ) - content.print buf[0 ... (buf.size - (EOL + boundary + EOL).size)] - buf[0 ... (buf.size - (EOL + boundary + EOL).size)] = "" - end - - c = if bufsize < body_size - body.read(bufsize) - else - body.read(body_size) - end - if c.nil? || c.empty? - raise EOFError, "bad content body" - end - buf.concat(c) - body_size -= c.size - end - - buf = buf.sub(/\A((?:.|\n)*?)(?:[\r\n]{1,2})?#{quoted_boundary}([\r\n]{1,2}|--)/n) do - content.print $1 - if "--" == $2 - body_size = -1 - end - boundary_end = $2.dup - "" - end - - content.rewind - - head =~ /Content-Disposition:.* filename=(?:"((?:\\.|[^\"])*)"|([^;]*))/ni - if filename = $1 || $2 - if /Mac/ni.match(env['HTTP_USER_AGENT']) and - /Mozilla/ni.match(env['HTTP_USER_AGENT']) and - (not /MSIE/ni.match(env['HTTP_USER_AGENT'])) - filename = CGI.unescape(filename) - end - content.original_path = filename.dup - end - - head =~ /Content-Type: ([^\r]*)/ni - content.content_type = $1.dup if $1 - - head =~ /Content-Disposition:.* name="?([^\";]*)"?/ni - name = $1.dup if $1 - - if params.has_key?(name) - params[name].push(content) - else - params[name] = [content] - end - break if body_size == -1 - end - raise EOFError, "bad boundary end of body part" unless boundary_end=~/--/ - - begin - body.rewind if body.respond_to?(:rewind) - rescue Errno::ESPIPE - # Handles exceptions raised by input streams that cannot be rewound - # such as when using plain CGI under Apache - end - - params - end - end # class << self - end -end diff --git a/actionpack/lib/action_controller/dispatch/rescue.rb b/actionpack/lib/action_controller/dispatch/rescue.rb index 0293e62fc7..df0a976204 100644 --- a/actionpack/lib/action_controller/dispatch/rescue.rb +++ b/actionpack/lib/action_controller/dispatch/rescue.rb @@ -60,8 +60,8 @@ module ActionController #:nodoc: module ClassMethods def call_with_exception(env, exception) #:nodoc: - request = env["action_controller.rescue.request"] ||= ActionController::Request.new(env) - response = env["action_controller.rescue.response"] ||= ActionController::Response.new + request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env) + response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new new.process(request, response, :rescue_action, exception) end end diff --git a/actionpack/lib/action_controller/rack_ext.rb b/actionpack/lib/action_controller/rack_ext.rb deleted file mode 100644 index 2ba6654e3d..0000000000 --- a/actionpack/lib/action_controller/rack_ext.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'action_controller/rack_ext/lock' -require 'action_controller/rack_ext/multipart' -require 'action_controller/rack_ext/parse_query' diff --git a/actionpack/lib/action_controller/routing/route_set.rb b/actionpack/lib/action_controller/routing/route_set.rb index 044ace7de1..70cd1f642d 100644 --- a/actionpack/lib/action_controller/routing/route_set.rb +++ b/actionpack/lib/action_controller/routing/route_set.rb @@ -428,7 +428,7 @@ module ActionController end def call(env) - request = Request.new(env) + request = ActionDispatch::Request.new(env) app = Routing::Routes.recognize(request) app.call(env).to_a end diff --git a/actionpack/lib/action_controller/session/management.rb b/actionpack/lib/action_controller/session/management.rb index b556f04649..ffce8e1bd1 100644 --- a/actionpack/lib/action_controller/session/management.rb +++ b/actionpack/lib/action_controller/session/management.rb @@ -26,7 +26,7 @@ module ActionController #:nodoc: if defined? @@session_store @@session_store else - Session::CookieStore + ActionDispatch::Session::CookieStore end end diff --git a/actionpack/lib/action_controller/testing/assertions/response.rb b/actionpack/lib/action_controller/testing/assertions/response.rb index 5976090273..ca0a9bbf52 100644 --- a/actionpack/lib/action_controller/testing/assertions/response.rb +++ b/actionpack/lib/action_controller/testing/assertions/response.rb @@ -11,7 +11,7 @@ module ActionController # # You can also pass an explicit status number like assert_response(501) # or its symbolic equivalent assert_response(:not_implemented). - # See ActionController::StatusCodes for a full list. + # See ActionDispatch::StatusCodes for a full list. # # ==== Examples # @@ -27,7 +27,7 @@ module ActionController assert_block("") { true } # to count the assertion elsif type.is_a?(Fixnum) && @response.response_code == type assert_block("") { true } # to count the assertion - elsif type.is_a?(Symbol) && @response.response_code == ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE[type] + elsif type.is_a?(Symbol) && @response.response_code == ActionDispatch::StatusCodes::SYMBOL_TO_STATUS_CODE[type] assert_block("") { true } # to count the assertion else if @response.error? diff --git a/actionpack/lib/action_controller/testing/integration.rb b/actionpack/lib/action_controller/testing/integration.rb index 163ba84a3e..0da23f9dc8 100644 --- a/actionpack/lib/action_controller/testing/integration.rb +++ b/actionpack/lib/action_controller/testing/integration.rb @@ -316,7 +316,7 @@ module ActionController @html_document = nil @status = status.to_i - @status_message = StatusCodes::STATUS_CODES[@status] + @status_message = ActionDispatch::StatusCodes::STATUS_CODES[@status] @headers = Rack::Utils::HeaderHash.new(headers) @@ -335,7 +335,7 @@ module ActionController else # Decorate responses from Rack Middleware and Rails Metal # as an Response for the purposes of integration testing - @response = Response.new + @response = ActionDispatch::Response.new @response.status = status.to_s @response.headers.replace(@headers) @response.body = @body @@ -374,7 +374,7 @@ module ActionController "SERVER_PORT" => https? ? "443" : "80", "HTTPS" => https? ? "on" : "off" } - UrlRewriter.new(Request.new(env), {}) + UrlRewriter.new(ActionDispatch::Request.new(env), {}) end def name_with_prefix(prefix, name) diff --git a/actionpack/lib/action_controller/testing/process.rb b/actionpack/lib/action_controller/testing/process.rb index 22b97fc157..199ffb702c 100644 --- a/actionpack/lib/action_controller/testing/process.rb +++ b/actionpack/lib/action_controller/testing/process.rb @@ -1,5 +1,5 @@ module ActionController #:nodoc: - class TestRequest < Request #:nodoc: + class TestRequest < ActionDispatch::Request #:nodoc: attr_accessor :cookies, :session_options attr_accessor :query_parameters, :path, :session attr_accessor :host @@ -270,7 +270,7 @@ module ActionController #:nodoc: # controller actions. # # See Response for more information on controller response objects. - class TestResponse < Response + class TestResponse < ActionDispatch::Response include TestResponseBehavior def recycle! diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb new file mode 100644 index 0000000000..393ccaa795 --- /dev/null +++ b/actionpack/lib/action_dispatch.rb @@ -0,0 +1,64 @@ +#-- +# Copyright (c) 2004-2009 David Heinemeier Hansson +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#++ + +begin + require 'active_support' +rescue LoadError + activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib" + if File.directory?(activesupport_path) + $:.unshift activesupport_path + require 'active_support' + end +end + +gem 'rack', '>= 0.9.0' +require 'rack' +require 'action_dispatch/rack' + +module ActionDispatch + autoload :Request, 'action_dispatch/http/request' + autoload :Response, 'action_dispatch/http/response' + autoload :StatusCodes, 'action_dispatch/http/status_codes' + + autoload :Failsafe, 'action_dispatch/middleware/failsafe' + autoload :ParamsParser, 'action_dispatch/middleware/params_parser' + autoload :RewindableInput, 'action_dispatch/middleware/rewindable_input' + + autoload :MiddlewareStack, 'action_dispatch/utils/middleware_stack' + autoload :UploadedFile, 'action_dispatch/utils/uploaded_file' + autoload :UploadedStringIO, 'action_dispatch/utils/uploaded_file' + autoload :UploadedTempfile, 'action_dispatch/utils/uploaded_file' + autoload :UrlEncodedPairParser, 'action_dispatch/utils/url_encoded_pair_parser' + + module Http + autoload :Headers, 'action_dispatch/http/headers' + end + + module Session + autoload :AbstractStore, 'action_dispatch/middleware/session/abstract_store' + autoload :CookieStore, 'action_dispatch/middleware/session/cookie_store' + autoload :MemCacheStore, 'action_dispatch/middleware/session/mem_cache_store' + end +end + +autoload :Mime, 'action_dispatch/http/mime_type' diff --git a/actionpack/lib/action_controller/base/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb similarity index 96% rename from actionpack/lib/action_controller/base/headers.rb rename to actionpack/lib/action_dispatch/http/headers.rb index 139669c66f..2a41b4dbad 100644 --- a/actionpack/lib/action_controller/base/headers.rb +++ b/actionpack/lib/action_dispatch/http/headers.rb @@ -1,6 +1,6 @@ require 'active_support/memoizable' -module ActionController +module ActionDispatch module Http class Headers < ::Hash extend ActiveSupport::Memoizable diff --git a/actionpack/lib/action_controller/mime/type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb similarity index 99% rename from actionpack/lib/action_controller/mime/type.rb rename to actionpack/lib/action_dispatch/http/mime_type.rb index 23a39dff54..0a7b1001c8 100644 --- a/actionpack/lib/action_controller/mime/type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -211,4 +211,4 @@ module Mime end end -require 'action_controller/mime/default_types' +require 'action_dispatch/http/mime_types' diff --git a/actionpack/lib/action_controller/mime/default_types.rb b/actionpack/lib/action_dispatch/http/mime_types.rb similarity index 100% rename from actionpack/lib/action_controller/mime/default_types.rb rename to actionpack/lib/action_dispatch/http/mime_types.rb diff --git a/actionpack/lib/action_controller/dispatch/request.rb b/actionpack/lib/action_dispatch/http/request.rb similarity index 97% rename from actionpack/lib/action_controller/dispatch/request.rb rename to actionpack/lib/action_dispatch/http/request.rb index f8c77241b9..0da7daacf2 100755 --- a/actionpack/lib/action_controller/dispatch/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -5,7 +5,7 @@ require 'strscan' require 'active_support/memoizable' require 'action_controller/cgi_ext' -module ActionController +module ActionDispatch class Request < Rack::Request extend ActiveSupport::Memoizable @@ -33,7 +33,7 @@ module ActionController # :get. If the request \method is not listed in the HTTP_METHODS # constant above, an UnknownHttpMethod exception is raised. def request_method - HTTP_METHOD_LOOKUP[super] || raise(UnknownHttpMethod, "#{super}, accepted HTTP methods are #{HTTP_METHODS.to_sentence}") + HTTP_METHOD_LOOKUP[super] || raise(ActionController::UnknownHttpMethod, "#{super}, accepted HTTP methods are #{HTTP_METHODS.to_sentence}") end memoize :request_method @@ -75,7 +75,7 @@ module ActionController # # request.headers["Content-Type"] # => "text/plain" def headers - ActionController::Http::Headers.new(@env) + Http::Headers.new(@env) end memoize :headers @@ -162,7 +162,7 @@ module ActionController @format ||= if parameters[:format] Mime[parameters[:format]] - elsif Base.use_accept_header && !(accepts == ONLY_ALL) + elsif ActionController::Base.use_accept_header && !(accepts == ONLY_ALL) accepts.first elsif xhr? then Mime::JS else Mime::HTML @@ -171,7 +171,7 @@ module ActionController def formats @formats = - if Base.use_accept_header + if ActionController::Base.use_accept_header ret = Array(Mime[parameters[:format]] || accepts) else [format] @@ -243,7 +243,7 @@ module ActionController if @env.include? 'HTTP_CLIENT_IP' if ActionController::Base.ip_spoofing_check && remote_ips && !remote_ips.include?(@env['HTTP_CLIENT_IP']) # We don't know which came from the proxy, and which from the user - raise ActionControllerError.new(<"text/plain") + @headers = ActionDispatch::Http::Headers.new("HTTP_CONTENT_TYPE"=>"text/plain") end def test_content_type_works diff --git a/actionpack/test/controller/middleware_stack_test.rb b/actionpack/test/controller/middleware_stack_test.rb index 2a141697da..e5496c848b 100644 --- a/actionpack/test/controller/middleware_stack_test.rb +++ b/actionpack/test/controller/middleware_stack_test.rb @@ -6,7 +6,7 @@ class MiddlewareStackTest < ActiveSupport::TestCase class BazMiddleware; end def setup - @stack = ActionController::MiddlewareStack.new + @stack = ActionDispatch::MiddlewareStack.new @stack.use FooMiddleware @stack.use BarMiddleware end diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index 8ad42614b4..c29902c722 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -43,10 +43,10 @@ class BaseRackTest < Test::Unit::TestCase "REDIRECT_STATUS" => "200", "REQUEST_METHOD" => "GET" } - @request = ActionController::Request.new(@env) + @request = ActionDispatch::Request.new(@env) # some Nokia phone browsers omit the space after the semicolon separator. # some developers have grown accustomed to using comma in cookie values. - @alt_cookie_fmt_request = ActionController::Request.new(@env.merge({"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"})) + @alt_cookie_fmt_request = ActionDispatch::Request.new(@env.merge({"HTTP_COOKIE"=>"_session_id=c84ace847,96670c052c6ceb2451fb0f2;is_admin=yes"})) end def default_test; end @@ -195,7 +195,7 @@ class RackRequestNeedsRewoundTest < BaseRackTest @env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded; charset=utf-8' # Read the request body by parsing params. - request = ActionController::Request.new(@env) + request = ActionDispatch::Request.new(@env) request.request_parameters # Should have rewound the body. @@ -206,7 +206,7 @@ end class RackResponseTest < BaseRackTest def setup super - @response = ActionController::Response.new + @response = ActionDispatch::Response.new end def test_simple_output @@ -252,7 +252,7 @@ end class RackResponseHeadersTest < BaseRackTest def setup super - @response = ActionController::Response.new + @response = ActionDispatch::Response.new @response.status = "200 OK" end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 11b502a564..a339bb524c 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -1223,7 +1223,7 @@ class RenderTest < ActionController::TestCase assert !@response.headers.include?('Content-Length') assert_response :no_content - ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE.each do |status, code| + ActionDispatch::StatusCodes::SYMBOL_TO_STATUS_CODE.each do |status, code| get :head_with_symbolic_status, :status => status.to_s assert_equal code, @response.response_code assert_response status @@ -1231,7 +1231,7 @@ class RenderTest < ActionController::TestCase end def test_head_with_integer_status - ActionController::StatusCodes::STATUS_CODES.each do |code, message| + ActionDispatch::StatusCodes::STATUS_CODES.each do |code, message| get :head_with_integer_status, :status => code.to_s assert_equal message, @response.message end diff --git a/actionpack/test/controller/request/multipart_params_parsing_test.rb b/actionpack/test/controller/request/multipart_params_parsing_test.rb index 054519d0d2..5b9728cc42 100644 --- a/actionpack/test/controller/request/multipart_params_parsing_test.rb +++ b/actionpack/test/controller/request/multipart_params_parsing_test.rb @@ -215,7 +215,7 @@ class MultipartParamsParsingTest < ActionController::IntegrationTest def with_muck_middleware original_middleware = ActionController::Dispatcher.middleware middleware = original_middleware.dup - middleware.insert_after ActionController::RewindableInput, MuckMiddleware + middleware.insert_after ActionDispatch::RewindableInput, MuckMiddleware ActionController::Dispatcher.middleware = middleware yield ActionController::Dispatcher.middleware = original_middleware diff --git a/actionpack/test/controller/request/url_encoded_params_parsing_test.rb b/actionpack/test/controller/request/url_encoded_params_parsing_test.rb index 89239687de..9f0535bbcc 100644 --- a/actionpack/test/controller/request/url_encoded_params_parsing_test.rb +++ b/actionpack/test/controller/request/url_encoded_params_parsing_test.rb @@ -195,7 +195,7 @@ class UrlEncodedParamsParsingTest < ActionController::IntegrationTest def with_muck_middleware original_middleware = ActionController::Dispatcher.middleware middleware = original_middleware.dup - middleware.insert_after ActionController::RewindableInput, MuckMiddleware + middleware.insert_after ActionDispatch::RewindableInput, MuckMiddleware ActionController::Dispatcher.middleware = middleware yield ActionController::Dispatcher.middleware = original_middleware diff --git a/actionpack/test/controller/rescue_test.rb b/actionpack/test/controller/rescue_test.rb index 9f6b45f065..a2a2a3ee29 100644 --- a/actionpack/test/controller/rescue_test.rb +++ b/actionpack/test/controller/rescue_test.rb @@ -393,7 +393,7 @@ class RescueControllerTest < ActionController::TestCase def test_rescue_dispatcher_exceptions_without_request_set @request.env['REQUEST_URI'] = '/no_way' response = RescueController.call_with_exception(@request.env, ActionController::RoutingError.new("Route not found")) - assert_kind_of ActionController::Response, response + assert_kind_of ActionDispatch::Response, response assert_equal "no way", response.body end diff --git a/actionpack/test/controller/session/cookie_store_test.rb b/actionpack/test/controller/session/cookie_store_test.rb index b6a38f47aa..d77be31c9a 100644 --- a/actionpack/test/controller/session/cookie_store_test.rb +++ b/actionpack/test/controller/session/cookie_store_test.rb @@ -6,7 +6,7 @@ class CookieStoreTest < ActionController::IntegrationTest SessionSecret = 'b3c631c314c0bbca50c1b2843150fe33' DispatcherApp = ActionController::Dispatcher.new - CookieStoreApp = ActionController::Session::CookieStore.new(DispatcherApp, + CookieStoreApp = ActionDispatch::Session::CookieStore.new(DispatcherApp, :key => SessionKey, :secret => SessionSecret) Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, 'SHA1') @@ -51,41 +51,41 @@ class CookieStoreTest < ActionController::IntegrationTest def test_raises_argument_error_if_missing_session_key assert_raise(ArgumentError, nil.inspect) { - ActionController::Session::CookieStore.new(nil, + ActionDispatch::Session::CookieStore.new(nil, :key => nil, :secret => SessionSecret) } assert_raise(ArgumentError, ''.inspect) { - ActionController::Session::CookieStore.new(nil, + ActionDispatch::Session::CookieStore.new(nil, :key => '', :secret => SessionSecret) } end def test_raises_argument_error_if_missing_secret assert_raise(ArgumentError, nil.inspect) { - ActionController::Session::CookieStore.new(nil, + ActionDispatch::Session::CookieStore.new(nil, :key => SessionKey, :secret => nil) } assert_raise(ArgumentError, ''.inspect) { - ActionController::Session::CookieStore.new(nil, + ActionDispatch::Session::CookieStore.new(nil, :key => SessionKey, :secret => '') } end def test_raises_argument_error_if_secret_is_probably_insecure assert_raise(ArgumentError, "password".inspect) { - ActionController::Session::CookieStore.new(nil, + ActionDispatch::Session::CookieStore.new(nil, :key => SessionKey, :secret => "password") } assert_raise(ArgumentError, "secret".inspect) { - ActionController::Session::CookieStore.new(nil, + ActionDispatch::Session::CookieStore.new(nil, :key => SessionKey, :secret => "secret") } assert_raise(ArgumentError, "12345678901234567890123456789".inspect) { - ActionController::Session::CookieStore.new(nil, + ActionDispatch::Session::CookieStore.new(nil, :key => SessionKey, :secret => "12345678901234567890123456789") } end @@ -119,7 +119,7 @@ class CookieStoreTest < ActionController::IntegrationTest def test_close_raises_when_data_overflows with_test_route_set do - assert_raise(ActionController::Session::CookieStore::CookieOverflow) { + assert_raise(ActionDispatch::Session::CookieStore::CookieOverflow) { get '/raise_data_overflow' } end diff --git a/actionpack/test/controller/session/mem_cache_store_test.rb b/actionpack/test/controller/session/mem_cache_store_test.rb index eb896a344c..2e2bf79148 100644 --- a/actionpack/test/controller/session/mem_cache_store_test.rb +++ b/actionpack/test/controller/session/mem_cache_store_test.rb @@ -26,7 +26,7 @@ class MemCacheStoreTest < ActionController::IntegrationTest begin DispatcherApp = ActionController::Dispatcher.new - MemCacheStoreApp = ActionController::Session::MemCacheStore.new( + MemCacheStoreApp = ActionDispatch::Session::MemCacheStore.new( DispatcherApp, :key => '_session_id') diff --git a/activerecord/lib/active_record/session_store.rb b/activerecord/lib/active_record/session_store.rb index 5e45cf65ab..74d91f129e 100644 --- a/activerecord/lib/active_record/session_store.rb +++ b/activerecord/lib/active_record/session_store.rb @@ -40,7 +40,7 @@ module ActiveRecord # # The example SqlBypass class is a generic SQL session store. You may # use it as a basis for high-performance database-specific stores. - class SessionStore < ActionController::Session::AbstractStore + class SessionStore < ActionDispatch::Session::AbstractStore # The default Active Record class. class Session < ActiveRecord::Base ##