Monday, April 05, 2010

lib/webrat/adapters/mechanize.rb ignores http headers

Looks webrat ignores http headers (when we tried to manually set http headers), for example
def rating
   url_path = '/rating';# + id
   header "Accept", "text/xml"
   visit(
       @url + url_path,
       :post
   )
end
So i take a look closer into lib/webrat/adapters/mechanize.rb, and i saw this line of code inside method 'post'
@response = mechanize.post(url, post_data)
, i think this is the problem.

I change the line with
@response = mechanize.post(url, post_data, headers_argument_not_used)

And now looks everything is okay (i hope).

Thursday, April 01, 2010

Gracefully support HTTP errors

require 'rubygems'
require 'mechanize'

a = Mechanize.new { |agent| agent.user_agent_alias = 'Mac Safari'  }
a.get(:url => 'http://example.com',
      :headers => {'Accept' => 'text/xml', 'Connection' =>'keep-live'}
     )
puts a.page.body

If mechanize found error code '401' (for example) then mechanize will raise error message:
/usr/lib/ruby/gems/1.8/gems/mechanize-1.0.0/lib/mechanize.rb:614:in 
`fetch_page': 401 => Net::HTTPUnauthorized (Mechanize::ResponseCodeError)
from /usr/lib/ruby/gems/1.8/gems/mechanize-1.0.0/lib \
/mechanize.rb:259:in `get'
from agent-test.rb:6

I dont know but what i really want from this gem is return 'http error message' rather than raise an error and die (if they found http error codes).

So far to get things done maybe i'll replace this line of code (mechanize.rb, def fetch_page)
raise ResponseCodeError.new(page) unless @user || @password
With
return page unless @user || @password

Also you can watch the request here http://github.com/tenderlove/mechanize/issues#issue/16


**Update**
Maybe using rescue is better
begin
  a.get(:url => 'http://example.com',
        :headers => {
                     'Accept' => 'text/xml', 
                     'Connection' =>'keep-alive'
                    })
  rescue WWW::Mechanize::ResponseCodeError
  puts $!.page.body
end