Setting Cookies and Other HTTP Response Headers






Setting Cookies and Other HTTP Response Headers

Credit: Mauro Cicio

Problem

You're writing a CGI program and you want to customize the HTTP headers you send in response to a request. For instance, you may want to set a client-side cookie so that you can track state between HTTP requests.

Solution

Pass a hash of headers into the CGI#out method that creates the HTTP response. Each key of the hash is the name of a header to set, or a special value (like cookie), which the CGI class knows how to interpret.

Here's a CGI script that demonstrates how to set some response headers, including a cookie and a custom HTTP header called "Recipe Name".

First we process any incoming cookie. Every time you hit this CGI, the value stored in your cookie will be incremented, and the date of your last visit will be reset.

	#!/usr/bin/ruby
	# headers.cgi

	require "cgi"
	cgi = CGI.new("html3")

	# Retrieve or create the "rubycookbook" cookie
	cookie = cgi. 
cookies['rubycookbook']
	cookie = CGI::Cookie.new('rubycookbook', 'hits=0',
	                         "last=#{Time.now}") if cookie.empty?

	# Read the values in the cookie for future use
	hits = cookie.value[0].split('=')[1]
	last = cookie.value[1].split('=')[1]

	# Set new values in the cookie
	cookie.value[0] = "hits=#{hits.succ}"
	cookie.value[1] = "last=#{Time.now}"

Next, we build a hash of HTTP headers, and send the headers by passing the hash into CGI#out. We then generate the output document. Since the end user doesn't usually see the HTTP headers they're served, we'll make them visible by repeating them in the output document (Figure):

	# Create a hash of HTTP response headers.
	header = { 'status'      => 'OK',
	           'cookie'      => [cookie],
	           'Refresh'     => 2,
	           'Recipe Name' => 'Setting HTTP Response Headers',
	           'server'      => ENV['SERVER_SOFTWARE'] }

	cgi.out(header) do
	  cgi.html('PRETTY' => ' ') do
	    cgi.head { cgi.title { 'Setting HTTP Response Headers' } } +
	    cgi.body do
	      cgi.p('Your headers:') +
	      cgi.pre{ cgi.header(header) } +
	      cgi.pre do
	        "Number of times your browser hit this cgi: #{hits}\n"+
	        "Last connected: #{last}"
	      end
	    end
	 end
	end

This CGI lets you see the response headers, including the cookie


The Refresh header makes your web browser refresh the page every two seconds. You can visit this CGI once and watch the number of hits (stored in the client-side cookie) start to mount up.

Discussion

An HTTP Response consists of two sections (a header section and a body section) separated by a blank line. The body contains the document to be rendered by the browser (usually an HTML page) and the header carries metadata: information about the connection, the response, and the document itself. The CGI#out method takes a hash representing the HTTP headers, and a code block that generates the body.

CGI#out recognizes a few special values that make it easier to set custom headers. For instance, the header hash in the example above maps the key "cookie" to a CGI::Cookie object. CGI#out knows enough to turn cookie into the standard HTTP header Set-Cookie, and to transform the CGI::Cookie object into a string rendition.

If CGI#out doesn't know about a certain key, it simply sends it as an HTTP header, as-is. CGI#out has no special knowledge of our "Refresh" and "Recipe Name" headers, so it writes them verbatim to the HTTP response. "Refresh" is a standard HTTP response header recognized by most web browsers; "Recipe Name" is a header I made up for this recipe, and web browsers should ignore it.

See Also



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows