使用 HTTParty 解析 HTTP header 'set-cookie'
Parsing HTTP header 'set-cookie' with HTTParty
我正在使用 HTTParty 来发出 HTTP 请求和使用 REST API。现在我想通过 POST.
调用的登录页面设置 re-use cookie
class SomeImporter
include HTTParty
def self.login
response = self.post('https://www.example.com/login', :query => {:user => 'myusername', :password => 'secret'})
self.default_cookies.add_cookies(response.header['set-cookie'])
self.get('https://www.example.com/protected')
end
end
此代码未正确设置 cookie。
如何正确解析HTTParty给出的'set-cookie' header并为下一次请求设置cookie?
通常 HTTP header 中的每个 Set-Cookie
都有一个条目。 HTTParty 将它们合并为一个字符串作为 comma-separated 列表。但是 HTTParty 在将它们添加回默认 cookie 时不会自行拆分它们。你必须自己解析它们。
可以用下面的方法解析'set-cookie'。将其添加到您的 class:
# Parse the 'set-cookie' string
# @param [String] all_cookies_string
# @return [Hash]
def self.parse_set_cookie(all_cookies_string)
cookies = Hash.new
if all_cookies_string.present?
# single cookies are devided with comma
all_cookies_string.split(',').each {
# @type [String] cookie_string
|single_cookie_string|
# parts of single cookie are seperated by semicolon; first part is key and value of this cookie
# @type [String]
cookie_part_string = single_cookie_string.strip.split(';')[0]
# remove whitespaces at beginning and end in place and split at '='
# @type [Array]
cookie_part = cookie_part_string.strip.split('=')
# @type [String]
key = cookie_part[0]
# @type [String]
value = cookie_part[1]
# add cookie to Hash
cookies[key] = value
}
end
cookies
end
可以通过调整此行将 cookie 添加到 HTTParty 以用于以下请求:
self.default_cookies.add_cookies(self.parse_set_cookie(response.header['set-cookie']))
在 self.parse_set_cookie
中,提取的 cookie 仅包含名称和值。您可以扩展它以获得更多详细信息,例如 Path
、Domain
等。有关详细信息,请参阅 RFC 2109(4.2.2 Set-Cookie 语法)。
def cookies_to_hash(acookies)
vs = acookies.split(',')
ak = Array.new
# Avoiding break in expiry date comma
vs.each_cons(2) do |v, vn|
unless(vn.include?("="))
ak << "#{v}#{vn}"
else
ak << v if(v.include?("="))
end
end
# Cookies as array of hashes
all_cookies = []
ak.each do |each_cookie|
ecookie = []
each_cookie.split(';').each do |cookie_attr|
ecookie << cookie_attr.split("=")
end
all_cookies << Hash[ecookie]
end
all_cookies
end
上述方法将帮助您将 set-cookies 响应 headers 转换为有效的哈希数组。处理过期时附加逗号的问题。
感谢@dineshspabu,我能够按照他的模式添加一些修改来处理过期日期。希望对您有所帮助:
def cookies_to_hash(set_cookie)
set_cookie = set_cookie.gsub(/Expires=[a-zA-Z]+,/) do |m|
# replace , with #####
m[0..-2] + "#####"
end
set_cookie = set_cookie.split(',')
# Cookies as array of hashes
all_cookies = []
set_cookie.each do |each_cookie|
ecookie = []
each_cookie.strip.split(';').each do |cookie_attr|
# replace ##### with , back
ecookie << cookie_attr.split("=").map{|e| e.gsub(/#####/, ',') if e}
end
all_cookies << Hash[ecookie]
end
all_cookies
end
我正在使用 HTTParty 来发出 HTTP 请求和使用 REST API。现在我想通过 POST.
调用的登录页面设置 re-use cookieclass SomeImporter
include HTTParty
def self.login
response = self.post('https://www.example.com/login', :query => {:user => 'myusername', :password => 'secret'})
self.default_cookies.add_cookies(response.header['set-cookie'])
self.get('https://www.example.com/protected')
end
end
此代码未正确设置 cookie。 如何正确解析HTTParty给出的'set-cookie' header并为下一次请求设置cookie?
通常 HTTP header 中的每个 Set-Cookie
都有一个条目。 HTTParty 将它们合并为一个字符串作为 comma-separated 列表。但是 HTTParty 在将它们添加回默认 cookie 时不会自行拆分它们。你必须自己解析它们。
可以用下面的方法解析'set-cookie'。将其添加到您的 class:
# Parse the 'set-cookie' string
# @param [String] all_cookies_string
# @return [Hash]
def self.parse_set_cookie(all_cookies_string)
cookies = Hash.new
if all_cookies_string.present?
# single cookies are devided with comma
all_cookies_string.split(',').each {
# @type [String] cookie_string
|single_cookie_string|
# parts of single cookie are seperated by semicolon; first part is key and value of this cookie
# @type [String]
cookie_part_string = single_cookie_string.strip.split(';')[0]
# remove whitespaces at beginning and end in place and split at '='
# @type [Array]
cookie_part = cookie_part_string.strip.split('=')
# @type [String]
key = cookie_part[0]
# @type [String]
value = cookie_part[1]
# add cookie to Hash
cookies[key] = value
}
end
cookies
end
可以通过调整此行将 cookie 添加到 HTTParty 以用于以下请求:
self.default_cookies.add_cookies(self.parse_set_cookie(response.header['set-cookie']))
在 self.parse_set_cookie
中,提取的 cookie 仅包含名称和值。您可以扩展它以获得更多详细信息,例如 Path
、Domain
等。有关详细信息,请参阅 RFC 2109(4.2.2 Set-Cookie 语法)。
def cookies_to_hash(acookies)
vs = acookies.split(',')
ak = Array.new
# Avoiding break in expiry date comma
vs.each_cons(2) do |v, vn|
unless(vn.include?("="))
ak << "#{v}#{vn}"
else
ak << v if(v.include?("="))
end
end
# Cookies as array of hashes
all_cookies = []
ak.each do |each_cookie|
ecookie = []
each_cookie.split(';').each do |cookie_attr|
ecookie << cookie_attr.split("=")
end
all_cookies << Hash[ecookie]
end
all_cookies
end
上述方法将帮助您将 set-cookies 响应 headers 转换为有效的哈希数组。处理过期时附加逗号的问题。
感谢@dineshspabu,我能够按照他的模式添加一些修改来处理过期日期。希望对您有所帮助:
def cookies_to_hash(set_cookie)
set_cookie = set_cookie.gsub(/Expires=[a-zA-Z]+,/) do |m|
# replace , with #####
m[0..-2] + "#####"
end
set_cookie = set_cookie.split(',')
# Cookies as array of hashes
all_cookies = []
set_cookie.each do |each_cookie|
ecookie = []
each_cookie.strip.split(';').each do |cookie_attr|
# replace ##### with , back
ecookie << cookie_attr.split("=").map{|e| e.gsub(/#####/, ',') if e}
end
all_cookies << Hash[ecookie]
end
all_cookies
end