httpclient 2.3.0.1 → 2.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +85 -0
  3. data/bin/httpclient +18 -6
  4. data/bin/jsonclient +85 -0
  5. data/lib/http-access2.rb +1 -1
  6. data/lib/httpclient.rb +262 -88
  7. data/lib/httpclient/auth.rb +269 -244
  8. data/lib/httpclient/cacert.pem +3952 -0
  9. data/lib/httpclient/cacert1024.pem +3866 -0
  10. data/lib/httpclient/connection.rb +1 -1
  11. data/lib/httpclient/cookie.rb +161 -514
  12. data/lib/httpclient/http.rb +57 -21
  13. data/lib/httpclient/include_client.rb +2 -0
  14. data/lib/httpclient/jruby_ssl_socket.rb +588 -0
  15. data/lib/httpclient/session.rb +259 -317
  16. data/lib/httpclient/ssl_config.rb +141 -188
  17. data/lib/httpclient/ssl_socket.rb +150 -0
  18. data/lib/httpclient/timeout.rb +1 -1
  19. data/lib/httpclient/util.rb +62 -1
  20. data/lib/httpclient/version.rb +1 -1
  21. data/lib/httpclient/webagent-cookie.rb +459 -0
  22. data/lib/jsonclient.rb +63 -0
  23. data/lib/oauthclient.rb +2 -1
  24. data/sample/jsonclient.rb +67 -0
  25. data/sample/oauth_twitter.rb +4 -4
  26. data/test/{ca-chain.cert → ca-chain.pem} +0 -0
  27. data/test/client-pass.key +18 -0
  28. data/test/helper.rb +10 -8
  29. data/test/jruby_ssl_socket/test_pemutils.rb +32 -0
  30. data/test/test_auth.rb +175 -4
  31. data/test/test_cookie.rb +147 -243
  32. data/test/test_http-access2.rb +17 -16
  33. data/test/test_httpclient.rb +458 -77
  34. data/test/test_jsonclient.rb +80 -0
  35. data/test/test_ssl.rb +341 -17
  36. data/test/test_webagent-cookie.rb +465 -0
  37. metadata +57 -55
  38. data/README.txt +0 -721
  39. data/lib/httpclient/cacert.p7s +0 -1858
  40. data/lib/httpclient/cacert_sha1.p7s +0 -1858
  41. data/sample/oauth_salesforce_10.rb +0 -63
