diff options
Diffstat (limited to 'actionpack/lib')
19 files changed, 240 insertions, 148 deletions
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index e14818e464..24f3b552ba 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -1,3 +1,5 @@ +require 'active_support/ordered_options' + module AbstractController class Error < StandardError; end class ActionNotFound < StandardError; end @@ -28,6 +30,10 @@ module AbstractController @descendants ||= [] end + def config + @config ||= ActiveSupport::InheritableOptions.new(superclass < Base ? superclass.config : {}) + end + # A list of all internal methods for a controller. This finds the first # abstract superclass of a controller, and gets a list of all public # instance methods on that abstract class. Public instance methods of @@ -95,6 +101,10 @@ module AbstractController @_formats = nil end + def config + @config ||= ActiveSupport::InheritableOptions.new(self.class.config) + end + # Calls the action going through the entire action dispatch stack. # # The actual method that is called is determined by calling 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] diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 479ea959e6..dfb8919561 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -48,6 +48,7 @@ module ActionDispatch autoload :Flash autoload :Head autoload :ParamsParser + autoload :RemoteIp autoload :Rescue autoload :ShowExceptions autoload :Static diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 7a17023ed2..56a2b9bf6a 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -119,36 +119,7 @@ module ActionDispatch # delimited list in the case of multiple chained proxies; the last # address which is not trusted is the originating IP. def remote_ip - remote_addr_list = @env['REMOTE_ADDR'] && @env['REMOTE_ADDR'].scan(/[^,\s]+/) - - unless remote_addr_list.blank? - not_trusted_addrs = remote_addr_list.reject {|addr| addr =~ TRUSTED_PROXIES || addr =~ ActionController::Base.trusted_proxies} - return not_trusted_addrs.first unless not_trusted_addrs.empty? - end - remote_ips = @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_X_FORWARDED_FOR'].split(',') - - 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 ActionController::ActionControllerError.new <<EOM -IP spoofing attack?! -HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect} -HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect} -EOM - end - - return @env['HTTP_CLIENT_IP'] - end - - if remote_ips - while remote_ips.size > 1 && (TRUSTED_PROXIES =~ remote_ips.last.strip || ActionController::Base.trusted_proxies =~ remote_ips.last.strip) - remote_ips.pop - end - - return remote_ips.last.strip - end - - @env['REMOTE_ADDR'] + (@env["action_dispatch.remote_ip"] || ip).to_s end # Returns the lowercase name of the HTTP server software. diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 42ad19044d..b64a83c62e 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -3,7 +3,7 @@ module ActionDispatch module URL # Returns the complete URL used for this request. def url - protocol + host_with_port + request_uri + protocol + host_with_port + fullpath end # Returns 'https://' if this is an SSL request and 'http://' otherwise. @@ -85,42 +85,11 @@ module ActionDispatch subdomains(tld_length).join('.') end - # Returns the query string, accounting for server idiosyncrasies. - def query_string - @env['QUERY_STRING'].present? ? @env['QUERY_STRING'] : (@env['REQUEST_URI'].to_s.split('?', 2)[1] || '') - end - # Returns the request URI, accounting for server idiosyncrasies. # WEBrick includes the full URL. IIS leaves REQUEST_URI blank. def request_uri - if uri = @env['REQUEST_URI'] - # Remove domain, which webrick puts into the request_uri. - (%r{^\w+\://[^/]+(/.*|$)$} =~ uri) ? $1 : uri - else - # Construct IIS missing REQUEST_URI from SCRIPT_NAME and PATH_INFO. - uri = @env['PATH_INFO'].to_s - - if script_filename = @env['SCRIPT_NAME'].to_s.match(%r{[^/]+$}) - uri = uri.sub(/#{script_filename}\//, '') - end - - env_qs = @env['QUERY_STRING'].to_s - uri += "?#{env_qs}" unless env_qs.empty? - - if uri.blank? - @env.delete('REQUEST_URI') - else - @env['REQUEST_URI'] = uri - end - end - end - - # Returns the interpreted \path to requested resource after all the installation - # directory of this application was taken into account. - def path - path = request_uri.to_s[/\A[^\?]*/] - path.sub!(/\A#{ActionController::Base.relative_url_root}/, '') - path + ActiveSupport::Deprecation.warn "Using #request_uri is deprecated. Use fullpath instead.", caller + fullpath end private diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb new file mode 100644 index 0000000000..c7d710b98e --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -0,0 +1,51 @@ +module ActionDispatch + class RemoteIp + class IpSpoofAttackError < StandardError ; end + + class RemoteIpGetter + def initialize(env, check_ip_spoofing, trusted_proxies) + @env = env + @check_ip_spoofing = check_ip_spoofing + @trusted_proxies = trusted_proxies + end + + def remote_addrs + @remote_addrs ||= begin + list = @env['REMOTE_ADDR'] ? @env['REMOTE_ADDR'].split(/[,\s]+/) : [] + list.reject { |addr| addr =~ @trusted_proxies } + end + end + + def to_s + return remote_addrs.first if remote_addrs.any? + + forwarded_ips = @env['HTTP_X_FORWARDED_FOR'] ? @env['HTTP_X_FORWARDED_FOR'].strip.split(/[,\s]+/) : [] + + if client_ip = @env['HTTP_CLIENT_IP'] + if @check_ip_spoofing && !forwarded_ips.include?(client_ip) + # We don't know which came from the proxy, and which from the user + raise IpSpoofAttackError, "IP spoofing attack?!" \ + "HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect}" \ + "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" + end + return client_ip + end + + return forwarded_ips.reject { |ip| ip =~ @trusted_proxies }.last || @env["REMOTE_ADDR"] + end + end + + def initialize(app, check_ip_spoofing = true, trusted_proxies = nil) + @app = app + @check_ip_spoofing = check_ip_spoofing + regex = '(^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.)' + regex << "|(#{trusted_proxies})" if trusted_proxies + @trusted_proxies = Regexp.new(regex, "i") + end + + def call(env) + env["action_dispatch.remote_ip"] = RemoteIpGetter.new(env, @check_ip_spoofing, @trusted_proxies) + @app.call(env) + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index 79e9464337..e486bd4079 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -6,6 +6,7 @@ module ActionDispatch railtie_name :action_dispatch config.action_dispatch.x_sendfile_header = "X-Sendfile" + config.action_dispatch.ip_spoofing_check = true # Prepare dispatcher callbacks and run 'prepare' callbacks initializer "action_dispatch.prepare_dispatcher" do |app| diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 2d2b53a6ce..76f9eb2b0d 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -175,15 +175,6 @@ module ActionView #:nodoc: include Helpers, Rendering, Partials, ::ERB::Util - def config - self.config = DEFAULT_CONFIG unless @config - @config - end - - def config=(config) - @config = ActiveSupport::OrderedOptions.new.merge(config) - end - extend ActiveSupport::Memoizable attr_accessor :base_path, :assigns, :template_extension @@ -306,12 +297,13 @@ module ActionView #:nodoc: @helpers = self.class.helpers || Module.new @_controller = controller + @_config = ActiveSupport::InheritableOptions.new(controller.config) if controller @_content_for = Hash.new {|h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil self.view_paths = view_paths end - attr_internal :controller, :template + attr_internal :controller, :template, :config attr_reader :view_paths def view_paths=(paths) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 96976ce45f..b52d255d1f 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -133,13 +133,6 @@ module ActionView # change. You can use something like Live HTTP Headers for Firefox to verify # that the cache is indeed working. module AssetTagHelper - 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", - } - JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls', 'rails'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES) # Returns a link tag that browsers and news readers can use to auto-detect @@ -648,8 +641,8 @@ module ActionView source = rewrite_asset_path(source) if has_request && include_host - unless source =~ %r{^#{ActionController::Base.relative_url_root}/} - source = "#{ActionController::Base.relative_url_root}#{source}" + unless source =~ %r{^#{controller.config.relative_url_root}/} + source = "#{controller.config.relative_url_root}#{source}" end end end diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index a26a8c9b4b..58c3a8752e 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -114,7 +114,7 @@ module ActionView feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)} xml.feed(feed_opts) do - xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}") + xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}") xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:root_url] || (request.protocol + request.host_with_port)) xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:url] || request.url) diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index d9607c0095..148f2868e9 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -544,10 +544,11 @@ module ActionView # submitted url doesn't have any either. This lets the function # work with things like ?order=asc if url_string.index("?") - request_uri = request.request_uri + request_uri = request.fullpath else - request_uri = request.request_uri.split('?').first + request_uri = request.path end + if url_string =~ /^\w+:\/\// url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}" else diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index f639700eaf..72dbead14b 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -34,6 +34,8 @@ module ActionView @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new + @request.env.delete('PATH_INFO') + @params = {} end end @@ -60,6 +62,10 @@ module ActionView make_test_case_available_to_view! end + def config + @controller.config + end + def render(options = {}, local_assigns = {}, &block) @rendered << output = _view.render(options, local_assigns, &block) output |