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、生のクッキー文字列を渡すことを除いて、インスタンスが機能するようなものです:

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

私が理解できないのは、生のクッキー文字列から雄弁にこれを行う方法です。

編集 - -

次のコードは~/.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

編集 - -

これは Ruby のCGI::Cookie.parseメソッドのバグのようです。Ruby バグ トラッカーでバグ レポートを開きました - https://bugs.ruby-lang.org/issues/7364

4

2 に答える 2

2

私はちょうど同じ問題を抱えていました。CGI::Cookie.new生成されたものを消費することができCGI::Cookie::parseないだけで、当時私たちが期待していたようにお互いを補完していないようです.

gem をすばやく検索すると、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

これは、生の Cookie 文字列を解析して生成できるという、Cookie で 1 つのことだけを行う宝石の呼び出しであると思います。しかし、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.

Cookie で暗黙の .to_s が提供する名前であるため、おそらく名前が出力されているだけです。

代わりに name.path または name.value (または Cookie オブジェクトのアクセサのいずれか) を出力してみてください。

于 2012-11-15T14:50:00.183 に答える