diff options
author | Carl Lerche <carllerche@mac.com> | 2010-03-03 22:35:43 -0800 |
---|---|---|
committer | Carl Lerche <carllerche@mac.com> | 2010-03-03 22:35:43 -0800 |
commit | 5ce25aecee062c11fc0186ae2df625ba3f013a46 (patch) | |
tree | 2c0dc0f69d4ff0dc182cc9f32d59d85257a6723b /actionpack/lib/action_controller | |
parent | 2a60cc682224f8a0923de1e0bf769d5333084480 (diff) | |
parent | 13a932cddcd3165792d3454009b6d07471031a2c (diff) | |
download | rails-5ce25aecee062c11fc0186ae2df625ba3f013a46.tar.gz rails-5ce25aecee062c11fc0186ae2df625ba3f013a46.tar.bz2 rails-5ce25aecee062c11fc0186ae2df625ba3f013a46.zip |
Merge branch 'configuration_refactor'
Diffstat (limited to 'actionpack/lib/action_controller')
8 files changed, 159 insertions, 62 deletions
diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 2b1ada1426..4c2136de8a 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -7,16 +7,17 @@ module ActionController class ::ActionController::ActionControllerError < StandardError #:nodoc: end + module ClassMethods + end + # Temporary hax included do ::ActionController::UnknownAction = ::AbstractController::ActionNotFound ::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError - cattr_accessor :session_options - self.session_options = {} - - cattr_accessor :relative_url_root - self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] + # ROUTES TODO: This should be handled by a middleware and route generation + # should be able to handle SCRIPT_NAME + self.config.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] class << self delegate :default_charset=, :to => "ActionDispatch::Response" @@ -31,11 +32,24 @@ module ActionController @_response) # Controls the resource action separator - cattr_accessor :resource_action_separator - self.resource_action_separator = "/" + def self.resource_action_separator + @resource_action_separator ||= "/" + end - cattr_accessor :use_accept_header - self.use_accept_header = true + def self.resource_action_separator=(val) + ActiveSupport::Deprecation.warn "ActionController::Base.resource_action_separator is deprecated and only " \ + "works with the deprecated router DSL." + @resource_action_separator = val + end + + def self.use_accept_header + ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \ + "The accept header is always taken into account." + end + + def self.use_accept_header=(val) + use_accept_header + end self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" @@ -43,13 +57,44 @@ module ActionController # and images to a dedicated asset server away from the main web server. Example: # ActionController::Base.asset_host = "http://assets.example.com" cattr_accessor :asset_host + end + + def self.deprecated_config_accessor(option, message = nil) + deprecated_config_reader(option, message) + deprecated_config_writer(option, message) + end - cattr_accessor :ip_spoofing_check - self.ip_spoofing_check = true + def self.deprecated_config_reader(option, message = nil) + message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \ + "Please read it from config.#{option}" - cattr_accessor :trusted_proxies + ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{option} + ActiveSupport::Deprecation.warn #{message.inspect}, caller + config.#{option} + end + RUBY end + def self.deprecated_config_writer(option, message = nil) + message ||= "Setting #{option} directly on ActionController::Base is deprecated. " \ + "Please set it on config.action_controller.#{option}" + + ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{option}=(val) + ActiveSupport::Deprecation.warn #{message.inspect}, caller + config.#{option} = val + end + RUBY + end + + deprecated_config_writer :session_store + deprecated_config_writer :session_options + deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it" + deprecated_config_accessor :assets_dir + deprecated_config_accessor :javascripts_dir + deprecated_config_accessor :stylesheets_dir + # For old tests def initialize_template_class(*) end def assign_shortcuts(*) end @@ -67,28 +112,52 @@ module ActionController module ClassMethods def consider_all_requests_local ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " << - "use Rails.application.config.consider_all_requests_local instead" + "use Rails.application.config.consider_all_requests_local instead", caller Rails.application.config.consider_all_requests_local end def consider_all_requests_local=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is no longer effective. " << - "Please configure it on your application with config.consider_all_requests_local=" + ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " << + "Please configure it on your application with config.consider_all_requests_local=", caller Rails.application.config.consider_all_requests_local = value end def allow_concurrency ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " << - "use Rails.application.config.allow_concurrency instead" + "use Rails.application.config.allow_concurrency instead", caller Rails.application.config.allow_concurrency end def allow_concurrency=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is no longer effective. " << - "Please configure it on your application with config.allow_concurrency=" + ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " << + "Please configure it on your application with config.allow_concurrency=", caller Rails.application.config.allow_concurrency = value end + def ip_spoofing_check=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << + "Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller + Rails.application.config.action_disaptch.ip_spoofing_check = value + end + + def ip_spoofing_check + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " << + "Configuring ip_spoofing_check on the application configures a middleware.", caller + Rails.application.config.action_disaptch.ip_spoofing_check + end + + def trusted_proxies=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " << + "Please configure it on your application with config.action_dispatch.trusted_proxies=", caller + Rails.application.config.action_dispatch.ip_spoofing_check = value + end + + def trusted_proxies + ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " << + "Configuring trusted_proxies on the application configures a middleware.", caller + Rails.application.config.action_dispatch.ip_spoofing_check = value + end + def rescue_action(env) raise env["action_dispatch.rescue.exception"] end diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index 0f35a7c040..afa7674e40 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -165,7 +165,7 @@ module ActionController # Authenticate with HTTP Digest, returns true or false def authenticate_with_http_digest(realm = "Application", &password_procedure) - HttpAuthentication::Digest.authenticate(request, realm, &password_procedure) + HttpAuthentication::Digest.authenticate(config.session_options[:secret], request, realm, &password_procedure) end # Render output including the HTTP Digest authentication header @@ -175,8 +175,8 @@ module ActionController end # Returns false on a valid response, true otherwise - def authenticate(request, realm, &password_procedure) - authorization(request) && validate_digest_response(request, realm, &password_procedure) + def authenticate(secret_key, request, realm, &password_procedure) + authorization(request) && validate_digest_response(secret_key, request, realm, &password_procedure) end def authorization(request) @@ -189,16 +189,16 @@ module ActionController # Returns false unless the request credentials response value matches the expected value. # First try the password as a ha1 digest password. If this fails, then try it as a plain # text password. - def validate_digest_response(request, realm, &password_procedure) + def validate_digest_response(secret_key, request, realm, &password_procedure) credentials = decode_credentials_header(request) - valid_nonce = validate_nonce(request, credentials[:nonce]) + valid_nonce = validate_nonce(secret_key, request, credentials[:nonce]) - if valid_nonce && realm == credentials[:realm] && opaque == credentials[:opaque] + if valid_nonce && realm == credentials[:realm] && opaque(secret_key) == credentials[:opaque] password = password_procedure.call(credentials[:username]) return false unless password method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD'] - uri = credentials[:uri][0,1] == '/' ? request.request_uri : request.url + uri = credentials[:uri][0,1] == '/' ? request.fullpath : request.url [true, false].any? do |password_is_ha1| expected = expected_response(method, uri, credentials, password, password_is_ha1) @@ -238,6 +238,9 @@ module ActionController end def authentication_header(controller, realm) + secret_key = controller.config.session_options[:secret] + nonce = self.nonce(secret_key) + opaque = opaque(secret_key) controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}") end @@ -280,7 +283,7 @@ module ActionController # The nonce is opaque to the client. Composed of Time, and hash of Time with secret # key from the Rails session secret generated upon creation of project. Ensures # the time cannot be modified by client. - def nonce(time = Time.now) + def nonce(secret_key, time = Time.now) t = time.to_i hashed = [t, secret_key] digest = ::Digest::MD5.hexdigest(hashed.join(":")) @@ -292,21 +295,16 @@ module ActionController # Can be much shorter if the Stale directive is implemented. This would # allow a user to use new nonce without prompting user again for their # username and password. - def validate_nonce(request, value, seconds_to_timeout=5*60) + def validate_nonce(secret_key, request, value, seconds_to_timeout=5*60) t = ActiveSupport::Base64.decode64(value).split(":").first.to_i - nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout + nonce(secret_key, t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout end # Opaque based on random generation - but changing each request? - def opaque() + def opaque(secret_key) ::Digest::MD5.hexdigest(secret_key) end - # Set in /initializers/session_store.rb, and loaded even if sessions are not in use. - def secret_key - ActionController::Base.session_options[:secret] - end - end end end diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb index 85035dc09c..d69de65f28 100644 --- a/actionpack/lib/action_controller/metal/instrumentation.rb +++ b/actionpack/lib/action_controller/metal/instrumentation.rb @@ -20,7 +20,7 @@ module ActionController :params => request.filtered_parameters, :formats => request.formats.map(&:to_sym), :method => request.method, - :path => (request.request_uri rescue "unknown") + :path => (request.fullpath rescue "unknown") } ActiveSupport::Notifications.instrument("action_controller.start_processing", raw_payload.dup) diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index 6997257844..ce8b20964b 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -2,28 +2,29 @@ module ActionController #:nodoc: module SessionManagement #:nodoc: extend ActiveSupport::Concern + included do + # This is still needed for the session secret for some reason. + self.config.session_options ||= {} + end + + def self.session_store_for(store) + case store + when :active_record_store + ActiveRecord::SessionStore + when Symbol + ActionDispatch::Session.const_get(store.to_s.camelize) + else + store + end + end + module ClassMethods - # Set the session store to be used for keeping the session data between requests. - # By default, sessions are stored in browser cookies (<tt>:cookie_store</tt>), - # but you can also specify one of the other included stores (<tt>:active_record_store</tt>, - # <tt>:mem_cache_store</tt>, or your own custom class. - def session_store=(store) - if store == :active_record_store - self.session_store = ActiveRecord::SessionStore - else - @@session_store = store.is_a?(Symbol) ? - ActionDispatch::Session.const_get(store.to_s.camelize) : - store - end + def session_options + config.session_options end - # Returns the session store class currently used. def session_store - if defined? @@session_store - @@session_store - else - ActionDispatch::Session::CookieStore - end + SessionManagement.session_store_for(config.session_store) end def session=(options = {}) diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 8a06f34d23..c890dc51d4 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -9,6 +9,10 @@ module ActionController super.reverse_merge( :host => request.host_with_port, :protocol => request.protocol, + # ROUTES TODO: relative_url_root should be middleware + # and the generator should take SCRIPT_NAME into + # consideration + :relative_url_root => config.relative_url_root, :_path_segments => request.symbolized_path_parameters ) end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 07c6b8f2b6..3a084cdf67 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -13,11 +13,28 @@ module ActionController log_subscriber ActionController::Railties::LogSubscriber.new + config.action_controller.session_store = :cookie_store + config.action_controller.session_options = {} + initializer "action_controller.logger" do ActionController::Base.logger ||= Rails.logger end + # assets_dir = defined?(Rails.public_path) ? Rails.public_path : "public" + # ActionView::DEFAULT_CONFIG = { + # :assets_dir => assets_dir, + # :javascripts_dir => "#{assets_dir}/javascripts", + # :stylesheets_dir => "#{assets_dir}/stylesheets", + # } + + initializer "action_controller.set_configs" do |app| + paths = app.config.paths + ac = app.config.action_controller + ac.assets_dir = paths.public + ac.javascripts_dir = paths.public.javascripts + ac.stylesheets_dir = paths.public.stylesheets + app.config.action_controller.each do |k,v| ActionController::Base.send "#{k}=", v end diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 64d9bdab2a..7e0a833dfa 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -322,6 +322,8 @@ module ActionController @controller ||= klass.new rescue nil end + @request.env.delete('PATH_INFO') + if @controller @controller.request = @request @controller.params = {} @@ -333,15 +335,19 @@ module ActionController @request.remote_addr = '208.77.188.166' # example.com end - private - def build_request_uri(action, parameters) - unless @request.env['REQUEST_URI'] - options = @controller.__send__(:url_options).merge(parameters) - options.update(:only_path => true, :action => action) + private + def build_request_uri(action, parameters) + unless @request.env["PATH_INFO"] + options = @controller.__send__(:url_options).merge(parameters) + options.update(:only_path => true, :action => action, :relative_url_root => nil) + rewriter = ActionController::UrlRewriter.new(@request, parameters) - url = ActionController::UrlRewriter.new(@request, parameters) - @request.request_uri = url.rewrite(@router, options) - end + url, query_string = rewriter.rewrite(@router, options).split("?", 2) + + @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root + @request.env["PATH_INFO"] = url + @request.env["QUERY_STRING"] = query_string || "" end + end end end diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 807b21cd0e..973a6facd7 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -32,6 +32,7 @@ module ActionController # ROUTES TODO: Fix the tests segments = options.delete(:_path_segments) + relative_url_root = options.delete(:relative_url_root).to_s path_segments = path_segments ? path_segments.merge(segments || {}) : segments unless options[:only_path] @@ -49,7 +50,8 @@ module ActionController path_options = yield(path_options) if block_given? path = router.generate(path_options, path_segments || {}) - rewritten_url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root] + # ROUTES TODO: This can be called directly, so relative_url_root should probably be set in the router + rewritten_url << relative_url_root rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor] |