Ruby's open-uri and cookies Ruby's open-uri and cookies ruby ruby

Ruby's open-uri and cookies


I thought someone would just know, but I guess it's not commonly done with open-uri.Here's the ugly version that neither checks for privacy, expiration, the correct domain, nor the correct path:

h1 = open("http://www.w3.org/")h2 = open("http://www.w3.org/People/Berners-Lee/",          "Cookie" => h1.meta['set-cookie'].split('; ',2)[0])

Yes, it works. No it's not pretty, nor fully compliant with recommendations, nor does it handle multiple cookies (as is).

Clearly, HTTP is a very straight-forward protocol, and open-uri lets you at most of it. I guess what I really needed to know was how to get the cookie from the h1 request so that it could be passed to the h2 request (that part I already knew and showed). The surprising thing here is how many people basically felt like answering by telling me not to use open-uri, and only one of those showed how to get a cookie set in one request passed to the next request.


You need to add a "Cookie" header.

I'm not sure if open-uri can do this or not, but it can be done using Net::HTTP.

# Create a new connection object.conn = Net::HTTP.new(site, port)# Get the response when we login, to set the cookie.# body is the encoded arguments to log in.resp, data = conn.post(login_path, body, {})cookie = resp.response['set-cookie']# Headers need to be in a hash.headers = { "Cookie" => cookie }# On a get, we don't need a body.resp, data = conn.get(path, headers)


Thanks Matthew Schinckel your answer was really useful. Using Net::HTTP I was successful

        # Create a new connection object.          site = "google.com"          port = 80          conn = Net::HTTP.new(site, port)        # Get the response when we login, to set the cookie.        # body is the encoded arguments to log in.          resp, data = conn.post(login_path, body, {})          cookie = resp.response['set-cookie']        # Headers need to be in a hash.          headers = { "Cookie" => cookie }        # On a get, we don't need a body.          resp, data = conn.get(path, headers)          puts resp.body