Customizing HTTP Request Headers

Problem

When you make an HTTP request, you want to specify custom HTTP headers like " User-Agent" or " Accept-Language".

Solution

Pass in a Hash of header values to Net::HTTP#get or Net::HTTP#post:

	require 
et/http
	require uri

	#A simple wrapper method that accepts either strings or URI objects
	#and performs an HTTP GET.
	module Net
	 class HTTP
	 def HTTP.get_with_headers(uri, headers=nil)
	 uri = URI.parse(uri) if uri.respond_to? :to_str
	 start(uri.host, uri.port) do | 
http|
	 return 
http.get(uri.path, headers)
	 end
	 end
	 end
	end

	#Lets get a web page in German.
	res = Net::HTTP.get_with_headers(http://www.google.com/,
	 { 
Accept-Language => de})

	#Check a bit of the body to make sure its really in German.
	s = res.body.size
	res.body[s-200..s-140]
	# => "ngebote</a> - <a href=/intl/de/about.html>Alles 374ber Google

Discussion

Usually you can retrieve the web pages you want without specifying any custom HTTP headers. As you start performing more complicated interactions with web servers, youll find yourself customizing the headers more.

For instance, if you write a web spider or client, youll want it to send a " User-Agent" header on every request, identifying itself to the web server. Unlike the HTTP client libraries for other programming languages, the net/http library doesn send a "User-Agent" header by default; its your reponsibility to send one.

	Net::HTTP.get_with_headers(url, {User-Agent => Ruby Web Browser v1.0})

You can often save bandwidth (at the expense of computer time) by sending an "Accept-Encoding" header, requesting that a web server compress data before sending it to you. Gzip compression is the most common way a server compresses HTTP response data; you can reverse it with Rubys zlib library:

	uncompressed = Net::HTTP.get_with_headers(http://www.cnn.com/)
	uncompressed.body.size
	# => 65150

	gzipped = Net::HTTP.get_with_headers(http://www.cnn.com/,
	 {Accept-Encoding => gzip})
	gzipped[Content-Encoding]
	# => "gzip"
	gzipped.body.size
	# => 14600

	require zlib
	require stringio
	body_io = StringIO.new(gzipped.body)
	unzipped_body = Zlib::GzipReader.new(body_io).read()
	unzipped_body.size
	# => 65150

If you want to build up a HTTP request with multiple values for the same HTTP header, you can construct a Net:: HTTP::Get (or Net::HTTP::Post) object and call the add_field method multiple times. The example in the Solution used the " Accept-Language" header to request a document in a specific language. The following code fetches the same URL, but its "Accept-Language" header indicates that it will accept a document written in any of four different dialects:

	uri = URI.parse(http://www.google.com/)

	request = Net::HTTP::Get.new(uri.path)
	[en_us, en, en_gb, ja].each do |language|
	 request.add_field(Accept-Language, language)
	end
	request[Accept-Language]
	# => "en_us, en, en_gb, ja"

	Net::HTTP.start(uri.host, uri.port) do |http|
	 response = http.request(request)
	 # … process the HTTPResponse object here
	end

See Also

  • Recipe 12.10, "Compressing and Archiving Files with Gzip and Tar," for more about the zlib library
  • Recipe 14.1, "Grabbing the Contents of a Web Page"
  • Recipe 14.20, "A Real-World HTTP Client," covers a lot of edge cases youll need to handle if you want to write a general-purpose client
  • REST web services often use the value of the "Accept" header to provide multiple representations of the same resource; Joe Gregorios article "Should you use Content Negotiation in your Web Services?" explains why its a better idea to provide a different URL for each representation (http://bitworking.org/news/WebServicesAndContentNegotiation)
  • Recipe 16.1 for more on REST web services


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net