How to Implement Cookie Support in Ruby Net/Http

How to implement cookie support in ruby net/http?

Taken from DZone Snippets

http = Net::HTTP.new('profil.wp.pl', 443)
http.use_ssl = true
path = '/login.html'

# GET request -> so the host can set his cookies
resp, data = http.get(path, nil)
cookie = resp.response['set-cookie'].split('; ')[0]


# POST request -> logging in
data = 'serwis=wp.pl&url=profil.html&tryLogin=1&countTest=1&logowaniessl=1&login_username=blah&login_password=blah'
headers = {
'Cookie' => cookie,
'Referer' => 'http://profil.wp.pl/login.html',
'Content-Type' => 'application/x-www-form-urlencoded'
}

resp, data = http.post(path, data, headers)


# Output on the screen -> we should get either a 302 redirect (after a successful login) or an error page
puts 'Code = ' + resp.code
puts 'Message = ' + resp.message
resp.each {|key, val| puts key + ' = ' + val}
puts data

update

#To save the cookies, you can use PStore
cookies = PStore.new("cookies.pstore")

# Save the cookie
cookies.transaction do
cookies[:some_identifier] = cookie
end

# Retrieve the cookie back
cookies.transaction do
cookie = cookies[:some_identifier]
end

Making Ruby Net::HTTP::Get request with cookie

You need to call CGI::Cookie.to_s method.

request['Cookie'] = cookie.to_s

Try following code with / without .to_s.

require 'net/http'
require 'cgi'

uri = URI("http://httpbin.org/cookies")
http = Net::HTTP.new(uri.host, 80)
request = Net::HTTP::Get.new(uri.request_uri)
cookie1 = CGI::Cookie.new('usr', 'blah')
request['Cookie'] = cookie1.to_s # <---
r = http.request(request)
puts r.body

UPDATE

As the other answer mentioned, the resulted string is for server output. You need to strip out ; path= part.

CGI::Cookie.new('usr', 'value').to_s.sub(/; path=$/, '')

Pass cookie to Net::HTTP.start

Here is the solution.

url = URI.parse("http://example.com")

found = false
until found
host, port = url.host, url.port if url.host && url.port
req = Net::HTTP::Get.new(url.path, {
"Cookie" => "sessid=123;"
})

res = Net::HTTP.start(url.host, url.port) do |http|
http.request(req)
end
puts res.header['location']
res.header['location'] ? url = URI.parse(res.header['location']) : found = true
end

Ruby HTTP post with session cookie

By using the nice_http gem: https://github.com/MarioRuiz/nice_http
NiceHttp will take care of your cookies so you don't have to do anything

require 'nice_http'
path = '/piwigo/ws.php'
data = '?method=pwg.session.login&username=admin&password=password'

http = NiceHttp.new('http://example.com')
resp = http.get(path+data)

if resp.code == 200
resp = http.post(path)
puts resp.code
puts resp.message
end

Also if you want you can add your own cookies by using http.cookies

Rails: Cookies with Net::HTTP

first question: Where do you want to place the cookie? On the client who is browsing your website?

Is your request flow like:

Client --[web browser]--> App 1 --[net::http]--> App2

If this is the flow, you have to proxy the cookie:

def get_content(url)

uri = URI.parse(url)

params = Hash[*uri.query.split("&").map {|part| part.split("=") }.flatten]

http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.path)
request.set_form_data( params )
request = Net::HTTP::Get.new( uri.path+ '?' + request.body )

if uri.scheme == "https" # enable SSL/TLS
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
http.start do
http.request(request) do |res|
# yummy, parse some cookies here
app2_cookies = CGI::Cookie.parse(res['Set-Cookie']);

app2_cookies.each do |c_name, c_cookie|
# this is the cookies object from rails! Make sure this is accessible here!
# the cookie will now be set on the client side
cookies[c_name] = c_cookie.value
end

return res.body
end
end
end

Make sure you require CGI::Cookie

Here are the docs:

http://www.ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTPHeader.html#M001307

http://ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI/Cookie.html#M000170

Ruby http/get cookie formating

It's really not that difficult. Just split on semicolon and filter. Or scan the string for the pairs that interest you. Something like this:

s1 = "ASP.NET_SessionId=mnxjnm140qvvt4wvlfielud3; domain=.e-konsulat.gov.pl; path=/; secure; HttpOnly, TSe20548=a4ad9705817edcebbdf2e0c3f869b10843e5bb63617303a3523b64a0; Path=/, TS7848cb=98330ff418e3c9a3b2afb5f10398363043e5bb63617303a3523b64a036af3f5e7cfaddf8; path=/; domain=.e-konsulat.gov.pl, TSe20548_31=88ba62b4efd7e40ff9fa891b1764eb6e43e5bb63617303a3000000000000000000e1d4e1bdb727a5ac9c00848b7c7c770a3b491a57; Path=/ "

regex = /(?<key>(ASP\.NET_SessionId|TS\w+)=[^;]+)/

a1 = s1.scan(regex).flatten # => ["ASP.NET_SessionId=mnxjnm140qvvt4wvlfielud3", "TSe20548=a4ad9705817edcebbdf2e0c3f869b10843e5bb63617303a3523b64a0", "TS7848cb=98330ff418e3c9a3b2afb5f10398363043e5bb63617303a3523b64a036af3f5e7cfaddf8", "TSe20548_31=88ba62b4efd7e40ff9fa891b1764eb6e43e5bb63617303a3000000000000000000e1d4e1bdb727a5ac9c00848b7c7c770a3b491a57"]
a2 = a1.map{|s| s.split('=')} # => [["ASP.NET_SessionId", "mnxjnm140qvvt4wvlfielud3"], ["TSe20548", "a4ad9705817edcebbdf2e0c3f869b10843e5bb63617303a3523b64a0"], ["TS7848cb", "98330ff418e3c9a3b2afb5f10398363043e5bb63617303a3523b64a036af3f5e7cfaddf8"], ["TSe20548_31", "88ba62b4efd7e40ff9fa891b1764eb6e43e5bb63617303a3000000000000000000e1d4e1bdb727a5ac9c00848b7c7c770a3b491a57"]]
h1 = Hash[a2] # => {"ASP.NET_SessionId"=>"mnxjnm140qvvt4wvlfielud3", "TSe20548"=>"a4ad9705817edcebbdf2e0c3f869b10843e5bb63617303a3523b64a0", "TS7848cb"=>"98330ff418e3c9a3b2afb5f10398363043e5bb63617303a3523b64a036af3f5e7cfaddf8", "TSe20548_31"=>"88ba62b4efd7e40ff9fa891b1764eb6e43e5bb63617303a3000000000000000000e1d4e1bdb727a5ac9c00848b7c7c770a3b491a57"}


Related Topics



Leave a reply



Submit