mirror of
https://github.com/samsonjs/http-cookie.git
synced 2026-03-25 08:55:53 +00:00
Import cookie related stuff from Mechanize.
This commit is contained in:
commit
060fc63c2a
13 changed files with 1630 additions and 0 deletions
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
*.gem
|
||||
*.rbc
|
||||
.bundle
|
||||
.config
|
||||
.yardoc
|
||||
Gemfile.lock
|
||||
InstalledFiles
|
||||
_yardoc
|
||||
coverage
|
||||
doc/
|
||||
lib/bundler/man
|
||||
pkg
|
||||
rdoc
|
||||
spec/reports
|
||||
test/tmp
|
||||
test/version_tmp
|
||||
tmp
|
||||
4
Gemfile
Normal file
4
Gemfile
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
# Specify your gem's dependencies in http-cookie.gemspec
|
||||
gemspec
|
||||
23
LICENSE.txt
Normal file
23
LICENSE.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
Copyright (c) 2011-2012 Akinori MUSHA, Eric Hodel
|
||||
Copyright (c) 2006-2011 Aaron Patterson, Mike Dalessio
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
49
README.md
Normal file
49
README.md
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# HTTP::Cookie
|
||||
|
||||
HTTP::Cookie is a ruby library to handle HTTP cookies in a way both
|
||||
compliant with RFCs and compatible with today's major browsers.
|
||||
|
||||
It was originally a part of the Mechanize library, separated as an
|
||||
independent library in the hope of serving as a common component that
|
||||
is reusable from any HTTP related piece of software.
|
||||
|
||||
## Installation
|
||||
|
||||
Add this line to your application's Gemfile:
|
||||
|
||||
gem 'http-cookie'
|
||||
|
||||
And then execute:
|
||||
|
||||
$ bundle
|
||||
|
||||
Or install it yourself as:
|
||||
|
||||
$ gem install http-cookie
|
||||
|
||||
## Usage
|
||||
|
||||
# Initialize a cookie jar
|
||||
jar = HTTP::CookieJar.new
|
||||
|
||||
# Load from a file
|
||||
jar.load(filename) if File.exist?(filename)
|
||||
|
||||
# Store received cookies
|
||||
HTTP::Cookie.parse(uri, set_cookie_header_value) { |cookie|
|
||||
jar << cookie
|
||||
}
|
||||
|
||||
# Extract cookies to send
|
||||
cookie_value_to_send = jar.cookies(uri).join(', ')
|
||||
|
||||
# Save to a file
|
||||
jar.save_as(filename)
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork it
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create new Pull Request
|
||||
20
Rakefile
Normal file
20
Rakefile
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
require "bundler/gem_tasks"
|
||||
|
||||
require 'rake/testtask'
|
||||
Rake::TestTask.new(:test) do |test|
|
||||
test.libs << 'lib' << 'test'
|
||||
test.pattern = 'test/**/test_*.rb'
|
||||
test.verbose = true
|
||||
end
|
||||
|
||||
task :default => :test
|
||||
|
||||
require 'rdoc/task'
|
||||
Rake::RDocTask.new do |rdoc|
|
||||
version = HTTP::Cookie::VERSION
|
||||
|
||||
rdoc.rdoc_dir = 'rdoc'
|
||||
rdoc.title = "http-cookie #{version}"
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
rdoc.rdoc_files.include(Bundler::GemHelper.gemspec.extra_rdoc_files)
|
||||
end
|
||||
26
http-cookie.gemspec
Normal file
26
http-cookie.gemspec
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
lib = File.expand_path('../lib', __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
require 'http/cookie/version'
|
||||
|
||||
Gem::Specification.new do |gem|
|
||||
gem.name = "http-cookie"
|
||||
gem.version = HTTP::Cookie::VERSION
|
||||
gem.authors, gem.email = {
|
||||
'Akinori MUSHA' => 'knu@idaemons.org',
|
||||
'Aaron Patterson' => 'aaronp@rubyforge.org',
|
||||
'Eric Hodel' => 'drbrain@segment7.net',
|
||||
'Mike Dalessio' => 'mike.dalessio@gmail.com',
|
||||
}.instance_eval { [keys, values] }
|
||||
|
||||
gem.description = %q{A Ruby library to handle HTTP Cookies}
|
||||
gem.summary = %q{A Ruby library to handle HTTP Cookies}
|
||||
gem.homepage = "https://github.com/sparklemotion/http-cookie"
|
||||
|
||||
gem.files = `git ls-files`.split($/)
|
||||
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
||||
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
||||
gem.require_paths = ["lib"]
|
||||
|
||||
gem.add_runtime_dependency("domain_name", ["~> 0.5"])
|
||||
end
|
||||
1
lib/http-cookie.rb
Normal file
1
lib/http-cookie.rb
Normal file
|
|
@ -0,0 +1 @@
|
|||
require 'http/cookie'
|
||||
243
lib/http/cookie.rb
Normal file
243
lib/http/cookie.rb
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
require 'http/cookie/version'
|
||||
require 'time'
|
||||
require 'webrick/httputils'
|
||||
require 'domain_name'
|
||||
|
||||
module HTTP
|
||||
autoload :CookieJar, 'http/cookie_jar'
|
||||
end
|
||||
|
||||
# This class is used to represent an HTTP Cookie.
|
||||
class HTTP::Cookie
|
||||
attr_reader :name
|
||||
attr_accessor :value, :version
|
||||
attr_accessor :domain, :path, :secure
|
||||
attr_accessor :comment, :max_age
|
||||
|
||||
attr_accessor :session
|
||||
|
||||
attr_accessor :created_at
|
||||
attr_accessor :accessed_at
|
||||
|
||||
# :call-seq:
|
||||
# new(name, value)
|
||||
# new(name, value, attr_hash)
|
||||
# new(attr_hash)
|
||||
#
|
||||
# Creates a cookie object. For each key of +attr_hash+, the setter
|
||||
# is called if defined. Each key can be either a symbol or a
|
||||
# string, downcased or not.
|
||||
#
|
||||
# e.g.
|
||||
# new("uid", "a12345")
|
||||
# new("uid", "a12345", :domain => 'example.org',
|
||||
# :for_domain => true, :expired => Time.now + 7*86400)
|
||||
# new("name" => "uid", "value" => "a12345", "Domain" => 'www.example.org')
|
||||
#
|
||||
def initialize(*args)
|
||||
@version = 0 # Netscape Cookie
|
||||
|
||||
@domain = @path = @secure = @comment = @max_age =
|
||||
@expires = @comment_url = @discard = @port = nil
|
||||
|
||||
@created_at = @accessed_at = Time.now
|
||||
case args.size
|
||||
when 2
|
||||
@name, @value = *args
|
||||
@for_domain = false
|
||||
return
|
||||
when 3
|
||||
@name, @value, attr_hash = *args
|
||||
when 1
|
||||
attr_hash = args.first
|
||||
else
|
||||
raise ArgumentError, "wrong number of arguments (#{args.size} for 1-3)"
|
||||
end
|
||||
for_domain = false
|
||||
attr_hash.each_pair { |key, val|
|
||||
skey = key.to_s.downcase
|
||||
skey.sub!(/[!?]\z/, '')
|
||||
case skey
|
||||
when 'for_domain'
|
||||
for_domain = !!val
|
||||
when 'name'
|
||||
@name = val
|
||||
when 'value'
|
||||
@value = val
|
||||
else
|
||||
setter = :"#{skey}="
|
||||
send(setter, val) if respond_to?(setter)
|
||||
end
|
||||
}
|
||||
@for_domain = for_domain
|
||||
end
|
||||
|
||||
# If this flag is true, this cookie will be sent to any host in the
|
||||
# +domain+. If it is false, this cookie will be sent only to the
|
||||
# host indicated by the +domain+.
|
||||
attr_accessor :for_domain
|
||||
alias for_domain? for_domain
|
||||
|
||||
class << self
|
||||
# Parses a Set-Cookie header line +str+ sent from +uri+ into an
|
||||
# array of Cookie objects. Note that this array may contain
|
||||
# nil's when some of the cookie-pairs are malformed.
|
||||
def parse(uri, str, log = nil)
|
||||
return str.split(/,(?=[^;,]*=)|,$/).map { |c|
|
||||
cookie_elem = c.split(/;+/)
|
||||
first_elem = cookie_elem.shift
|
||||
first_elem.strip!
|
||||
key, value = first_elem.split(/\=/, 2)
|
||||
|
||||
begin
|
||||
cookie = new(key, value.dup)
|
||||
rescue
|
||||
log.warn("Couldn't parse key/value: #{first_elem}") if log
|
||||
next
|
||||
end
|
||||
|
||||
cookie_elem.each do |pair|
|
||||
pair.strip!
|
||||
key, value = pair.split(/=/, 2)
|
||||
next unless key
|
||||
value = WEBrick::HTTPUtils.dequote(value.strip) if value
|
||||
|
||||
case key.downcase
|
||||
when 'domain'
|
||||
next unless value && !value.empty?
|
||||
begin
|
||||
cookie.domain = value
|
||||
cookie.for_domain = true
|
||||
rescue
|
||||
log.warn("Couldn't parse domain: #{value}") if log
|
||||
end
|
||||
when 'path'
|
||||
next unless value && !value.empty?
|
||||
cookie.path = value
|
||||
when 'expires'
|
||||
next unless value && !value.empty?
|
||||
begin
|
||||
cookie.expires = Time::parse(value)
|
||||
rescue
|
||||
log.warn("Couldn't parse expires: #{value}") if log
|
||||
end
|
||||
when 'max-age'
|
||||
next unless value && !value.empty?
|
||||
begin
|
||||
cookie.max_age = Integer(value)
|
||||
rescue
|
||||
log.warn("Couldn't parse max age '#{value}'") if log
|
||||
end
|
||||
when 'comment'
|
||||
next unless value
|
||||
cookie.comment = value
|
||||
when 'version'
|
||||
next unless value
|
||||
begin
|
||||
cookie.version = Integer(value)
|
||||
rescue
|
||||
log.warn("Couldn't parse version '#{value}'") if log
|
||||
cookie.version = nil
|
||||
end
|
||||
when 'secure'
|
||||
cookie.secure = true
|
||||
end
|
||||
end
|
||||
|
||||
cookie.path ||= (uri + './').path
|
||||
cookie.secure ||= false
|
||||
cookie.domain ||= uri.host
|
||||
|
||||
# RFC 6265 4.1.2.2
|
||||
cookie.expires = Time.now + cookie.max_age if cookie.max_age
|
||||
cookie.session = !cookie.expires
|
||||
|
||||
# Move this in to the cookie jar
|
||||
yield cookie if block_given?
|
||||
|
||||
cookie
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
alias set_domain domain=
|
||||
|
||||
# Sets the domain attribute. A leading dot in +domain+ implies
|
||||
# turning the +for_domain?+ flag on.
|
||||
def domain=(domain)
|
||||
if DomainName === domain
|
||||
@domain_name = domain
|
||||
else
|
||||
domain.is_a?(String) or
|
||||
(domain.respond_to?(:to_str) && (domain = domain.to_str).is_a?(String)) or
|
||||
raise TypeError, "#{domain.class} is not a String"
|
||||
if domain.start_with?('.')
|
||||
@for_domain = true
|
||||
domain = domain[1..-1]
|
||||
end
|
||||
# Do we really need to support this?
|
||||
if domain.match(/\A([^:]+):[0-9]+\z/)
|
||||
domain = $1
|
||||
end
|
||||
@domain_name = DomainName.new(domain)
|
||||
end
|
||||
set_domain(@domain_name.hostname)
|
||||
end
|
||||
|
||||
def expires=(t)
|
||||
@expires = t && (t.is_a?(Time) ? t.httpdate : t.to_s)
|
||||
end
|
||||
|
||||
def expires
|
||||
@expires && Time.parse(@expires)
|
||||
end
|
||||
|
||||
def expired?
|
||||
return false unless expires
|
||||
Time.now > expires
|
||||
end
|
||||
|
||||
alias secure? secure
|
||||
|
||||
def acceptable_from_uri?(uri)
|
||||
host = DomainName.new(uri.host)
|
||||
|
||||
# RFC 6265 5.3
|
||||
# When the user agent "receives a cookie":
|
||||
return host.hostname == domain unless @for_domain
|
||||
|
||||
if host.cookie_domain?(@domain_name)
|
||||
true
|
||||
elsif host.hostname == domain
|
||||
@for_domain = false
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def valid_for_uri?(uri)
|
||||
return false if secure? && uri.scheme != 'https'
|
||||
acceptable_from_uri?(uri) && uri.path.start_with?(path)
|
||||
end
|
||||
|
||||
def to_s
|
||||
"#{@name}=#{@value}"
|
||||
end
|
||||
|
||||
def init_with(coder)
|
||||
yaml_initialize(coder.tag, coder.map)
|
||||
end
|
||||
|
||||
def yaml_initialize(tag, map)
|
||||
@for_domain = true # for forward compatibility
|
||||
map.each { |key, value|
|
||||
case key
|
||||
when 'domain'
|
||||
self.domain = value # ditto
|
||||
else
|
||||
instance_variable_set(:"@#{key}", value)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
5
lib/http/cookie/version.rb
Normal file
5
lib/http/cookie/version.rb
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
module HTTP
|
||||
class Cookie
|
||||
VERSION = "0.0.1"
|
||||
end
|
||||
end
|
||||
221
lib/http/cookie_jar.rb
Normal file
221
lib/http/cookie_jar.rb
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
module HTTP
|
||||
autoload :Cookie, 'http/cookie'
|
||||
end
|
||||
|
||||
##
|
||||
# This class is used to manage the Cookies that have been returned from
|
||||
# any particular website.
|
||||
|
||||
class HTTP::CookieJar
|
||||
include Enumerable
|
||||
|
||||
# add_cookie wants something resembling a URI.
|
||||
|
||||
attr_reader :jar
|
||||
|
||||
def initialize
|
||||
@jar = {}
|
||||
end
|
||||
|
||||
def initialize_copy other # :nodoc:
|
||||
@jar = Marshal.load Marshal.dump other.jar
|
||||
end
|
||||
|
||||
# Add a +cookie+ to the jar if it is considered acceptable from
|
||||
# +uri+. Return nil if the cookie was not added, otherwise return
|
||||
# the cookie added.
|
||||
def add(uri, cookie)
|
||||
return nil unless cookie.acceptable_from_uri?(uri)
|
||||
add!(cookie)
|
||||
cookie
|
||||
end
|
||||
|
||||
# Add a +cookie+ to the jar and return self.
|
||||
def add!(cookie)
|
||||
normal_domain = cookie.domain.downcase
|
||||
|
||||
@jar[normal_domain] ||= {} unless @jar.has_key?(normal_domain)
|
||||
|
||||
@jar[normal_domain][cookie.path] ||= {}
|
||||
@jar[normal_domain][cookie.path][cookie.name] = cookie
|
||||
|
||||
self
|
||||
end
|
||||
alias << add!
|
||||
|
||||
# Fetch the cookies that should be used for the URI object passed in.
|
||||
def cookies(url)
|
||||
cleanup
|
||||
url.path = '/' if url.path.empty?
|
||||
now = Time.now
|
||||
|
||||
select { |cookie|
|
||||
!cookie.expired? && cookie.valid_for_uri?(url) && (cookie.accessed_at = now)
|
||||
}.sort_by { |cookie|
|
||||
# RFC 6265 5.4
|
||||
# Precedence: 1. longer path 2. older creation
|
||||
[-cookie.path.length, cookie.created_at]
|
||||
}
|
||||
end
|
||||
|
||||
def empty?(url)
|
||||
cookies(url).length > 0 ? false : true
|
||||
end
|
||||
|
||||
def each
|
||||
block_given? or return enum_for(__method__)
|
||||
cleanup
|
||||
@jar.each { |domain, paths|
|
||||
paths.each { |path, hash|
|
||||
hash.each_value { |cookie|
|
||||
yield cookie
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
# call-seq:
|
||||
# jar.save_as(file, format = :yaml)
|
||||
# jar.save_as(file, options)
|
||||
#
|
||||
# Save the cookie jar to a file in the format specified and return
|
||||
# self.
|
||||
#
|
||||
# Available option keywords are below:
|
||||
#
|
||||
# * +format+
|
||||
# [<tt>:yaml</tt>]
|
||||
# YAML structure (default)
|
||||
# [<tt>:cookiestxt</tt>]
|
||||
# Mozilla's cookies.txt format
|
||||
# * +session+
|
||||
# [+true+]
|
||||
# Save session cookies as well.
|
||||
# [+false+]
|
||||
# Do not save session cookies. (default)
|
||||
def save_as(file, options = nil)
|
||||
if Symbol === options
|
||||
format = options
|
||||
session = false
|
||||
else
|
||||
options ||= {}
|
||||
format = options[:format] || :yaml
|
||||
session = !!options[:session]
|
||||
end
|
||||
|
||||
jar = dup
|
||||
jar.cleanup !session
|
||||
|
||||
open(file, 'w') { |f|
|
||||
case format
|
||||
when :yaml then
|
||||
load_yaml
|
||||
|
||||
YAML.dump(jar.jar, f)
|
||||
when :cookiestxt then
|
||||
jar.dump_cookiestxt(f)
|
||||
else
|
||||
raise ArgumentError, "Unknown cookie jar file format"
|
||||
end
|
||||
}
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
# Load cookie jar from a file in the format specified.
|
||||
#
|
||||
# Available formats:
|
||||
# :yaml <- YAML structure.
|
||||
# :cookiestxt <- Mozilla's cookies.txt format
|
||||
def load(file, format = :yaml)
|
||||
@jar = open(file) { |f|
|
||||
case format
|
||||
when :yaml then
|
||||
load_yaml
|
||||
|
||||
YAML.load(f)
|
||||
when :cookiestxt then
|
||||
load_cookiestxt(f)
|
||||
else
|
||||
raise ArgumentError, "Unknown cookie jar file format"
|
||||
end
|
||||
}
|
||||
|
||||
cleanup
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def load_yaml # :nodoc:
|
||||
begin
|
||||
require 'psych'
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
require 'yaml'
|
||||
end
|
||||
|
||||
# Clear the cookie jar
|
||||
def clear!
|
||||
@jar = {}
|
||||
end
|
||||
|
||||
# Read cookies from Mozilla cookies.txt-style IO stream
|
||||
def load_cookiestxt(io)
|
||||
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)
|
||||
end
|
||||
|
||||
@jar
|
||||
end
|
||||
|
||||
# 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"))
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Remove expired cookies
|
||||
def cleanup session = false
|
||||
@jar.each do |domain, paths|
|
||||
paths.each do |path, names|
|
||||
names.each do |cookie_name, cookie|
|
||||
paths[path].delete(cookie_name) if
|
||||
cookie.expired? or (session and cookie.session)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
21
test/helper.rb
Normal file
21
test/helper.rb
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
require 'rubygems'
|
||||
require 'test/unit'
|
||||
require 'uri'
|
||||
require 'http/cookie'
|
||||
|
||||
module Enumerable
|
||||
def combine
|
||||
masks = inject([[], 1]){|(ar, m), e| [ar << m, m << 1 ] }[0]
|
||||
all = masks.inject(0){ |al, m| al|m }
|
||||
|
||||
result = []
|
||||
for i in 1..all do
|
||||
tmp = []
|
||||
each_with_index do |e, idx|
|
||||
tmp << e unless (masks[idx] & i) == 0
|
||||
end
|
||||
result << tmp
|
||||
end
|
||||
result
|
||||
end
|
||||
end
|
||||
482
test/test_http_cookie.rb
Normal file
482
test/test_http_cookie.rb
Normal file
|
|
@ -0,0 +1,482 @@
|
|||
require File.expand_path('helper', File.dirname(__FILE__))
|
||||
|
||||
class TestHTTPCookie < Test::Unit::TestCase
|
||||
#class TestHTTPCookie < MiniTest::Unit::TestCase
|
||||
def silently
|
||||
warn_level = $VERBOSE
|
||||
$VERBOSE = false
|
||||
res = yield
|
||||
$VERBOSE = warn_level
|
||||
res
|
||||
end
|
||||
|
||||
def test_parse_dates
|
||||
url = URI.parse('http://localhost/')
|
||||
|
||||
yesterday = Time.now - 86400
|
||||
|
||||
dates = [ "14 Apr 89 03:20:12",
|
||||
"14 Apr 89 03:20 GMT",
|
||||
"Fri, 17 Mar 89 4:01:33",
|
||||
"Fri, 17 Mar 89 4:01 GMT",
|
||||
"Mon Jan 16 16:12 PDT 1989",
|
||||
"Mon Jan 16 16:12 +0130 1989",
|
||||
"6 May 1992 16:41-JST (Wednesday)",
|
||||
#"22-AUG-1993 10:59:12.82",
|
||||
"22-AUG-1993 10:59pm",
|
||||
"22-AUG-1993 12:59am",
|
||||
"22-AUG-1993 12:59 PM",
|
||||
#"Friday, August 04, 1995 3:54 PM",
|
||||
#"06/21/95 04:24:34 PM",
|
||||
#"20/06/95 21:07",
|
||||
"95-06-08 19:32:48 EDT",
|
||||
]
|
||||
|
||||
dates.each do |date|
|
||||
cookie = "PREF=1; expires=#{date}"
|
||||
silently do
|
||||
HTTP::Cookie.parse(url, cookie) { |c|
|
||||
assert c.expires, "Tried parsing: #{date}"
|
||||
assert_equal(true, c.expires < yesterday)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_parse_empty
|
||||
cookie_str = 'a=b; ; c=d'
|
||||
|
||||
uri = URI.parse 'http://example'
|
||||
|
||||
HTTP::Cookie.parse uri, cookie_str do |cookie|
|
||||
assert_equal 'a', cookie.name
|
||||
assert_equal 'b', cookie.value
|
||||
end
|
||||
end
|
||||
|
||||
def test_parse_no_space
|
||||
cookie_str = "foo=bar;Expires=Sun, 06 Nov 2011 00:28:06 GMT;Path=/"
|
||||
|
||||
uri = URI.parse 'http://example'
|
||||
|
||||
HTTP::Cookie.parse uri, cookie_str do |cookie|
|
||||
assert_equal 'foo', cookie.name
|
||||
assert_equal 'bar', cookie.value
|
||||
assert_equal '/', cookie.path
|
||||
assert_equal Time.at(1320539286), cookie.expires
|
||||
end
|
||||
end
|
||||
|
||||
def test_parse_quoted
|
||||
cookie_str =
|
||||
"quoted=\"value\"; Expires=Sun, 06 Nov 2011 00:11:18 GMT; Path=/"
|
||||
|
||||
uri = URI.parse 'http://example'
|
||||
|
||||
HTTP::Cookie.parse uri, cookie_str do |cookie|
|
||||
assert_equal 'quoted', cookie.name
|
||||
assert_equal '"value"', cookie.value
|
||||
end
|
||||
end
|
||||
|
||||
def test_parse_weird_cookie
|
||||
cookie = 'n/a, ASPSESSIONIDCSRRQDQR=FBLDGHPBNDJCPCGNCPAENELB; path=/'
|
||||
url = URI.parse('http://www.searchinnovation.com/')
|
||||
HTTP::Cookie.parse(url, cookie) { |c|
|
||||
assert_equal('ASPSESSIONIDCSRRQDQR', c.name)
|
||||
assert_equal('FBLDGHPBNDJCPCGNCPAENELB', c.value)
|
||||
}
|
||||
end
|
||||
|
||||
def test_double_semicolon
|
||||
double_semi = 'WSIDC=WEST;; domain=.williams-sonoma.com; path=/'
|
||||
url = URI.parse('http://williams-sonoma.com/')
|
||||
HTTP::Cookie.parse(url, double_semi) { |cookie|
|
||||
assert_equal('WSIDC', cookie.name)
|
||||
assert_equal('WEST', cookie.value)
|
||||
}
|
||||
end
|
||||
|
||||
def test_parse_bad_version
|
||||
bad_cookie = 'PRETANET=TGIAqbFXtt; Name=/PRETANET; Path=/; Version=1.2; Content-type=text/html; Domain=192.168.6.196; expires=Friday, 13-November-2026 23:01:46 GMT;'
|
||||
url = URI.parse('http://localhost/')
|
||||
HTTP::Cookie.parse(url, bad_cookie) { |cookie|
|
||||
assert_nil(cookie.version)
|
||||
}
|
||||
end
|
||||
|
||||
def test_parse_bad_max_age
|
||||
bad_cookie = 'PRETANET=TGIAqbFXtt; Name=/PRETANET; Path=/; Max-Age=1.2; Content-type=text/html; Domain=192.168.6.196; expires=Friday, 13-November-2026 23:01:46 GMT;'
|
||||
url = URI.parse('http://localhost/')
|
||||
HTTP::Cookie.parse(url, bad_cookie) { |cookie|
|
||||
assert_nil(cookie.max_age)
|
||||
}
|
||||
end
|
||||
|
||||
def test_parse_date_fail
|
||||
url = URI.parse('http://localhost/')
|
||||
|
||||
dates = [
|
||||
"20/06/95 21:07",
|
||||
]
|
||||
|
||||
silently do
|
||||
dates.each do |date|
|
||||
cookie = "PREF=1; expires=#{date}"
|
||||
HTTP::Cookie.parse(url, cookie) { |c|
|
||||
assert_equal(true, c.expires.nil?)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_parse_domain_dot
|
||||
url = URI.parse('http://host.example.com/')
|
||||
|
||||
cookie_str = 'a=b; domain=.example.com'
|
||||
|
||||
cookie = HTTP::Cookie.parse(url, cookie_str).first
|
||||
|
||||
assert_equal 'example.com', cookie.domain
|
||||
assert cookie.for_domain?
|
||||
end
|
||||
|
||||
def test_parse_domain_no_dot
|
||||
url = URI.parse('http://host.example.com/')
|
||||
|
||||
cookie_str = 'a=b; domain=example.com'
|
||||
|
||||
cookie = HTTP::Cookie.parse(url, cookie_str).first
|
||||
|
||||
assert_equal 'example.com', cookie.domain
|
||||
assert cookie.for_domain?
|
||||
end
|
||||
|
||||
def test_parse_domain_none
|
||||
url = URI.parse('http://example.com/')
|
||||
|
||||
cookie_str = 'a=b;'
|
||||
|
||||
cookie = HTTP::Cookie.parse(url, cookie_str).first
|
||||
|
||||
assert_equal 'example.com', cookie.domain
|
||||
assert !cookie.for_domain?
|
||||
end
|
||||
|
||||
def test_parse_max_age
|
||||
url = URI.parse('http://localhost/')
|
||||
|
||||
date = 'Mon, 19 Feb 2012 19:26:04 GMT'
|
||||
|
||||
cookie = HTTP::Cookie.parse(url, "name=Akinori; expires=#{date}").first
|
||||
assert_equal Time.at(1329679564), cookie.expires
|
||||
|
||||
cookie = HTTP::Cookie.parse(url, 'name=Akinori; max-age=3600').first
|
||||
assert_in_delta Time.now + 3600, cookie.expires, 1
|
||||
|
||||
# Max-Age has precedence over Expires
|
||||
cookie = HTTP::Cookie.parse(url, "name=Akinori; max-age=3600; expires=#{date}").first
|
||||
assert_in_delta Time.now + 3600, cookie.expires, 1
|
||||
|
||||
cookie = HTTP::Cookie.parse(url, "name=Akinori; expires=#{date}; max-age=3600").first
|
||||
assert_in_delta Time.now + 3600, cookie.expires, 1
|
||||
end
|
||||
|
||||
def test_parse_expires_session
|
||||
url = URI.parse('http://localhost/')
|
||||
|
||||
[
|
||||
'name=Akinori',
|
||||
'name=Akinori; expires',
|
||||
'name=Akinori; max-age',
|
||||
'name=Akinori; expires=',
|
||||
'name=Akinori; max-age=',
|
||||
].each { |str|
|
||||
cookie = HTTP::Cookie.parse(url, str).first
|
||||
assert cookie.session, str
|
||||
}
|
||||
|
||||
[
|
||||
'name=Akinori; expires=Mon, 19 Feb 2012 19:26:04 GMT',
|
||||
'name=Akinori; max-age=3600',
|
||||
].each { |str|
|
||||
cookie = HTTP::Cookie.parse(url, str).first
|
||||
assert !cookie.session, str
|
||||
}
|
||||
end
|
||||
|
||||
def test_parse_many
|
||||
url = URI 'http://example/'
|
||||
cookie_str =
|
||||
"name=Aaron; Domain=localhost; Expires=Sun, 06 Nov 2011 00:29:51 GMT; Path=/, " \
|
||||
"name=Aaron; Domain=localhost; Expires=Sun, 06 Nov 2011 00:29:51 GMT; Path=/, " \
|
||||
"name=Aaron; Domain=localhost; Expires=Sun, 06 Nov 2011 00:29:51 GMT; Path=/, " \
|
||||
"name=Aaron; Domain=localhost; Expires=Sun, 06 Nov 2011 00:29:51 GMT; Path=/; HttpOnly, " \
|
||||
"expired=doh; Expires=Fri, 04 Nov 2011 00:29:51 GMT; Path=/, " \
|
||||
"a_path=some_path; Expires=Sun, 06 Nov 2011 00:29:51 GMT; Path=/some_path, " \
|
||||
"no_path1=no_path; Expires=Sun, 06 Nov 2011 00:29:52 GMT, no_expires=nope; Path=/, " \
|
||||
"no_path2=no_path; Expires=Sun, 06 Nov 2011 00:29:52 GMT; no_expires=nope; Path, " \
|
||||
"no_path3=no_path; Expires=Sun, 06 Nov 2011 00:29:52 GMT; no_expires=nope; Path=, " \
|
||||
"no_domain1=no_domain; Expires=Sun, 06 Nov 2011 00:29:53 GMT; no_expires=nope, " \
|
||||
"no_domain2=no_domain; Expires=Sun, 06 Nov 2011 00:29:53 GMT; no_expires=nope; Domain, " \
|
||||
"no_domain3=no_domain; Expires=Sun, 06 Nov 2011 00:29:53 GMT; no_expires=nope; Domain="
|
||||
|
||||
cookies = HTTP::Cookie.parse url, cookie_str
|
||||
assert_equal 13, cookies.length
|
||||
|
||||
name = cookies.find { |c| c.name == 'name' }
|
||||
assert_equal "Aaron", name.value
|
||||
assert_equal "/", name.path
|
||||
assert_equal Time.at(1320539391), name.expires
|
||||
|
||||
a_path = cookies.find { |c| c.name == 'a_path' }
|
||||
assert_equal "some_path", a_path.value
|
||||
assert_equal "/some_path", a_path.path
|
||||
assert_equal Time.at(1320539391), a_path.expires
|
||||
|
||||
no_expires = cookies.find { |c| c.name == 'no_expires' }
|
||||
assert_equal "nope", no_expires.value
|
||||
assert_equal "/", no_expires.path
|
||||
assert_nil no_expires.expires
|
||||
|
||||
no_path_cookies = cookies.select { |c| c.value == 'no_path' }
|
||||
assert_equal 3, no_path_cookies.size
|
||||
no_path_cookies.each { |c|
|
||||
assert_equal "/", c.path, c.name
|
||||
assert_equal Time.at(1320539392), c.expires, c.name
|
||||
}
|
||||
|
||||
no_domain_cookies = cookies.select { |c| c.value == 'no_domain' }
|
||||
assert_equal 3, no_domain_cookies.size
|
||||
no_domain_cookies.each { |c|
|
||||
assert !c.for_domain?, c.name
|
||||
assert_equal c.domain, url.host, c.name
|
||||
assert_equal Time.at(1320539393), c.expires, c.name
|
||||
}
|
||||
|
||||
assert cookies.find { |c| c.name == 'expired' }
|
||||
end
|
||||
|
||||
def test_parse_valid_cookie
|
||||
url = URI.parse('http://rubyforge.org/')
|
||||
cookie_params = {}
|
||||
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
||||
cookie_params['path'] = 'path=/'
|
||||
cookie_params['domain'] = 'domain=.rubyforge.org'
|
||||
cookie_params['httponly'] = 'HttpOnly'
|
||||
cookie_value = '12345%7D=ASDFWEE345%3DASda'
|
||||
|
||||
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
||||
|
||||
cookie_params.keys.combine.each do |c|
|
||||
cookie_text = "#{cookie_value}; "
|
||||
c.each_with_index do |key, idx|
|
||||
if idx == (c.length - 1)
|
||||
cookie_text << "#{cookie_params[key]}"
|
||||
else
|
||||
cookie_text << "#{cookie_params[key]}; "
|
||||
end
|
||||
end
|
||||
cookie = nil
|
||||
HTTP::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
||||
|
||||
assert_equal('12345%7D=ASDFWEE345%3DASda', cookie.to_s)
|
||||
assert_equal('/', cookie.path)
|
||||
|
||||
# if expires was set, make sure we parsed it
|
||||
if c.find { |k| k == 'expires' }
|
||||
assert_equal(expires, cookie.expires)
|
||||
else
|
||||
assert_nil(cookie.expires)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_parse_valid_cookie_empty_value
|
||||
url = URI.parse('http://rubyforge.org/')
|
||||
cookie_params = {}
|
||||
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
||||
cookie_params['path'] = 'path=/'
|
||||
cookie_params['domain'] = 'domain=.rubyforge.org'
|
||||
cookie_params['httponly'] = 'HttpOnly'
|
||||
cookie_value = '12345%7D='
|
||||
|
||||
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
||||
|
||||
cookie_params.keys.combine.each do |c|
|
||||
cookie_text = "#{cookie_value}; "
|
||||
c.each_with_index do |key, idx|
|
||||
if idx == (c.length - 1)
|
||||
cookie_text << "#{cookie_params[key]}"
|
||||
else
|
||||
cookie_text << "#{cookie_params[key]}; "
|
||||
end
|
||||
end
|
||||
cookie = nil
|
||||
HTTP::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
||||
|
||||
assert_equal('12345%7D=', cookie.to_s)
|
||||
assert_equal('', cookie.value)
|
||||
assert_equal('/', cookie.path)
|
||||
|
||||
# if expires was set, make sure we parsed it
|
||||
if c.find { |k| k == 'expires' }
|
||||
assert_equal(expires, cookie.expires)
|
||||
else
|
||||
assert_nil(cookie.expires)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# If no path was given, use the one from the URL
|
||||
def test_cookie_using_url_path
|
||||
url = URI.parse('http://rubyforge.org/login.php')
|
||||
cookie_params = {}
|
||||
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
||||
cookie_params['path'] = 'path=/'
|
||||
cookie_params['domain'] = 'domain=.rubyforge.org'
|
||||
cookie_params['httponly'] = 'HttpOnly'
|
||||
cookie_value = '12345%7D=ASDFWEE345%3DASda'
|
||||
|
||||
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
||||
|
||||
cookie_params.keys.combine.each do |c|
|
||||
next if c.find { |k| k == 'path' }
|
||||
cookie_text = "#{cookie_value}; "
|
||||
c.each_with_index do |key, idx|
|
||||
if idx == (c.length - 1)
|
||||
cookie_text << "#{cookie_params[key]}"
|
||||
else
|
||||
cookie_text << "#{cookie_params[key]}; "
|
||||
end
|
||||
end
|
||||
cookie = nil
|
||||
HTTP::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
||||
|
||||
assert_equal('12345%7D=ASDFWEE345%3DASda', cookie.to_s)
|
||||
assert_equal('/', cookie.path)
|
||||
|
||||
# if expires was set, make sure we parsed it
|
||||
if c.find { |k| k == 'expires' }
|
||||
assert_equal(expires, cookie.expires)
|
||||
else
|
||||
assert_nil(cookie.expires)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Test using secure cookies
|
||||
def test_cookie_with_secure
|
||||
url = URI.parse('http://rubyforge.org/')
|
||||
cookie_params = {}
|
||||
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
||||
cookie_params['path'] = 'path=/'
|
||||
cookie_params['domain'] = 'domain=.rubyforge.org'
|
||||
cookie_params['secure'] = 'secure'
|
||||
cookie_value = '12345%7D=ASDFWEE345%3DASda'
|
||||
|
||||
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
||||
|
||||
cookie_params.keys.combine.each do |c|
|
||||
next unless c.find { |k| k == 'secure' }
|
||||
cookie_text = "#{cookie_value}; "
|
||||
c.each_with_index do |key, idx|
|
||||
if idx == (c.length - 1)
|
||||
cookie_text << "#{cookie_params[key]}"
|
||||
else
|
||||
cookie_text << "#{cookie_params[key]}; "
|
||||
end
|
||||
end
|
||||
cookie = nil
|
||||
HTTP::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
||||
|
||||
assert_equal('12345%7D=ASDFWEE345%3DASda', cookie.to_s)
|
||||
assert_equal('/', cookie.path)
|
||||
assert_equal(true, cookie.secure)
|
||||
|
||||
# if expires was set, make sure we parsed it
|
||||
if c.find { |k| k == 'expires' }
|
||||
assert_equal(expires, cookie.expires)
|
||||
else
|
||||
assert_nil(cookie.expires)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_parse_cookie_no_spaces
|
||||
url = URI.parse('http://rubyforge.org/')
|
||||
cookie_params = {}
|
||||
cookie_params['expires'] = 'expires=Sun, 27-Sep-2037 00:00:00 GMT'
|
||||
cookie_params['path'] = 'path=/'
|
||||
cookie_params['domain'] = 'domain=.rubyforge.org'
|
||||
cookie_params['httponly'] = 'HttpOnly'
|
||||
cookie_value = '12345%7D=ASDFWEE345%3DASda'
|
||||
|
||||
expires = Time.parse('Sun, 27-Sep-2037 00:00:00 GMT')
|
||||
|
||||
cookie_params.keys.combine.each do |c|
|
||||
cookie_text = "#{cookie_value};"
|
||||
c.each_with_index do |key, idx|
|
||||
if idx == (c.length - 1)
|
||||
cookie_text << "#{cookie_params[key]}"
|
||||
else
|
||||
cookie_text << "#{cookie_params[key]};"
|
||||
end
|
||||
end
|
||||
cookie = nil
|
||||
HTTP::Cookie.parse(url, cookie_text) { |p_cookie| cookie = p_cookie }
|
||||
|
||||
assert_equal('12345%7D=ASDFWEE345%3DASda', cookie.to_s)
|
||||
assert_equal('/', cookie.path)
|
||||
|
||||
# if expires was set, make sure we parsed it
|
||||
if c.find { |k| k == 'expires' }
|
||||
assert_equal(expires, cookie.expires)
|
||||
else
|
||||
assert_nil(cookie.expires)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_new
|
||||
cookie = HTTP::Cookie.new('key', 'value')
|
||||
assert_equal 'key', cookie.name
|
||||
assert_equal 'value', cookie.value
|
||||
assert_equal nil, cookie.expires
|
||||
|
||||
# Minimum unit for the expires attribute is second
|
||||
expires = Time.at((Time.now + 3600).to_i)
|
||||
|
||||
cookie = HTTP::Cookie.new('key', 'value', :expires => expires.dup)
|
||||
assert_equal 'key', cookie.name
|
||||
assert_equal 'value', cookie.value
|
||||
assert_equal expires, cookie.expires
|
||||
|
||||
cookie = HTTP::Cookie.new(:value => 'value', :name => 'key', :expires => expires.dup)
|
||||
assert_equal 'key', cookie.name
|
||||
assert_equal 'value', cookie.value
|
||||
assert_equal expires, cookie.expires
|
||||
end
|
||||
|
||||
def test_domain=
|
||||
url = URI.parse('http://host.dom.example.com:8080/')
|
||||
|
||||
cookie_str = 'a=b; domain=Example.Com'
|
||||
cookie = HTTP::Cookie.parse(url, cookie_str).first
|
||||
assert 'example.com', cookie.domain
|
||||
|
||||
cookie.domain = DomainName(url.host)
|
||||
assert 'host.dom.example.com', cookie.domain
|
||||
|
||||
cookie.domain = 'Dom.example.com'
|
||||
assert 'dom.example.com', cookie.domain
|
||||
|
||||
cookie.domain = Object.new.tap { |o|
|
||||
def o.to_str
|
||||
'Example.com'
|
||||
end
|
||||
}
|
||||
assert 'example.com', cookie.domain
|
||||
end
|
||||
end
|
||||
|
||||
518
test/test_http_cookie_jar.rb
Normal file
518
test/test_http_cookie_jar.rb
Normal file
|
|
@ -0,0 +1,518 @@
|
|||
require File.expand_path('helper', File.dirname(__FILE__))
|
||||
|
||||
class TestMechanizeCookieJar < Test::Unit::TestCase
|
||||
#class TestMechanizeCookieJar < MiniTest::Unit::TestCase
|
||||
|
||||
def setup
|
||||
@jar = HTTP::CookieJar.new
|
||||
end
|
||||
|
||||
def in_tmpdir
|
||||
Dir.mktmpdir do |dir|
|
||||
Dir.chdir dir do
|
||||
yield
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def cookie_values(options = {})
|
||||
{
|
||||
:name => 'Foo',
|
||||
:value => 'Bar',
|
||||
:path => '/',
|
||||
:expires => Time.now + (10 * 86400),
|
||||
:for_domain => true,
|
||||
:domain => 'rubyforge.org'
|
||||
}.merge(options)
|
||||
end
|
||||
|
||||
def test_two_cookies_same_domain_and_name_different_paths
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
cookie = HTTP::Cookie.new(cookie_values)
|
||||
@jar.add(url, cookie)
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:path => '/onetwo')))
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
assert_equal 2, @jar.cookies(URI('http://rubyforge.org/onetwo')).length
|
||||
end
|
||||
|
||||
def test_domain_case
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(cookie_values)
|
||||
@jar.add(url, cookie)
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
@jar.add(url, HTTP::Cookie.new(
|
||||
cookie_values(:domain => 'RuByForge.Org', :name => 'aaron')))
|
||||
|
||||
assert_equal(2, @jar.cookies(url).length)
|
||||
|
||||
url2 = URI 'http://RuByFoRgE.oRg/'
|
||||
assert_equal(2, @jar.cookies(url2).length)
|
||||
end
|
||||
|
||||
def test_host_only
|
||||
url = URI.parse('http://rubyforge.org/')
|
||||
|
||||
@jar.add(url, HTTP::Cookie.new(
|
||||
cookie_values(:domain => 'rubyforge.org', :for_domain => false)))
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
assert_equal(1, @jar.cookies(URI('http://RubyForge.org/')).length)
|
||||
|
||||
assert_equal(1, @jar.cookies(URI('https://RubyForge.org/')).length)
|
||||
|
||||
assert_equal(0, @jar.cookies(URI('http://www.rubyforge.org/')).length)
|
||||
end
|
||||
|
||||
def test_empty_value
|
||||
values = cookie_values(:value => "")
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(values)
|
||||
@jar.add(url, cookie)
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
@jar.add url, HTTP::Cookie.new(values.merge(:domain => 'RuByForge.Org',
|
||||
:name => 'aaron'))
|
||||
|
||||
assert_equal(2, @jar.cookies(url).length)
|
||||
|
||||
url2 = URI 'http://RuByFoRgE.oRg/'
|
||||
assert_equal(2, @jar.cookies(url2).length)
|
||||
end
|
||||
|
||||
def test_add_future_cookies
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(cookie_values)
|
||||
@jar.add(url, cookie)
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
# Add the same cookie, and we should still only have one
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values))
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
# Make sure we can get the cookie from different paths
|
||||
assert_equal(1, @jar.cookies(URI('http://rubyforge.org/login')).length)
|
||||
|
||||
# Make sure we can't get the cookie from different domains
|
||||
assert_equal(0, @jar.cookies(URI('http://google.com/')).length)
|
||||
end
|
||||
|
||||
def test_add_multiple_cookies
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(cookie_values)
|
||||
@jar.add(url, cookie)
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
# Add the same cookie, and we should still only have one
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:name => 'Baz')))
|
||||
assert_equal(2, @jar.cookies(url).length)
|
||||
|
||||
# Make sure we can get the cookie from different paths
|
||||
assert_equal(2, @jar.cookies(URI('http://rubyforge.org/login')).length)
|
||||
|
||||
# Make sure we can't get the cookie from different domains
|
||||
assert_equal(0, @jar.cookies(URI('http://google.com/')).length)
|
||||
end
|
||||
|
||||
def test_add_rejects_cookies_that_do_not_contain_an_embedded_dot
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
tld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.org'))
|
||||
@jar.add(url, tld_cookie)
|
||||
single_dot_cookie = HTTP::Cookie.new(cookie_values(:domain => '.'))
|
||||
@jar.add(url, single_dot_cookie)
|
||||
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_fall_back_rules_for_local_domains
|
||||
url = URI 'http://www.example.local'
|
||||
|
||||
tld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.local'))
|
||||
@jar.add(url, tld_cookie)
|
||||
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
|
||||
sld_cookie = HTTP::Cookie.new(cookie_values(:domain => '.example.local'))
|
||||
@jar.add(url, sld_cookie)
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_add_makes_exception_for_localhost
|
||||
url = URI 'http://localhost'
|
||||
|
||||
tld_cookie = HTTP::Cookie.new(cookie_values(:domain => 'localhost'))
|
||||
@jar.add(url, tld_cookie)
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_add_cookie_for_the_parent_domain
|
||||
url = URI 'http://x.foo.com'
|
||||
|
||||
cookie = HTTP::Cookie.new(cookie_values(:domain => '.foo.com'))
|
||||
@jar.add(url, cookie)
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_add_does_not_reject_cookies_from_a_nested_subdomain
|
||||
url = URI 'http://y.x.foo.com'
|
||||
|
||||
cookie = HTTP::Cookie.new(cookie_values(:domain => '.foo.com'))
|
||||
@jar.add(url, cookie)
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_cookie_without_leading_dot_does_not_cause_substring_match
|
||||
url = URI 'http://arubyforge.org/'
|
||||
|
||||
cookie = HTTP::Cookie.new(cookie_values(:domain => 'rubyforge.org'))
|
||||
@jar.add(url, cookie)
|
||||
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_cookie_without_leading_dot_matches_subdomains
|
||||
url = URI 'http://admin.rubyforge.org/'
|
||||
|
||||
cookie = HTTP::Cookie.new(cookie_values(:domain => 'rubyforge.org'))
|
||||
@jar.add(url, cookie)
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_cookies_with_leading_dot_match_subdomains
|
||||
url = URI 'http://admin.rubyforge.org/'
|
||||
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:domain => '.rubyforge.org')))
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_cookies_with_leading_dot_match_parent_domains
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:domain => '.rubyforge.org')))
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_cookies_with_leading_dot_match_parent_domains_exactly
|
||||
url = URI 'http://arubyforge.org/'
|
||||
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:domain => '.rubyforge.org')))
|
||||
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_cookie_for_ipv4_address_matches_the_exact_ipaddress
|
||||
url = URI 'http://192.168.0.1/'
|
||||
|
||||
cookie = HTTP::Cookie.new(cookie_values(:domain => '192.168.0.1'))
|
||||
@jar.add(url, cookie)
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_cookie_for_ipv4_address_does_not_cause_subdomain_match
|
||||
url = URI 'http://192.168.0.1/'
|
||||
|
||||
cookie = HTTP::Cookie.new(cookie_values(:domain => '.0.1'))
|
||||
@jar.add(url, cookie)
|
||||
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_cookie_for_ipv6_address_matches_the_exact_ipaddress
|
||||
url = URI 'http://[fe80::0123:4567:89ab:cdef]/'
|
||||
|
||||
cookie = HTTP::Cookie.new(cookie_values(:domain => '[fe80::0123:4567:89ab:cdef]'))
|
||||
@jar.add(url, cookie)
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_cookies_dot
|
||||
url = URI 'http://www.host.example/'
|
||||
|
||||
@jar.add(url,
|
||||
HTTP::Cookie.new(cookie_values(:domain => 'www.host.example')))
|
||||
|
||||
url = URI 'http://wwwxhost.example/'
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_clear_bang
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(cookie_values)
|
||||
@jar.add(url, cookie)
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:name => 'Baz')))
|
||||
assert_equal(2, @jar.cookies(url).length)
|
||||
|
||||
@jar.clear!
|
||||
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_save_cookies_yaml
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(cookie_values)
|
||||
s_cookie = HTTP::Cookie.new(cookie_values(:name => 'Bar',
|
||||
:expires => nil,
|
||||
:session => true))
|
||||
|
||||
@jar.add(url, cookie)
|
||||
@jar.add(url, s_cookie)
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:name => 'Baz')))
|
||||
|
||||
assert_equal(3, @jar.cookies(url).length)
|
||||
|
||||
in_tmpdir do
|
||||
value = @jar.save_as("cookies.yml")
|
||||
assert_same @jar, value
|
||||
|
||||
jar = HTTP::CookieJar.new
|
||||
jar.load("cookies.yml")
|
||||
assert_equal(2, jar.cookies(url).length)
|
||||
end
|
||||
|
||||
assert_equal(3, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_save_session_cookies_yaml
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(cookie_values)
|
||||
s_cookie = HTTP::Cookie.new(cookie_values(:name => 'Bar',
|
||||
:expires => nil,
|
||||
:session => true))
|
||||
|
||||
@jar.add(url, cookie)
|
||||
@jar.add(url, s_cookie)
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:name => 'Baz')))
|
||||
|
||||
assert_equal(3, @jar.cookies(url).length)
|
||||
|
||||
in_tmpdir do
|
||||
@jar.save_as("cookies.yml", :format => :yaml, :session => true)
|
||||
|
||||
jar = HTTP::CookieJar.new
|
||||
jar.load("cookies.yml")
|
||||
assert_equal(3, jar.cookies(url).length)
|
||||
end
|
||||
|
||||
assert_equal(3, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
|
||||
def test_save_cookies_cookiestxt
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(cookie_values)
|
||||
s_cookie = HTTP::Cookie.new(cookie_values(:name => 'Bar',
|
||||
:expires => nil,
|
||||
:session => true))
|
||||
|
||||
@jar.add(url, cookie)
|
||||
@jar.add(url, s_cookie)
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:name => 'Baz')))
|
||||
|
||||
assert_equal(3, @jar.cookies(url).length)
|
||||
|
||||
in_tmpdir do
|
||||
@jar.save_as("cookies.txt", :cookiestxt)
|
||||
|
||||
jar = HTTP::CookieJar.new
|
||||
jar.load("cookies.txt", :cookiestxt) # HACK test the format
|
||||
assert_equal(2, jar.cookies(url).length)
|
||||
end
|
||||
|
||||
assert_equal(3, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_expire_cookies
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(cookie_values)
|
||||
@jar.add(url, cookie)
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
# Add a second cookie
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:name => 'Baz')))
|
||||
assert_equal(2, @jar.cookies(url).length)
|
||||
|
||||
# Make sure we can get the cookie from different paths
|
||||
assert_equal(2, @jar.cookies(URI('http://rubyforge.org/login')).length)
|
||||
|
||||
# Expire the first cookie
|
||||
@jar.add(url, HTTP::Cookie.new(
|
||||
cookie_values(:expires => Time.now - (10 * 86400))))
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
# Expire the second cookie
|
||||
@jar.add(url, HTTP::Cookie.new(
|
||||
cookie_values( :name => 'Baz', :expires => Time.now - (10 * 86400))))
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_session_cookies
|
||||
values = cookie_values(:expires => nil)
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(values)
|
||||
@jar.add(url, cookie)
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
# Add a second cookie
|
||||
@jar.add(url, HTTP::Cookie.new(values.merge(:name => 'Baz')))
|
||||
assert_equal(2, @jar.cookies(url).length)
|
||||
|
||||
# Make sure we can get the cookie from different paths
|
||||
assert_equal(2, @jar.cookies(URI('http://rubyforge.org/login')).length)
|
||||
|
||||
# Expire the first cookie
|
||||
@jar.add(url, HTTP::Cookie.new(values.merge(:expires => Time.now - (10 * 86400))))
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
# Expire the second cookie
|
||||
@jar.add(url, HTTP::Cookie.new(
|
||||
values.merge(:name => 'Baz', :expires => Time.now - (10 * 86400))))
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
|
||||
# When given a URI with a blank path, CookieJar#cookies should return
|
||||
# cookies with the path '/':
|
||||
url = URI 'http://rubyforge.org'
|
||||
assert_equal '', url.path
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
# Now add a cookie with the path set to '/':
|
||||
@jar.add(url, HTTP::Cookie.new(values.merge( :name => 'has_root_path',
|
||||
:path => '/')))
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_paths
|
||||
values = cookie_values(:path => "/login", :expires => nil)
|
||||
url = URI 'http://rubyforge.org/login'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(values)
|
||||
@jar.add(url, cookie)
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
# Add a second cookie
|
||||
@jar.add(url, HTTP::Cookie.new(values.merge( :name => 'Baz' )))
|
||||
assert_equal(2, @jar.cookies(url).length)
|
||||
|
||||
# Make sure we don't get the cookie in a different path
|
||||
assert_equal(0, @jar.cookies(URI('http://rubyforge.org/hello')).length)
|
||||
assert_equal(0, @jar.cookies(URI('http://rubyforge.org/')).length)
|
||||
|
||||
# Expire the first cookie
|
||||
@jar.add(url, HTTP::Cookie.new(values.merge( :expires => Time.now - (10 * 86400))))
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
|
||||
# Expire the second cookie
|
||||
@jar.add(url, HTTP::Cookie.new(values.merge( :name => 'Baz',
|
||||
:expires => Time.now - (10 * 86400))))
|
||||
assert_equal(0, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_save_and_read_cookiestxt
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
# Add one cookie with an expiration date in the future
|
||||
cookie = HTTP::Cookie.new(cookie_values)
|
||||
@jar.add(url, cookie)
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:name => 'Baz')))
|
||||
assert_equal(2, @jar.cookies(url).length)
|
||||
|
||||
in_tmpdir do
|
||||
@jar.save_as("cookies.txt", :cookiestxt)
|
||||
@jar.clear!
|
||||
|
||||
@jar.load("cookies.txt", :cookiestxt)
|
||||
end
|
||||
|
||||
assert_equal(2, @jar.cookies(url).length)
|
||||
end
|
||||
|
||||
def test_save_and_read_cookiestxt_with_session_cookies
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
@jar.add(url, HTTP::Cookie.new(cookie_values(:expires => nil)))
|
||||
|
||||
in_tmpdir do
|
||||
@jar.save_as("cookies.txt", :cookiestxt)
|
||||
@jar.clear!
|
||||
|
||||
@jar.load("cookies.txt", :cookiestxt)
|
||||
end
|
||||
|
||||
assert_equal(1, @jar.cookies(url).length)
|
||||
assert_nil @jar.cookies(url).first.expires
|
||||
end
|
||||
|
||||
def test_save_and_read_expired_cookies
|
||||
url = URI 'http://rubyforge.org/'
|
||||
|
||||
@jar.jar['rubyforge.org'] = {}
|
||||
|
||||
|
||||
@jar.add url, HTTP::Cookie.new(cookie_values)
|
||||
|
||||
# HACK no asertion
|
||||
end
|
||||
|
||||
def test_ssl_cookies
|
||||
# thanks to michal "ocher" ochman for reporting the bug responsible for this test.
|
||||
values = cookie_values(:expires => nil)
|
||||
values_ssl = values.merge(:name => 'Baz', :domain => "#{values[:domain]}:443")
|
||||
url = URI 'https://rubyforge.org/login'
|
||||
|
||||
cookie = HTTP::Cookie.new(values)
|
||||
@jar.add(url, cookie)
|
||||
assert_equal(1, @jar.cookies(url).length, "did not handle SSL cookie")
|
||||
|
||||
cookie = HTTP::Cookie.new(values_ssl)
|
||||
@jar.add(url, cookie)
|
||||
assert_equal(2, @jar.cookies(url).length, "did not handle SSL cookie with :443")
|
||||
end
|
||||
|
||||
def test_secure_cookie
|
||||
nurl = URI 'http://rubyforge.org/login'
|
||||
surl = URI 'https://rubyforge.org/login'
|
||||
|
||||
ncookie = HTTP::Cookie.new(cookie_values(:name => 'Foo1'))
|
||||
scookie = HTTP::Cookie.new(cookie_values(:name => 'Foo2', :secure => true))
|
||||
|
||||
@jar.add(nurl, ncookie)
|
||||
@jar.add(nurl, scookie)
|
||||
@jar.add(surl, ncookie)
|
||||
@jar.add(surl, scookie)
|
||||
|
||||
assert_equal('Foo1', @jar.cookies(nurl).map { |c| c.name }.sort.join(' ') )
|
||||
assert_equal('Foo1 Foo2', @jar.cookies(surl).map { |c| c.name }.sort.join(' ') )
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue