dwaite-cookiejar 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/cookiejar/cookie.rb +167 -53
- data/lib/cookiejar/cookie_common.rb +11 -1
- data/lib/cookiejar/cookie_logic.rb +0 -73
- data/lib/cookiejar/jar.rb +4 -6
- data/test/cookie_logic_test.rb +0 -79
- data/test/cookie_test.rb +98 -7
- data/test/jar_test.rb +7 -0
- metadata +2 -2
data/lib/cookiejar/cookie.rb
CHANGED
@@ -1,64 +1,66 @@
|
|
1
1
|
require 'time'
|
2
2
|
require 'cookiejar/cookie_logic'
|
3
|
+
|
3
4
|
module CookieJar
|
5
|
+
|
6
|
+
# Defines the parsing logic and data model of a HTTP Cookie.
|
7
|
+
# Note that the data values within the cookie may be different from the
|
8
|
+
# values described in the literal cookie declaration.
|
9
|
+
# Specifically, the 'domain' and 'path' values may be set to defaults
|
10
|
+
# based on the requested resource that resulted in the cookie being set.
|
4
11
|
class Cookie
|
5
12
|
include CookieLogic
|
6
|
-
|
13
|
+
extend CookieLogic
|
14
|
+
|
15
|
+
# The mandatory name and value of the cookie
|
7
16
|
attr_reader :name, :value
|
8
|
-
|
9
|
-
|
17
|
+
# The domain and path of the cookie. These values will be set on all
|
18
|
+
# legal cookie objects, based on the requested URI if not set literally
|
10
19
|
attr_reader :domain, :path
|
11
|
-
|
20
|
+
# The secure flag is set to indicate that the cookie should only be
|
21
|
+
# sent securely. Nearly all implementations assume this to mean over
|
22
|
+
# SSL/TLS
|
23
|
+
attr_reader :secure
|
24
|
+
# Popular browser extension to mark a cookie as invisible to code running
|
25
|
+
# within the browser, such as JavaScript
|
26
|
+
attr_reader :http_only
|
27
|
+
|
28
|
+
#-- Attributes for RFC 2965 cookies
|
29
|
+
|
30
|
+
# Version indicator - version is 0 for netscape cookies,
|
31
|
+
# and 1 for RFC 2965 cookies
|
12
32
|
attr_reader :version
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
33
|
+
# Comment (or location) describing cookie.
|
34
|
+
attr_reader :comment, :comment_url
|
35
|
+
# Discard
|
36
|
+
attr_reader :discard
|
37
|
+
attr_reader :ports
|
38
|
+
attr_reader :created_at
|
17
39
|
|
18
40
|
def expires_at
|
19
|
-
if expiry.nil?
|
20
|
-
|
21
|
-
elsif expiry.is_a? Time
|
22
|
-
expiry
|
41
|
+
if @expiry.nil? || @expiry.is_a?(Time)
|
42
|
+
@expiry
|
23
43
|
else
|
24
|
-
|
44
|
+
@created_at + @expiry
|
25
45
|
end
|
26
46
|
end
|
47
|
+
|
27
48
|
def max_age
|
28
|
-
if expiry.is_a?
|
29
|
-
expiry
|
49
|
+
if @expiry.is_a? Time
|
50
|
+
@expiry - @created_at
|
30
51
|
else
|
31
|
-
expiry
|
32
|
-
end
|
33
|
-
end
|
34
|
-
def port
|
35
|
-
nil
|
36
|
-
end
|
37
|
-
def initialize(uri, *params)
|
38
|
-
case params.length
|
39
|
-
when 1
|
40
|
-
args = params[0]
|
41
|
-
when 2
|
42
|
-
args = {:name => args[0], :value => args[1]}
|
43
|
-
else
|
44
|
-
raise ArgumentError.new "wrong number of arguments (expected 1 or 2)"
|
52
|
+
@expiry
|
45
53
|
end
|
54
|
+
end
|
46
55
|
|
47
|
-
|
48
|
-
|
49
|
-
@path = determine_cookie_path(uri, args[:path])
|
50
|
-
@secure = args[:secure] || false
|
51
|
-
@http_only = args[:http_only] ||false
|
52
|
-
@name = args[:name]
|
53
|
-
@value = args[:value]
|
54
|
-
@version = args[:version]
|
55
|
-
@created_at = DateTime.now
|
56
|
+
def expired?
|
57
|
+
expires_at != nil && (Time.now > expires_at)
|
56
58
|
end
|
57
|
-
|
58
|
-
PARAM1 = /\A(#{PATTERN::TOKEN})(?:=#{PATTERN::VALUE1})?\Z/
|
59
|
-
# PARAM2 = /\A(#{PATTERN::TOKEN})(?:=#{PATTERN::VALUE2})?\Z/
|
60
59
|
|
60
|
+
# Create a cookie based on an absolute URI and the string value of a
|
61
|
+
# 'Set-Cookie' header.
|
61
62
|
def self.from_set_cookie(request_uri, set_cookie_value)
|
63
|
+
include CookieLogic
|
62
64
|
args = {}
|
63
65
|
params=set_cookie_value.split(/;\s*/)
|
64
66
|
params.each do |param|
|
@@ -66,14 +68,14 @@ module CookieJar
|
|
66
68
|
if (!result)
|
67
69
|
raise InvalidCookieError.new("Invalid cookie parameter in cookie '#{set_cookie_value}'")
|
68
70
|
end
|
69
|
-
key = result[1].
|
70
|
-
keyvalue = result[2]
|
71
|
+
key = result[1].downcase.to_sym
|
72
|
+
keyvalue = result[2]
|
71
73
|
case key
|
72
|
-
when
|
73
|
-
args[:expires_at] =
|
74
|
-
when
|
75
|
-
args[:domain] = keyvalue
|
76
|
-
when
|
74
|
+
when :expires
|
75
|
+
args[:expires_at] = Time.parse(keyvalue)
|
76
|
+
when :domain
|
77
|
+
args[:domain] = keyvalue
|
78
|
+
when :path
|
77
79
|
args[:path] = keyvalue
|
78
80
|
when 'SECURE'
|
79
81
|
args[:secure] = true
|
@@ -84,12 +86,124 @@ module CookieJar
|
|
84
86
|
args[:value] = keyvalue
|
85
87
|
end
|
86
88
|
end
|
89
|
+
args[:domain] = determine_cookie_domain request_uri, args[:domain]
|
90
|
+
args[:path] = determine_cookie_path request_uri, args[:path]
|
87
91
|
args[:version] = 0
|
88
|
-
Cookie.new
|
92
|
+
cookie = Cookie.new args
|
93
|
+
validate_cookie request_uri, cookie
|
94
|
+
cookie
|
89
95
|
end
|
90
|
-
|
96
|
+
|
91
97
|
def to_s
|
92
|
-
|
93
|
-
end
|
98
|
+
%^"#{name}=#{value}#{if(domain) then "; domain=#{domain}" end}#{if (expiry) then "; expiry=#{expiry}" end}#{if (path) then "; path=#{path}" end}#{if (secure) then "; secure" end }#{if (http_only) then "; HTTPOnly" end}^
|
99
|
+
end
|
100
|
+
|
101
|
+
# Check whether a cookie meets all of the rules to be created, based on
|
102
|
+
# its internal settings and the URI it came from.
|
103
|
+
#
|
104
|
+
# returns true on success, but will raise an InvalidCookieError on failure
|
105
|
+
# with an appropriate error message
|
106
|
+
def self.validate_cookie request_uri, cookie
|
107
|
+
uri = request_uri.is_a?(URI) ? request_uri : URI.parse(request_uri)
|
108
|
+
|
109
|
+
request_host = effective_host uri.host
|
110
|
+
request_path = uri.path
|
111
|
+
request_secure = (uri.scheme == 'https')
|
112
|
+
cookie_host = cookie.domain
|
113
|
+
cookie_path = cookie.path
|
114
|
+
|
115
|
+
errors = []
|
116
|
+
|
117
|
+
# From RFC 2965, Section 3.3.2 Rejecting Cookies
|
118
|
+
|
119
|
+
# A user agent rejects (SHALL NOT store its information) if the
|
120
|
+
# Version attribute is missing. Note that the legacy Set-Cookie
|
121
|
+
# directive will result in an implicit version 0.
|
122
|
+
unless cookie.version
|
123
|
+
errors << "Version missing"
|
124
|
+
end
|
125
|
+
|
126
|
+
# The value for the Path attribute is not a prefix of the request-URI
|
127
|
+
unless request_path.start_with? cookie_path
|
128
|
+
errors << "Path is not a prefix of the request uri path"
|
129
|
+
end
|
130
|
+
|
131
|
+
unless cookie_host =~ IPADDR || #is an IPv4 or IPv6 address
|
132
|
+
cookie_host =~ /.\../ || #contains an embedded dot
|
133
|
+
cookie_host == '.local' #is the domain cookie for local addresses
|
134
|
+
errors << "Domain format is illegal"
|
135
|
+
end
|
136
|
+
|
137
|
+
# The effective host name that derives from the request-host does
|
138
|
+
# not domain-match the Domain attribute.
|
139
|
+
#
|
140
|
+
# The request-host is a HDN (not IP address) and has the form HD,
|
141
|
+
# where D is the value of the Domain attribute, and H is a string
|
142
|
+
# that contains one or more dots.
|
143
|
+
effective_host = effective_host uri
|
144
|
+
unless domains_match effective_host, cookie_host
|
145
|
+
errors << "Domain is inappropriate based on request URI hostname"
|
146
|
+
end
|
147
|
+
|
148
|
+
# The Port attribute has a "port-list", and the request-port was
|
149
|
+
# not in the list.
|
150
|
+
unless cookie.ports.nil? || cookie.ports.length != 0
|
151
|
+
unless cookie.ports.find_index uri.port
|
152
|
+
errors << "Ports list does not contain request URI port"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
raise InvalidCookieError.new(errors) unless errors.empty?
|
157
|
+
|
158
|
+
# Note: 'secure' is not explicitly defined as an SSL channel, and no
|
159
|
+
# test is defined around validity and the 'secure' attribute
|
160
|
+
true
|
161
|
+
end
|
162
|
+
# Return true if (given a URI, a cookie object and other options) a cookie
|
163
|
+
# should be sent to a host. Note that this currently ignores domain.
|
164
|
+
#
|
165
|
+
# The third option, 'script', indicates that cookies with the 'http only'
|
166
|
+
# extension should be ignored
|
167
|
+
def should_send? uri, script
|
168
|
+
# cookie path must start with the uri, it must not be a secure cookie being sent over http,
|
169
|
+
# and it must not be a http_only cookie sent to a script
|
170
|
+
path_match = uri.path.start_with? @path
|
171
|
+
secure_match = !(@secure && uri.scheme == 'http')
|
172
|
+
script_match = !(script && @http_only)
|
173
|
+
expiry_match = !expired?
|
174
|
+
path_match && secure_match && script_match && expiry_match
|
175
|
+
end
|
176
|
+
protected
|
177
|
+
PARAM1 = /\A(#{PATTERN::TOKEN})(?:=#{PATTERN::VALUE1})?\Z/
|
178
|
+
# PARAM2 = /\A(#{PATTERN::TOKEN})(?:=#{PATTERN::VALUE2})?\Z/
|
179
|
+
|
180
|
+
def initialize(*params)
|
181
|
+
case params.length
|
182
|
+
when 1
|
183
|
+
args = params[0]
|
184
|
+
when 2
|
185
|
+
args = {:name => params[0], :value => params[1], :version => 0}
|
186
|
+
else
|
187
|
+
raise ArgumentError.new "wrong number of arguments (expected 1 or 2)"
|
188
|
+
end
|
189
|
+
|
190
|
+
@created_at = Time.now
|
191
|
+
@domain = args[:domain]
|
192
|
+
@expiry = args[:max_age] || args[:expires_at] || nil
|
193
|
+
@path = args[:path]
|
194
|
+
@secure = args[:secure] || false
|
195
|
+
@http_only = args[:http_only] || false
|
196
|
+
@name = args[:name]
|
197
|
+
@value = args[:value]
|
198
|
+
@version = args[:version]
|
199
|
+
@comment = args[:comment]
|
200
|
+
@comment_url = args[:comment_url]
|
201
|
+
@discard = args[:discard]
|
202
|
+
@ports = args[:ports]
|
203
|
+
|
204
|
+
if @ports.is_a? Integer
|
205
|
+
@ports = [@ports]
|
206
|
+
end
|
207
|
+
end
|
94
208
|
end
|
95
|
-
end
|
209
|
+
end
|
@@ -1,4 +1,14 @@
|
|
1
1
|
module CookieJar
|
2
2
|
class CookieError < StandardError; end
|
3
|
-
|
3
|
+
# Represents all cookie validation errors
|
4
|
+
class InvalidCookieError < CookieError;
|
5
|
+
attr_reader :messages
|
6
|
+
def initialize message
|
7
|
+
if message.is_a? Array
|
8
|
+
@messages = message
|
9
|
+
message = message.join ', '
|
10
|
+
end
|
11
|
+
super(message)
|
12
|
+
end
|
13
|
+
end
|
4
14
|
end
|
@@ -108,64 +108,6 @@ module CookieJar
|
|
108
108
|
rhs = effective_host base_domain
|
109
109
|
lhs == rhs || ".#{lhs}" == rhs || hostname_reach(lhs) == rhs || ".#{hostname_reach lhs}" == rhs
|
110
110
|
end
|
111
|
-
|
112
|
-
# Check whether a cookie meets all of the rules to be created, based on
|
113
|
-
# its internal settings and the URI it came from.
|
114
|
-
#
|
115
|
-
# returns true on success, but will raise an InvalidCookieError on failure
|
116
|
-
# with an appropriate error message
|
117
|
-
def validate_cookie request_uri, cookie
|
118
|
-
uri = request_uri.is_a?(URI) ? request_uri : URI.parse(request_uri)
|
119
|
-
|
120
|
-
request_host = effective_host uri.host
|
121
|
-
request_path = uri.path
|
122
|
-
request_secure = (uri.scheme == 'https')
|
123
|
-
cookie_host = cookie.domain
|
124
|
-
cookie_path = cookie.path
|
125
|
-
|
126
|
-
# From RFC 2965, Section 3.3.2 Rejecting Cookies
|
127
|
-
|
128
|
-
# A user agent rejects (SHALL NOT store its information) if the
|
129
|
-
# Version attribute is missing. Note that the legacy Set-Cookie
|
130
|
-
# directive will result in an implicit version 0.
|
131
|
-
unless cookie.version
|
132
|
-
raise InvalidCookieError, "Cookie version not supplied (or implicit with Set-Cookie)"
|
133
|
-
end
|
134
|
-
|
135
|
-
# The value for the Path attribute is not a prefix of the request-URI
|
136
|
-
unless request_path.start_with? cookie_path
|
137
|
-
raise InvalidCookieError, "Cookie path should match or be a subset of the request path"
|
138
|
-
end
|
139
|
-
|
140
|
-
# The value for the Domain attribute contains no embedded dots, and the value is not .local
|
141
|
-
# Note: we also allow IPv4 and IPv6 addresses
|
142
|
-
unless cookie_host =~ IPADDR || cookie_host =~ /.\../ || cookie_host == '.local'
|
143
|
-
raise InvalidCookieError, "Cookie domain format is not legal"
|
144
|
-
end
|
145
|
-
|
146
|
-
# The effective host name that derives from the request-host does
|
147
|
-
# not domain-match the Domain attribute.
|
148
|
-
#
|
149
|
-
# The request-host is a HDN (not IP address) and has the form HD,
|
150
|
-
# where D is the value of the Domain attribute, and H is a string
|
151
|
-
# that contains one or more dots.
|
152
|
-
effective_host = effective_host uri
|
153
|
-
unless domains_match effective_host, cookie_host
|
154
|
-
raise InvalidCookieError, "Cookie domain is inappropriate based on request hostname"
|
155
|
-
end
|
156
|
-
|
157
|
-
# The Port attribute has a "port-list", and the request-port was
|
158
|
-
# not in the list.
|
159
|
-
if cookie.port.to_a.length != 0
|
160
|
-
unless cookie.port.to_a.find_index uri.port
|
161
|
-
raise InvalidCookieError, "incoming request port does not match cookie port(s)"
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
# Note: 'secure' is not explicitly defined as an SSL channel, and no
|
166
|
-
# test is defined around validity and the 'secure' attribute
|
167
|
-
true
|
168
|
-
end
|
169
111
|
|
170
112
|
# Given a URI, compute the relevant search domains for pre-existing
|
171
113
|
# cookies. This includes all the valid dotted forms for a named or IP
|
@@ -183,20 +125,5 @@ module CookieJar
|
|
183
125
|
end
|
184
126
|
result
|
185
127
|
end
|
186
|
-
|
187
|
-
# Return true if (given a URI, a cookie object and other options) a cookie
|
188
|
-
# should be sent to a host. Note that this currently ignores domain.
|
189
|
-
#
|
190
|
-
# The third option, 'script', indicates that cookies with the 'http only'
|
191
|
-
# extension should be ignored
|
192
|
-
def send_cookie? uri, cookie, script
|
193
|
-
# cookie path must start with the uri, it must not be a secure cookie being sent over http,
|
194
|
-
# and it must not be a http_only cookie sent to a script
|
195
|
-
path_match = uri.path.start_with? cookie.path
|
196
|
-
secure_match = !(cookie.secure && uri.scheme == 'http')
|
197
|
-
script_match = !(script && cookie.http_only)
|
198
|
-
expiry_match = cookie.expires_at.nil? || cookie.expires_at > Time.now
|
199
|
-
path_match && secure_match && script_match && expiry_match
|
200
|
-
end
|
201
128
|
end
|
202
129
|
end
|
data/lib/cookiejar/jar.rb
CHANGED
@@ -56,11 +56,9 @@ module CookieJar
|
|
56
56
|
uri = request_uri.is_a?(URI) ? request_uri : URI.parse(request_uri)
|
57
57
|
host = effective_host uri
|
58
58
|
cookie = Cookie.from_set_cookie(uri, cookie_header_value)
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
cookie
|
63
|
-
end
|
59
|
+
domain_paths = find_or_add_domain_for_cookie(cookie.domain)
|
60
|
+
add_cookie_to_path(domain_paths,cookie)
|
61
|
+
cookie
|
64
62
|
end
|
65
63
|
|
66
64
|
# Given a request URI, return a sorted list of Cookie objects. Cookies
|
@@ -79,7 +77,7 @@ module CookieJar
|
|
79
77
|
domain.each do |path, cookies|
|
80
78
|
if uri.path.start_with? path
|
81
79
|
results += cookies.select do |name, cookie|
|
82
|
-
|
80
|
+
cookie.should_send? uri, args[:script]
|
83
81
|
end.collect do |name, cookie|
|
84
82
|
cookie
|
85
83
|
end
|
data/test/cookie_logic_test.rb
CHANGED
@@ -136,85 +136,6 @@ describe CookieLogic do
|
|
136
136
|
domains_match('foo.com.', 'foo.com').should be_false
|
137
137
|
end
|
138
138
|
end
|
139
|
-
describe '.validate_cookie' do
|
140
|
-
localaddr = 'http://localhost/foo/bar/'
|
141
|
-
it "should fail if version unset" do
|
142
|
-
unversioned = Cookie.new localaddr, :name => 'foo', :value => 'bar', :version => nil
|
143
|
-
lambda do
|
144
|
-
validate_cookie localaddr, unversioned
|
145
|
-
end.should raise_error InvalidCookieError
|
146
|
-
end
|
147
|
-
it "should fail if the path is more specific" do
|
148
|
-
subdirred = Cookie.new localaddr, :name => 'foo', :value => 'bar', :version => 0, :path => '/foo/bar/baz'
|
149
|
-
lambda do
|
150
|
-
validate_cookie localaddr, subdirred
|
151
|
-
end.should raise_error InvalidCookieError
|
152
|
-
end
|
153
|
-
it "should fail if the path is different than the request" do
|
154
|
-
difdirred = Cookie.new localaddr, :name => 'foo', :value => 'bar', :version => 0, :path => '/baz/'
|
155
|
-
lambda do
|
156
|
-
validate_cookie localaddr, difdirred
|
157
|
-
end.should raise_error InvalidCookieError
|
158
|
-
end
|
159
|
-
it "should fail if the domain has no dots" do
|
160
|
-
nodot = Cookie.new 'http://zero/', :name => 'foo', :value => 'bar', :version => 0, :domain => 'zero'
|
161
|
-
lambda do
|
162
|
-
validate_cookie 'http://zero/', nodot
|
163
|
-
end.should raise_error InvalidCookieError
|
164
|
-
end
|
165
|
-
it "should fail for explicit localhost" do
|
166
|
-
localhost = Cookie.new localaddr, :name => 'foo', :value => 'bar', :version => 0, :domain => 'localhost'
|
167
|
-
lambda do
|
168
|
-
validate_cookie localaddr, localhost
|
169
|
-
end.should raise_error InvalidCookieError
|
170
|
-
end
|
171
|
-
it "should fail for mismatched domains" do
|
172
|
-
foobar = Cookie.new 'http://www.foo.com/', :name => 'foo', :value => 'bar', :version => 0, :domain => 'bar.com'
|
173
|
-
lambda do
|
174
|
-
validate_cookie 'http://www.foo.com/', foobar
|
175
|
-
end.should raise_error InvalidCookieError
|
176
|
-
end
|
177
|
-
it "should fail for domains more than one level up" do
|
178
|
-
xyz = Cookie.new 'http://x.y.z.com/', :name => 'foo', :value => 'bar', :version => 0, :domain => 'z.com'
|
179
|
-
lambda do
|
180
|
-
validate_cookie 'http://x.y.z.com/', xyz
|
181
|
-
end.should raise_error InvalidCookieError
|
182
|
-
end
|
183
|
-
it "should fail for setting subdomain cookies" do
|
184
|
-
subdomain = Cookie.new 'http://foo.com/', :name => 'foo', :value => 'bar', :version => 0, :domain => 'auth.foo.com'
|
185
|
-
lambda do
|
186
|
-
validate_cookie 'http://foo.com/', subdomain
|
187
|
-
end.should raise_error InvalidCookieError
|
188
|
-
end
|
189
|
-
it "should handle a normal implicit internet cookie" do
|
190
|
-
normal = Cookie.new 'http://foo.com/', :name => 'foo', :value => 'bar', :version => 0
|
191
|
-
validate_cookie('http://foo.com/', normal).should be_true
|
192
|
-
end
|
193
|
-
it "should handle a normal implicit localhost cookie" do
|
194
|
-
localhost = Cookie.new 'http://localhost/', :name => 'foo', :value => 'bar', :version => 0
|
195
|
-
validate_cookie('http://localhost/', localhost).should be_true
|
196
|
-
end
|
197
|
-
it "should handle an implicit IP address cookie" do
|
198
|
-
ipaddr = Cookie.new 'http://127.0.0.1/', :name => 'foo', :value => 'bar', :version => 0
|
199
|
-
validate_cookie('http://127.0.0.1/', ipaddr).should be_true
|
200
|
-
end
|
201
|
-
it "should handle an explicit domain on an internet site" do
|
202
|
-
explicit = Cookie.new 'http://foo.com/', :name => 'foo', :value => 'bar', :version => 0, :domain => '.foo.com'
|
203
|
-
validate_cookie('http://foo.com/', explicit).should be_true
|
204
|
-
end
|
205
|
-
it "should handle setting a cookie explicitly on a superdomain" do
|
206
|
-
superdomain = Cookie.new 'http://auth.foo.com/', :name => 'foo', :value => 'bar', :version => 0, :domain => '.foo.com'
|
207
|
-
validate_cookie('http://foo.com/', superdomain).should be_true
|
208
|
-
end
|
209
|
-
it "should handle explicitly setting a cookie" do
|
210
|
-
explicit = Cookie.new 'http://foo.com/bar/', :name => 'foo', :value => 'bar', :version => 0, :path => '/bar/'
|
211
|
-
validate_cookie('http://foo.com/bar/', explicit)
|
212
|
-
end
|
213
|
-
it "should handle setting a cookie on a higher path" do
|
214
|
-
higher = Cookie.new 'http://foo.com/bar/baz/', :name => 'foo', :value => 'bar', :version => 0, :path => '/bar/'
|
215
|
-
validate_cookie('http://foo.com/bar/baz/', higher)
|
216
|
-
end
|
217
|
-
end
|
218
139
|
describe '.compute_search_domains' do
|
219
140
|
it "should handle subdomains" do
|
220
141
|
compute_search_domains('http://www.auth.foo.com/').should ==
|
data/test/cookie_test.rb
CHANGED
@@ -1,18 +1,29 @@
|
|
1
1
|
require 'cookiejar'
|
2
|
+
require 'cookiejar/cookie_logic'
|
3
|
+
|
2
4
|
include CookieJar
|
5
|
+
include CookieLogic
|
3
6
|
|
7
|
+
FOO_URL = 'http://localhost/foo'
|
8
|
+
AMMO_URL = 'http://localhost/ammo'
|
4
9
|
NETSCAPE_SPEC_SET_COOKIE_HEADERS =
|
5
|
-
['CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT',
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
[['CUSTOMER=WILE_E_COYOTE; path=/; expires=Wednesday, 09-Nov-99 23:12:40 GMT',
|
11
|
+
FOO_URL],
|
12
|
+
['PART_NUMBER=ROCKET_LAUNCHER_0001; path=/',
|
13
|
+
FOO_URL],
|
14
|
+
['SHIPPING=FEDEX; path=/foo',
|
15
|
+
FOO_URL],
|
16
|
+
['PART_NUMBER=ROCKET_LAUNCHER_0001; path=/',
|
17
|
+
FOO_URL],
|
18
|
+
['PART_NUMBER=RIDING_ROCKET_0023; path=/ammo',
|
19
|
+
AMMO_URL]]
|
10
20
|
|
11
21
|
describe Cookie do
|
12
22
|
describe "#from_set_cookie" do
|
13
23
|
it "should handle cookies from the netscape spec" do
|
14
|
-
NETSCAPE_SPEC_SET_COOKIE_HEADERS.each do |
|
15
|
-
|
24
|
+
NETSCAPE_SPEC_SET_COOKIE_HEADERS.each do |value|
|
25
|
+
header, url = *value
|
26
|
+
cookie = Cookie.from_set_cookie url, header
|
16
27
|
end
|
17
28
|
end
|
18
29
|
it "should give back the input names and values" do
|
@@ -21,4 +32,84 @@ describe Cookie do
|
|
21
32
|
cookie.value.should == 'bar'
|
22
33
|
end
|
23
34
|
end
|
35
|
+
describe '.validate_cookie' do
|
36
|
+
localaddr = 'http://localhost/foo/bar/'
|
37
|
+
it "should fail if version unset" do
|
38
|
+
lambda do
|
39
|
+
unversioned = Cookie.from_set_cookie localaddr, 'foo=bar'
|
40
|
+
unversioned.instance_variable_set :@version, nil
|
41
|
+
Cookie.validate_cookie localaddr, unversioned
|
42
|
+
end.should raise_error InvalidCookieError
|
43
|
+
end
|
44
|
+
it "should fail if the path is more specific" do
|
45
|
+
lambda do
|
46
|
+
subdirred = Cookie.from_set_cookie localaddr, 'foo=bar;path=/foo/bar/baz'
|
47
|
+
# validate_cookie localaddr, subdirred
|
48
|
+
end.should raise_error InvalidCookieError
|
49
|
+
end
|
50
|
+
it "should fail if the path is different than the request" do
|
51
|
+
lambda do
|
52
|
+
difdirred = Cookie.from_set_cookie localaddr, 'foo=bar;path=/baz/'
|
53
|
+
# validate_cookie localaddr, difdirred
|
54
|
+
end.should raise_error InvalidCookieError
|
55
|
+
end
|
56
|
+
it "should fail if the domain has no dots" do
|
57
|
+
lambda do
|
58
|
+
nodot = Cookie.from_set_cookie 'http://zero/', 'foo=bar;domain=zero'
|
59
|
+
# validate_cookie 'http://zero/', nodot
|
60
|
+
end.should raise_error InvalidCookieError
|
61
|
+
end
|
62
|
+
it "should fail for explicit localhost" do
|
63
|
+
lambda do
|
64
|
+
localhost = Cookie.from_set_cookie localaddr, 'foo=bar;domain=localhost'
|
65
|
+
# validate_cookie localaddr, localhost
|
66
|
+
end.should raise_error InvalidCookieError
|
67
|
+
end
|
68
|
+
it "should fail for mismatched domains" do
|
69
|
+
lambda do
|
70
|
+
foobar = Cookie.from_set_cookie 'http://www.foo.com/', 'foo=bar;domain=bar.com'
|
71
|
+
# validate_cookie 'http://www.foo.com/', foobar
|
72
|
+
end.should raise_error InvalidCookieError
|
73
|
+
end
|
74
|
+
it "should fail for domains more than one level up" do
|
75
|
+
lambda do
|
76
|
+
xyz = Cookie.from_set_cookie 'http://x.y.z.com/', 'foo=bar;domain=z.com'
|
77
|
+
# validate_cookie 'http://x.y.z.com/', xyz
|
78
|
+
end.should raise_error InvalidCookieError
|
79
|
+
end
|
80
|
+
it "should fail for setting subdomain cookies" do
|
81
|
+
lambda do
|
82
|
+
subdomain = Cookie.from_set_cookie 'http://foo.com/', 'foo=bar;domain=auth.foo.com'
|
83
|
+
# validate_cookie 'http://foo.com/', subdomain
|
84
|
+
end.should raise_error InvalidCookieError
|
85
|
+
end
|
86
|
+
it "should handle a normal implicit internet cookie" do
|
87
|
+
normal = Cookie.from_set_cookie 'http://foo.com/', 'foo=bar'
|
88
|
+
Cookie.validate_cookie('http://foo.com/', normal).should be_true
|
89
|
+
end
|
90
|
+
it "should handle a normal implicit localhost cookie" do
|
91
|
+
localhost = Cookie.from_set_cookie 'http://localhost/', 'foo=bar'
|
92
|
+
Cookie.validate_cookie('http://localhost/', localhost).should be_true
|
93
|
+
end
|
94
|
+
it "should handle an implicit IP address cookie" do
|
95
|
+
ipaddr = Cookie.from_set_cookie 'http://127.0.0.1/', 'foo=bar'
|
96
|
+
Cookie.validate_cookie('http://127.0.0.1/', ipaddr).should be_true
|
97
|
+
end
|
98
|
+
it "should handle an explicit domain on an internet site" do
|
99
|
+
explicit = Cookie.from_set_cookie 'http://foo.com/', 'foo=bar;domain=.foo.com'
|
100
|
+
Cookie.validate_cookie('http://foo.com/', explicit).should be_true
|
101
|
+
end
|
102
|
+
it "should handle setting a cookie explicitly on a superdomain" do
|
103
|
+
superdomain = Cookie.from_set_cookie 'http://auth.foo.com/', 'foo=bar;domain=.foo.com'
|
104
|
+
Cookie.validate_cookie('http://foo.com/', superdomain).should be_true
|
105
|
+
end
|
106
|
+
it "should handle explicitly setting a cookie" do
|
107
|
+
explicit = Cookie.from_set_cookie 'http://foo.com/bar/', 'foo=bar;path=/bar/'
|
108
|
+
Cookie.validate_cookie('http://foo.com/bar/', explicit)
|
109
|
+
end
|
110
|
+
it "should handle setting a cookie on a higher path" do
|
111
|
+
higher = Cookie.from_set_cookie 'http://foo.com/bar/baz/', 'foo=bar;path=/bar/'
|
112
|
+
Cookie.validate_cookie('http://foo.com/bar/baz/', higher)
|
113
|
+
end
|
114
|
+
end
|
24
115
|
end
|
data/test/jar_test.rb
CHANGED
@@ -39,6 +39,13 @@ describe Jar do
|
|
39
39
|
cookies[2].name.should == 'c'
|
40
40
|
cookies[3].name.should == 'd'
|
41
41
|
end
|
42
|
+
it "should not return expired cookies" do
|
43
|
+
jar = Jar.new
|
44
|
+
uri = 'http://localhost/'
|
45
|
+
jar.set_cookie uri, 'foo=bar;expires=Wednesday, 09-Nov-99 23:12:40 GMT'
|
46
|
+
cookies = jar.get_cookies(uri)
|
47
|
+
cookies.should have(0).items
|
48
|
+
end
|
42
49
|
end
|
43
50
|
describe '.get_cookie_headers' do
|
44
51
|
it "should return cookie headers" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dwaite-cookiejar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Waite
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-09-
|
12
|
+
date: 2009-09-10 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|