CgiRequest and TestRequest provide concrete implementations.

Methods
Constants
TRUSTED_PROXIES = /^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\./i
  Which IP addresses are "trusted proxies" that can be stripped from the right-hand-side of X-Forwarded-For
MULTIPART_BOUNDARY = %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n
EOL = "\015\012"
Attributes
[R] env The hash of environment variables for this request, such as { ‘RAILS_ENV’ => ‘production’ }.
Public Instance methods
accepts()

Returns the accepted MIME type for the request

    # File lib/action_controller/request.rb, line 83
83:     def accepts
84:       @accepts ||=
85:         if @env['HTTP_ACCEPT'].to_s.strip.empty?
86:           [ content_type, Mime::ALL ].compact # make sure content_type being nil is not included
87:         else
88:           Mime::Type.parse(@env['HTTP_ACCEPT'])
89:         end
90:     end
body()

The request body is an IO input stream.

     # File lib/action_controller/request.rb, line 335
335:     def body
336:     end
content_length()
    # File lib/action_controller/request.rb, line 70
70:     def content_length
71:       @content_length ||= env['CONTENT_LENGTH'].to_i
72:     end
content_type()

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.

    # File lib/action_controller/request.rb, line 78
78:     def content_type
79:       @content_type ||= Mime::Type.lookup(content_type_without_parameters)
80:     end
delete?()

Is this a DELETE request? Equivalent to request.method == :delete.

    # File lib/action_controller/request.rb, line 54
54:     def delete?
55:       request_method == :delete
56:     end
domain(tld_length = 1)

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".

     # File lib/action_controller/request.rb, line 221
221:     def domain(tld_length = 1)
222:       return nil unless named_host?(host)
223: 
224:       host.split('.').last(1 + tld_length).join('.')
225:     end
format()

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)
     # File lib/action_controller/request.rb, line 98
 98:     def format
 99:       @format ||= parameters[:format] ? Mime::Type.lookup_by_extension(parameters[:format]) : accepts.first
100:     end
format=(extension)

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
     # File lib/action_controller/request.rb, line 114
114:     def format=(extension)
115:       parameters[:format] = extension.to_s
116:       @format = Mime::Type.lookup_by_extension(parameters[:format])
117:     end
get?()

Is this a GET (or HEAD) request? Equivalent to request.method == :get.

    # File lib/action_controller/request.rb, line 39
39:     def get?
40:       method == :get
41:     end
head?()

Is this a HEAD request? request.method sees HEAD as :get, so check the HTTP method directly.

    # File lib/action_controller/request.rb, line 60
60:     def head?
61:       request_method == :head
62:     end
headers()

Provides acccess to the request‘s HTTP headers, for example:

 request.headers["Content-Type"] # => "text/plain"
    # File lib/action_controller/request.rb, line 66
66:     def headers
67:       @headers ||= ActionController::Http::Headers.new(@env)
68:     end
host()

Returns the host for this request, such as example.com.

     # File lib/action_controller/request.rb, line 191
191:     def host
192:     end
host_with_port()

Returns a host:port string for this request, such as example.com or example.com:8080.

     # File lib/action_controller/request.rb, line 196
196:     def host_with_port
197:       @host_with_port ||= host + port_string
198:     end
method()

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.

    # File lib/action_controller/request.rb, line 34
34:     def method
35:       request_method == :head ? :get : request_method
36:     end
parameters()

Returns both GET and POST parameters in a single hash.

     # File lib/action_controller/request.rb, line 305
305:     def parameters
306:       @parameters ||= request_parameters.merge(query_parameters).update(path_parameters).with_indifferent_access
307:     end
path()

Returns the interpreted path to requested resource after all the installation directory of this application was taken into account

     # File lib/action_controller/request.rb, line 270
