Wednesday, November 26, 2008

Basic Auth over HTTP using Ruby, Net::HTTP

I'm writing this one down because it took way too long for me to stumble around it. The Net::HTTP class provides http transport level page access. Most of the time I use open-uri, which treats web pages like files, because that is, as the kids say, one hella fine way to roll.

Too bad it doesn't work with Basic Auth.

I've got a service at http://db-import that listens on 8080. It requires valid credentials. I want to get some type data from it and parse it with Hpricot. Normally I would do this like so:

doc = open("http://db-import:8080/rest/entityTypes.xml) { |f| Hpricot(f) }

however, the requirement of basic auth makes me do this:

ENTITY_TYPES_REQUEST = "http://db-import:8080/importapi/rest/entityTypes.xml"
.....
uri = URI.parse(ENTITY_TYPES_REQUEST)
Net::HTTP.start(uri.host,uri.port) do |http|
req = Net::HTTP::Get.new(uri.path)
req.basic_auth user,pass
response = http.request(req)
end

doc = Hpricot(response.body)


A couple of things to note (that got me):
  1. I needed to specify the hostname w/o the transport. Instead of "http://db-import", specify "db-import". Yeah, that's kind of obvious after the fact :). I URI
  2. HTTP.start only opens the connection, the user then makes all requests/process all responses within the connection block. So in the code above I first configure the request object with basic auth and then use it to make the request.

Not terribly hard, but I do tend to trip up on details and wanted to spare some pain the next time around.

1 comment: