Sunday, March 15, 2009

Handling HTTP Redirection in Ruby

I have a Ruby project where I'm dumping a bunch of bookmarks from delicious.com, then fetching each bookmarked page for analysis.

One of the problems I encountered early on is that the some of the web pages bookmarked would redirect to some other location. Simply checking for HTTP response code 200 was insufficient. I needed to check for redirection as well.

A quick Google search for "ruby follow http redirect" yields lots of results. Unfortunately, they're all very similar, and not quite right. In general, the examples you come across (even the one in the official Ruby documentation) don't handle the case when the redirected location is path relative to the original location. So you end up doing a get on a URL that looks like "../../redirected/location/index.html," which clearly won't work.

It turns out that detecting relative redirection is fairly straightforward:

until( found || attempts>=@@MAX_ATTEMPTS)
attempts+=1
http=Net::HTTP.new(url.host,url.port)
http.open_timeout = 10
http.read_timeout = 10
path=url.path
path="/" if path==""

req=Net::HTTP::Get.new(path,{'User-Agent'=>@@AGENT})
if url.instance_of? URI::HTTPS
http.use_ssl=true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
resp=http.request(req)
if resp.code=="200"
break
end
if (resp.header['location']!=nil)
newurl=URI.parse(resp.header['location'])
if(newurl.relative?)
puts "url was relative"
newurl=url+resp.header['location']
end
url=newurl

else
found=true #resp was 404, etc
end #end if location
end #until


The trick here is to ask the redirected url object if it is relative. If it is, then add the redirected path onto the old url object. the URI class overrides the '+' operator (what is this, C++?) so that you can concatenate the new path onto the old URL, by doing:
newurl=url+resp.header['location']

Thursday, March 12, 2009

Mounting LVM Disks in Ubuntu

I always thought LVM (Linux's Logical Volume Manager) was kind of neat for the flexibility it gives you in adding and removing disks and resizing volumes such. However, in practice, I find it's usually more trouble than it's worth. It adds a layer of complexity between me and my data.

Often I need to mount a disk configured with LVM on another Linux machine or in an Ubuntu live CD environment. Out of the box the logical volumes aren't recognized, so I can't mount them.

It's fairly easy to add LVM support and mount the volumes though.

You install the lvm2 package, load the device mapper kernel module, and then activate any lvm volume groups on your disk.

$ sudo apt-get install lvm2
$ sudo modprobe dm-mod
$ sudo vgchange -a y

(assuming your disk with logical volumes is already connected)
$ sudo mount /dev/mapper/<logical volume name> /mnt

And that's all there is to it.

If you want to deactivate the volume groups (recommended before unplugging a USB disk with logical volumes):
$ sudo vgchange -a n
Warning: the above command will deactivate all volume groups, so check the vgchange manpage first, if that's not what you want.

Monday, March 09, 2009

The Rules of the Time Hole

There was a great video on College Humor addressing why terminators travel back in time naked.



That said, I think it's worth discussing the rules of time travel or "the time hole" as my colleague Ross and I put it. So if you've followed the Terminator movies, and, more recently, Terminator: The Sarah Connor Chronicles, the rules of the time hole are fairly easy to infer.

Things can go through the time hole if:
  1. They are made of meat
  2. They are wrappped in meat
  3. They look very much like they are made of meat
  4. If several things meeting the above rules go through all at once, something else may sneak through behind them.
In the original Terminator movie, we saw Kyle Reese, John Connor's soon-to-be father, come through the time hole. As he is 100% human, Kyle clearly qualifies for time travel under rule #1--he is made of meat. Also in the same film, the Terminator, a Cyberdyne Systems Model 101, comes through the time hole, qualifying under rule #2. The 101 consists of a metal skeleton that is wrapped in meat.

In Terminator 2, we see the T-1000, which is constructed of a "mimetic poly-alloy," i.e., liquid metal, travel through time. Clearly, the T-1000 qualifies under rule #3 as it looks, very convincingly, like it is made of meat. Similarly, in Terminator 3, we see the T-X come back in time. The T-X is much like the T-1000, except hot.

Later, in the The Sarah Connor Chronicles, we see Cameron (a terminator wrapped in meat), John, and Sarah (both made of meat) travel back in time. However, just before the time hole closes, Cromartie's severed head (devoid of its meat wrapping) flies through after them.

I checked all terminator-related facts presented above on wikipedia.org.