http-cookie 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +28 -0
- data/http-cookie.gemspec +2 -2
- data/lib/http/cookie.rb +8 -5
- data/lib/http/cookie/version.rb +1 -1
- data/lib/http/cookie_jar.rb +49 -26
- data/test/test_http_cookie.rb +13 -0
- data/test/test_http_cookie_jar.rb +13 -12
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e01904534ca62610f72b5aba64d20f403ef41334
|
4
|
+
data.tar.gz: b7194473dbb2106fc6fea76fc8077135721518a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11de16cdf76a561e3dfcf5af1fcc78d6231a352cba9460fed867b4a6a4548dd71b6615c75eb70507599f23906877c05e878b1ed1b5abb33ddcf3410cf5d2794e
|
7
|
+
data.tar.gz: 9cd258c417a7f5f80a5b718a6f4c3b1a59086c871ae62500b3809fce95bbd57a75e45dd9d11deced0052996fa12e32769aae9f7547f82efbab4d1f1a4a2c68a7
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
## 1.0.1 (2013-04-21)
|
2
|
+
|
3
|
+
- Minor error handling improvements and documentation updates.
|
4
|
+
|
5
|
+
- Argument error regarding specifying store/saver classes no longer
|
6
|
+
raises IndexError, but either ArgumentError or TypeError.
|
7
|
+
|
8
|
+
## 1.0.0 (2013-04-17)
|
9
|
+
|
10
|
+
- Initial Release.
|
data/README.md
CHANGED
@@ -8,6 +8,34 @@ It was originally a part of the
|
|
8
8
|
separated as an independent library in the hope of serving as a common
|
9
9
|
component that is reusable from any HTTP related piece of software.
|
10
10
|
|
11
|
+
The following is an incomplete list of its features:
|
12
|
+
|
13
|
+
* Its behavior is highly compatible with that of today's major web
|
14
|
+
browsers.
|
15
|
+
|
16
|
+
* It is based on and conforms to RFC 6265 (the latest standard for the
|
17
|
+
HTTP cookie mechanism) to a high extent, with real world conventions
|
18
|
+
deeply in mind.
|
19
|
+
|
20
|
+
* It takes eTLD (effective TLD, also known as "Public Suffix") into
|
21
|
+
account just as major browsers do, to reject cookies with an eTLD
|
22
|
+
domain like "org", "co.jp", or "appspot.com". This feature is
|
23
|
+
brought to you by the domain_name gem.
|
24
|
+
|
25
|
+
* The number of cookies and the size are properly capped so that a
|
26
|
+
cookie store does not get flooded.
|
27
|
+
|
28
|
+
* It supports the legacy Netscape cookies.txt format for
|
29
|
+
serialization, maximizing the interoperability with other
|
30
|
+
implementations.
|
31
|
+
|
32
|
+
* It supports the cookies.sqlite format adopted by Mozilla Firefox for
|
33
|
+
backend store database which can be shared among multiple program
|
34
|
+
instances.
|
35
|
+
|
36
|
+
* It is relatively easy to add a new serialization format or a backend
|
37
|
+
store because of its modular API.
|
38
|
+
|
11
39
|
## Installation
|
12
40
|
|
13
41
|
Add this line to your application's `Gemfile`:
|
data/http-cookie.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |gem|
|
|
13
13
|
'Mike Dalessio' => 'mike.dalessio@gmail.com',
|
14
14
|
}.instance_eval { [keys, values] }
|
15
15
|
|
16
|
-
gem.description = %q{
|
17
|
-
gem.summary = %q{A Ruby library to handle HTTP Cookies}
|
16
|
+
gem.description = %q{HTTP::Cookie is a Ruby library to handle HTTP Cookies based on RFC 6265. It has with security, standards compliance and compatibility in mind, to behave just the same as today's major web browsers. It has builtin support for the legacy cookies.txt and the latest cookies.sqlite formats of Mozilla Firefox, and its modular API makes it easy to add support for a new backend store.}
|
17
|
+
gem.summary = %q{A Ruby library to handle HTTP Cookies based on RFC 6265}
|
18
18
|
gem.homepage = "https://github.com/sparklemotion/http-cookie"
|
19
19
|
|
20
20
|
gem.files = `git ls-files`.split($/)
|
data/lib/http/cookie.rb
CHANGED
@@ -174,7 +174,7 @@ class HTTP::Cookie
|
|
174
174
|
# Let max_age take precedence over expires
|
175
175
|
max_age = val
|
176
176
|
when :expires, :expires_at
|
177
|
-
self.expires = val
|
177
|
+
self.expires = val unless max_age
|
178
178
|
when :httponly, :httponly?
|
179
179
|
@httponly = val
|
180
180
|
when :secure, :secure?
|
@@ -288,7 +288,9 @@ class HTTP::Cookie
|
|
288
288
|
case aname
|
289
289
|
when 'domain'
|
290
290
|
cookie.for_domain = true
|
291
|
-
|
291
|
+
# The following may negate @for_domain if the value is
|
292
|
+
# an eTLD or IP address, hence this order.
|
293
|
+
cookie.domain = avalue
|
292
294
|
when 'path'
|
293
295
|
cookie.path = avalue
|
294
296
|
when 'expires'
|
@@ -447,6 +449,7 @@ class HTTP::Cookie
|
|
447
449
|
return origin if origin == @origin
|
448
450
|
@origin.nil? or
|
449
451
|
raise ArgumentError, "origin cannot be changed once it is set"
|
452
|
+
# Delay setting @origin because #domain= or #path= may fail
|
450
453
|
origin = URI(origin)
|
451
454
|
if URI::HTTP === origin
|
452
455
|
self.domain ||= origin.host
|
@@ -497,7 +500,6 @@ class HTTP::Cookie
|
|
497
500
|
|
498
501
|
# See #max_age.
|
499
502
|
def max_age= sec
|
500
|
-
@expires = nil
|
501
503
|
case sec
|
502
504
|
when Integer, nil
|
503
505
|
else
|
@@ -507,6 +509,7 @@ class HTTP::Cookie
|
|
507
509
|
raise ArgumentError, "invalid Max-Age: #{sec.inspect}"
|
508
510
|
sec = str.to_i
|
509
511
|
end
|
512
|
+
@expires = nil
|
510
513
|
if @session = sec.nil?
|
511
514
|
@max_age = nil
|
512
515
|
else
|
@@ -600,7 +603,7 @@ class HTTP::Cookie
|
|
600
603
|
if @domain
|
601
604
|
string << "; Domain=#{@domain}"
|
602
605
|
else
|
603
|
-
raise "for_domain is specified but domain is
|
606
|
+
raise "for_domain is specified but domain is unknown"
|
604
607
|
end
|
605
608
|
end
|
606
609
|
if @path
|
@@ -608,7 +611,7 @@ class HTTP::Cookie
|
|
608
611
|
string << "; Path=#{@path}"
|
609
612
|
end
|
610
613
|
else
|
611
|
-
raise "path is
|
614
|
+
raise "path is unknown"
|
612
615
|
end
|
613
616
|
if @max_age
|
614
617
|
string << "; Max-Age=#{@max_age}"
|
data/lib/http/cookie/version.rb
CHANGED
data/lib/http/cookie_jar.rb
CHANGED
@@ -29,16 +29,38 @@ class HTTP::CookieJar
|
|
29
29
|
|
30
30
|
attr_reader :store
|
31
31
|
|
32
|
+
def get_impl(base, value, *args)
|
33
|
+
case value
|
34
|
+
when base
|
35
|
+
value
|
36
|
+
when Symbol
|
37
|
+
begin
|
38
|
+
base.implementation(value).new(*args)
|
39
|
+
rescue IndexError => e
|
40
|
+
raise ArgumentError, e.message
|
41
|
+
end
|
42
|
+
when Class
|
43
|
+
if base >= value
|
44
|
+
value.new(*args)
|
45
|
+
else
|
46
|
+
raise TypeError, 'not a subclass of %s: %s' % [base, value]
|
47
|
+
end
|
48
|
+
else
|
49
|
+
raise TypeError, 'invalid object: %s' % value.inspect
|
50
|
+
end
|
51
|
+
end
|
52
|
+
private :get_impl
|
53
|
+
|
32
54
|
# Generates a new cookie jar.
|
33
55
|
#
|
34
56
|
# Available option keywords are as below:
|
35
57
|
#
|
36
58
|
# :store
|
37
59
|
# : The store class that backs this jar. (default: `:hash`)
|
38
|
-
# A symbol
|
39
|
-
#
|
40
|
-
# HTTP::CookieJar::HashStore and `:mozilla`
|
41
|
-
# HTTP::CookieJar::MozillaStore.
|
60
|
+
# A symbol addressing a store class, a store class, or an instance
|
61
|
+
# of a store class is accepted. Symbols are mapped to store
|
62
|
+
# classes, like `:hash` to HTTP::CookieJar::HashStore and `:mozilla`
|
63
|
+
# to HTTP::CookieJar::MozillaStore.
|
42
64
|
#
|
43
65
|
# Any options given are passed through to the initializer of the
|
44
66
|
# specified store class. For example, the `:mozilla`
|
@@ -49,14 +71,7 @@ class HTTP::CookieJar
|
|
49
71
|
:store => :hash,
|
50
72
|
}
|
51
73
|
opthash.update(options) if options
|
52
|
-
|
53
|
-
when Symbol
|
54
|
-
@store = AbstractStore.implementation(store).new(opthash)
|
55
|
-
when AbstractStore
|
56
|
-
@store = store
|
57
|
-
else
|
58
|
-
raise TypeError, 'wrong object given as cookie store: %s' % store.inspect
|
59
|
-
end
|
74
|
+
@store = get_impl(AbstractStore, opthash[:store], opthash)
|
60
75
|
end
|
61
76
|
|
62
77
|
# The copy constructor. Not all backend store classes support cloning.
|
@@ -191,6 +206,10 @@ class HTTP::CookieJar
|
|
191
206
|
#
|
192
207
|
# * `:format`
|
193
208
|
#
|
209
|
+
# Specifies the format for saving. A saver class, a symbol
|
210
|
+
# addressing a saver class, or a pre-generated instance of a
|
211
|
+
# saver class is accepted.
|
212
|
+
#
|
194
213
|
# <dl class="rdoc-list note-list">
|
195
214
|
# <dt>:yaml</dt>
|
196
215
|
# <dd>YAML structure (default)</dd>
|
@@ -221,20 +240,20 @@ class HTTP::CookieJar
|
|
221
240
|
when Symbol
|
222
241
|
opthash[:format] = options
|
223
242
|
else
|
224
|
-
|
243
|
+
if hash = Hash.try_convert(options)
|
244
|
+
opthash.update(hash)
|
245
|
+
end
|
225
246
|
end
|
226
247
|
when 2
|
227
248
|
opthash[:format], options = options
|
228
|
-
|
249
|
+
if hash = Hash.try_convert(options)
|
250
|
+
opthash.update(hash)
|
251
|
+
end
|
229
252
|
else
|
230
253
|
raise ArgumentError, 'wrong number of arguments (%d for 1-3)' % (1 + options.size)
|
231
254
|
end
|
232
255
|
|
233
|
-
|
234
|
-
saver = AbstractSaver.implementation(opthash[:format]).new(opthash)
|
235
|
-
rescue IndexError => e
|
236
|
-
raise ArgumentError, e.message
|
237
|
-
end
|
256
|
+
saver = get_impl(AbstractSaver, opthash[:format], opthash)
|
238
257
|
|
239
258
|
if writable.respond_to?(:write)
|
240
259
|
saver.save(writable, self)
|
@@ -259,6 +278,10 @@ class HTTP::CookieJar
|
|
259
278
|
#
|
260
279
|
# * `:format`
|
261
280
|
#
|
281
|
+
# Specifies the format for loading. A saver class, a symbol
|
282
|
+
# addressing a saver class, or a pre-generated instance of a
|
283
|
+
# saver class is accepted.
|
284
|
+
#
|
262
285
|
# <dl class="rdoc-list note-list">
|
263
286
|
# <dt>:yaml</dt>
|
264
287
|
# <dd>YAML structure (default)</dd>
|
@@ -280,20 +303,20 @@ class HTTP::CookieJar
|
|
280
303
|
when Symbol
|
281
304
|
opthash[:format] = options
|
282
305
|
else
|
283
|
-
|
306
|
+
if hash = Hash.try_convert(options)
|
307
|
+
opthash.update(hash)
|
308
|
+
end
|
284
309
|
end
|
285
310
|
when 2
|
286
311
|
opthash[:format], options = options
|
287
|
-
|
312
|
+
if hash = Hash.try_convert(options)
|
313
|
+
opthash.update(hash)
|
314
|
+
end
|
288
315
|
else
|
289
316
|
raise ArgumentError, 'wrong number of arguments (%d for 1-3)' % (1 + options.size)
|
290
317
|
end
|
291
318
|
|
292
|
-
|
293
|
-
saver = AbstractSaver.implementation(opthash[:format]).new(opthash)
|
294
|
-
rescue IndexError => e
|
295
|
-
raise ArgumentError, e.message
|
296
|
-
end
|
319
|
+
saver = get_impl(AbstractSaver, opthash[:format], opthash)
|
297
320
|
|
298
321
|
if readable.respond_to?(:write)
|
299
322
|
saver.load(readable, self)
|
data/test/test_http_cookie.rb
CHANGED
@@ -692,19 +692,32 @@ class TestHTTPCookie < Test::Unit::TestCase
|
|
692
692
|
|
693
693
|
def test_max_age=
|
694
694
|
cookie = HTTP::Cookie.new(cookie_values)
|
695
|
+
expires = cookie.expires
|
695
696
|
|
696
697
|
assert_raises(ArgumentError) {
|
697
698
|
cookie.max_age = "+1"
|
698
699
|
}
|
700
|
+
# make sure #expires is not destroyed
|
701
|
+
assert_equal expires, cookie.expires
|
702
|
+
|
699
703
|
assert_raises(ArgumentError) {
|
700
704
|
cookie.max_age = "1.5"
|
701
705
|
}
|
706
|
+
# make sure #expires is not destroyed
|
707
|
+
assert_equal expires, cookie.expires
|
708
|
+
|
702
709
|
assert_raises(ArgumentError) {
|
703
710
|
cookie.max_age = "1 day"
|
704
711
|
}
|
712
|
+
# make sure #expires is not destroyed
|
713
|
+
assert_equal expires, cookie.expires
|
714
|
+
|
705
715
|
assert_raises(TypeError) {
|
706
716
|
cookie.max_age = [1]
|
707
717
|
}
|
718
|
+
# make sure #expires is not destroyed
|
719
|
+
assert_equal expires, cookie.expires
|
720
|
+
|
708
721
|
cookie.max_age = "12"
|
709
722
|
assert_equal 12, cookie.max_age
|
710
723
|
|
@@ -355,14 +355,6 @@ module TestHTTPCookieJar
|
|
355
355
|
assert_equal(0, @jar.cookies(url).length)
|
356
356
|
end
|
357
357
|
|
358
|
-
def test_save_nonexistent_saver
|
359
|
-
Dir.mktmpdir { |dir|
|
360
|
-
assert_raises(ArgumentError) {
|
361
|
-
@jar.save(File.join(dir, "file"), :nonexistent)
|
362
|
-
}
|
363
|
-
}
|
364
|
-
end
|
365
|
-
|
366
358
|
def test_save_cookies_yaml
|
367
359
|
url = URI 'http://rubyforge.org/'
|
368
360
|
|
@@ -403,12 +395,18 @@ module TestHTTPCookieJar
|
|
403
395
|
@jar.save(filename, :format => :cookiestxt)
|
404
396
|
@jar.save(filename, :cookiestxt, :session => true)
|
405
397
|
@jar.save(filename, :cookiestxt)
|
398
|
+
@jar.save(filename, HTTP::CookieJar::CookiestxtSaver)
|
399
|
+
@jar.save(filename, HTTP::CookieJar::CookiestxtSaver.new)
|
406
400
|
@jar.save(filename, :session => true)
|
407
401
|
@jar.save(filename)
|
402
|
+
|
408
403
|
assert_raises(ArgumentError) {
|
409
404
|
@jar.save()
|
410
405
|
}
|
411
406
|
assert_raises(ArgumentError) {
|
407
|
+
@jar.save(filename, :nonexistent)
|
408
|
+
}
|
409
|
+
assert_raises(TypeError) {
|
412
410
|
@jar.save(filename, { :format => :cookiestxt }, { :session => true })
|
413
411
|
}
|
414
412
|
assert_raises(ArgumentError) {
|
@@ -418,6 +416,8 @@ module TestHTTPCookieJar
|
|
418
416
|
@jar.load(filename, :format => :cookiestxt, :linefeed => "\n")
|
419
417
|
@jar.load(filename, :format => :cookiestxt, :linefeed => "\n")
|
420
418
|
@jar.load(filename, :format => :cookiestxt)
|
419
|
+
@jar.load(filename, HTTP::CookieJar::CookiestxtSaver)
|
420
|
+
@jar.load(filename, HTTP::CookieJar::CookiestxtSaver.new)
|
421
421
|
@jar.load(filename, :cookiestxt, :linefeed => "\n")
|
422
422
|
@jar.load(filename, :cookiestxt)
|
423
423
|
@jar.load(filename, :linefeed => "\n")
|
@@ -426,6 +426,9 @@ module TestHTTPCookieJar
|
|
426
426
|
@jar.load()
|
427
427
|
}
|
428
428
|
assert_raises(ArgumentError) {
|
429
|
+
@jar.load(filename, :nonexistent)
|
430
|
+
}
|
431
|
+
assert_raises(TypeError) {
|
429
432
|
@jar.load(filename, { :format => :cookiestxt }, { :linefeed => "\n" })
|
430
433
|
}
|
431
434
|
assert_raises(ArgumentError) {
|
@@ -850,16 +853,14 @@ module TestHTTPCookieJar
|
|
850
853
|
jar = HTTP::CookieJar.new(:store => :hash)
|
851
854
|
assert_instance_of HTTP::CookieJar::HashStore, jar.store
|
852
855
|
|
853
|
-
assert_raises(
|
856
|
+
assert_raises(ArgumentError) {
|
854
857
|
jar = HTTP::CookieJar.new(:store => :nonexistent)
|
855
858
|
}
|
856
859
|
|
857
860
|
jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore.new)
|
858
861
|
assert_instance_of HTTP::CookieJar::HashStore, jar.store
|
859
862
|
|
860
|
-
|
861
|
-
jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore)
|
862
|
-
}
|
863
|
+
jar = HTTP::CookieJar.new(:store => HTTP::CookieJar::HashStore)
|
863
864
|
end
|
864
865
|
|
865
866
|
def test_clone
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http-cookie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Akinori MUSHA
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-04-
|
14
|
+
date: 2013-04-21 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: domain_name
|
@@ -111,7 +111,11 @@ dependencies:
|
|
111
111
|
- - '>='
|
112
112
|
- !ruby/object:Gem::Version
|
113
113
|
version: '0'
|
114
|
-
description:
|
114
|
+
description: HTTP::Cookie is a Ruby library to handle HTTP Cookies based on RFC 6265. It
|
115
|
+
has with security, standards compliance and compatibility in mind, to behave just
|
116
|
+
the same as today's major web browsers. It has builtin support for the legacy cookies.txt
|
117
|
+
and the latest cookies.sqlite formats of Mozilla Firefox, and its modular API makes
|
118
|
+
it easy to add support for a new backend store.
|
115
119
|
email:
|
116
120
|
- knu@idaemons.org
|
117
121
|
- aaronp@rubyforge.org
|
@@ -125,6 +129,7 @@ extra_rdoc_files:
|
|
125
129
|
files:
|
126
130
|
- .gitignore
|
127
131
|
- .travis.yml
|
132
|
+
- CHANGELOG.md
|
128
133
|
- Gemfile
|
129
134
|
- LICENSE.txt
|
130
135
|
- README.md
|
@@ -169,7 +174,7 @@ rubyforge_project:
|
|
169
174
|
rubygems_version: 2.0.3
|
170
175
|
signing_key:
|
171
176
|
specification_version: 4
|
172
|
-
summary: A Ruby library to handle HTTP Cookies
|
177
|
+
summary: A Ruby library to handle HTTP Cookies based on RFC 6265
|
173
178
|
test_files:
|
174
179
|
- test/helper.rb
|
175
180
|
- test/mechanize.yml
|