The last couple of examples do something very interesting: the first alters the HTTP headers for the response that is about to be sent, and the second accesses the HTTP REFERER of the request. This is neat, but Rails offers much more when it comes to accessing request and response information.
The following is a list of special identifiers that you can use from within your controller: action_name, cookies, headers, logger, params, request, and response.
Their names are self-descriptive: action_name is a method that returns the name of the current action; cookies represents the cookies for the request; headers is a hash of HTTP headers for the response; logger is a ActiveSupport::BufferedLogger object that's available throughout the application as discussed before; and params is the parameters hash.
request and response are objects that represent the request being processed and the response that is about to be sent, respectively.
You rarely have to modify the response object directly, because Rails takes care of formulating a proper response on its own. However, in the few circumstances where you need to alter the object before it's sent to the client, you can do so easily by accessing one or more of its attributes. Among these, the two that will most likely be used to alter the response object are body and headers.
request, on the other hand, is slightly more complex, and is used frequently enough to warrant further explanation.
To learn more about these two objects, check the documentation for the abstract classes ActionController::AbstractRequest and ActionController::AbstractResponse.
The environment of a request is captured in the read-only attribute env. From within a debugging session for a simple request, I obtained the following output for request.env:
(rdb:5) request.env {"SERVER_NAME"=>"localhost", "PATH_INFO"=>"/main", "HTTP_ACCEPT_ENCODING"=>"gzip,deflate,bzip2", "HTTP_USER_AGENT"=>"Moz illa/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.30 Safari/525.13", "S CRIPT_NAME"=>"/", "SERVER_PROTOCOL"=>"HTTP/1.1", "HTTP_HOST"= >"localhost:3000", "HTTP_ACCEPT_LANGUAGE"=>"en-US,en", "REM OTE_ADDR"=>"127.0.0.1", "SERVER_SOFTWARE"=>"Mongrel 1.1.5", "REQUEST_PATH"=>"/main", "HTTP_ACCEPT_CHARSET"=>"ISO-8859-1, *,utf-8", "HTTP_VERSION"=>"HTTP/1.1", "REQUEST_URI"=>"/main", "SERVER_PORT"=>"3000", "GATEWAY_INTERFACE"=>"CGI/1.2", "HT TP_ACCEPT"=>"text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/pl ain;q=0.8,image/png,*/*;q=0.5", "HTTP _CONNECTION"=>"Keep-Alive", "REQUEST_METHOD"=>"GET"}
That's a lot of information that can be used to obtain details about the client and the request. For example, request.env["HTTP_USER_AGENT"] retrieves the user agent for the browser that's being used (in this case Google Chrome).
env is the only attribute for request, but many methods are defined by this object.
Purposely, many of these methods are there to facilitate access to the same information that's available in the env hash-like object.
headers returns a hash of HTTP headers:
(rdb:5) request.headers {"SERVER_NAME"=>"localhost", "HTTP_USER_AGENT"=>"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US) AppleWebKit/525.13 (KHT ML, like Gecko) Chrome/0.2.149.30 Safari/525.13", "HTTP_ACCEPT_ENCODING"=>"gzip,deflate,bzip2", "PATH_INFO"=>"/main", "H TTP_ACCEPT_LANGUAGE"=>"en-US,en", "HTTP_HOST"=>"localhost:3000",
"SERVER_PROTOCOL"=>"HTTP/1.1", "SCRIPT_NAME"=>"/", "REQ UEST_PATH"=>"/main", "SERVER_SOFTWARE"=>"Mongrel 1.1.5", "REMOTE_ADDR"=>"127.0.0.1", "HTTP_VERSION"=>"HTTP/1.1", "HTTP_A CCEPT_CHARSET"=>"ISO-8859-1,*,utf-8", "REQUEST_URI"=>"/main", "SERVER_PORT"=>"3000", "GATEWAY_INTERFACE"=>"CGI/1.2", "HT TP_ACCEPT"=>"text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/pl ain;q=0.8,image/png,*/*;q=0.5", "REQU EST_METHOD"=>"GET", "HTTP_CONNECTION"=>"Keep-Alive"}
Similarly, body, content_type, and content_length return the request's body as an IO stream, the MIME type (for example, Mime::XML), and the length of the body in bytes. accepts and format, respectively, return the accepted MIME types and the format (as a MIME type as well) used in the request. If no format is available, the first of the accepted types will be used (for browsers this is usually Mime::HTML).
When you are using the respond_to method introduced in Chapter 5, there is usually no need to invoke these "low-level" mime methods directly. The logic that needs to be implemented for each format in the request (among the registered ones, known to Rails) will be defined within the block passed to the method respond_to.
host, domain, port, port_string, host_with_port, protocol, request_uri, url, and parameters all work as you'd probably expect them to:
(rdb:5) request.host "localhost" (rdb:5) request.domain "localhost" (rdb:5) request.port 3000 (rdb:5) request.port_string ":3000" (rdb:5) request.host_with_port "localhost:3000" (rdb:5) request.protocol "http://" (rdb:5) request.request_uri "/main" (rdb:5) request.url "http://localhost:3000/main" (rdb:5) request.parameters {"action"=>"index", "controller"=>"main"}
remote_ip is used to retrieve the IP address that issued the request. This method returns a string containing a single IP, or more IPs if one or more proxies are involved.
The request object also has the two methods method and request_method. These return the HTTP method used for the request as a symbol:
(rdb:5) request.method :get (rdb:5) request.request_method :get
The difference between the two is that method will return :get when a :head request is issued. The reason for this is that from an application standpoint there is usually no need to distinguish between a :get and a :head request.
There is a series of methods that return Boolean values. These methods follow Ruby's convention of ending with a question mark. Among the most common are get?, post?, put?, delete?, head?, ssl?, xhr?, and xml_http_request?.
The first five, corresponding to their five respective verbs, will return true only if the request was issued using the proper HTTP method. request.post?, for example, will return true for POST requests and false for any other type of request verb.
It is common to see an if request.get? or if request.post? statement within an action. This is usually present whenever an action acts differently based on whether the incoming request was a GET or a POST request. In a RESTful controller, if an action is accessible only by a GET or only by a POST request, there is no need to use these methods to check the verb.
ssl? is used to determine whether this was an SSL request, and finally, xml_http_request? (and its alias xhr?) are used to check if the incoming request is an Ajax request. This is done by verifying that the value "XMLHttpRequest" was assigned to the request's X-Requested-With header.
This method is fundamental to Ajax applications, because a response will typically vary depending on whether or not the request was an Ajax one. Ajax requests will normally require a response that updates only certain elements of the page, whereas a regular HTML request requires rendering the whole page.
18.189.178.237