From c727d390769cb591e14d47a190292a2a1a7eec63 Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Mon, 22 Oct 2012 03:30:01 +0900 Subject: [PATCH] Move cookies.txt parser and serializer from HTTP::CookieJar to HTTP::Cookie. Fix a bug where anything after '#' in cookies.txt are removed. --- lib/http/cookie.rb | 44 ++++++++++++++++++++++++++++++++++++++++++ lib/http/cookie_jar.rb | 30 ++-------------------------- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/lib/http/cookie.rb b/lib/http/cookie.rb index ed61774..6f069af 100644 --- a/lib/http/cookie.rb +++ b/lib/http/cookie.rb @@ -15,6 +15,8 @@ class HTTP::Cookie secure expires created_at accessed_at ] + True = "TRUE" + False = "FALSE" # In Ruby < 1.9.3 URI() does not accept an URI object. if RUBY_VERSION < "1.9.3" @@ -226,6 +228,35 @@ class HTTP::Cookie } } end + + # Parses a line from cookies.txt and returns a cookie object if + # the line represents a cookie record or returns nil otherwise. + def parse_cookiestxt_line(line) + return nil if line.match(/^#/) + + domain, + s_for_domain, # Whether this cookie is for domain + path, # Path for which the cookie is relevant + s_secure, # Requires a secure connection + s_expires, # Time the cookie expires (Unix epoch time) + name, value = line.split("\t") + return nil if value.nil? + + value.chomp! + + if (expires_seconds = s_expires.to_i).nonzero? + expires = Time.at(expires_seconds) + return nil if expires < Time.now + end + + HTTP::Cookie.new(name, value, + :domain => domain, + :for_domain => s_for_domain == True, + :path => path, + :secure => s_secure == True, + :expires => expires, + :version => 0) + end end # Sets the domain attribute. A leading dot in +domain+ implies @@ -317,6 +348,19 @@ class HTTP::Cookie end include Comparable + # Serializes the cookie into a cookies.txt line. + def to_cookiestxt_line(linefeed = "\n") + [ + @domain, + @for_domain ? True : False, + @path, + @secure ? True : False, + @expires.to_i.to_s, + @name, + @value + ].join("\t") << linefeed + end + # YAML serialization helper for Syck. def to_yaml_properties PERSISTENT_PROPERTIES.map { |name| "@#{name}" } diff --git a/lib/http/cookie_jar.rb b/lib/http/cookie_jar.rb index 977be99..fd8fc49 100644 --- a/lib/http/cookie_jar.rb +++ b/lib/http/cookie_jar.rb @@ -152,25 +152,7 @@ class HTTP::CookieJar now = Time.now io.each_line do |line| - line.chomp! - line.gsub!(/#.+/, '') - fields = line.split("\t") - - next if fields.length != 7 - - expires_seconds = fields[4].to_i - expires = (expires_seconds == 0) ? nil : Time.at(expires_seconds) - next if expires and (expires < now) - - c = HTTP::Cookie.new(fields[5], fields[6]) - c.domain = fields[0] - c.for_domain = (fields[1] == "TRUE") # Whether this cookie is for domain - c.path = fields[2] # Path for which the cookie is relevant - c.secure = (fields[3] == "TRUE") # Requires a secure connection - c.expires = expires # Time the cookie expires. - c.version = 0 # Conforms to Netscape cookie spec. - - add(c) + c = HTTP::Cookie.parse_cookiestxt_line(line) and add(c) end @jar @@ -179,15 +161,7 @@ class HTTP::CookieJar # Write cookies to Mozilla cookies.txt-style IO stream def dump_cookiestxt(io) to_a.each do |cookie| - io.puts([ - cookie.domain, - cookie.for_domain? ? "TRUE" : "FALSE", - cookie.path, - cookie.secure ? "TRUE" : "FALSE", - cookie.expires.to_i.to_s, - cookie.name, - cookie.value - ].join("\t")) + io.print cookie.to_cookiestxt_line end end