@@ -0,0 +1,465 @@
1
+ require 'test/unit'
2
+ require 'uri'
3
+ require 'tempfile'
4
+
5
+ # This testcase is located for reference, not for running.
6
+ if false
7
+
8
+ require 'httpclient/webagent-cookie'
9
+
10
+ class TestCookie < Test::Unit::TestCase
11
+ include HTTPClient::Util
12
+
13
+ def setup()
14
+ @c = WebAgent::Cookie.new()
15
+ end
16
+
17
+ def test_s_new()
18
+ assert_instance_of(WebAgent::Cookie, @c)
19
+ end
20
+
21
+ def test_discard?
22
+ assert_equal(false, !!(@c.discard?))
23
+ @c.discard = true
24
+ assert_equal(true, !!(@c.discard?))
25
+ end
26
+
27
+ def test_match()
28
+ url = urify('http://www.rubycolor.org/hoge/funi/#919191')
29
+
30
+ @c.domain = 'www.rubycolor.org'
31
+ assert_equal(true, @c.match?(url))
32
+
33
+ @c.domain = '.rubycolor.org'
34
+ assert_equal(true, @c.match?(url))
35
+
36
+ @c.domain = 'aaa.www.rubycolor.org'
37
+ assert_equal(false, @c.match?(url))
38
+
39
+ @c.domain = 'aaa.www.rubycolor.org'
40
+ assert_equal(false, @c.match?(url))
41
+
42
+ @c.domain = 'www.rubycolor.org'
43
+ @c.path = '/'
44
+ assert_equal(true, @c.match?(url))
45
+
46
+ @c.domain = 'www.rubycolor.org'
47
+ @c.path = '/hoge'
48
+ assert_equal(true, @c.match?(url))
49
+
50
+ @c.domain = 'www.rubycolor.org'
51
+ @c.path = '/hoge/hoge'
52
+ assert_equal(false, @c.match?(url))
53
+
54
+ @c.domain = 'www.rubycolor.org'
55
+ @c.path = '/hoge'
56
+ @c.secure = true
57
+ assert_equal(false, @c.match?(url))
58
+
59
+ url2 = urify('https://www.rubycolor.org/hoge/funi/#919191')
60
+ @c.domain = 'www.rubycolor.org'
61
+ @c.path = '/hoge'
62
+ @c.secure = true
63
+ assert_equal(true, @c.match?(url2))
64
+
65
+ @c.domain = 'www.rubycolor.org'
66
+ @c.path = '/hoge'
67
+ @c.secure = nil
68
+ assert_equal(true, @c.match?(url2)) ## not false!
69
+
70
+ url.port = 80
71
+ @c.domain = 'www.rubycolor.org'
72
+ @c.path = '/hoge'
73
+ # @c.port = [80,8080]
74
+ assert_equal(true, @c.match?(url))
75
+
76
+ url_nopath = URI.parse('http://www.rubycolor.org')
77
+ @c.domain = 'www.rubycolor.org'
78
+ @c.path = '/'
79
+ assert_equal(true, @c.match?(url_nopath))
80
+
81
+ end
82
+
83
+ def test_head_match?()
84
+ assert_equal(true, @c.head_match?("",""))
85
+ assert_equal(false, @c.head_match?("a",""))
86
+ assert_equal(true, @c.head_match?("","a"))
87
+ assert_equal(true, @c.head_match?("abcde","abcde"))
88
+ assert_equal(true, @c.head_match?("abcde","abcdef"))
89
+ assert_equal(false, @c.head_match?("abcdef","abcde"))
90
+ assert_equal(false, @c.head_match?("abcde","bcde"))
91
+ assert_equal(false, @c.head_match?("bcde","abcde"))
92
+ end
93
+
94
+ def test_tail_match?()
95
+ assert_equal(true, @c.tail_match?("",""))
96
+ assert_equal(false, @c.tail_match?("a",""))
97
+ assert_equal(true, @c.tail_match?("","a"))
98
+ assert_equal(true, @c.tail_match?("abcde","abcde"))
99
+ assert_equal(false, @c.tail_match?("abcde","abcdef"))
100
+ assert_equal(false, @c.tail_match?("abcdef","abcde"))
101
+ assert_equal(false, @c.tail_match?("abcde","bcde"))
102
+ assert_equal(true, @c.tail_match?("bcde","abcde"))
103
+ end
104
+
105
+
106
+ def test_domain_match()
107
+ extend WebAgent::CookieUtils
108
+ assert_equal(true, !!domain_match("hoge.co.jp","."))
109
+ # assert_equal(true, !!domain_match("locahost",".local"))
110
+ assert_equal(true, !!domain_match("192.168.10.1","192.168.10.1"))
111
+ assert_equal(false, !!domain_match("192.168.10.1","192.168.10.2"))
112
+ # assert_equal(false, !!domain_match("hoge.co.jp",".hoge.co.jp"))
113
+ # allows; host == rubyforge.org, domain == .rubyforge.org
114
+ assert_equal(true, !!domain_match("hoge.co.jp",".hoge.co.jp"))
115
+ assert_equal(true, !!domain_match("www.hoge.co.jp", "www.hoge.co.jp"))
116
+ assert_equal(false, !!domain_match("www.hoge.co.jp", "www2.hoge.co.jp"))
117
+ assert_equal(true, !!domain_match("www.hoge.co.jp", ".hoge.co.jp"))
118
+ assert_equal(true, !!domain_match("www.aa.hoge.co.jp", ".hoge.co.jp"))
119
+ assert_equal(false, !!domain_match("www.hoge.co.jp", "hoge.co.jp"))
120
+ end
121
+
122
+ def test_join_quotedstr()
123
+ arr1 = ['hoge=funi', 'hoge2=funi2']
124
+ assert_equal(arr1, @c.instance_eval{join_quotedstr(arr1,';')})
125
+ arr2 = ['hoge="fu', 'ni"', 'funi=funi']
126
+ assert_equal(['hoge="fu;ni"','funi=funi'],
127
+ @c.instance_eval{join_quotedstr(arr2,';')})
128
+ arr3 = ['hoge="funi";hoge2="fu','ni2";hoge3="hoge"', 'funi="funi"']
129
+ assert_equal(['hoge="funi";hoge2="fu,ni2";hoge3="hoge"', 'funi="funi"'],
130
+ @c.instance_eval{join_quotedstr(arr3,',')})
131
+ end
132
+
133
+ end
134
+
135
+ class TestCookieManager < Test::Unit::TestCase
136
+ include HTTPClient::Util
137
+
138
+ def setup()
139
+ @cm = WebAgent::CookieManager.new()
140
+ end
141
+
142
+ def teardown()
143
+ end
144
+
145
+ def test_parse()
146
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; expires=Wed, 01-Dec-2010 00:00:00 GMT; path=/"
147
+ @cm.parse(str, urify('http://www.test.jp'))
148
+ cookie = @cm.cookies[0]
149
+ assert_instance_of(WebAgent::Cookie, cookie)
150
+ assert_equal("inkid", cookie.name)
151
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
152
+ assert_equal(Time.gm(2010, 12, 1, 0,0,0), cookie.expires)
153
+ assert_equal("/", cookie.path)
154
+ end
155
+
156
+ def test_parse2()
157
+ str = "xmen=off,0,0,1; path=/; domain=.excite.co.jp; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
158
+ @cm.parse(str, urify('http://www.excite.co.jp'))
159
+ cookie = @cm.cookies[0]
160
+ assert_instance_of(WebAgent::Cookie, cookie)
161
+ assert_equal("xmen", cookie.name)
162
+ assert_equal("off,0,0,1", cookie.value)
163
+ assert_equal("/", cookie.path)
164
+ assert_equal(".excite.co.jp", cookie.domain)
165
+ assert_equal(Time.gm(2037,12,31,12,0,0), cookie.expires)
166
+ end
167
+
168
+ def test_parse3()
169
+ str = "xmen=off,0,0,1; path=/; domain=.excite.co.jp; expires=Wednesday, 31-Dec-2037 12:00:00 GMT;Secure;HTTPOnly"
170
+ @cm.parse(str, urify('http://www.excite.co.jp'))
171
+ cookie = @cm.cookies[0]
172
+ assert_instance_of(WebAgent::Cookie, cookie)
173
+ assert_equal("xmen", cookie.name)
174
+ assert_equal("off,0,0,1", cookie.value)
175
+ assert_equal("/", cookie.path)
176
+ assert_equal(".excite.co.jp", cookie.domain)
177
+ assert_equal(Time.gm(2037,12,31,12,0,0), cookie.expires)
178
+ assert_equal(true, cookie.secure?)
179
+ assert_equal(true, cookie.http_only?)
180
+ end
181
+
182
+ def test_parse_double_semicolon()
183
+ str = "xmen=off,0,0,1;; path=\"/;;\"; domain=.excite.co.jp; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
184
+ @cm.parse(str, urify('http://www.excite.co.jp'))
185
+ cookie = @cm.cookies[0]
186
+ assert_instance_of(WebAgent::Cookie, cookie)
187
+ assert_equal("xmen", cookie.name)
188
+ assert_equal("off,0,0,1", cookie.value)
189
+ assert_equal("/;;", cookie.path)
190
+ assert_equal(".excite.co.jp", cookie.domain)
191
+ assert_equal(Time.gm(2037,12,31,12,0,0), cookie.expires)
192
+ end
193
+
194
+ # def test_make_portlist()
195
+ # assert_equal([80,8080], @cm.instance_eval{make_portlist("80,8080")})
196
+ # assert_equal([80], @cm.instance_eval{make_portlist("80")})
197
+ # assert_equal([80,8080,10080], @cm.instance_eval{make_portlist(" 80, 8080, 10080 \n")})
198
+ # end
199
+
200
+ def test_check_expired_cookies()
201
+ c1 = WebAgent::Cookie.new()
202
+ c2 = c1.dup
203
+ c3 = c1.dup
204
+ c4 = c1.dup
205
+ c1.expires = Time.now - 100
206
+ c2.expires = Time.now + 100
207
+ c3.expires = Time.now - 10
208
+ c4.expires = nil
209
+ cookies = [c1,c2,c3,c4]
210
+ @cm.cookies = cookies
211
+ @cm.check_expired_cookies()
212
+ # expires == nil cookies (session cookie) exists.
213
+ assert_equal([c2,c4], @cm.cookies)
214
+ end
215
+
216
+ def test_parse_expires
217
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; expires=; path=/"
218
+ @cm.parse(str, urify('http://www.test.jp'))
219
+ cookie = @cm.cookies[0]
220
+ assert_equal("inkid", cookie.name)
221
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
222
+ assert_equal(nil, cookie.expires)
223
+ assert_equal("/", cookie.path)
224
+ #
225
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; path=/; expires="
226
+ @cm.parse(str, urify('http://www.test.jp'))
227
+ cookie = @cm.cookies[0]
228
+ assert_equal("inkid", cookie.name)
229
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
230
+ assert_equal(nil, cookie.expires)
231
+ assert_equal("/", cookie.path)
232
+ #
233
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; path=/; expires=\"\""
234
+ @cm.parse(str, urify('http://www.test.jp'))
235
+ cookie = @cm.cookies[0]
236
+ assert_equal("inkid", cookie.name)
237
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
238
+ assert_equal(nil, cookie.expires)
239
+ assert_equal("/", cookie.path)
240
+ end
241
+
242
+ def test_parse_after_expiration
243
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; expires=Wed, 01-Dec-2010 00:00:00 GMT; path=/"
244
+ @cm.parse(str, urify('http://www.test.jp'))
245
+ cookie = @cm.cookies[0]
246
+ assert_instance_of(WebAgent::Cookie, cookie)
247
+ assert_equal("inkid", cookie.name)
248
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
249
+ assert_equal(Time.gm(2010, 12, 1, 0,0,0), cookie.expires)
250
+ assert_equal("/", cookie.path)
251
+
252
+ time = Time.at(Time.now.to_i + 60).utc
253
+ expires = time.strftime("%a, %d-%b-%Y %H:%M:%S GMT")
254
+ str = "inkid=n92b0ADOgACIgUb9lsjHqAAAHu2a; expires=#{expires}; path=/"
255
+ @cm.parse(str, urify('http://www.test.jp'))
256
+ cookie = @cm.cookies[0]
257
+ assert_equal("inkid", cookie.name)
258
+ assert_equal("n92b0ADOgACIgUb9lsjHqAAAHu2a", cookie.value)
259
+ assert_equal(time, cookie.expires)
260
+ assert_equal("/", cookie.path)
261
+ end
262
+
263
+ def test_find_cookie()
264
+ str = "xmen=off,0,0,1; path=/; domain=.excite2.co.jp; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
265
+ @cm.parse(str, urify("http://www.excite2.co.jp/"))
266
+
267
+ str = "xmen=off,0,0,2; path=/; domain=.excite.co.jp; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
268
+ @cm.parse(str, urify("http://www.excite.co.jp/"))
269
+
270
+ @cm.cookies[0].use = true
271
+ @cm.cookies[1].use = true
272
+
273
+ url = urify('http://www.excite.co.jp/hoge/funi/')
274
+ cookie_str = @cm.find(url)
275
+ assert_equal("xmen=off,0,0,2", cookie_str)
276
+ end
277
+
278
+ def test_load_cookies()
279
+ begin
280
+ File.open("tmp_test.tmp","w") {|f|
281
+ f.write <<EOF
282
+ http://www.zdnet.co.jp/news/0106/08/e_gibson.html NGUserID d29b8f49-10875-992421294-1 2145801600 www.zdnet.co.jp / 9 0
283
+ http://www.zdnet.co.jp/news/0106/08/e_gibson.html PACK zd3-992421294-7436 1293839999 .zdnet.co.jp / 13 0
284
+ http://example.org/ key value 0 .example.org / 13 0
285
+ http://example.org/ key value .example.org / 13 0
286
+ EOF
287
+ }
288
+
289
+ @cm.cookies_file = 'tmp_test.tmp'
290
+ @cm.load_cookies()
291
+ c0, c1, c2, c3 = @cm.cookies
292
+ assert_equal('http://www.zdnet.co.jp/news/0106/08/e_gibson.html', c0.url.to_s)
293
+ assert_equal('NGUserID', c0.name)
294
+ assert_equal('d29b8f49-10875-992421294-1', c0.value)
295
+ assert_equal(Time.at(2145801600), c0.expires)
296
+ assert_equal('www.zdnet.co.jp', c0.domain)
297
+ assert_equal('/', c0.path)
298
+ assert_equal(9, c0.flag)
299
+ #
300
+ assert_equal('http://www.zdnet.co.jp/news/0106/08/e_gibson.html', c1.url.to_s)
301
+ assert_equal('PACK', c1.name)
302
+ assert_equal('zd3-992421294-7436', c1.value)
303
+ assert_equal(Time.at(1293839999), c1.expires)
304
+ assert_equal('.zdnet.co.jp', c1.domain)
305
+ assert_equal('/', c1.path)
306
+ assert_equal(13, c1.flag)
307
+ #
308
+ assert_equal(nil, c2.expires)
309
+ assert_equal(nil, c3.expires) # allow empty 'expires' (should not happen)
310
+ ensure
311
+ File.unlink("tmp_test.tmp")
312
+ end
313
+ end
314
+
315
+ def test_save_cookie()
316
+ str = <<EOF
317
+ http://www.zdnet.co.jp/news/0106/08/e_gibson.html NGUserID d29b8f49-10875-992421294-1 2145801600 www.zdnet.co.jp / 9
318
+ http://www.zdnet.co.jp/news/0106/08/e_gibson.html PACK zd3-992421294-7436 2145801600 .zdnet.co.jp / 13
319
+ EOF
320
+ begin
321
+ File.open("tmp_test.tmp","w") {|f|
322
+ f.write str
323
+ }
324
+ @cm.cookies_file = 'tmp_test.tmp'
325
+ @cm.load_cookies()
326
+ @cm.instance_eval{@is_saved = false}
327
+ @cm.cookies_file = 'tmp_test2.tmp'
328
+ @cm.save_cookies()
329
+ str2 = ''
330
+ File.open("tmp_test2.tmp","r") {|f|
331
+ str2 = f.read()
332
+ }
333
+ assert_equal(str, str2)
334
+ #
335
+ assert(File.exist?('tmp_test2.tmp'))
336
+ File.unlink("tmp_test2.tmp")
337
+ @cm.save_cookies()
338
+ assert(!File.exist?('tmp_test2.tmp'))
339
+ @cm.save_cookies(true)
340
+ assert(File.exist?('tmp_test2.tmp'))
341
+ ensure
342
+ File.unlink("tmp_test.tmp")
343
+ if FileTest.exist?("tmp_test2.tmp")
344
+ File.unlink("tmp_test2.tmp")
345
+ end
346
+ end
347
+ end
348
+
349
+ def test_not_saved_expired_cookies
350
+ begin
351
+ @cm.cookies_file = 'tmp_test.tmp'
352
+ uri = urify('http://www.example.org')
353
+ @cm.parse("foo=1; path=/", uri)
354
+ @cm.parse("bar=2; path=/; expires=", uri)
355
+ @cm.parse("baz=3; path=/; expires=\"\"", uri)
356
+ @cm.parse("qux=4; path=/; expires=#{(Time.now + 10).asctime}", uri)
357
+ @cm.parse("quxx=5; path=/; expires=#{(Time.now - 10).asctime}", uri)
358
+ @cm.save_cookies()
359
+ @cm.load_cookies
360
+ assert_equal(1, @cm.cookies.size) # +10 cookies only
361
+ ensure
362
+ File.unlink("tmp_test.tmp") if File.exist?("tmp_test.tmp")
363
+ end
364
+ end
365
+
366
+ def test_add()
367
+ c = WebAgent::Cookie.new()
368
+ c.name = "hoge"
369
+ c.value = "funi"
370
+ c.url = urify("http://www.inac.co.jp/hoge")
371
+ @cm.add(c)
372
+ c = @cm.cookies[0]
373
+ assert_equal('hoge', c.name)
374
+ assert_equal('funi', c.value)
375
+ assert_equal(nil, c.expires)
376
+ end
377
+
378
+ def test_add2()
379
+ c = WebAgent::Cookie.new()
380
+ c.name = "hoge"
381
+ c.value = "funi"
382
+ c.path = ''
383
+ c.url = urify("http://www.inac.co.jp/hoge/hoge2/hoge3")
384
+ @cm.add(c)
385
+ #
386
+ c = WebAgent::Cookie.new()
387
+ c.name = "hoge"
388
+ c.value = "funi"
389
+ #c.path = '' NO path given -> same as URL
390
+ c.url = urify("http://www.inac.co.jp/hoge/hoge2/hoge3")
391
+ @cm.add(c)
392
+ #
393
+ c1, c2 = @cm.cookies
394
+ assert_equal('', c1.path)
395
+ assert_equal('/hoge/hoge2', c2.path)
396
+ end
397
+
398
+ def test_check_cookie_accept_domain()
399
+ @cm.accept_domains = [".example1.co.jp", "www1.example.jp"]
400
+ @cm.reject_domains = [".example2.co.jp", "www2.example.jp"]
401
+ check1 = @cm.check_cookie_accept_domain("www.example1.co.jp")
402
+ assert_equal(true, check1)
403
+ check2 = @cm.check_cookie_accept_domain("www.example2.co.jp")
404
+ assert_equal(false, check2)
405
+ check3 = @cm.check_cookie_accept_domain("www1.example.jp")
406
+ assert_equal(true, check3)
407
+ check4 = @cm.check_cookie_accept_domain("www2.example.jp")
408
+ assert_equal(false, check4)
409
+ check5 = @cm.check_cookie_accept_domain("aa.www2.example.jp")
410
+ assert_equal(true, check5)
411
+ check6 = @cm.check_cookie_accept_domain("aa.www2.example.jp")
412
+ assert_equal(true, check6)
413
+ assert_equal(false, @cm.check_cookie_accept_domain(nil))
414
+ end
415
+
416
+ def test_escaped
417
+ uri = urify('http://www.example.org')
418
+
419
+ @cm.parse("bar=2; path=/", uri)
420
+ c = @cm.cookies.first
421
+ assert_equal('2', c.value)
422
+ assert_equal('bar=2', @cm.find(uri))
423
+
424
+ @cm.parse("bar=2; path=/", uri)
425
+ c = @cm.cookies.first
426
+ assert_equal('2', c.value)
427
+ assert_equal('bar=2', @cm.find(uri))
428
+
429
+ @cm.parse("bar=; path=/", uri)
430
+ c = @cm.cookies.first
431
+ assert_equal(nil, c.value)
432
+ assert_equal('bar=', @cm.find(uri))
433
+
434
+ @cm.parse("bar=; path=/", uri)
435
+ c = @cm.cookies.first
436
+ assert_equal(nil, c.value)
437
+ assert_equal('bar=', @cm.find(uri))
438
+ end
439
+
440
+ def test_load_cookies_escaped
441
+ uri = urify('http://example.org/')
442
+ f = Tempfile.new('test_cookie')
443
+ File.open(f.path, 'w') do |out|
444
+ out.write <<EOF
445
+ http://example.org/ key "value" 0 .example.org / 13 0
446
+ http://example.org/ key "" .example.org / 13 0
447
+ http://example.org/ key .example.org / 13 0
448
+ EOF
449
+ end
450
+ @cm.cookies_file = f.path
451
+ @cm.load_cookies
452
+ c0, c1, c2 = @cm.cookies
453
+ assert_equal('"value"', c0.value)
454
+ assert_equal('""', c1.value)
455
+ assert_equal('', c2.value)
456
+ assert_equal('key="value"', @cm.find(uri))
457
+ c0.value = ''
458
+ assert_equal('key=', @cm.find(uri))
459
+ c0.value = '""'
460
+ assert_equal('key=""', @cm.find(uri))
461
+ end
462
+
463
+ end
464
+
465
+ end