RailsとCookieではまったこと
( Rails )今回Railsで起きた問題、ちと自分の中で迷ったの纏めておく。
PHPで運用していたものをRuby(Rails)にのせ変えようとしたときに置きました。
以前、前の仕様でCookieでカンマ区切りにして保存していた情報があったのですが
それを気にしないでRailsを導入していたら初期表示でサーバエラーになるという
問題が発生しました。
保存していたもの
document.cookie = "HOGE=1,,1,1"
どうもRack側で発生していることに気づきましてCookieの文字列を解析している箇所で「;」「,」の
二つでハッシュ化していることが原因だとわかりました。
# According to RFC 2109:
# If multiple cookies satisfy the criteria above, they are ordered in
# the Cookie header such that those with more specific Path attributes
# precede those with less specific. Ordering with respect to other
# attributes (e.g., Domain) is unspecified.
Utils.parse_query(string, ';,').each { |k,v| hash[k] = Array === v ? v.first : v }
@env["rack.request.cookie_string"] = string
hash
Rackが悪いのでは?と思っていてけどRFCまわりをよくよく調査してみるとNAME,VALUEにセミコロン、コンマ、空白文字を
除いた文字列を指定すべきで、いれるときはエンコードすべき。あと、サーバは将来の互換性のためにカンマも受け入れるべきです。
てきなことが記述されていたので間違っていないことは確認しました。
とはいっても、サーバエラーにしてクッキー削除してから閲覧してねという訳にもいかないので一時凌ぎとして
コロンで解析しないようにしました。
修正したこと
# environment.rb
module Rack
class Request
def cookies
hash = @env["rack.request.cookie_hash"] ||= {}
string = @env["HTTP_COOKIE"]
return hash if string == @env["rack.request.cookie_string"]
hash.clear
Utils.parse_query(string, ';').each { |k,v| hash[k] = Array === v ? v.first : v}
@env["rack.request.cookie_string"] = string
hash
rescue => error
error.message.replace "cannot parse Cookie header: #{error.message}"
raise
end
end
end
Reference
- http://www.ietf.org/rfc/rfc2109.txt
