aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/http
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/http')
-rw-r--r--actionpack/lib/action_dispatch/http/cache.rb19
-rw-r--r--actionpack/lib/action_dispatch/http/filter_parameters.rb4
-rw-r--r--actionpack/lib/action_dispatch/http/filter_redirect.rb6
-rw-r--r--actionpack/lib/action_dispatch/http/headers.rb18
-rw-r--r--actionpack/lib/action_dispatch/http/mime_negotiation.rb34
-rw-r--r--actionpack/lib/action_dispatch/http/mime_type.rb52
-rw-r--r--actionpack/lib/action_dispatch/http/parameter_filter.rb10
-rw-r--r--actionpack/lib/action_dispatch/http/parameters.rb48
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb67
-rw-r--r--actionpack/lib/action_dispatch/http/response.rb49
-rw-r--r--actionpack/lib/action_dispatch/http/upload.rb2
-rw-r--r--actionpack/lib/action_dispatch/http/url.rb112
12 files changed, 199 insertions, 222 deletions
diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb
index 9fa2e38ae3..985e0fb972 100644
--- a/actionpack/lib/action_dispatch/http/cache.rb
+++ b/actionpack/lib/action_dispatch/http/cache.rb
@@ -2,9 +2,8 @@ module ActionDispatch
module Http
module Cache
module Request
-
- HTTP_IF_MODIFIED_SINCE = 'HTTP_IF_MODIFIED_SINCE'.freeze
- HTTP_IF_NONE_MATCH = 'HTTP_IF_NONE_MATCH'.freeze
+ HTTP_IF_MODIFIED_SINCE = "HTTP_IF_MODIFIED_SINCE".freeze
+ HTTP_IF_NONE_MATCH = "HTTP_IF_NONE_MATCH".freeze
def if_modified_since
if since = get_header(HTTP_IF_MODIFIED_SINCE)
@@ -27,7 +26,7 @@ module ActionDispatch
def etag_matches?(etag)
if etag
validators = if_none_match_etags
- validators.include?(etag) || validators.include?('*')
+ validators.include?(etag) || validators.include?("*")
end
end
@@ -102,11 +101,11 @@ module ActionDispatch
end
def weak_etag=(weak_validators)
- set_header 'ETag', generate_weak_etag(weak_validators)
+ set_header "ETag", generate_weak_etag(weak_validators)
end
def strong_etag=(strong_validators)
- set_header 'ETag', generate_strong_etag(strong_validators)
+ set_header "ETag", generate_strong_etag(strong_validators)
end
def etag?; etag; end
@@ -123,7 +122,7 @@ module ActionDispatch
private
- DATE = 'Date'.freeze
+ DATE = "Date".freeze
LAST_MODIFIED = "Last-Modified".freeze
SPECIAL_KEYS = Set.new(%w[extras no-cache max-age public private must-revalidate])
@@ -137,7 +136,7 @@ module ActionDispatch
def cache_control_segments
if cache_control = _cache_control
- cache_control.delete(' ').split(',')
+ cache_control.delete(" ").split(",")
else
[]
end
@@ -147,10 +146,10 @@ module ActionDispatch
cache_control = {}
cache_control_segments.each do |segment|
- directive, argument = segment.split('=', 2)
+ directive, argument = segment.split("=", 2)
if SPECIAL_KEYS.include? directive
- key = directive.tr('-', '_')
+ key = directive.tr("-", "_")
cache_control[key.to_sym] = argument || true
else
cache_control[:extras] ||= []
diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb
index 041eca48ca..e5874a39f6 100644
--- a/actionpack/lib/action_dispatch/http/filter_parameters.rb
+++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb
@@ -1,4 +1,4 @@
-require 'action_dispatch/http/parameter_filter'
+require "action_dispatch/http/parameter_filter"
module ActionDispatch
module Http
@@ -70,7 +70,7 @@ module ActionDispatch
ParameterFilter.new(filters)
end
- KV_RE = '[^&;=]+'
+ KV_RE = "[^&;=]+"
PAIR_RE = %r{(#{KV_RE})=(#{KV_RE})}
def filtered_query_string
query_string.gsub(PAIR_RE) do |_|
diff --git a/actionpack/lib/action_dispatch/http/filter_redirect.rb b/actionpack/lib/action_dispatch/http/filter_redirect.rb
index f4b806b8b5..fc3c44582a 100644
--- a/actionpack/lib/action_dispatch/http/filter_redirect.rb
+++ b/actionpack/lib/action_dispatch/http/filter_redirect.rb
@@ -1,8 +1,7 @@
module ActionDispatch
module Http
module FilterRedirect
-
- FILTERED = '[FILTERED]'.freeze # :nodoc:
+ FILTERED = "[FILTERED]".freeze # :nodoc:
def filtered_location # :nodoc:
if location_filter_match?
@@ -16,7 +15,7 @@ module ActionDispatch
def location_filters
if request
- request.get_header('action_dispatch.redirect_filter') || []
+ request.get_header("action_dispatch.redirect_filter") || []
else
[]
end
@@ -31,7 +30,6 @@ module ActionDispatch
end
end
end
-
end
end
end
diff --git a/actionpack/lib/action_dispatch/http/headers.rb b/actionpack/lib/action_dispatch/http/headers.rb
index 69a934b7cd..0528a6ad08 100644
--- a/actionpack/lib/action_dispatch/http/headers.rb
+++ b/actionpack/lib/action_dispatch/http/headers.rb
@@ -3,7 +3,7 @@ module ActionDispatch
# Provides access to the request's HTTP headers from the environment.
#
# env = { "CONTENT_TYPE" => "text/plain", "HTTP_USER_AGENT" => "curl/7.43.0" }
- # headers = ActionDispatch::Http::Headers.new(env)
+ # headers = ActionDispatch::Http::Headers.from_hash(env)
# headers["Content-Type"] # => "text/plain"
# headers["User-Agent"] # => "curl/7.43.0"
#
@@ -86,7 +86,7 @@ module ActionDispatch
@req.fetch_header(env_name(key)) do
return default unless default == DEFAULT
return yield if block_given?
- raise NameError, key
+ raise KeyError, key
end
end
@@ -117,14 +117,14 @@ module ActionDispatch
# Converts an HTTP header name to an environment variable name if it is
# not contained within the headers hash.
- def env_name(key)
- key = key.to_s
- if key =~ HTTP_HEADER
- key = key.upcase.tr('-', '_')
- key = "HTTP_" + key unless CGI_VARIABLES.include?(key)
+ def env_name(key)
+ key = key.to_s
+ if key =~ HTTP_HEADER
+ key = key.upcase.tr("-", "_")
+ key = "HTTP_" + key unless CGI_VARIABLES.include?(key)
+ end
+ key
end
- key
- end
end
end
end
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index 0a58ce2b96..d0c9413efa 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -1,4 +1,4 @@
-require 'active_support/core_ext/module/attribute_accessors'
+require "active_support/core_ext/module/attribute_accessors"
module ActionDispatch
module Http
@@ -16,7 +16,7 @@ module ActionDispatch
# X-Post-Data-Format HTTP header if present.
def content_mime_type
fetch_header("action_dispatch.request.content_type") do |k|
- v = if get_header('CONTENT_TYPE') =~ /^([^,\;]*)/
+ v = if get_header("CONTENT_TYPE") =~ /^([^,\;]*)/
Mime::Type.lookup($1.strip.downcase)
else
nil
@@ -30,13 +30,13 @@ module ActionDispatch
end
def has_content_type?
- has_header? 'CONTENT_TYPE'
+ has_header? "CONTENT_TYPE"
end
# Returns the accepted MIME type for the request.
def accepts
fetch_header("action_dispatch.request.accepts") do |k|
- header = get_header('HTTP_ACCEPT').to_s.strip
+ header = get_header("HTTP_ACCEPT").to_s.strip
v = if header.empty?
[content_mime_type]
@@ -152,23 +152,23 @@ module ActionDispatch
protected
- BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/
+ BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/
- def valid_accept_header
- (xhr? && (accept.present? || content_mime_type)) ||
- (accept.present? && accept !~ BROWSER_LIKE_ACCEPTS)
- end
+ def valid_accept_header
+ (xhr? && (accept.present? || content_mime_type)) ||
+ (accept.present? && accept !~ BROWSER_LIKE_ACCEPTS)
+ end
- def use_accept_header
- !self.class.ignore_accept_header
- end
+ def use_accept_header
+ !self.class.ignore_accept_header
+ end
- def format_from_path_extension
- path = get_header('action_dispatch.original_path') || get_header('PATH_INFO')
- if match = path && path.match(/\.(\w+)\z/)
- Mime[match.captures.first]
+ def format_from_path_extension
+ path = get_header("action_dispatch.original_path") || get_header("PATH_INFO")
+ if match = path && path.match(/\.(\w+)\z/)
+ Mime[match.captures.first]
+ end
end
- end
end
end
end
diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb
index 4672ea7199..b9121a577c 100644
--- a/actionpack/lib/action_dispatch/http/mime_type.rb
+++ b/actionpack/lib/action_dispatch/http/mime_type.rb
@@ -1,8 +1,8 @@
# -*- frozen-string-literal: true -*-
-require 'singleton'
-require 'active_support/core_ext/module/attribute_accessors'
-require 'active_support/core_ext/string/starts_ends_with'
+require "singleton"
+require "active_support/core_ext/module/attribute_accessors"
+require "active_support/core_ext/string/starts_ends_with"
module Mime
class Mimes
@@ -99,7 +99,7 @@ module Mime
def initialize(index, name, q = nil)
@index = index
@name = name
- q ||= 0.0 if @name == '*/*'.freeze # default wildcard match to end of list
+ q ||= 0.0 if @name == "*/*".freeze # default wildcard match to end of list
@q = ((q || 1.0).to_f * 100).to_i
end
@@ -114,7 +114,7 @@ module Mime
def self.sort!(list)
list.sort!
- text_xml_idx = find_item_by_name list, 'text/xml'
+ text_xml_idx = find_item_by_name list, "text/xml"
app_xml_idx = find_item_by_name list, Mime[:xml].to_s
# Take care of the broken text/xml entry by renaming or deleting it
@@ -141,7 +141,7 @@ module Mime
type = list[idx]
break if type.q < app_xml.q
- if type.name.ends_with? '+xml'
+ if type.name.ends_with? "+xml"
list[app_xml_idx], list[idx] = list[idx], app_xml
app_xml_idx = idx
end
@@ -195,12 +195,12 @@ module Mime
end
def parse(accept_header)
- if !accept_header.include?(',')
+ if !accept_header.include?(",")
accept_header = accept_header.split(PARAMETER_SEPARATOR_REGEXP).first
parse_trailing_star(accept_header) || [Mime::Type.lookup(accept_header)].compact
else
list, index = [], 0
- accept_header.split(',').each do |header|
+ accept_header.split(",").each do |header|
params, q = header.split(PARAMETER_SEPARATOR_REGEXP)
next unless params
@@ -306,31 +306,31 @@ module Mime
protected
- attr_reader :string, :synonyms
+ attr_reader :string, :synonyms
private
- def to_ary; end
- def to_a; end
+ def to_ary; end
+ def to_a; end
- def method_missing(method, *args)
- if method.to_s.ends_with? '?'
- method[0..-2].downcase.to_sym == to_sym
- else
- super
+ def method_missing(method, *args)
+ if method.to_s.ends_with? "?"
+ method[0..-2].downcase.to_sym == to_sym
+ else
+ super
+ end
end
- end
- def respond_to_missing?(method, include_private = false) #:nodoc:
- method.to_s.ends_with? '?'
- end
+ def respond_to_missing?(method, include_private = false) #:nodoc:
+ method.to_s.ends_with? "?"
+ end
end
class AllType < Type
include Singleton
def initialize
- super '*/*', :all
+ super "*/*", :all
end
def all?; true; end
@@ -352,14 +352,14 @@ module Mime
def ref; end
def respond_to_missing?(method, include_private = false)
- method.to_s.ends_with? '?'
+ method.to_s.ends_with? "?"
end
private
- def method_missing(method, *args)
- false if method.to_s.ends_with? '?'
- end
+ def method_missing(method, *args)
+ false if method.to_s.ends_with? "?"
+ end
end
end
-require 'action_dispatch/http/mime_types'
+require "action_dispatch/http/mime_types"
diff --git a/actionpack/lib/action_dispatch/http/parameter_filter.rb b/actionpack/lib/action_dispatch/http/parameter_filter.rb
index 01f1666b9b..01fe35f5c6 100644
--- a/actionpack/lib/action_dispatch/http/parameter_filter.rb
+++ b/actionpack/lib/action_dispatch/http/parameter_filter.rb
@@ -1,9 +1,9 @@
-require 'active_support/core_ext/object/duplicable'
+require "active_support/core_ext/object/duplicable"
module ActionDispatch
module Http
class ParameterFilter
- FILTERED = '[FILTERED]'.freeze # :nodoc:
+ FILTERED = "[FILTERED]".freeze # :nodoc:
def initialize(filters = [])
@filters = filters
@@ -39,8 +39,8 @@ module ActionDispatch
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.".freeze) }
deep_strings, strings = strings.partition { |s| s.include?("\\.".freeze) }
- regexps << Regexp.new(strings.join('|'.freeze), true) unless strings.empty?
- deep_regexps << Regexp.new(deep_strings.join('|'.freeze), true) unless deep_strings.empty?
+ regexps << Regexp.new(strings.join("|".freeze), true) unless strings.empty?
+ deep_regexps << Regexp.new(deep_strings.join("|".freeze), true) unless deep_strings.empty?
new regexps, deep_regexps, blocks
end
@@ -60,7 +60,7 @@ module ActionDispatch
parents.push(key) if deep_regexps
if regexps.any? { |r| key =~ r }
value = FILTERED
- elsif deep_regexps && (joined = parents.join('.')) && deep_regexps.any? { |r| joined =~ r }
+ elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| joined =~ r }
value = FILTERED
elsif value.is_a?(Hash)
value = call(value, parents)
diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb
index ea0e2ee41f..31ef0af791 100644
--- a/actionpack/lib/action_dispatch/http/parameters.rb
+++ b/actionpack/lib/action_dispatch/http/parameters.rb
@@ -3,12 +3,12 @@ module ActionDispatch
module Parameters
extend ActiveSupport::Concern
- PARAMETERS_KEY = 'action_dispatch.request.path_parameters'
+ PARAMETERS_KEY = "action_dispatch.request.path_parameters"
DEFAULT_PARSERS = {
Mime[:json].symbol => -> (raw_post) {
data = ActiveSupport::JSON.decode(raw_post)
- data.is_a?(Hash) ? data : {:_json => data}
+ data.is_a?(Hash) ? data : { _json: data }
}
}
@@ -37,13 +37,14 @@ module ActionDispatch
query_parameters.dup
end
params.merge!(path_parameters)
+ params = set_custom_encoding(params)
set_header("action_dispatch.request.parameters", params)
params
end
alias :params :parameters
def path_parameters=(parameters) #:nodoc:
- delete_header('action_dispatch.request.parameters')
+ delete_header("action_dispatch.request.parameters")
# If any of the path parameters has an invalid encoding then
# raise since it's likely to trigger errors further on.
@@ -64,24 +65,39 @@ module ActionDispatch
private
- def parse_formatted_parameters(parsers)
- return yield if content_length.zero? || content_mime_type.nil?
+ def set_custom_encoding(params)
+ action = params[:action]
+ params.each do |k, v|
+ if v.is_a?(String) && v.encoding != encoding_template(action, k)
+ params[k] = v.force_encoding(encoding_template(action, k))
+ end
+ end
- strategy = parsers.fetch(content_mime_type.symbol) { return yield }
+ params
+ end
+
+ def encoding_template(action, param)
+ controller_class.encoding_for_param(action, param)
+ end
+
+ def parse_formatted_parameters(parsers)
+ return yield if content_length.zero? || content_mime_type.nil?
- begin
- strategy.call(raw_post)
- rescue # JSON or Ruby code block errors
- my_logger = logger || ActiveSupport::Logger.new($stderr)
- my_logger.debug "Error occurred while parsing request parameters.\nContents:\n\n#{raw_post}"
+ strategy = parsers.fetch(content_mime_type.symbol) { return yield }
- raise ParamsParser::ParseError
+ begin
+ strategy.call(raw_post)
+ rescue # JSON or Ruby code block errors
+ my_logger = logger || ActiveSupport::Logger.new($stderr)
+ my_logger.debug "Error occurred while parsing request parameters.\nContents:\n\n#{raw_post}"
+
+ raise ParamsParser::ParseError
+ end
end
- end
- def params_parsers
- ActionDispatch::Request.parameter_parsers
- end
+ def params_parsers
+ ActionDispatch::Request.parameter_parsers
+ end
end
end
end
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 954dd4f354..e4ef9783f3 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -1,16 +1,16 @@
-require 'stringio'
-
-require 'active_support/inflector'
-require 'action_dispatch/http/headers'
-require 'action_controller/metal/exceptions'
-require 'rack/request'
-require 'action_dispatch/http/cache'
-require 'action_dispatch/http/mime_negotiation'
-require 'action_dispatch/http/parameters'
-require 'action_dispatch/http/filter_parameters'
-require 'action_dispatch/http/upload'
-require 'action_dispatch/http/url'
-require 'active_support/core_ext/array/conversions'
+require "stringio"
+
+require "active_support/inflector"
+require "action_dispatch/http/headers"
+require "action_controller/metal/exceptions"
+require "rack/request"
+require "action_dispatch/http/cache"
+require "action_dispatch/http/mime_negotiation"
+require "action_dispatch/http/parameters"
+require "action_dispatch/http/filter_parameters"
+require "action_dispatch/http/upload"
+require "action_dispatch/http/url"
+require "active_support/core_ext/array/conversions"
module ActionDispatch
class Request
@@ -22,8 +22,8 @@ module ActionDispatch
include ActionDispatch::Http::URL
include Rack::Request::Env
- autoload :Session, 'action_dispatch/request/session'
- autoload :Utils, 'action_dispatch/request/utils'
+ autoload :Session, "action_dispatch/request/session"
+ autoload :Utils, "action_dispatch/request/utils"
LOCALHOST = Regexp.union [/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]
@@ -68,7 +68,8 @@ module ActionDispatch
PASS_NOT_FOUND = Class.new { # :nodoc:
def self.action(_); self; end
- def self.call(_); [404, {'X-Cascade' => 'pass'}, []]; end
+ def self.call(_); [404, { "X-Cascade" => "pass" }, []]; end
+ def self.encoding_for_param(action, param); ::Encoding::UTF_8; end
}
def controller_class
@@ -76,7 +77,7 @@ module ActionDispatch
if params.key?(:controller)
controller_param = params[:controller].underscore
- params[:action] ||= 'index'
+ params[:action] ||= "index"
const_name = "#{controller_param.camelize}Controller"
ActiveSupport::Dependencies.constantize(const_name)
else
@@ -148,11 +149,11 @@ module ActionDispatch
end
def controller_instance # :nodoc:
- get_header('action_controller.instance'.freeze)
+ get_header("action_controller.instance".freeze)
end
def controller_instance=(controller) # :nodoc:
- set_header('action_controller.instance'.freeze, controller)
+ set_header("action_controller.instance".freeze, controller)
end
def http_auth_salt
@@ -163,7 +164,7 @@ module ActionDispatch
# We're treating `nil` as "unset", and we want the default setting to be
# `true`. This logic should be extracted to `env_config` and calculated
# once.
- !(get_header('action_dispatch.show_exceptions'.freeze) == false)
+ !(get_header("action_dispatch.show_exceptions".freeze) == false)
end
# Returns a symbol form of the #request_method
@@ -175,7 +176,7 @@ module ActionDispatch
# even if it was overridden by middleware. See #request_method for
# more information.
def method
- @method ||= check_method(get_header("rack.methodoverride.original_method") || get_header('REQUEST_METHOD'))
+ @method ||= check_method(get_header("rack.methodoverride.original_method") || get_header("REQUEST_METHOD"))
end
# Returns a symbol form of the #method
@@ -237,7 +238,7 @@ module ActionDispatch
# (case-insensitive), which may need to be manually added depending on the
# choice of JavaScript libraries and frameworks.
def xml_http_request?
- get_header('HTTP_X_REQUESTED_WITH') =~ /XMLHttpRequest/i
+ get_header("HTTP_X_REQUESTED_WITH") =~ /XMLHttpRequest/i
end
alias :xhr? :xml_http_request?
@@ -276,24 +277,24 @@ module ActionDispatch
# Returns the lowercase name of the HTTP server software.
def server_software
- (get_header('SERVER_SOFTWARE') && /^([a-zA-Z]+)/ =~ get_header('SERVER_SOFTWARE')) ? $1.downcase : nil
+ (get_header("SERVER_SOFTWARE") && /^([a-zA-Z]+)/ =~ get_header("SERVER_SOFTWARE")) ? $1.downcase : nil
end
# Read the request \body. This is useful for web services that need to
# work with raw requests directly.
def raw_post
- unless has_header? 'RAW_POST_DATA'
+ unless has_header? "RAW_POST_DATA"
raw_post_body = body
- set_header('RAW_POST_DATA', raw_post_body.read(content_length))
+ set_header("RAW_POST_DATA", raw_post_body.read(content_length))
raw_post_body.rewind if raw_post_body.respond_to?(:rewind)
end
- get_header 'RAW_POST_DATA'
+ get_header "RAW_POST_DATA"
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 = get_header('RAW_POST_DATA')
+ if raw_post = get_header("RAW_POST_DATA")
raw_post.force_encoding(Encoding::BINARY)
StringIO.new(raw_post)
else
@@ -314,7 +315,7 @@ module ActionDispatch
end
def body_stream #:nodoc:
- get_header('rack.input')
+ get_header("rack.input")
end
# TODO This should be broken apart into AD::Request::Session and probably
@@ -367,10 +368,10 @@ module ActionDispatch
# Returns the authorization header regardless of whether it was specified directly or through one of the
# proxy alternatives.
def authorization
- get_header('HTTP_AUTHORIZATION') ||
- get_header('X-HTTP_AUTHORIZATION') ||
- get_header('X_HTTP_AUTHORIZATION') ||
- get_header('REDIRECT_X_HTTP_AUTHORIZATION')
+ get_header("HTTP_AUTHORIZATION") ||
+ get_header("X-HTTP_AUTHORIZATION") ||
+ get_header("X_HTTP_AUTHORIZATION") ||
+ get_header("REDIRECT_X_HTTP_AUTHORIZATION")
end
# True if the request came from localhost, 127.0.0.1, or ::1.
@@ -391,7 +392,7 @@ module ActionDispatch
end
def ssl?
- super || scheme == 'wss'.freeze
+ super || scheme == "wss".freeze
end
private
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb
index 1515d59df3..e8173e2a99 100644
--- a/actionpack/lib/action_dispatch/http/response.rb
+++ b/actionpack/lib/action_dispatch/http/response.rb
@@ -1,7 +1,7 @@
-require 'active_support/core_ext/module/attribute_accessors'
-require 'action_dispatch/http/filter_redirect'
-require 'action_dispatch/http/cache'
-require 'monitor'
+require "active_support/core_ext/module/attribute_accessors"
+require "action_dispatch/http/filter_redirect"
+require "action_dispatch/http/cache"
+require "monitor"
module ActionDispatch # :nodoc:
# Represents an HTTP response generated by a controller action. Use it to
@@ -41,7 +41,7 @@ module ActionDispatch # :nodoc:
def []=(k,v)
if @response.sending? || @response.sent?
- raise ActionDispatch::IllegalStateError, 'header already sent'
+ raise ActionDispatch::IllegalStateError, "header already sent"
end
super
@@ -67,7 +67,7 @@ module ActionDispatch # :nodoc:
alias_method :headers, :header
- delegate :[], :[]=, :to => :@header
+ delegate :[], :[]=, to: :@header
def each(&block)
sending!
@@ -103,8 +103,8 @@ module ActionDispatch # :nodoc:
def body
@str_body ||= begin
- buf = ''
- each { |chunk| buf << chunk }
+ buf = ""
+ each { |chunk| buf << chunk }
buf
end
end
@@ -224,8 +224,10 @@ module ActionDispatch # :nodoc:
# Sets the HTTP content type.
def content_type=(content_type)
- header_info = parse_content_type
- set_content_type content_type.to_s, header_info.charset || self.class.default_charset
+ return unless content_type
+ new_header_info = parse_content_type(content_type.to_s)
+ prev_header_info = parsed_content_type_header
+ set_content_type new_header_info.mime_type, new_header_info.charset || prev_header_info.charset || self.class.default_charset
end
# Sets the HTTP response's content MIME type. For example, in the controller
@@ -238,7 +240,7 @@ module ActionDispatch # :nodoc:
# information.
def content_type
- parse_content_type.mime_type
+ parsed_content_type_header.mime_type
end
def sending_file=(v)
@@ -253,7 +255,7 @@ module ActionDispatch # :nodoc:
# response.charset = 'utf-16' # => 'utf-16'
# response.charset = nil # => 'utf-8'
def charset=(charset)
- header_info = parse_content_type
+ header_info = parsed_content_type_header
if false == charset
set_header CONTENT_TYPE, header_info.mime_type
else
@@ -265,7 +267,7 @@ module ActionDispatch # :nodoc:
# The charset of the response. HTML wants to know the encoding of the
# content you're giving them, so we need to send that along.
def charset
- header_info = parse_content_type
+ header_info = parsed_content_type_header
header_info.charset || self.class.default_charset
end
@@ -329,7 +331,7 @@ module ActionDispatch # :nodoc:
# Stream the file's contents if Rack::Sendfile isn't present.
def each
- File.open(to_path, 'rb') do |file|
+ File.open(to_path, "rb") do |file|
while chunk = file.read(16384)
yield chunk
end
@@ -389,7 +391,7 @@ module ActionDispatch # :nodoc:
if header = get_header(SET_COOKIE)
header = header.split("\n") if header.respond_to?(:to_str)
header.each do |cookie|
- if pair = cookie.split(';').first
+ if pair = cookie.split(";").first
key, value = pair.split("=").map { |v| Rack::Utils.unescape(v) }
cookies[key] = value
end
@@ -403,8 +405,7 @@ module ActionDispatch # :nodoc:
ContentTypeHeader = Struct.new :mime_type, :charset
NullContentTypeHeader = ContentTypeHeader.new nil, nil
- def parse_content_type
- content_type = get_header CONTENT_TYPE
+ def parse_content_type(content_type)
if content_type
type, charset = content_type.split(/;\s*charset=/)
type = nil if type.empty?
@@ -414,8 +415,14 @@ module ActionDispatch # :nodoc:
end
end
+ # Small internal convenience method to get the parsed version of the current
+ # content type header.
+ def parsed_content_type_header
+ parse_content_type(get_header(CONTENT_TYPE))
+ end
+
def set_content_type(content_type, charset)
- type = (content_type || '').dup
+ type = (content_type || "").dup
type << "; charset=#{charset}" if charset
set_header CONTENT_TYPE, type
end
@@ -450,7 +457,7 @@ module ActionDispatch # :nodoc:
def assign_default_content_type_and_charset!
return if content_type
- ct = parse_content_type
+ ct = parsed_content_type_header
set_content_type(ct.mime_type || Mime[:html].to_s,
ct.charset || self.class.default_charset)
end
@@ -475,7 +482,7 @@ module ActionDispatch # :nodoc:
end
def respond_to?(method, include_private = false)
- if method.to_s == 'to_path'
+ if method.to_s == "to_path"
@response.stream.respond_to?(method)
else
super
@@ -494,7 +501,7 @@ module ActionDispatch # :nodoc:
def handle_no_content!
if NO_CONTENT_CODES.include?(@status)
@header.delete CONTENT_TYPE
- @header.delete 'Content-Length'
+ @header.delete "Content-Length"
end
end
diff --git a/actionpack/lib/action_dispatch/http/upload.rb b/actionpack/lib/action_dispatch/http/upload.rb
index a221f4c5af..9aa73c862b 100644
--- a/actionpack/lib/action_dispatch/http/upload.rb
+++ b/actionpack/lib/action_dispatch/http/upload.rb
@@ -25,7 +25,7 @@ module ActionDispatch
def initialize(hash) # :nodoc:
@tempfile = hash[:tempfile]
- raise(ArgumentError, ':tempfile is required') unless @tempfile
+ raise(ArgumentError, ":tempfile is required") unless @tempfile
@original_filename = hash[:filename]
if @original_filename
diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb
index 7a1350a46d..06ffa983d1 100644
--- a/actionpack/lib/action_dispatch/http/url.rb
+++ b/actionpack/lib/action_dispatch/http/url.rb
@@ -1,4 +1,4 @@
-require 'active_support/core_ext/module/attribute_accessors'
+require "active_support/core_ext/module/attribute_accessors"
module ActionDispatch
module Http
@@ -42,7 +42,7 @@ module ActionDispatch
# # Second-level domain example
# extract_subdomain('dev.www.example.co.uk', 2) # => "dev.www"
def extract_subdomain(host, tld_length)
- extract_subdomains(host, tld_length).join('.')
+ extract_subdomains(host, tld_length).join(".")
end
def url_for(options)
@@ -59,7 +59,7 @@ module ActionDispatch
port = options[:port]
unless host
- raise ArgumentError, 'Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true'
+ raise ArgumentError, "Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true"
end
build_host_url(host, port, protocol, options, path_for(options))
@@ -92,17 +92,17 @@ module ActionDispatch
end
def extract_domain_from(host, tld_length)
- host.split('.').last(1 + tld_length).join('.')
+ host.split(".").last(1 + tld_length).join(".")
end
def extract_subdomains_from(host, tld_length)
- parts = host.split('.')
+ parts = host.split(".")
parts[0..-(tld_length + 2)]
end
def add_trailing_slash(path)
# includes querysting
- if path.include?('?')
+ if path.include?("?")
path.sub!(/\?/, '/\&')
# does not have a .format
elsif !path.include?(".")
@@ -162,7 +162,7 @@ module ActionDispatch
if subdomain == true
return _host if domain.nil?
- host << extract_subdomains_from(_host, tld_length).join('.')
+ host << extract_subdomains_from(_host, tld_length).join(".")
elsif subdomain
host << subdomain.to_param
end
@@ -192,11 +192,7 @@ module ActionDispatch
# Returns the complete URL used for this request.
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'HTTP_HOST' => 'example.com'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
# req.url # => "http://example.com"
def url
protocol + host_with_port + fullpath
@@ -204,68 +200,52 @@ module ActionDispatch
# Returns 'https://' if this is an SSL request and 'http://' otherwise.
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'HTTP_HOST' => 'example.com'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
# req.protocol # => "http://"
#
- # req = Request.new 'HTTP_HOST' => 'example.com', 'HTTPS' => 'on'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com', 'HTTPS' => 'on'
# req.protocol # => "https://"
def protocol
- @protocol ||= ssl? ? 'https://' : 'http://'
+ @protocol ||= ssl? ? "https://" : "http://"
end
# Returns the \host and port for this request, such as "example.com:8080".
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'HTTP_HOST' => 'example.com'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
# req.raw_host_with_port # => "example.com"
#
- # req = Request.new 'HTTP_HOST' => 'example.com:80'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
# req.raw_host_with_port # => "example.com:80"
#
- # req = Request.new 'HTTP_HOST' => 'example.com:8080'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
# req.raw_host_with_port # => "example.com:8080"
def raw_host_with_port
if forwarded = x_forwarded_host.presence
forwarded.split(/,\s?/).last
else
- get_header('HTTP_HOST') || "#{server_name || server_addr}:#{get_header('SERVER_PORT')}"
+ get_header("HTTP_HOST") || "#{server_name || server_addr}:#{get_header('SERVER_PORT')}"
end
end
# Returns the host for this request, such as "example.com".
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'HTTP_HOST' => 'example.com:8080'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
# req.host # => "example.com"
def host
- raw_host_with_port.sub(/:\d+$/, ''.freeze)
+ raw_host_with_port.sub(/:\d+$/, "".freeze)
end
# Returns a \host:\port string for this request, such as "example.com" or
# "example.com:8080". Port is only included if it is not a default port
# (80 or 443)
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'HTTP_HOST' => 'example.com'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
# req.host_with_port # => "example.com"
#
- # req = Request.new 'HTTP_HOST' => 'example.com:80'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
# req.host_with_port # => "example.com"
#
- # req = Request.new 'HTTP_HOST' => 'example.com:8080'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
# req.host_with_port # => "example.com:8080"
def host_with_port
"#{host}#{port_string}"
@@ -273,14 +253,10 @@ module ActionDispatch
# Returns the port number of this request as an integer.
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'HTTP_HOST' => 'example.com'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
# req.port # => 80
#
- # req = Request.new 'HTTP_HOST' => 'example.com:8080'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
# req.port # => 8080
def port
@port ||= begin
@@ -294,29 +270,21 @@ module ActionDispatch
# Returns the standard \port number for this request's protocol.
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'HTTP_HOST' => 'example.com:8080'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
# req.standard_port # => 80
def standard_port
case protocol
- when 'https://' then 443
+ when "https://" then 443
else 80
end
end
# Returns whether this request is using the standard port
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'HTTP_HOST' => 'example.com:80'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
# req.standard_port? # => true
#
- # req = Request.new 'HTTP_HOST' => 'example.com:8080'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
# req.standard_port? # => false
def standard_port?
port == standard_port
@@ -325,14 +293,10 @@ module ActionDispatch
# Returns a number \port suffix like 8080 if the \port number of this request
# is not the default HTTP \port 80 or HTTPS \port 443.
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'HTTP_HOST' => 'example.com:80'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
# req.optional_port # => nil
#
- # req = Request.new 'HTTP_HOST' => 'example.com:8080'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
# req.optional_port # => 8080
def optional_port
standard_port? ? nil : port
@@ -341,32 +305,24 @@ module ActionDispatch
# Returns a string \port suffix, including colon, like ":8080" if the \port
# number of this request is not the default HTTP \port 80 or HTTPS \port 443.
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'HTTP_HOST' => 'example.com:80'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
# req.port_string # => ""
#
- # req = Request.new 'HTTP_HOST' => 'example.com:8080'
+ # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
# req.port_string # => ":8080"
def port_string
- standard_port? ? '' : ":#{port}"
+ standard_port? ? "" : ":#{port}"
end
# Returns the requested port, such as 8080, based on SERVER_PORT
#
- # class Request < Rack::Request
- # include ActionDispatch::Http::URL
- # end
- #
- # req = Request.new 'SERVER_PORT' => '80'
+ # req = ActionDispatch::Request.new 'SERVER_PORT' => '80'
# req.server_port # => 80
#
- # req = Request.new 'SERVER_PORT' => '8080'
+ # req = ActionDispatch::Request.new 'SERVER_PORT' => '8080'
# req.server_port # => 8080
def server_port
- get_header('SERVER_PORT').to_i
+ get_header("SERVER_PORT").to_i
end
# Returns the \domain part of a \host, such as "rubyonrails.org" in "www.rubyonrails.org". You can specify