4

我希望能够解析 ruby​​ 1.9.3p194(2012-04-20 修订版 35410)[x86_64-darwin10.8.0] 中的原始 cookie 字符串。

CGI::Cookie库看起来很有希望,但是,它并没有像我想象的那样工作。

例如,

CGI::Cookie::parse("ASPSESSIONIDSCDRSRTS=HHALOHOBJGJMLPIANNLDOMCJ; path=/").each_key {|name| p 'Cookie name: ' + name}

将返回:

"Cookie name: ASPSESSIONIDSCDRSRTS"
"Cookie name: path"

我想要的是类似于CGI::new实例工作的东西,除了你向它传递一个原始的 cookie 字符串:

cookie1 = CGI::Cookie::new('name'    => 'name',
                       'value'   => ['value1', 'value2', ...],
                       'path'    => 'path',   # optional
                       'domain'  => 'domain', # optional
                       'expires' => Time.now, # optional
                       'secure'  => true      # optional
                      )

name    = cookie1.name
values  = cookie1.value
path    = cookie1.path
domain  = cookie1.domain
expires = cookie1.expires
secure  = cookie1.secure

我不知道如何从原始 cookie 字符串中雄辩地做到这一点。

编辑 - -

以下代码在~/.rvm/src/ruby-1.9.3-p194/lib/cgi/cookie.rb文件中。所以它应该返回如下评论cookies[name] = Cookie::new(name, *values)。我似乎没有得到。

# Parse a raw cookie string into a hash of cookie-name=>Cookie
# pairs.
#
#   cookies = CGI::Cookie::parse("raw_cookie_string")
#     # { "name1" => cookie1, "name2" => cookie2, ... }
#
def Cookie::parse(raw_cookie)
  cookies = Hash.new([])
  return cookies unless raw_cookie

  raw_cookie.split(/[;,]\s?/).each do |pairs|
    name, values = pairs.split('=',2)
    next unless name and values
    name = CGI::unescape(name)
    values ||= ""
    values = values.split('&').collect{|v| CGI::unescape(v,@@accept_charset) }
    if cookies.has_key?(name)
      values = cookies[name].value + values
    end
    cookies[name] = Cookie::new(name, *values)
  end

  cookies
end

编辑 - -

这似乎是 RubyCGI::Cookie.parse方法中的一个错误。我已经打开了关于 Ruby 错误跟踪器的错误报告 - https://bugs.ruby-lang.org/issues/7364

4

2 回答 2

2

我只是有同样的问题。CGI::Cookie.new只是无法消费所CGI::Cookie::parse生产的东西,它们似乎并没有像我们当时预期的那样相互补充。

快速搜索宝石,我找到了https://github.com/dwaite/cookiejar。看起来这个 gem 做了很多尝试,但至少它有代码可以像我们期望的那样正确解析原始 cookie。我没有尝试理解该库,因为它似乎做了很多事情,而我实际上只关心“使用 cookie -> 修改它 -> 生成 cookie”。

我想出了这个快速破解:

require 'cgi'
require 'cookiejar'

# Some sample
raw_cookie = "somecookie=some%7Cvalue; expires=Wed, 02 Apr 2014 13:36:50 GMT; path=/; domain=.somedomain.com"

parts = CookieJar::CookieValidation.parse_set_cookie raw_cookie
# Needs manual unescape
parts[:value] = CGI::unescape(parts[:value])
# Per spec, this name is different
parts[:expires] = parts[:expires_at]
# Remove old ones
parts.delete :expires_at
# CookieJar adds them always, remove
parts.delete :version
# Convert symbol keys to strings for GGI::Cookie
cookie = parts.inject(Hash.new) do |acc, (k,v)|
  acc[k.to_s] = v 
  acc 
end
puts CGI::Cookie.new(cookie).to_s
#=> somecookie=some%7Cvalue; domain=.somedomain.com; path=/; expires=Wed, 02 Apr 2014 13:36:50 GMT

我想这应该是对一个 gem 的调用,它只对 cookie 做一件事并且做得很好:能够解析和生成原始 cookie 字符串。但是 TBH,问题域可能比我像我做的那样愚弄要复杂得多。

于 2012-11-18T21:04:37.617 回答
1

我没有使用该库,但根据 Ruby 文档(http://www.ruby-doc.org/stdlib-1.9.3/libdoc/cgi/rdoc/CGI/Cookie.html)你在调用什么|姓名| 在您的块中实际上是一个 Cookie 对象。

parse(raw_cookie) 
Parse a raw cookie string into a hash of cookie-name=>Cookie pairs.

您可能只是看到打印出来的名称,因为这就是隐含的 .to_s 将在 Cookie 上为您提供的内容。

尝试打印 name.path 或 name.value(或 Cookie 对象的任何访问器)。

于 2012-11-15T14:50:00.183 回答