Class: ActionController::Request
- Defined in:
- lib/action_controller/request.rb
Direct Known Subclasses
Constant Summary collapse
- HTTP_METHODS =
%w(get head put post delete options)
- HTTP_METHOD_LOOKUP =
HTTP_METHODS.inject({}) { |h, m| h[m] = h[m.upcase] = m.to_sym; h }
- TRUSTED_PROXIES =
Which IP addresses are “trusted proxies” that can be stripped from the right-hand-side of X-Forwarded-For
/^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\./i
Instance Method Summary collapse
-
#accepts ⇒ Object
Returns the accepted MIME type for the request.
-
#body ⇒ Object
The request body is an IO input stream.
-
#body_stream ⇒ Object
:nodoc:.
- #cache_format ⇒ Object
-
#content_length ⇒ Object
Returns the content length of the request as an integer.
-
#content_type ⇒ Object
The MIME type of the HTTP request, such as Mime::XML.
-
#delete? ⇒ Boolean
Is this a DELETE request? Equivalent to
request.method == :delete
. -
#domain(tld_length = 1) ⇒ Object
Returns the domain part of a host, such as “rubyonrails.org” in “www.rubyonrails.org”.
- #etag_matches?(etag) ⇒ Boolean
- #form_data? ⇒ Boolean
-
#format ⇒ Object
Returns the Mime type for the format used in the request.
-
#format=(extension) ⇒ Object
Sets the format by string extension, which can be used to force custom formats that are not controlled by the extension.
-
#fresh?(response) ⇒ Boolean
Check response freshness (Last-Modified and ETag) against request If-Modified-Since and If-None-Match conditions.
-
#GET ⇒ Object
(also: #query_parameters)
Override Rack’s GET method to support indifferent access.
-
#get? ⇒ Boolean
Is this a GET (or HEAD) request? Equivalent to
request.method == :get
. -
#head? ⇒ Boolean
Is this a HEAD request? Since
request.method
sees HEAD as:get
, this method checks the actual HTTP method directly. -
#headers ⇒ Object
Provides access to the request’s HTTP headers, for example:.
-
#host ⇒ Object
Returns the host for this request, such as example.com.
-
#host_with_port ⇒ Object
Returns a host:port string for this request, such as “example.com” or “example.com:8080”.
- #if_modified_since ⇒ Object
- #if_none_match ⇒ Object
- #key?(key) ⇒ Boolean
- #media_type ⇒ Object
-
#method ⇒ Object
Returns the HTTP request method used for action processing as a lowercase symbol, such as
:post
. - #not_modified?(modified_at) ⇒ Boolean
-
#parameters ⇒ Object
(also: #params)
Returns both GET and POST parameters in a single hash.
-
#path ⇒ Object
Returns the interpreted path to requested resource after all the installation directory of this application was taken into account.
-
#path_parameters ⇒ Object
Returns a hash with the parameters used to form the path of the request.
-
#path_parameters=(parameters) ⇒ Object
:nodoc:.
-
#port ⇒ Object
Returns the port number of this request as an integer.
-
#port_string ⇒ Object
Returns a port suffix like “:8080” if the port number of this request is not the default HTTP port 80 or HTTPS port 443.
-
#POST ⇒ Object
(also: #request_parameters)
Override Rack’s POST method to support indifferent access.
-
#post? ⇒ Boolean
Is this a POST request? Equivalent to
request.method == :post
. -
#protocol ⇒ Object
Returns ‘https://’ if this is an SSL request and ‘http://’ otherwise.
-
#put? ⇒ Boolean
Is this a PUT request? Equivalent to
request.method == :put
. -
#query_string ⇒ Object
Returns the query string, accounting for server idiosyncrasies.
-
#raw_host_with_port ⇒ Object
Returns the host for this request, such as “example.com”.
-
#raw_post ⇒ Object
Read the request body.
-
#remote_ip ⇒ Object
Determines originating IP address.
-
#request_method ⇒ Object
Returns the true HTTP request method as a lowercase symbol, such as
:get
. -
#request_uri ⇒ Object
Returns the request URI, accounting for server idiosyncrasies.
- #reset_session ⇒ Object
- #server_port ⇒ Object
-
#server_software ⇒ Object
Returns the lowercase name of the HTTP server software.
- #session ⇒ Object
-
#session=(session) ⇒ Object
:nodoc:.
- #session_options ⇒ Object
- #session_options=(options) ⇒ Object
-
#ssl? ⇒ Boolean
Is this an SSL request?.
-
#standard_port ⇒ Object
Returns the standard port number for this request’s protocol.
-
#subdomains(tld_length = 1) ⇒ Object
Returns all the subdomains as an array, so
["dev", "www"]
would be returned for “dev.www.rubyonrails.org”. -
#symbolized_path_parameters ⇒ Object
The same as
path_parameters
with explicitly symbolized keys. -
#template_format ⇒ Object
Returns a symbolized version of the
:format
parameter of the request. -
#url ⇒ Object
Returns the complete URL used for this request.
-
#xml_http_request? ⇒ Boolean
(also: #xhr?)
Returns true if the request’s “X-Requested-With” header contains “XMLHttpRequest”.
Instance Method Details
#accepts ⇒ Object
Returns the accepted MIME type for the request.
103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/action_controller/request.rb', line 103 def accepts @accepts ||= begin header = @env['HTTP_ACCEPT'].to_s.strip if header.empty? [content_type, Mime::ALL].compact else Mime::Type.parse(header) end end end |
#body ⇒ Object
The request body is an IO input stream. If the RAW_POST_DATA environment variable is already set, wrap it in a StringIO.
411 412 413 414 415 416 417 418 |
# File 'lib/action_controller/request.rb', line 411 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 |
#body_stream ⇒ Object
:nodoc:
436 437 438 |
# File 'lib/action_controller/request.rb', line 436 def body_stream #:nodoc: @env['rack.input'] end |
#cache_format ⇒ Object
199 200 201 |
# File 'lib/action_controller/request.rb', line 199 def cache_format parameters[:format] end |
#content_length ⇒ Object
Returns the content length of the request as an integer.
80 81 82 |
# File 'lib/action_controller/request.rb', line 80 def content_length super.to_i end |
#content_type ⇒ Object
The MIME type of the HTTP request, such as Mime::XML.
For backward compatibility, the post format is extracted from the X-Post-Data-Format HTTP header if present.
88 89 90 91 92 93 94 95 96 |
# File 'lib/action_controller/request.rb', line 88 def content_type @content_type ||= begin if @env['CONTENT_TYPE'] =~ /^([^,\;]*)/ Mime::Type.lookup($1.strip.downcase) else nil end end end |
#delete? ⇒ Boolean
Is this a DELETE request? Equivalent to request.method == :delete
.
62 63 64 |
# File 'lib/action_controller/request.rb', line 62 def delete? request_method == :delete end |
#domain(tld_length = 1) ⇒ Object
Returns the domain part of a host, such as “rubyonrails.org” in “www.rubyonrails.org”. You can specify a different tld_length
, such as 2 to catch rubyonrails.co.uk in “www.rubyonrails.co.uk”.
319 320 321 322 323 |
# File 'lib/action_controller/request.rb', line 319 def domain(tld_length = 1) return nil unless named_host?(host) host.split('.').last(1 + tld_length).join('.') end |
#etag_matches?(etag) ⇒ Boolean
129 130 131 |
# File 'lib/action_controller/request.rb', line 129 def etag_matches?(etag) if_none_match && if_none_match == etag end |
#form_data? ⇒ Boolean
420 421 422 |
# File 'lib/action_controller/request.rb', line 420 def form_data? FORM_DATA_MEDIA_TYPES.include?(content_type.to_s) end |
#format ⇒ Object
Returns the Mime type for the format used in the request.
GET /posts/5.xml | request.format => Mime::XML
GET /posts/5.xhtml | request.format => Mime::HTML
GET /posts/5 | request.format => Mime::HTML or MIME::JS, or request.accepts.first depending on the value of <tt>ActionController::Base.use_accept_header</tt>
154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/action_controller/request.rb', line 154 def format @format ||= if parameters[:format] Mime::Type.lookup_by_extension(parameters[:format]) elsif ActionController::Base.use_accept_header accepts.first elsif xhr? Mime::Type.lookup_by_extension("js") else Mime::Type.lookup_by_extension("html") end end |
#format=(extension) ⇒ Object
Sets the format by string extension, which can be used to force custom formats that are not controlled by the extension.
class ApplicationController < ActionController::Base
before_filter :adjust_format_for_iphone
private
def adjust_format_for_iphone
request.format = :iphone if request.env["HTTP_USER_AGENT"][/iPhone/]
end
end
179 180 181 182 |
# File 'lib/action_controller/request.rb', line 179 def format=(extension) parameters[:format] = extension.to_s @format = Mime::Type.lookup_by_extension(parameters[:format]) end |
#fresh?(response) ⇒ Boolean
Check response freshness (Last-Modified and ETag) against request If-Modified-Since and If-None-Match conditions. If both headers are supplied, both must match, or the request is not considered fresh.
136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/action_controller/request.rb', line 136 def fresh?(response) case when if_modified_since && if_none_match not_modified?(response.last_modified) && etag_matches?(response.etag) when if_modified_since not_modified?(response.last_modified) when if_none_match etag_matches?(response.etag) else false end end |
#GET ⇒ Object Also known as: query_parameters
Override Rack’s GET method to support indifferent access
425 426 427 |
# File 'lib/action_controller/request.rb', line 425 def GET @env["action_controller.request.query_parameters"] ||= normalize_parameters(super) end |
#get? ⇒ Boolean
Is this a GET (or HEAD) request? Equivalent to request.method == :get
.
47 48 49 |
# File 'lib/action_controller/request.rb', line 47 def get? method == :get end |
#head? ⇒ Boolean
Is this a HEAD request? Since request.method
sees HEAD as :get
, this method checks the actual HTTP method directly.
68 69 70 |
# File 'lib/action_controller/request.rb', line 68 def head? request_method == :head end |
#headers ⇒ Object
Provides access to the request’s HTTP headers, for example:
request.headers["Content-Type"] # => "text/plain"
75 76 77 |
# File 'lib/action_controller/request.rb', line 75 def headers @headers ||= ActionController::Http::Headers.new(@env) end |
#host ⇒ Object
Returns the host for this request, such as example.com.
284 285 286 |
# File 'lib/action_controller/request.rb', line 284 def host raw_host_with_port.sub(/:\d+$/, '') end |
#host_with_port ⇒ Object
Returns a host:port string for this request, such as “example.com” or “example.com:8080”.
290 291 292 |
# File 'lib/action_controller/request.rb', line 290 def host_with_port "#{host}#{port_string}" end |
#if_modified_since ⇒ Object
115 116 117 118 119 |
# File 'lib/action_controller/request.rb', line 115 def if_modified_since if since = env['HTTP_IF_MODIFIED_SINCE'] Time.rfc2822(since) rescue nil end end |
#if_none_match ⇒ Object
121 122 123 |
# File 'lib/action_controller/request.rb', line 121 def if_none_match env['HTTP_IF_NONE_MATCH'] end |
#key?(key) ⇒ Boolean
24 25 26 |
# File 'lib/action_controller/request.rb', line 24 def key?(key) @env.key?(key) end |
#media_type ⇒ Object
98 99 100 |
# File 'lib/action_controller/request.rb', line 98 def media_type content_type.to_s end |
#method ⇒ Object
Returns the HTTP request method used for action processing as a lowercase symbol, such as :post
. (Unlike #request_method, this method returns :get
for a HEAD request because the two are functionally equivalent from the application’s perspective.)
42 43 44 |
# File 'lib/action_controller/request.rb', line 42 def method request_method == :head ? :get : request_method end |
#not_modified?(modified_at) ⇒ Boolean
125 126 127 |
# File 'lib/action_controller/request.rb', line 125 def not_modified?(modified_at) if_modified_since && modified_at && if_modified_since >= modified_at end |
#parameters ⇒ Object Also known as: params
Returns both GET and POST parameters in a single hash.
384 385 386 |
# File 'lib/action_controller/request.rb', line 384 def parameters @parameters ||= request_parameters.merge(query_parameters).update(path_parameters).with_indifferent_access end |
#path ⇒ Object
Returns the interpreted path to requested resource after all the installation directory of this application was taken into account.
367 368 369 370 371 |
# File 'lib/action_controller/request.rb', line 367 def path path = request_uri.to_s[/\A[^\?]*/] path.sub!(/\A#{ActionController::Base.relative_url_root}/, '') path end |
#path_parameters ⇒ Object
Returns a hash with the parameters used to form the path of the request. Returned hash keys are strings:
{'action' => 'my_action', 'controller' => 'my_controller'}
See symbolized_path_parameters
for symbolized keys.
405 406 407 |
# File 'lib/action_controller/request.rb', line 405 def path_parameters @env["action_controller.request.path_parameters"] ||= {} end |
#path_parameters=(parameters) ⇒ Object
:nodoc:
389 390 391 392 |
# File 'lib/action_controller/request.rb', line 389 def path_parameters=(parameters) #:nodoc: @env["action_controller.request.path_parameters"] = parameters @symbolized_path_parameters = @parameters = nil end |
#port ⇒ Object
Returns the port number of this request as an integer.
295 296 297 298 299 300 301 |
# File 'lib/action_controller/request.rb', line 295 def port if raw_host_with_port =~ /:(\d+)$/ $1.to_i else standard_port end end |
#port_string ⇒ Object
Returns a port suffix like “:8080” if the port number of this request is not the default HTTP port 80 or HTTPS port 443.
313 314 315 |
# File 'lib/action_controller/request.rb', line 313 def port_string port == standard_port ? '' : ":#{port}" end |
#POST ⇒ Object Also known as: request_parameters
Override Rack’s POST method to support indifferent access
431 432 433 |
# File 'lib/action_controller/request.rb', line 431 def POST @env["action_controller.request.request_parameters"] ||= normalize_parameters(super) end |
#post? ⇒ Boolean
Is this a POST request? Equivalent to request.method == :post
.
52 53 54 |
# File 'lib/action_controller/request.rb', line 52 def post? request_method == :post end |
#protocol ⇒ Object
Returns ‘https://’ if this is an SSL request and ‘http://’ otherwise.
265 266 267 |
# File 'lib/action_controller/request.rb', line 265 def protocol ssl? ? 'https://' : 'http://' end |
#put? ⇒ Boolean
Is this a PUT request? Equivalent to request.method == :put
.
57 58 59 |
# File 'lib/action_controller/request.rb', line 57 def put? request_method == :put end |
#query_string ⇒ Object
Returns the query string, accounting for server idiosyncrasies.
336 337 338 |
# File 'lib/action_controller/request.rb', line 336 def query_string @env['QUERY_STRING'].present? ? @env['QUERY_STRING'] : (@env['REQUEST_URI'].split('?', 2)[1] || '') end |
#raw_host_with_port ⇒ Object
Returns the host for this request, such as “example.com”.
275 276 277 278 279 280 281 |
# File 'lib/action_controller/request.rb', line 275 def raw_host_with_port if forwarded = env["HTTP_X_FORWARDED_HOST"] forwarded.split(/,\s?/).last else env['HTTP_HOST'] || "#{env['SERVER_NAME'] || env['SERVER_ADDR']}:#{env['SERVER_PORT']}" end end |
#raw_post ⇒ Object
Read the request body. This is useful for web services that need to work with raw requests directly.
375 376 377 378 379 380 381 |
# File 'lib/action_controller/request.rb', line 375 def raw_post unless @env.include? 'RAW_POST_DATA' @env['RAW_POST_DATA'] = body.read(@env['CONTENT_LENGTH'].to_i) body.rewind if body.respond_to?(:rewind) end @env['RAW_POST_DATA'] end |
#remote_ip ⇒ Object
Determines originating IP address. REMOTE_ADDR is the standard but will fail if the user is behind a proxy. HTTP_CLIENT_IP and/or HTTP_X_FORWARDED_FOR are set by proxies so check for these if REMOTE_ADDR is a proxy. HTTP_X_FORWARDED_FOR may be a comma- delimited list in the case of multiple chained proxies; the last address which is not trusted is the originating IP.
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/action_controller/request.rb', line 221 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} 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 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 remote_ips.pop end return remote_ips.last.strip end @env['REMOTE_ADDR'] end |
#request_method ⇒ Object
Returns the true HTTP request method as a lowercase symbol, such as :get
. If the request method is not listed in the HTTP_METHODS constant above, an UnknownHttpMethod exception is raised.
34 35 36 |
# File 'lib/action_controller/request.rb', line 34 def request_method @request_method ||= HTTP_METHOD_LOOKUP[super] || raise(UnknownHttpMethod, "#{super}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}") end |
#request_uri ⇒ Object
Returns the request URI, accounting for server idiosyncrasies. WEBrick includes the full URL. IIS leaves REQUEST_URI blank.
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
# File 'lib/action_controller/request.rb', line 342 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 |
#reset_session ⇒ Object
448 449 450 451 |
# File 'lib/action_controller/request.rb', line 448 def reset_session @env['rack.session.options'].delete(:id) @env['rack.session'] = {} end |
#server_port ⇒ Object
461 462 463 |
# File 'lib/action_controller/request.rb', line 461 def server_port @env['SERVER_PORT'].to_i end |
#server_software ⇒ Object
Returns the lowercase name of the HTTP server software.
255 256 257 |
# File 'lib/action_controller/request.rb', line 255 def server_software (@env['SERVER_SOFTWARE'] && /^([a-zA-Z]+)/ =~ @env['SERVER_SOFTWARE']) ? $1.downcase : nil end |
#session ⇒ Object
440 441 442 |
# File 'lib/action_controller/request.rb', line 440 def session @env['rack.session'] ||= {} end |
#session=(session) ⇒ Object
:nodoc:
444 445 446 |
# File 'lib/action_controller/request.rb', line 444 def session=(session) #:nodoc: @env['rack.session'] = session end |
#session_options ⇒ Object
453 454 455 |
# File 'lib/action_controller/request.rb', line 453 def @env['rack.session.options'] ||= {} end |
#session_options=(options) ⇒ Object
457 458 459 |
# File 'lib/action_controller/request.rb', line 457 def () @env['rack.session.options'] = end |
#ssl? ⇒ Boolean
Is this an SSL request?
270 271 272 |
# File 'lib/action_controller/request.rb', line 270 def ssl? @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https' end |
#standard_port ⇒ Object
Returns the standard port number for this request’s protocol.
304 305 306 307 308 309 |
# File 'lib/action_controller/request.rb', line 304 def standard_port case protocol when 'https://' then 443 else 80 end end |
#subdomains(tld_length = 1) ⇒ Object
Returns all the subdomains as an array, so ["dev", "www"]
would be returned for “dev.www.rubyonrails.org”. You can specify a different tld_length
, such as 2 to catch ["www"]
instead of ["www", "rubyonrails"]
in “www.rubyonrails.co.uk”.
329 330 331 332 333 |
# File 'lib/action_controller/request.rb', line 329 def subdomains(tld_length = 1) return [] unless named_host?(host) parts = host.split('.') parts[0..-(tld_length+2)] end |
#symbolized_path_parameters ⇒ Object
The same as path_parameters
with explicitly symbolized keys.
395 396 397 |
# File 'lib/action_controller/request.rb', line 395 def symbolized_path_parameters @symbolized_path_parameters ||= path_parameters.symbolize_keys end |
#template_format ⇒ Object
Returns a symbolized version of the :format
parameter of the request. If no format is given it returns :js
for Ajax requests and :html
otherwise.
187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/action_controller/request.rb', line 187 def template_format parameter_format = parameters[:format] if parameter_format parameter_format elsif xhr? :js else :html end end |
#url ⇒ Object
Returns the complete URL used for this request.
260 261 262 |
# File 'lib/action_controller/request.rb', line 260 def url protocol + host_with_port + request_uri end |
#xml_http_request? ⇒ Boolean Also known as: xhr?
Returns true if the request’s “X-Requested-With” header contains “XMLHttpRequest”. (The Prototype Javascript library sends this header with every Ajax request.)
206 207 208 |
# File 'lib/action_controller/request.rb', line 206 def xml_http_request? !(@env['HTTP_X_REQUESTED_WITH'] !~ /XMLHttpRequest/i) end |