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