rubyforge 0.4.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,537 +0,0 @@
1
- # cookie.rb is redistributed file which is originally included in Webagent
2
- # version 0.6.2 by TAKAHASHI `Maki' Masayoshi. And it contains some bug fixes.
3
- # You can download the entire package of Webagent from
4
- # http://www.rubycolor.org/arc/.
5
-
6
-
7
- # Cookie class
8
- #
9
- # I refered to w3m's source to make these classes. Some comments
10
- # are quoted from it. I'm thanksful for author(s) of it.
11
- #
12
- # w3m homepage: http://ei5nazha.yz.yamagata-u.ac.jp/~aito/w3m/eng/
13
-
14
- require 'uri'
15
-
16
- class WebAgent
17
-
18
- module CookieUtils
19
-
20
- def head_match?(str1, str2)
21
- str1 == str2[0, str1.length]
22
- end
23
-
24
- def tail_match?(str1, str2)
25
- if str1.length > 0
26
- str1 == str2[-str1.length..-1].to_s
27
- else
28
- true
29
- end
30
- end
31
-
32
- def domain_match(host, domain)
33
- case domain
34
- when /\d+\.\d+\.\d+\.\d+/
35
- return (host == domain)
36
- when '.'
37
- return true
38
- when /^\./
39
- return tail_match?(domain, host)
40
- else
41
- return (host == domain)
42
- end
43
- end
44
-
45
- def total_dot_num(string)
46
- string.scan(/\./).length()
47
- end
48
-
49
- end
50
-
51
- class Cookie
52
- include CookieUtils
53
-
54
- require 'time'
55
-
56
- attr_accessor :name, :value
57
- attr_accessor :domain, :path
58
- attr_accessor :expires ## for Netscape Cookie
59
- attr_accessor :url
60
- attr_writer :use, :secure, :discard, :domain_orig, :path_orig, :override
61
-
62
- USE = 1
63
- SECURE = 2
64
- DOMAIN = 4
65
- PATH = 8
66
- DISCARD = 16
67
- OVERRIDE = 32
68
- OVERRIDE_OK = 32
69
-
70
- def initialize()
71
- @discard = @use = @secure = @domain_orig = @path_orig = @override = nil
72
- end
73
-
74
- def discard?
75
- @discard
76
- end
77
-
78
- def use?
79
- @use
80
- end
81
-
82
- def secure?
83
- @secure
84
- end
85
-
86
- def domain_orig?
87
- @domain_orig
88
- end
89
-
90
- def path_orig?
91
- @path_orig
92
- end
93
-
94
- def override?
95
- @override
96
- end
97
-
98
- def flag
99
- flg = 0
100
- flg += USE if @use
101
- flg += SECURE if @secure
102
- flg += DOMAIN if @domain_orig
103
- flg += PATH if @path_orig
104
- flg += DISCARD if @discard
105
- flg += OVERRIDE if @override
106
- flg
107
- end
108
-
109
- def set_flag(flag)
110
- flag = flag.to_i
111
- @use = true if flag & USE > 0
112
- @secure = true if flag & SECURE > 0
113
- @domain_orig = true if flag & DOMAIN > 0
114
- @path_orig = true if flag & PATH > 0
115
- @discard = true if flag & DISCARD > 0
116
- @override = true if flag & OVERRIDE > 0
117
- end
118
-
119
- def match?(url)
120
- domainname = url.host
121
- if (!domainname ||
122
- !domain_match(domainname, @domain) ||
123
- (@path && !head_match?(@path, url.path)) ||
124
- (@secure && (url.scheme != 'https')) )
125
- return false
126
- else
127
- return true
128
- end
129
- end
130
-
131
- def join_quotedstr(array, sep)
132
- ret = Array.new()
133
- old_elem = nil
134
- array.each{|elem|
135
- if (elem.scan(/"/).length % 2) == 0
136
- if old_elem
137
- old_elem << sep << elem
138
- else
139
- ret << elem
140
- old_elem = nil
141
- end
142
- else
143
- if old_elem
144
- old_elem << sep << elem
145
- ret << old_elem
146
- old_elem = nil
147
- else
148
- old_elem = elem.dup
149
- end
150
- end
151
- }
152
- ret
153
- end
154
-
155
- def parse(str, url)
156
- @url = url
157
- cookie_elem = str.split(/;/)
158
- cookie_elem = join_quotedstr(cookie_elem, ';')
159
- first_elem = cookie_elem.shift
160
- if first_elem !~ /([^=]*)(\=(.*))?/
161
- return
162
- ## raise ArgumentError 'invalid cookie value'
163
- end
164
- @name = $1.strip
165
- @value = $3
166
- if @value
167
- if @value =~ /^\s*"(.*)"\s*$/
168
- @value = $1
169
- else
170
- @value.dup.strip!
171
- end
172
- end
173
- cookie_elem.each{|pair|
174
- key, value = pair.split(/=/) ## value may nil
175
- key.strip!
176
- if value
177
- value = value.strip.sub(/\A"(.*)"\z/) { $1 }
178
- end
179
- case key.downcase
180
- when 'domain'
181
- @domain = value
182
- when 'expires'
183
- begin
184
- @expires = Time.parse(value).gmtime
185
- rescue ArgumentError
186
- @expires = nil
187
- end
188
- when 'path'
189
- @path = value
190
- when 'secure'
191
- @secure = true ## value may nil, but must 'true'.
192
- else
193
- ## ignore
194
- end
195
- }
196
- end
197
-
198
- end
199
-
200
- class CookieManager
201
- include CookieUtils
202
-
203
- ### errors
204
- class Error < StandardError; end
205
- class ErrorOverrideOK < Error; end
206
- class SpecialError < Error; end
207
- class NoDotError < ErrorOverrideOK; end
208
-
209
- SPECIAL_DOMAIN = [".com",".edu",".gov",".mil",".net",".org",".int"]
210
-
211
- attr_accessor :cookies
212
- attr_accessor :cookies_file
213
- attr_accessor :accept_domains, :reject_domains
214
- attr_accessor :netscape_rule
215
-
216
- def initialize(file=nil)
217
- @cookies = Array.new()
218
- @cookies_file = file
219
- @is_saved = true
220
- @reject_domains = Array.new()
221
- @accept_domains = Array.new()
222
- # for conformance to http://wp.netscape.com/newsref/std/cookie_spec.html
223
- @netscape_rule = false
224
- end
225
-
226
- def save_all_cookies(force = nil, save_unused = true, save_discarded = true)
227
- if @is_saved and !force
228
- return
229
- end
230
- File.open(@cookies_file, 'w') do |f|
231
- @cookies.each do |cookie|
232
- if (cookie.use? or save_unused) and
233
- (!cookie.discard? or save_discarded)
234
- f.print(cookie.url.to_s,"\t",
235
- cookie.name,"\t",
236
- cookie.value,"\t",
237
- cookie.expires.to_i,"\t",
238
- cookie.domain,"\t",
239
- cookie.path,"\t",
240
- cookie.flag,"\n")
241
- end
242
- end
243
- end
244
- end
245
-
246
- def save_cookies(force = nil)
247
- save_all_cookies(force, false, false)
248
- end
249
-
250
- def check_expired_cookies()
251
- @cookies.reject!{|cookie|
252
- is_expired = (cookie.expires && (cookie.expires < Time.now.gmtime))
253
- if is_expired && !cookie.discard?
254
- @is_saved = false
255
- end
256
- is_expired
257
- }
258
- end
259
-
260
- def parse(str, url)
261
- cookie = WebAgent::Cookie.new()
262
- cookie.parse(str, url)
263
- add(cookie)
264
- end
265
-
266
- def make_cookie_str(cookie_list)
267
- if cookie_list.empty?
268
- return nil
269
- end
270
-
271
- ret = ''
272
- c = cookie_list.shift
273
- ret += "#{c.name}=#{c.value}"
274
- cookie_list.each{|cookie|
275
- ret += "; #{cookie.name}=#{cookie.value}"
276
- }
277
- return ret
278
- end
279
- private :make_cookie_str
280
-
281
-
282
- def find(url)
283
-
284
- check_expired_cookies()
285
-
286
- cookie_list = Array.new()
287
-
288
- @cookies.each{|cookie|
289
- if cookie.use? && cookie.match?(url)
290
- if cookie_list.select{|c1| c1.name == cookie.name}.empty?
291
- cookie_list << cookie
292
- end
293
- end
294
- }
295
- return make_cookie_str(cookie_list)
296
- end
297
-
298
- def find_cookie_info(domain, path, name)
299
- @cookies.find{|c|
300
- c.domain == domain && c.path == path && c.name == name
301
- }
302
- end
303
- private :find_cookie_info
304
-
305
- def cookie_error(err, override)
306
- if err.kind_of?(ErrorOverrideOK) || !override
307
- raise err
308
- end
309
- end
310
- private :cookie_error
311
-
312
- def add(cookie)
313
- url = cookie.url
314
- name, value = cookie.name, cookie.value
315
- expires, domain, path =
316
- cookie.expires, cookie.domain, cookie.path
317
- secure, domain_orig, path_orig =
318
- cookie.secure?, cookie.domain_orig?, cookie.path_orig?
319
- discard, override =
320
- cookie.discard?, cookie.override?
321
-
322
- domainname = url.host
323
- domain_orig, path_orig = domain, path
324
- use_security = override
325
-
326
- if !domainname
327
- cookie_error(NodotError.new(), override)
328
- end
329
-
330
- if domain
331
-
332
- # [DRAFT 12] s. 4.2.2 (does not apply in the case that
333
- # host name is the same as domain attribute for version 0
334
- # cookie)
335
- # I think that this rule has almost the same effect as the
336
- # tail match of [NETSCAPE].
337
- if domain !~ /^\./ && domainname != domain
338
- domain = '.'+domain
339
- end
340
-
341
- n = total_dot_num(domain)
342
- if n < 2
343
- cookie_error(SpecialError.new(), override)
344
- elsif @netscape_rule and n == 2
345
- ## [NETSCAPE] rule
346
- ok = SPECIAL_DOMAIN.select{|sdomain|
347
- sdomain == domain[-(sdomain.length)..-1]
348
- }
349
- if ok.empty?
350
- cookie_error(SpecialError.new(), override)
351
- end
352
- end
353
-
354
- end
355
-
356
- path ||= url.path.sub!(%r|/[^/]*|, '')
357
- domain ||= domainname
358
- cookie = find_cookie_info(domain, path, name)
359
-
360
- if !cookie
361
- cookie = WebAgent::Cookie.new()
362
- cookie.use = true
363
- @cookies << cookie
364
- end
365
-
366
- cookie.url = url
367
- cookie.name = name
368
- cookie.value = value
369
- cookie.expires = expires
370
- cookie.domain = domain
371
- cookie.path = path
372
-
373
- ## for flag
374
- cookie.secure = secure
375
- cookie.domain_orig = domain_orig
376
- cookie.path_orig = path_orig
377
- if discard || cookie.expires == nil
378
- cookie.discard = true
379
- else
380
- cookie.discard = false
381
- @is_saved = false
382
- end
383
-
384
- check_expired_cookies()
385
- return false
386
- end
387
-
388
- def load_cookies()
389
- return if !File.readable?(@cookies_file)
390
- File.open(@cookies_file,'r'){|f|
391
- while line = f.gets
392
- cookie = WebAgent::Cookie.new()
393
- @cookies << cookie
394
- col = line.chomp.split(/\t/)
395
- cookie.url = URI.parse(col[0])
396
- cookie.name = col[1]
397
- cookie.value = col[2]
398
- cookie.expires = Time.at(col[3].to_i)
399
- cookie.domain = col[4]
400
- cookie.path = col[5]
401
- cookie.set_flag(col[6])
402
- end
403
- }
404
- end
405
-
406
- def check_cookie_accept_domain(domain)
407
- unless domain
408
- return false
409
- end
410
- @accept_domains.each{|dom|
411
- if domain_match(domain, dom)
412
- return true
413
- end
414
- }
415
- @reject_domains.each{|dom|
416
- if domain_match(domain, dom)
417
- return false
418
- end
419
- }
420
- return true
421
- end
422
- end
423
- end
424
-
425
- __END__
426
-
427
- =begin
428
-
429
- == WebAgent::CookieManager Class
430
-
431
- Load, save, parse and send cookies.
432
-
433
- === Usage
434
-
435
- ## initialize
436
- cm = WebAgent::CookieManager.new("/home/foo/bar/cookie")
437
-
438
- ## load cookie data
439
- cm.load_cookies()
440
-
441
- ## parse cookie from string (maybe "Set-Cookie:" header)
442
- cm.parse(str)
443
-
444
- ## send cookie data to url
445
- f.write(cm.find(url))
446
-
447
- ## save cookie to cookiefile
448
- cm.save_cookies()
449
-
450
-
451
- === Class Methods
452
-
453
- -- CookieManager::new(file=nil)
454
-
455
- create new CookieManager. If a file is provided,
456
- use it as cookies' file.
457
-
458
- === Methods
459
-
460
- -- CookieManager#save_cookies(force = nil)
461
-
462
- save cookies' data into file. if argument is true,
463
- save data although data is not modified.
464
-
465
- -- CookieManager#parse(str, url)
466
-
467
- parse string and store cookie (to parse HTTP response header).
468
-
469
- -- CookieManager#find(url)
470
-
471
- get cookies and make into string (to send as HTTP request header).
472
-
473
- -- CookieManager#add(cookie)
474
-
475
- add new cookie.
476
-
477
- -- CookieManager#load_cookies()
478
-
479
- load cookies' data from file.
480
-
481
-
482
- == WebAgent::CookieUtils Module
483
-
484
- -- CookieUtils::head_match?(str1, str2)
485
- -- CookieUtils::tail_match?(str1, str2)
486
- -- CookieUtils::domain_match(host, domain)
487
- -- CookieUtils::total_dot_num(str)
488
-
489
-
490
- == WebAgent::Cookie Class
491
-
492
- === Class Methods
493
-
494
- -- Cookie::new()
495
-
496
- create new cookie.
497
-
498
- === Methods
499
-
500
- -- Cookie#match?(url)
501
-
502
- match cookie by url. if match, return true. otherwise,
503
- return false.
504
-
505
- -- Cookie#name
506
- -- Cookie#name=(name)
507
- -- Cookie#value
508
- -- Cookie#value=(value)
509
- -- Cookie#domain
510
- -- Cookie#domain=(domain)
511
- -- Cookie#path
512
- -- Cookie#path=(path)
513
- -- Cookie#expires
514
- -- Cookie#expires=(expires)
515
- -- Cookie#url
516
- -- Cookie#url=(url)
517
-
518
- accessor methods for cookie's items.
519
-
520
- -- Cookie#discard?
521
- -- Cookie#discard=(discard)
522
- -- Cookie#use?
523
- -- Cookie#use=(use)
524
- -- Cookie#secure?
525
- -- Cookie#secure=(secure)
526
- -- Cookie#domain_orig?
527
- -- Cookie#domain_orig=(domain_orig)
528
- -- Cookie#path_orig?
529
- -- Cookie#path_orig=(path_orig)
530
- -- Cookie#override?
531
- -- Cookie#override=(override)
532
- -- Cookie#flag
533
- -- Cookie#set_flag(flag_num)
534
-
535
- accessor methods for flags.
536
-
537
- =end