Class: ActionController::AbstractRequest
- Defined in:
- lib/action_controller/request.rb
Overview
CgiRequest and TestRequest provide concrete implementations.
Direct Known Subclasses
Constant Summary collapse
- 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 Attribute Summary collapse
-
#env ⇒ Object
readonly
The hash of environment variables for this request, such as { ‘RAILS_ENV’ => ‘production’ }.
Class Method Summary collapse
- .clean_up_ajax_request_body!(body) ⇒ Object
- .extract_content_type_without_parameters(content_type_with_parameters) ⇒ Object
- .extract_multipart_boundary(content_type_with_parameters) ⇒ Object
- .parse_multipart_form_parameters(body, boundary, content_length, env) ⇒ Object
- .parse_query_parameters(query_string) ⇒ Object
- .parse_request_parameters(params) ⇒ Object
Instance Method Summary collapse
-
#accepts ⇒ Object
Returns the accepted MIME type for the request.
-
#body ⇒ Object
The request body is an IO input stream.
- #content_length ⇒ Object
-
#content_type ⇒ Object
The MIME type of the HTTP request, such as Mime::XML.
-
#cookies ⇒ Object
:nodoc:.
-
#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”.
-
#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.
-
#get? ⇒ Boolean
Is this a GET (or HEAD) request? Equivalent to request.method == :get.
-
#head? ⇒ Boolean
Is this a HEAD request? request.method sees HEAD as :get, so check the HTTP method directly.
- #headers ⇒ Object
-
#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.
-
#method ⇒ Object
The HTTP request method as a lowercase symbol, such as :get.
-
#parameters ⇒ Object
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? ⇒ Boolean
Is this a POST request? Equivalent to request.method == :post.
-
#protocol ⇒ Object
Return ‘https://’ if this is an SSL request and ‘http://’ otherwise.
-
#put? ⇒ Boolean
Is this a PUT request? Equivalent to request.method == :put.
-
#query_parameters ⇒ Object
:nodoc:.
-
#query_string ⇒ Object
Return the query string, accounting for server idiosyncracies.
-
#raw_post ⇒ Object
Read the request body.
-
#relative_url_root ⇒ Object
Returns the path minus the web server relative installation directory.
-
#remote_ip ⇒ Object
Determine originating IP address.
-
#request_method ⇒ Object
The true HTTP request method as a lowercase symbol, such as :get.
-
#request_parameters ⇒ Object
:nodoc:.
-
#request_uri ⇒ Object
Return the request URI, accounting for server idiosyncracies.
-
#reset_session ⇒ Object
:nodoc:.
-
#server_software ⇒ Object
Returns the lowercase name of the HTTP server software.
-
#session ⇒ Object
:nodoc:.
-
#session=(session) ⇒ Object
:nodoc:.
-
#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. -
#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 Attribute Details
#env ⇒ Object (readonly)
The hash of environment variables for this request, such as { ‘RAILS_ENV’ => ‘production’ }.
16 17 18 |
# File 'lib/action_controller/request.rb', line 16 def env @env end |
Class Method Details
.clean_up_ajax_request_body!(body) ⇒ Object
475 476 477 478 |
# File 'lib/action_controller/request.rb', line 475 def clean_up_ajax_request_body!(body) body.chop! if body[-1] == 0 body.gsub!(/&_=$/, '') end |
.extract_content_type_without_parameters(content_type_with_parameters) ⇒ Object
471 472 473 |
# File 'lib/action_controller/request.rb', line 471 def extract_content_type_without_parameters(content_type_with_parameters) $1.strip.downcase if content_type_with_parameters =~ /^([^,\;]*)/ end |
.extract_multipart_boundary(content_type_with_parameters) ⇒ Object
463 464 465 466 467 468 469 |
# File 'lib/action_controller/request.rb', line 463 def extract_multipart_boundary(content_type_with_parameters) if content_type_with_parameters =~ MULTIPART_BOUNDARY ['multipart/form-data', $1.dup] else extract_content_type_without_parameters(content_type_with_parameters) end end |
.parse_multipart_form_parameters(body, boundary, content_length, env) ⇒ Object
459 460 461 |
# File 'lib/action_controller/request.rb', line 459 def parse_multipart_form_parameters(body, boundary, content_length, env) parse_request_parameters(read_multipart(body, boundary, content_length, env)) end |
.parse_query_parameters(query_string) ⇒ Object
420 421 422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/action_controller/request.rb', line 420 def parse_query_parameters(query_string) return {} if query_string.blank? pairs = query_string.split('&').collect do |chunk| next if chunk.empty? key, value = chunk.split('=', 2) next if key.empty? value = value.nil? ? nil : CGI.unescape(value) [ CGI.unescape(key), value ] end.compact UrlEncodedPairParser.new(pairs).result end |
.parse_request_parameters(params) ⇒ Object
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/action_controller/request.rb', line 434 def parse_request_parameters(params) parser = UrlEncodedPairParser.new params = params.dup until params.empty? for key, value in params if key.blank? params.delete key elsif !key.include?('[') # much faster to test for the most common case first (GET) # and avoid the call to build_deep_hash parser.result[key] = get_typed_value(value[0]) params.delete key elsif value.is_a?(Array) parser.parse(key, get_typed_value(value.shift)) params.delete key if value.empty? else raise TypeError, "Expected array, found #{value.inspect}" end end end parser.result end |
Instance Method Details
#accepts ⇒ Object
Returns the accepted MIME type for the request
81 82 83 84 85 86 87 88 |
# File 'lib/action_controller/request.rb', line 81 def accepts @accepts ||= if @env['HTTP_ACCEPT'].to_s.strip.empty? [ content_type, Mime::ALL ].compact # make sure content_type being nil is not included else Mime::Type.parse(@env['HTTP_ACCEPT']) end end |
#body ⇒ Object
The request body is an IO input stream.
331 332 |
# File 'lib/action_controller/request.rb', line 331 def body end |
#content_length ⇒ Object
68 69 70 |
# File 'lib/action_controller/request.rb', line 68 def content_length @content_length ||= env['CONTENT_LENGTH'].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.
76 77 78 |
# File 'lib/action_controller/request.rb', line 76 def content_type @content_type ||= Mime::Type.lookup(content_type_without_parameters) end |
#cookies ⇒ Object
:nodoc:
340 341 |
# File 'lib/action_controller/request.rb', line 340 def #:nodoc: end |
#delete? ⇒ Boolean
Is this a DELETE request? Equivalent to request.method == :delete
54 55 56 |
# File 'lib/action_controller/request.rb', line 54 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”.
217 218 219 220 221 |
# File 'lib/action_controller/request.rb', line 217 def domain(tld_length = 1) return nil unless named_host?(host) host.split('.').last(1 + tld_length).join('.') end |
#format ⇒ Object
Returns the Mime type for the format used in the request. If there is no format available, the first of the accept types will be used. Examples:
GET /posts/5.xml | request.format => Mime::XML
GET /posts/5.xhtml | request.format => Mime::HTML
GET /posts/5 | request.format => request.accepts.first (usually Mime::HTML for browsers)
96 97 98 |
# File 'lib/action_controller/request.rb', line 96 def format @format ||= parameters[:format] ? Mime::Type.lookup_by_extension(parameters[:format]) : accepts.first 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. Example:
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
112 113 114 115 |
# File 'lib/action_controller/request.rb', line 112 def format=(extension) parameters[:format] = extension.to_s @format = Mime::Type.lookup_by_extension(parameters[:format]) end |
#get? ⇒ Boolean
Is this a GET (or HEAD) request? Equivalent to request.method == :get
39 40 41 |
# File 'lib/action_controller/request.rb', line 39 def get? method == :get end |
#head? ⇒ Boolean
Is this a HEAD request? request.method sees HEAD as :get, so check the HTTP method directly.
60 61 62 |
# File 'lib/action_controller/request.rb', line 60 def head? request_method == :head end |
#headers ⇒ Object
64 65 66 |
# File 'lib/action_controller/request.rb', line 64 def headers @env end |
#host ⇒ Object
Returns the host for this request, such as example.com.
187 188 |
# File 'lib/action_controller/request.rb', line 187 def host end |
#host_with_port ⇒ Object
Returns a host:port string for this request, such as example.com or example.com:8080.
192 193 194 |
# File 'lib/action_controller/request.rb', line 192 def host_with_port @host_with_port ||= host + port_string end |
#method ⇒ Object
The HTTP request method as a lowercase symbol, such as :get. Note, HEAD is returned as :get since the two are functionally equivalent from the application’s perspective.
34 35 36 |
# File 'lib/action_controller/request.rb', line 34 def method request_method == :head ? :get : request_method end |
#parameters ⇒ Object
Returns both GET and POST parameters in a single hash.
301 302 303 |
# File 'lib/action_controller/request.rb', line 301 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
266 267 268 269 270 271 272 |
# File 'lib/action_controller/request.rb', line 266 def path path = (uri = request_uri) ? uri.split('?').first.to_s : '' # Cut off the path to the installation directory if given path.sub!(%r/^#{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. See symbolized_path_parameters
for symbolized keys.
Example:
{'action' => 'my_action', 'controller' => 'my_controller'}
321 322 323 |
# File 'lib/action_controller/request.rb', line 321 def path_parameters @path_parameters ||= {} end |
#path_parameters=(parameters) ⇒ Object
:nodoc:
305 306 307 308 |
# File 'lib/action_controller/request.rb', line 305 def path_parameters=(parameters) #:nodoc: @path_parameters = parameters @symbolized_path_parameters = @parameters = nil end |
#port ⇒ Object
Returns the port number of this request as an integer.
197 198 199 |
# File 'lib/action_controller/request.rb', line 197 def port @port_as_int ||= @env['SERVER_PORT'].to_i 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.
211 212 213 |
# File 'lib/action_controller/request.rb', line 211 def port_string (port == standard_port) ? '' : ":#{port}" end |
#post? ⇒ Boolean
Is this a POST request? Equivalent to request.method == :post
44 45 46 |
# File 'lib/action_controller/request.rb', line 44 def post? request_method == :post end |
#protocol ⇒ Object
Return ‘https://’ if this is an SSL request and ‘http://’ otherwise.
177 178 179 |
# File 'lib/action_controller/request.rb', line 177 def protocol ssl? ? 'https://' : 'http://' end |
#put? ⇒ Boolean
Is this a PUT request? Equivalent to request.method == :put
49 50 51 |
# File 'lib/action_controller/request.rb', line 49 def put? request_method == :put end |
#query_parameters ⇒ Object
:nodoc:
334 335 |
# File 'lib/action_controller/request.rb', line 334 def query_parameters #:nodoc: end |
#query_string ⇒ Object
Return the query string, accounting for server idiosyncracies.
233 234 235 236 237 238 239 |
# File 'lib/action_controller/request.rb', line 233 def query_string if uri = @env['REQUEST_URI'] uri.split('?', 2)[1] || '' else @env['QUERY_STRING'] || '' end end |
#raw_post ⇒ Object
Read the request body. This is useful for web services that need to work with raw requests directly.
292 293 294 295 296 297 298 |
# File 'lib/action_controller/request.rb', line 292 def raw_post unless env.include? 'RAW_POST_DATA' env['RAW_POST_DATA'] = body.read(content_length) body.rewind if body.respond_to?(:rewind) end env['RAW_POST_DATA'] end |
#relative_url_root ⇒ Object
Returns the path minus the web server relative installation directory. This can be set with the environment variable RAILS_RELATIVE_URL_ROOT. It can be automatically extracted for Apache setups. If the server is not Apache, this method returns an empty string.
278 279 280 281 282 283 284 285 286 287 |
# File 'lib/action_controller/request.rb', line 278 def relative_url_root @@relative_url_root ||= case when @env["RAILS_RELATIVE_URL_ROOT"] @env["RAILS_RELATIVE_URL_ROOT"] when server_software == 'apache' @env["SCRIPT_NAME"].to_s.sub(/\/dispatch\.(fcgi|rb|cgi)$/, '') else '' end end |
#remote_ip ⇒ Object
Determine 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.
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/action_controller/request.rb', line 136 def remote_ip if TRUSTED_PROXIES !~ @env['REMOTE_ADDR'] return @env['REMOTE_ADDR'] end if @env.include? 'HTTP_CLIENT_IP' if @env.include? 'HTTP_X_FORWARDED_FOR' # 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 @env.include? 'HTTP_X_FORWARDED_FOR' then remote_ips = @env['HTTP_X_FORWARDED_FOR'].split(',') 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
The true HTTP request method as a lowercase symbol, such as :get. UnknownHttpMethod is raised for invalid methods not listed in ACCEPTED_HTTP_METHODS.
20 21 22 23 24 25 26 27 28 29 |
# File 'lib/action_controller/request.rb', line 20 def request_method @request_method ||= begin method = ((@env['REQUEST_METHOD'] == 'POST' && !parameters[:_method].blank?) ? parameters[:_method].to_s : @env['REQUEST_METHOD']).downcase if ACCEPTED_HTTP_METHODS.include?(method) method.to_sym else raise UnknownHttpMethod, "#{method}, accepted HTTP methods are #{ACCEPTED_HTTP_METHODS.to_a.to_sentence}" end end end |
#request_parameters ⇒ Object
:nodoc:
337 338 |
# File 'lib/action_controller/request.rb', line 337 def request_parameters #:nodoc: end |
#request_uri ⇒ Object
Return the request URI, accounting for server idiosyncracies. WEBrick includes the full URL. IIS leaves REQUEST_URI blank.
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/action_controller/request.rb', line 243 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. script_filename = @env['SCRIPT_NAME'].to_s.match(%r{[^/]+$}) uri = @env['PATH_INFO'] uri = uri.sub(/#{script_filename}\//, '') unless script_filename.nil? unless (env_qs = @env['QUERY_STRING']).nil? || env_qs.empty? uri << '?' << env_qs end if uri.nil? @env.delete('REQUEST_URI') uri else @env['REQUEST_URI'] = uri end end end |
#reset_session ⇒ Object
:nodoc:
350 351 |
# File 'lib/action_controller/request.rb', line 350 def reset_session #:nodoc: end |
#server_software ⇒ Object
Returns the lowercase name of the HTTP server software.
166 167 168 |
# File 'lib/action_controller/request.rb', line 166 def server_software (@env['SERVER_SOFTWARE'] && /^([a-zA-Z]+)/ =~ @env['SERVER_SOFTWARE']) ? $1.downcase : nil end |
#session ⇒ Object
:nodoc:
343 344 |
# File 'lib/action_controller/request.rb', line 343 def session #:nodoc: end |
#session=(session) ⇒ Object
:nodoc:
346 347 348 |
# File 'lib/action_controller/request.rb', line 346 def session=(session) #:nodoc: @session = session end |
#ssl? ⇒ Boolean
Is this an SSL request?
182 183 184 |
# File 'lib/action_controller/request.rb', line 182 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
202 203 204 205 206 207 |
# File 'lib/action_controller/request.rb', line 202 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”.
226 227 228 229 230 |
# File 'lib/action_controller/request.rb', line 226 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
311 312 313 |
# File 'lib/action_controller/request.rb', line 311 def symbolized_path_parameters @symbolized_path_parameters ||= path_parameters.symbolize_keys end |
#url ⇒ Object
Returns the complete URL used for this request
172 173 174 |
# File 'lib/action_controller/request.rb', line 172 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.)
120 121 122 |
# File 'lib/action_controller/request.rb', line 120 def xml_http_request? !(@env['HTTP_X_REQUESTED_WITH'] !~ /XMLHttpRequest/i) end |