dwaite-cookiejar 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|