270:     def path
271:       path = (uri = request_uri) ? uri.split('?').first.to_s : ''
272: 
273:       # Cut off the path to the installation directory if given
274:       path.sub!(%r/^#{relative_url_root}/, '')
275:       path || ''      
276:     end
path_parameters()

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'}
     # File lib/action_controller/request.rb, line 325
325:     def path_parameters
326:       @path_parameters ||= {}
327:     end
port()

Returns the port number of this request as an integer.

     # File lib/action_controller/request.rb, line 201
201:     def port
202:       @port_as_int ||= @env['SERVER_PORT'].to_i
203:     end
port_string()

Returns a port suffix like ":8080" if the port number of this request is not the default HTTP port 80 or HTTPS port 443.

     # File lib/action_controller/request.rb, line 215
215:     def port_string
216:       (port == standard_port) ? '' : ":#{port}"
217:     end
post?()

Is this a POST request? Equivalent to request.method == :post.

    # File lib/action_controller/request.rb, line 44
44:     def post?
45:       request_method == :post
46:     end
protocol()

Return ‘https://’ if this is an SSL request and ‘http://’ otherwise.

     # File lib/action_controller/request.rb, line 181
181:     def protocol
182:       ssl? ? 'https://' : 'http://'
183:     end
put?()

Is this a PUT request? Equivalent to request.method == :put.

    # File lib/action_controller/request.rb, line 49
49:     def put?
50:       request_method == :put
51:     end
query_string()

Return the query string, accounting for server idiosyncracies.

     # File lib/action_controller/request.rb, line 237
237:     def query_string
238:       if uri = @env['REQUEST_URI']
239:         uri.split('?', 2)[1] || ''
240:       else
241:         @env['QUERY_STRING'] || ''
242:       end
243:     end
raw_post()

Read the request body. This is useful for web services that need to work with raw requests directly.

     # File lib/action_controller/request.rb, line 296
296:     def raw_post
297:       unless env.include? 'RAW_POST_DATA'
298:         env['RAW_POST_DATA'] = body.read(content_length)
299:         body.rewind if body.respond_to?(:rewind)
300:       end
301:       env['RAW_POST_DATA']
302:     end
relative_url_root()

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.

     # File lib/action_controller/request.rb, line 282
282:     def relative_url_root
283:       @@relative_url_root ||= case
284:         when @env["RAILS_RELATIVE_URL_ROOT"]
285:           @env["RAILS_RELATIVE_URL_ROOT"]
286:         when server_software == 'apache'
287:           @env["SCRIPT_NAME"].to_s.sub(/\/dispatch\.(fcgi|rb|cgi)$/, '')
288:         else
289:           ''
290:       end
291:     end
remote_ip()

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.

     # File lib/action_controller/request.rb, line 137
137:     def remote_ip
138:       if TRUSTED_PROXIES !~ @env['REMOTE_ADDR']
139:         return @env['REMOTE_ADDR']
140:       end
141: 
142:       remote_ips = @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_X_FORWARDED_FOR'].split(',')
143: 
144:       if @env.include? 'HTTP_CLIENT_IP'
145:         if remote_ips && !remote_ips.include?(@env['HTTP_CLIENT_IP'])
146:           # We don't know which came from the proxy, and which from the user
147:           raise ActionControllerError.new("IP spoofing attack?!\nHTTP_CLIENT_IP=\#{@env['HTTP_CLIENT_IP'].inspect}\nHTTP_X_FORWARDED_FOR=\#{@env['HTTP_X_FORWARDED_FOR'].inspect}\n")
148:         end
149: 
150:         return @env['HTTP_CLIENT_IP']
151:       end
152: 
153:       if remote_ips
154:         while remote_ips.size > 1 && TRUSTED_PROXIES =~ remote_ips.last.strip
155:           remote_ips.pop
156:         end
157: 
158:         return remote_ips.last.strip
159:       end
160: 
161:       @env['REMOTE_ADDR']
162:     end
request_method()

The true HTTP request method as a lowercase symbol, such as :get. UnknownHttpMethod is raised for invalid methods not listed in ACCEPTED_HTTP_METHODS.

    # File lib/action_controller/request.rb, line 20
20:     def request_method
21:       @request_method ||= begin
22:         method = ((@env['REQUEST_METHOD'] == 'POST' && !parameters[:_method].blank?) ? parameters[:_method].to_s : @env['REQUEST_METHOD']).downcase
23:         if ACCEPTED_HTTP_METHODS.include?(method)
24:           method.to_sym
25:         else
26:           raise UnknownHttpMethod, "#{method}, accepted HTTP methods are #{ACCEPTED_HTTP_METHODS.to_a.to_sentence}"
27:         end
28:       end
29:     end
request_uri()

Return the request URI, accounting for server idiosyncracies. WEBrick includes the full URL. IIS leaves REQUEST_URI blank.

     # File lib/action_controller/request.rb, line 247
247:     def request_uri
248:       if uri = @env['REQUEST_URI']
249:         # Remove domain, which webrick puts into the request_uri.
250:         (%r{^\w+\://[^/]+(/.*|$)$} =~ uri) ? $1 : uri
251:       else
252:         # Construct IIS missing REQUEST_URI from SCRIPT_NAME and PATH_INFO.
253:         script_filename = @env['SCRIPT_NAME'].to_s.match(%r{[^/]+$})
254:         uri = @env['PATH_INFO']
255:         uri = uri.sub(/#{script_filename}\//, '') unless script_filename.nil?
256:         unless (env_qs = @env['QUERY_STRING']).nil? || env_qs.empty?
257:           uri << '?' << env_qs
258:         end
259: 
260:         if uri.nil?
261:           @env.delete('REQUEST_URI')
262:           uri
263:         else
264:           @env['REQUEST_URI'] = uri
265:         end
266:       end
267:     end
server_software()

Returns the lowercase name of the HTTP server software.

     # File lib/action_controller/request.rb, line 170
170:     def server_software
171:       (@env['SERVER_SOFTWARE'] && /^([a-zA-Z]+)/ =~ @env['SERVER_SOFTWARE']) ? $1.downcase : nil
172:     end
ssl?()

Is this an SSL request?

     # File lib/action_controller/request.rb, line 186
186:     def ssl?
187:       @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
188:     end
standard_port()

Returns the standard port number for this request‘s protocol

     # File lib/action_controller/request.rb, line 206
206:     def standard_port
207:       case protocol
208:         when 'https://' then 443
209:         else 80
210:       end
211:     end
subdomains(tld_length = 1)

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".

     # File lib/action_controller/request.rb, line 230
230:     def subdomains(tld_length = 1)
231:       return [] unless named_host?(host)
232:       parts = host.split('.')
233:       parts[0..-(tld_length+2)]
234:     end
symbolized_path_parameters()

The same as path_parameters with explicitly symbolized keys

     # File lib/action_controller/request.rb, line 315
315:     def symbolized_path_parameters 
316:       @symbolized_path_parameters ||= path_parameters.symbolize_keys
317:     end
url()

Returns the complete URL used for this request

     # File lib/action_controller/request.rb, line 176
176:     def url
177:       protocol + host_with_port + request_uri
178:     end
xhr?()

Alias for xml_http_request?

xml_http_request?()

Returns true if the request‘s "X-Requested-With" header contains "XMLHttpRequest". (The Prototype Javascript library sends this header with every Ajax request.)

This method is also aliased as xhr?
     # File lib/action_controller/request.rb, line 122
122:     def xml_http_request?
123:       !(@env['HTTP_X_REQUESTED_WITH'] !~ /XMLHttpRequest/i)
124:     end
Protected Instance methods
content_type_with_parameters()

The raw content type string. Use when you need parameters such as charset or boundary which aren‘t included in the content_type MIME type. Overridden by the X-POST_DATA_FORMAT header for backward compatibility.

     # File lib/action_controller/request.rb, line 361
361:       def content_type_with_parameters
362:         content_type_from_legacy_post_data_format_header ||
363:           env['CONTENT_TYPE'].to_s
364:       end
content_type_without_parameters()

The raw content type string with its parameters stripped off.

     # File lib/action_controller/request.rb, line 367
367:       def content_type_without_parameters
368:         @content_type_without_parameters ||= self.class.extract_content_type_without_parameters(content_type_with_parameters)
369:       end