ruby-yadis 0.2.2 → 0.3
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/INSTALL +1 -1
- data/lib/yadis.rb +5 -0
- data/lib/yadis.rb~ +1 -0
- data/lib/yadis/fetcher.rb +29 -17
- data/lib/yadis/fetcher.rb~ +79 -0
- data/lib/yadis/manager.rb +145 -0
- data/lib/yadis/manager.rb~ +138 -0
- data/lib/yadis/service.rb +22 -0
- data/lib/yadis/service.rb~ +24 -0
- data/lib/yadis/xrds.rb +70 -78
- data/lib/yadis/xrds.rb~ +128 -0
- data/lib/yadis/yadis.rb +21 -28
- data/lib/yadis/yadis.rb~ +104 -0
- data/test/test_discovery.rb +5 -0
- data/test/test_xrds.rb +13 -5
- data/test/test_yadis.rb +2 -40
- metadata +10 -2
data/INSTALL
CHANGED
data/lib/yadis.rb
CHANGED
data/lib/yadis.rb~
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'yadis/yadis'
|
data/lib/yadis/fetcher.rb
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
require "uri"
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require "net/https"
|
|
5
|
+
rescue LoadError
|
|
6
|
+
HAS_OPENSSL_ = false
|
|
7
|
+
require 'net/http'
|
|
8
|
+
else
|
|
9
|
+
HAS_OPENSSL_ = true
|
|
10
|
+
end
|
|
3
11
|
|
|
4
12
|
class NetHTTPFetcher
|
|
5
13
|
|
|
@@ -22,29 +30,31 @@ class NetHTTPFetcher
|
|
|
22
30
|
|
|
23
31
|
protected
|
|
24
32
|
|
|
25
|
-
# return a Net::HTTP object ready for use
|
|
26
|
-
|
|
33
|
+
# return a Net::HTTP object ready for use
|
|
27
34
|
def get_http_obj(uri)
|
|
28
35
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
29
36
|
http.read_timeout = @read_timeout
|
|
30
37
|
http.open_timeout = @open_timeout
|
|
31
38
|
|
|
32
|
-
if uri.scheme == 'https'
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
if uri.scheme == 'https'
|
|
40
|
+
if HAS_OPENSSL_
|
|
41
|
+
http.use_ssl = true
|
|
42
|
+
if @ca_path
|
|
43
|
+
http.ca_file = @ca_path
|
|
44
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
45
|
+
else
|
|
46
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
47
|
+
STDERR.puts("Warning: fetching over https without verifying server certificate")
|
|
48
|
+
end
|
|
37
49
|
else
|
|
38
|
-
|
|
39
|
-
STDERR.puts("Warning: fetching over https without verifying server certificate")
|
|
50
|
+
STDERR.puts('Warning: trying to fetch HTTPS URL without OpenSSL support')
|
|
40
51
|
end
|
|
41
52
|
end
|
|
42
53
|
|
|
43
|
-
http
|
|
54
|
+
return http
|
|
44
55
|
end
|
|
45
56
|
|
|
46
|
-
# do a GET following redirects limit deep
|
|
47
|
-
|
|
57
|
+
# do a GET following redirects limit deep
|
|
48
58
|
def do_get(url, params, limit=5)
|
|
49
59
|
if limit == 0
|
|
50
60
|
return nil
|
|
@@ -57,10 +67,12 @@ class NetHTTPFetcher
|
|
|
57
67
|
nil
|
|
58
68
|
else
|
|
59
69
|
case resp
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
70
|
+
when Net::HTTPSuccess
|
|
71
|
+
return [resp, URI.parse(url).to_s]
|
|
72
|
+
when Net::HTTPRedirection
|
|
73
|
+
return do_get(resp["location"], params, limit-1)
|
|
74
|
+
else
|
|
75
|
+
return nil
|
|
64
76
|
end
|
|
65
77
|
end
|
|
66
78
|
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require "uri"
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require "net/https"
|
|
5
|
+
rescue LoadError
|
|
6
|
+
HAS_OPENSSL_ = false
|
|
7
|
+
require 'net/http'
|
|
8
|
+
else
|
|
9
|
+
HAS_OPENSSL_ = true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class NetHTTPFetcher
|
|
13
|
+
|
|
14
|
+
attr_accessor :ca_path
|
|
15
|
+
|
|
16
|
+
def initialize(read_timeout=20, open_timeout=20)
|
|
17
|
+
@read_timeout = read_timeout
|
|
18
|
+
@open_timeout = open_timeout
|
|
19
|
+
@ca_path = nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get(url, params = nil)
|
|
23
|
+
resp, final_url = do_get(url, params)
|
|
24
|
+
if resp.nil?
|
|
25
|
+
nil
|
|
26
|
+
else
|
|
27
|
+
[final_url, resp]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
protected
|
|
32
|
+
|
|
33
|
+
# return a Net::HTTP object ready for use
|
|
34
|
+
def get_http_obj(uri)
|
|
35
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
36
|
+
http.read_timeout = @read_timeout
|
|
37
|
+
http.open_timeout = @open_timeout
|
|
38
|
+
|
|
39
|
+
if uri.scheme == 'https'
|
|
40
|
+
if HAS_OPENSSL_
|
|
41
|
+
http.use_ssl = true
|
|
42
|
+
if @ca_path
|
|
43
|
+
http.ca_file = @ca_path
|
|
44
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
45
|
+
else
|
|
46
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
47
|
+
STDERR.puts("Warning: fetching over https without verifying server certificate")
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
STDERR.puts('Warning: trying to fetch HTTPS URL without OpenSSL support')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
return http
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# do a GET following redirects limit deep
|
|
58
|
+
def do_get(url, params, limit=5)
|
|
59
|
+
if limit == 0
|
|
60
|
+
return nil
|
|
61
|
+
end
|
|
62
|
+
begin
|
|
63
|
+
uri = URI.parse(url)
|
|
64
|
+
http = get_http_obj(uri)
|
|
65
|
+
resp = http.request_get(uri.request_uri, params)
|
|
66
|
+
rescue
|
|
67
|
+
nil
|
|
68
|
+
else
|
|
69
|
+
case resp
|
|
70
|
+
when Net::HTTPSuccess then [resp, URI.parse(url).to_s]
|
|
71
|
+
when Net::HTTPRedirection then do_get(resp["location"], params, limit-1)
|
|
72
|
+
else
|
|
73
|
+
STDERR.puts("ERROR, what to do with #{resp}")
|
|
74
|
+
nil
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
require 'yadis/yadis'
|
|
2
|
+
|
|
3
|
+
class YadisServiceManager
|
|
4
|
+
|
|
5
|
+
attr_reader :starting_url, :yadis_url, :services, :session_key, :current
|
|
6
|
+
|
|
7
|
+
def initialize(starting_url, yadis_url, services)
|
|
8
|
+
@starting_url = starting_url
|
|
9
|
+
@yadis_url = yadis_url
|
|
10
|
+
@services = services
|
|
11
|
+
@current = nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def next
|
|
15
|
+
@current = @services.shift
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def for_url?(url)
|
|
19
|
+
url == @starting_url or url == @yadis_url
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def started?
|
|
23
|
+
not @current.nil?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def length
|
|
27
|
+
@services.length
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Discovery
|
|
33
|
+
|
|
34
|
+
@@default_suffix = 'auth'
|
|
35
|
+
@@prefix = '_yadis_services_'
|
|
36
|
+
|
|
37
|
+
# expects a normalized url
|
|
38
|
+
def initialize(session, url, session_key_suffix=nil)
|
|
39
|
+
@session = session
|
|
40
|
+
@url = url
|
|
41
|
+
@session_key = @@prefix + (session_key_suffix or @@default_suffix)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def next_service
|
|
45
|
+
manager = self.get_manager
|
|
46
|
+
if manager and manager.length <= 0
|
|
47
|
+
self.destroy_manager
|
|
48
|
+
manager = nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
unless manager
|
|
52
|
+
begin
|
|
53
|
+
yadis_url, services = self.discover
|
|
54
|
+
rescue YADISParseError, YADISHTTPError
|
|
55
|
+
manager = nil
|
|
56
|
+
else
|
|
57
|
+
manager = self.create_manager(services, yadis_url)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if manager
|
|
62
|
+
service = manager.next
|
|
63
|
+
self.store_manager(manager)
|
|
64
|
+
else
|
|
65
|
+
service = nil
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
return service
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def finish
|
|
72
|
+
manager = self.get_manager
|
|
73
|
+
return nil unless manager
|
|
74
|
+
|
|
75
|
+
service = manager.current
|
|
76
|
+
self.destroy_manager
|
|
77
|
+
return service
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def current
|
|
81
|
+
manager = self.get_manager
|
|
82
|
+
return nil unless manager
|
|
83
|
+
return manager.current
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def get_manager
|
|
87
|
+
manager = @session[@session_key]
|
|
88
|
+
|
|
89
|
+
# make sure we've got the right manager here
|
|
90
|
+
if manager and manager.for_url?(@url)
|
|
91
|
+
return manager
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
return nil
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def create_manager(services, yadis_url=nil)
|
|
98
|
+
if self.get_manager
|
|
99
|
+
raise ArgumentError, "There is already a manager for #{@url}"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
if services.length > 0
|
|
103
|
+
manager = YadisServiceManager.new(@url, yadis_url, services)
|
|
104
|
+
self.store_manager(manager)
|
|
105
|
+
else
|
|
106
|
+
manager = nil
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
return manager
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def destroy_manager
|
|
113
|
+
if self.get_manager
|
|
114
|
+
begin
|
|
115
|
+
@session.delete(@session_key)
|
|
116
|
+
rescue
|
|
117
|
+
# sometimes Hash like session objects don't have a delete
|
|
118
|
+
# method. We handle that case by assigning nil to the session[key]
|
|
119
|
+
@session[@session_key] = nil
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def store_manager(manager)
|
|
125
|
+
@session[@session_key] = manager
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# The filter argument is a Proc that will be used to call
|
|
129
|
+
# YADIS.filter_services. See the documentation for YADIS.filter_services
|
|
130
|
+
# for more information about writing filters.
|
|
131
|
+
def discover(filter=nil)
|
|
132
|
+
y = YADIS.new(@url)
|
|
133
|
+
|
|
134
|
+
# a default filter which sends through everything. you should
|
|
135
|
+
# probably consider writing a custom filter and passing it in.
|
|
136
|
+
unless filter
|
|
137
|
+
filter = lambda {|s| s}
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
return [y.uri, y.filter_services(filter)]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
require 'yadis/yadis'
|
|
2
|
+
|
|
3
|
+
class YadisServiceManager
|
|
4
|
+
|
|
5
|
+
attr_reader :starting_url, :yadis_url, :services, :session_key, :current
|
|
6
|
+
|
|
7
|
+
def initialize(starting_url, yadis_url, services)
|
|
8
|
+
@starting_url = starting_url
|
|
9
|
+
@yadis_url = yadis_url
|
|
10
|
+
@services = services
|
|
11
|
+
@current = nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def next
|
|
15
|
+
@current = @services.shift
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def for_url?(url)
|
|
19
|
+
url == @starting_url or url == @yadis_url
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def started?
|
|
23
|
+
not @current.nil?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def length
|
|
27
|
+
@services.length
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Discovery
|
|
33
|
+
|
|
34
|
+
@@default_suffix = nil
|
|
35
|
+
@@prefix = '_yadis_services_'
|
|
36
|
+
|
|
37
|
+
def initialize(session, url, session_key_siffix=nil)
|
|
38
|
+
@session = session
|
|
39
|
+
@url = url
|
|
40
|
+
@session_key = @@prefix + (session_key_suffix or @@default_suffix)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def next_service(discover_block)
|
|
44
|
+
manager = self.get_manager
|
|
45
|
+
if manager and manager.length <= 0
|
|
46
|
+
self.destroy_manager
|
|
47
|
+
manager = nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
unless manager
|
|
51
|
+
begin
|
|
52
|
+
yadis_url, services = self.discover
|
|
53
|
+
rescue YADISParseError, YADISHTTPError
|
|
54
|
+
manager = nil
|
|
55
|
+
else
|
|
56
|
+
manager = self.create_manager(services, yadis_url)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
if manager
|
|
61
|
+
service = manager.next
|
|
62
|
+
self.store_manager(manager)
|
|
63
|
+
else
|
|
64
|
+
service = nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
return service
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def finish
|
|
71
|
+
manager = self.get_manager
|
|
72
|
+
return nil unless manager
|
|
73
|
+
|
|
74
|
+
service = manager.current
|
|
75
|
+
self.destroy_manager
|
|
76
|
+
return service
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def get_manager
|
|
80
|
+
manager = @session[@session_key]
|
|
81
|
+
|
|
82
|
+
# make sure we've got the right manager here
|
|
83
|
+
if manager and manager.for_url?(@url)
|
|
84
|
+
return manager
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
return nil
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def create_manager(services, yadis_url=nil)
|
|
91
|
+
if self.get_manager
|
|
92
|
+
raise ArgumentError, "There is already a manager for #{@url}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if services.length > 0
|
|
96
|
+
manager = YadisServiceManager.new(@url, yadis_url, services)
|
|
97
|
+
self.store_manager(manager)
|
|
98
|
+
else
|
|
99
|
+
manager = nil
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
return manager
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def destroy_manager
|
|
106
|
+
if self.get_manager
|
|
107
|
+
begin
|
|
108
|
+
@session.delete(@session_key)
|
|
109
|
+
rescue
|
|
110
|
+
# sometimes Hash like session objects don't have a delete
|
|
111
|
+
# method. We handle that case by assigning nil to the session[key]
|
|
112
|
+
@session[@session_key] = nil
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def store_manager(manager)
|
|
118
|
+
@session[@session_key] = manager
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# The filter argument is a Proc that will be used to call
|
|
122
|
+
# YADIS.filter_services. See the documentation for YADIS.filter_services
|
|
123
|
+
# for more information about writing filters.
|
|
124
|
+
def discover(filter=nil)
|
|
125
|
+
y = YADIS.new(@url)
|
|
126
|
+
|
|
127
|
+
# a default filter which sends through everything. you should
|
|
128
|
+
# probably consider writing a custom filter and passing it in.
|
|
129
|
+
unless filter
|
|
130
|
+
filter = lambda {|s| s}
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
return [y.url, y.filter_services(filter)]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Class representing an XRD Service element.
|
|
2
|
+
class ServiceEndpoint
|
|
3
|
+
|
|
4
|
+
attr_accessor :service_types, :uri, :yadis_uri, :element, :yadis
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@service_types = []
|
|
8
|
+
@uri = nil
|
|
9
|
+
@yadis_uri = nil
|
|
10
|
+
@element = nil
|
|
11
|
+
@yadis_uri = nil
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def match_type_uris(type_uris)
|
|
15
|
+
type_uris.find_all {|t| @service_types.member?(t)}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def ==(other)
|
|
19
|
+
return self.instance_variables == other.instance_variables
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'rexml/document'
|
|
2
|
+
|
|
3
|
+
# Class representing an XRD Service element.
|
|
4
|
+
class ServiceEndpoint
|
|
5
|
+
|
|
6
|
+
attr_accessor :service_types, :uri, :yadis_uri, :element, :yadis
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
@service_types = []
|
|
10
|
+
@uri = nil
|
|
11
|
+
@yadis_uri = nil
|
|
12
|
+
@element = nil
|
|
13
|
+
@yadis_uri = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def match_type_uris(type_uris)
|
|
17
|
+
type_uris.find_all {|t| @service_types.member?(t)}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def ==(other)
|
|
21
|
+
return self.instance_variables == other.instance_variables
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
data/lib/yadis/xrds.rb
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
require 'rexml/document'
|
|
2
|
+
require 'yadis/service'
|
|
2
3
|
|
|
3
4
|
# Class that handles XRDS parsing and XRD Service element extraction.
|
|
5
|
+
|
|
6
|
+
module XRDSUtil
|
|
7
|
+
|
|
8
|
+
@@default_namespace = 'xri://$xrd*($v*2.0)'
|
|
9
|
+
@@xrds_namespace = {'xrds' => 'xri://$xrds'}
|
|
10
|
+
|
|
11
|
+
def last_xrd(root_element)
|
|
12
|
+
REXML::XPath.match(root_element, '/xrds:XRDS/XRD',
|
|
13
|
+
@@xrds_namespace)[-1]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
4
18
|
class XRDS
|
|
5
19
|
|
|
20
|
+
include XRDSUtil
|
|
21
|
+
attr_reader :xml
|
|
22
|
+
|
|
6
23
|
# Method for producing a valid XRDS object. Accepts an XML
|
|
7
24
|
# String. Returns an XRDS object on success, or nil on failure.
|
|
8
25
|
# Same as calling XRDS.new, but does not rails ArgumentErrors.
|
|
@@ -14,25 +31,24 @@ class XRDS
|
|
|
14
31
|
end
|
|
15
32
|
end
|
|
16
33
|
|
|
17
|
-
def XRDS.parse_verbose(xml)
|
|
18
|
-
new(xml)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
34
|
# Create a new XRDS object. Raises ArgumentError if xml_text is
|
|
22
35
|
# malformed or invalid XRDS.
|
|
23
36
|
def initialize(xml_text)
|
|
37
|
+
@xml_text = xml_text
|
|
24
38
|
parse_xml(xml_text)
|
|
25
39
|
end
|
|
26
40
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
def _dump(depth)
|
|
42
|
+
return @xml_text
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def XRDS._load(s)
|
|
46
|
+
XRDS.new(s)
|
|
47
|
+
end
|
|
48
|
+
|
|
33
49
|
def parse_xml(xml_text)
|
|
34
50
|
begin
|
|
35
|
-
xml = REXML::Document.new(xml_text)
|
|
51
|
+
xml = @xml = REXML::Document.new(xml_text)
|
|
36
52
|
rescue
|
|
37
53
|
raise ArgumentError, "Can't parse XRDS"
|
|
38
54
|
end
|
|
@@ -41,36 +57,25 @@ class XRDS
|
|
|
41
57
|
raise ArgumentError, "No document root"
|
|
42
58
|
end
|
|
43
59
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# get the last <XRD> element
|
|
49
|
-
xrd_elemets = xml.root.get_elements('/xrds:XRDS/XRD')
|
|
50
|
-
last_xrd = xrd_elemets[-1]
|
|
51
|
-
if last_xrd.nil?
|
|
52
|
-
raise ArgumentError, "No XRD Elements found"
|
|
60
|
+
xmlns = xml.root.attributes['xmlns']
|
|
61
|
+
if xmlns != @@default_namespace
|
|
62
|
+
raise ArgumentError, "Unknown XRID version #{xmlns.to_s}"
|
|
53
63
|
end
|
|
54
64
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
priority_index = _create_services(s, u, priority_index)
|
|
61
|
-
end
|
|
62
|
-
if !s.elements['URI']
|
|
63
|
-
priority_index = _create_services(s, nil, priority_index)
|
|
64
|
-
end
|
|
65
|
-
end
|
|
65
|
+
xrd = self.last_xrd(xml.root)
|
|
66
|
+
raise ArgumentError, "No XRD Elements found" if xrd.nil?
|
|
67
|
+
|
|
68
|
+
@services = {} # keyed by [service_priority, uri_priority]
|
|
69
|
+
xrd.elements.each('Service') {|s| _create_services(s)}
|
|
66
70
|
end
|
|
67
71
|
|
|
68
|
-
|
|
72
|
+
|
|
73
|
+
# Returns an Array of ServiceEndpoint objects, sorted by priority. Highest
|
|
69
74
|
# priority is at element 0.
|
|
70
75
|
def services
|
|
71
76
|
s = []
|
|
72
77
|
|
|
73
|
-
@services.keys.sort.each do |key|
|
|
78
|
+
@services.keys.sort.each do |key|
|
|
74
79
|
services_list = @services[key].dup
|
|
75
80
|
|
|
76
81
|
# randomize services with the same priority
|
|
@@ -85,61 +90,48 @@ class XRDS
|
|
|
85
90
|
|
|
86
91
|
private
|
|
87
92
|
|
|
88
|
-
def _add_service(priority_index, service)
|
|
89
|
-
unless @services.has_key?(priority_index)
|
|
90
|
-
@services[priority_index] = []
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# services with the same priority are appended to the list
|
|
94
|
-
@services[priority_index] << service
|
|
95
|
-
end
|
|
96
|
-
|
|
97
93
|
# create services objects
|
|
98
|
-
def _create_services(service_element
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
service.element = service_element
|
|
104
|
-
|
|
105
|
-
service_element.elements.each do |e|
|
|
106
|
-
service.add_other(e.prefix + ':' + e.name, e.text) if e.prefix
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
if service_element.attributes['priority']
|
|
110
|
-
priority = service_element.attributes['priority'].to_i
|
|
111
|
-
_add_service(priority, service)
|
|
94
|
+
def _create_services(service_element)
|
|
95
|
+
service = ServiceEndpoint.new
|
|
96
|
+
service.element = service_element
|
|
97
|
+
service.uri = nil
|
|
98
|
+
service.service_types = []
|
|
112
99
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
100
|
+
service_element.elements.each('Type') do |t|
|
|
101
|
+
service.service_types << t.text.strip
|
|
102
|
+
end
|
|
116
103
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
104
|
+
sp = service_element.attributes['priority']
|
|
105
|
+
service_priority = sp ? sp.to_i : -1
|
|
106
|
+
|
|
107
|
+
if service.element.elements['URI']
|
|
108
|
+
service.element.elements.each('URI') do |uri|
|
|
109
|
+
_service = service.dup
|
|
110
|
+
_service.uri = uri.text.strip
|
|
111
|
+
|
|
112
|
+
up = uri.attributes['priority']
|
|
113
|
+
uri_priority = up ? up.to_i : -1
|
|
114
|
+
priority = [service_priority, uri_priority]
|
|
115
|
+
|
|
116
|
+
_add_service(priority, _service)
|
|
120
117
|
end
|
|
118
|
+
|
|
119
|
+
else
|
|
120
|
+
priority = [service_priority, -1]
|
|
121
|
+
_add_service(priority, service)
|
|
121
122
|
|
|
122
123
|
end
|
|
123
124
|
|
|
124
|
-
return priority_index
|
|
125
125
|
end
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
attr_reader :service_type, :uri, :element
|
|
132
|
-
attr_writer :service_type, :uri, :element
|
|
133
|
-
|
|
134
|
-
def initialize
|
|
135
|
-
@other = Hash.new
|
|
136
|
-
end
|
|
127
|
+
def _add_service(priority, service)
|
|
128
|
+
unless @services.has_key?(priority)
|
|
129
|
+
@services[priority] = []
|
|
130
|
+
end
|
|
137
131
|
|
|
138
|
-
|
|
139
|
-
@
|
|
132
|
+
# services with the same priority are appended to the list
|
|
133
|
+
@services[priority] << service
|
|
140
134
|
end
|
|
141
135
|
|
|
142
|
-
def other
|
|
143
|
-
return @other
|
|
144
|
-
end
|
|
145
136
|
end
|
|
137
|
+
|
data/lib/yadis/xrds.rb~
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
require 'rexml/document'
|
|
2
|
+
require 'yadis/service'
|
|
3
|
+
|
|
4
|
+
# Class that handles XRDS parsing and XRD Service element extraction.
|
|
5
|
+
|
|
6
|
+
module XRDSUtil
|
|
7
|
+
|
|
8
|
+
@@default_namespace = 'xri://$xrd*($v*2.0)'
|
|
9
|
+
@@xrds_namespace = {'xrds' => 'xri://$xrds'}
|
|
10
|
+
|
|
11
|
+
def last_xrd(root_element)
|
|
12
|
+
REXML::XPath.match(root_element, '/xrds:XRDS/XRD',
|
|
13
|
+
@@xrds_namespace)[-1]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class XRDS
|
|
19
|
+
|
|
20
|
+
include XRDSUtil
|
|
21
|
+
attr_reader :xml
|
|
22
|
+
|
|
23
|
+
# Method for producing a valid XRDS object. Accepts an XML
|
|
24
|
+
# String. Returns an XRDS object on success, or nil on failure.
|
|
25
|
+
# Same as calling XRDS.new, but does not rails ArgumentErrors.
|
|
26
|
+
def XRDS.parse(xml)
|
|
27
|
+
begin
|
|
28
|
+
return new(xml)
|
|
29
|
+
rescue
|
|
30
|
+
return nil
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Create a new XRDS object. Raises ArgumentError if xml_text is
|
|
35
|
+
# malformed or invalid XRDS.
|
|
36
|
+
def initialize(xml_text)
|
|
37
|
+
parse_xml(xml_text)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def parse_xml(xml_text)
|
|
41
|
+
begin
|
|
42
|
+
xml = @xml = REXML::Document.new(xml_text)
|
|
43
|
+
rescue
|
|
44
|
+
raise ArgumentError, "Can't parse XRDS"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if xml.root.nil?
|
|
48
|
+
raise ArgumentError, "No document root"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
xmlns = xml.root.attributes['xmlns']
|
|
52
|
+
if xmlns != @@default_namespace
|
|
53
|
+
raise ArgumentError, "Unknown XRID version #{xmlns.to_s}"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
xrd = self.last_xrd(xml.root)
|
|
57
|
+
raise ArgumentError, "No XRD Elements found" if xrd.nil?
|
|
58
|
+
|
|
59
|
+
@services = {} # keyed by [service_priority, uri_priority]
|
|
60
|
+
xrd.elements.each('Service') {|s| _create_services(s)}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# Returns an Array of ServiceEndpoint objects, sorted by priority. Highest
|
|
65
|
+
# priority is at element 0.
|
|
66
|
+
def services
|
|
67
|
+
s = []
|
|
68
|
+
|
|
69
|
+
@services.keys.sort.each do |key|
|
|
70
|
+
services_list = @services[key].dup
|
|
71
|
+
|
|
72
|
+
# randomize services with the same priority
|
|
73
|
+
while services_list.length > 0
|
|
74
|
+
s << services_list.delete_at((rand * services_list.length).to_i)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
return s
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
# create services objects
|
|
85
|
+
def _create_services(service_element)
|
|
86
|
+
service = ServiceEndpoint.new
|
|
87
|
+
service.element = service_element
|
|
88
|
+
service.uri = nil
|
|
89
|
+
service.service_types = []
|
|
90
|
+
|
|
91
|
+
service_element.elements.each('Type') do |t|
|
|
92
|
+
service.service_types << t.text.strip
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
sp = service_element.attributes['priority']
|
|
96
|
+
service_priority = sp ? sp.to_i : -1
|
|
97
|
+
|
|
98
|
+
if service.element.elements['URI']
|
|
99
|
+
service.element.elements.each('URI') do |uri|
|
|
100
|
+
_service = service.dup
|
|
101
|
+
_service.uri = uri.text.strip
|
|
102
|
+
|
|
103
|
+
up = uri.attributes['priority']
|
|
104
|
+
uri_priority = up ? up.to_i : -1
|
|
105
|
+
priority = [service_priority, uri_priority]
|
|
106
|
+
|
|
107
|
+
_add_service(priority, _service)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
else
|
|
111
|
+
priority = [service_priority, -1]
|
|
112
|
+
_add_service(priority, service)
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def _add_service(priority, service)
|
|
119
|
+
unless @services.has_key?(priority)
|
|
120
|
+
@services[priority] = []
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# services with the same priority are appended to the list
|
|
124
|
+
@services[priority] << service
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end
|
|
128
|
+
|
data/lib/yadis/yadis.rb
CHANGED
|
@@ -5,14 +5,18 @@ require 'yadis/parsehtml'
|
|
|
5
5
|
class YADISParseError < StandardError; end
|
|
6
6
|
class YADISHTTPError < StandardError; end
|
|
7
7
|
|
|
8
|
+
|
|
9
|
+
# High level class for performing the Yadis protocol on a given URL. The
|
|
10
|
+
# YADIS.discover class method is a good place to get started in determining
|
|
11
|
+
# which services a URL supports.
|
|
8
12
|
class YADIS
|
|
9
13
|
|
|
10
14
|
@@ca_path = nil
|
|
11
15
|
attr_accessor :uri, :xrds_uri, :xrds
|
|
12
16
|
|
|
13
17
|
# Discover services for a given URI. Please note that no normalization
|
|
14
|
-
# will be done to the passed in URI, it should be
|
|
15
|
-
# discover.
|
|
18
|
+
# will be done to the passed in URI, it should be a textually
|
|
19
|
+
# valid URI string before calling discover.
|
|
16
20
|
#
|
|
17
21
|
# Returns nil if no XRDS was found, or a YADIS object on success. This
|
|
18
22
|
# method is essentially the same as YADIS.new, but does not raise any
|
|
@@ -46,9 +50,9 @@ class YADIS
|
|
|
46
50
|
# or YADISHTTPError is the URI cannot be fetched.
|
|
47
51
|
def initialize(uri)
|
|
48
52
|
http = NetHTTPFetcher.new
|
|
49
|
-
http.ca_path = @@ca_path if @@ca_path
|
|
50
|
-
|
|
53
|
+
http.ca_path = @@ca_path if @@ca_path
|
|
51
54
|
headers = {'Accept' => 'application/xrds+xml'}
|
|
55
|
+
|
|
52
56
|
response = http.get(uri, headers)
|
|
53
57
|
raise YADISHTTPError, "Could not fetch #{uri}" if response.nil?
|
|
54
58
|
|
|
@@ -82,34 +86,23 @@ class YADIS
|
|
|
82
86
|
|
|
83
87
|
# Returns an Array Service objects sorted by priority.
|
|
84
88
|
def services
|
|
89
|
+
@xrds.services.each {|s| s.yadis = self}
|
|
85
90
|
@xrds.services
|
|
86
91
|
end
|
|
87
92
|
|
|
88
|
-
# Returns
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
# Returns a list of services, ordered by priority,
|
|
94
|
+
# that match the filter. filter is a Proc object that produces
|
|
95
|
+
# ServiceEnpoint objects, subclasses of ServiceEnpoint or nil.
|
|
96
|
+
# This method is useful for extracting several types of services while
|
|
97
|
+
# maintaining priority, for example you may write a filter Proc to extract
|
|
98
|
+
# OpenID and LID ServiceEnpoint objects.
|
|
99
|
+
def filter_services(filter)
|
|
100
|
+
# product a list of filtered ServiceEndpoint objects. filtered
|
|
101
|
+
# will contain a list of nil or ServiceEnpoint (subclasses) objects.
|
|
102
|
+
filtered = self.services.collect {|s| filter.call(s)}
|
|
98
103
|
|
|
99
|
-
return
|
|
104
|
+
# return all object in filtered that are not nil
|
|
105
|
+
return filtered.find_all {|s| s}
|
|
100
106
|
end
|
|
101
107
|
|
|
102
|
-
# Returns an Array of Service objects that represent LID servers,
|
|
103
|
-
# sorted by priority.
|
|
104
|
-
#
|
|
105
|
-
# Optionally accpets an Array of LID protocol versions.Versions
|
|
106
|
-
# should be given as strings eg: '1.0'
|
|
107
|
-
def lid_servers(versions)
|
|
108
|
-
versions.collect! {|v| v.gsub('.', '\.')} if versions
|
|
109
|
-
|
|
110
|
-
base_url = 'http://lid.netmesh.org/sso/'
|
|
111
|
-
base_url += '(' + versions.join('|') + '){1}' if versions
|
|
112
|
-
|
|
113
|
-
return @xrds.services.find_all {|s| s.service_type.match(base_url)}
|
|
114
|
-
end
|
|
115
108
|
end
|
data/lib/yadis/yadis.rb~
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'yadis/xrds'
|
|
2
|
+
require 'yadis/fetcher'
|
|
3
|
+
require 'yadis/parsehtml'
|
|
4
|
+
|
|
5
|
+
class YADISParseError < StandardError; end
|
|
6
|
+
class YADISHTTPError < StandardError; end
|
|
7
|
+
|
|
8
|
+
class YADIS
|
|
9
|
+
|
|
10
|
+
@@ca_path = nil
|
|
11
|
+
attr_accessor :uri, :xrds_uri, :xrds
|
|
12
|
+
|
|
13
|
+
# Discover services for a given URI. Please note that no normalization
|
|
14
|
+
# will be done to the passed in URI, it should be a textually
|
|
15
|
+
# valid URI string before calling discover.
|
|
16
|
+
#
|
|
17
|
+
# Returns nil if no XRDS was found, or a YADIS object on success. This
|
|
18
|
+
# method is essentially the same as YADIS.new, but does not raise any
|
|
19
|
+
# exceptions.
|
|
20
|
+
def YADIS.discover(uri)
|
|
21
|
+
return nil unless uri
|
|
22
|
+
begin
|
|
23
|
+
return YADIS.new(uri)
|
|
24
|
+
rescue
|
|
25
|
+
return nil
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Set the path to a certificate authority pem file, for verifying
|
|
30
|
+
# server certificates of HTTPS pages. If you are interested in verifying
|
|
31
|
+
# certs like the mozilla web browser, have a look at the files here:
|
|
32
|
+
#
|
|
33
|
+
# http://curl.haxx.se/docs/caextract.html
|
|
34
|
+
def YADIS.ca_path=(ca_path)
|
|
35
|
+
ca_path = ca_path.to_s
|
|
36
|
+
if File.exists?(ca_path)
|
|
37
|
+
@@ca_path = ca_path
|
|
38
|
+
else
|
|
39
|
+
raise ArgumentError, "#{ca_path} is not a valid file path"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Discover services for a URI using the Yadis protocol. +uri+ should
|
|
44
|
+
# be a valid URI represented as a string. This method may raise
|
|
45
|
+
# YADISParseError in the case of an invalid or unparsable XRDS file,
|
|
46
|
+
# or YADISHTTPError is the URI cannot be fetched.
|
|
47
|
+
def initialize(uri)
|
|
48
|
+
http = NetHTTPFetcher.new
|
|
49
|
+
http.ca_path = @@ca_path if @@ca_path
|
|
50
|
+
headers = {'Accept' => 'application/xrds+xml'}
|
|
51
|
+
|
|
52
|
+
response = http.get(uri, headers)
|
|
53
|
+
raise YADISHTTPError, "Could not fetch #{uri}" if response.nil?
|
|
54
|
+
|
|
55
|
+
uri, resp_payload = response
|
|
56
|
+
xrds_uri = uri
|
|
57
|
+
|
|
58
|
+
header = resp_payload['x-xrds-location']
|
|
59
|
+
header = resp_payload['x-yadis-location'] if header.nil?
|
|
60
|
+
|
|
61
|
+
if header
|
|
62
|
+
xrds_uri = header
|
|
63
|
+
response = http.get(xrds_uri)
|
|
64
|
+
raise YADISHTTPError, "Could not fetch XRDS #{xrds_uri}" if response.nil?
|
|
65
|
+
resp_payload = response[1]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
unless resp_payload['content-type'] == 'application/xrds+xml'
|
|
69
|
+
loc = html_yadis_location(resp_payload.body)
|
|
70
|
+
unless loc.nil?
|
|
71
|
+
xrds_uri, resp_payload = http.get(loc)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
xrds = XRDS.parse(resp_payload.body)
|
|
76
|
+
raise YADISParseError, "Bad XRDS" if xrds.nil?
|
|
77
|
+
|
|
78
|
+
@uri = uri
|
|
79
|
+
@xrds_uri = xrds_uri
|
|
80
|
+
@xrds = xrds
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Returns an Array Service objects sorted by priority.
|
|
84
|
+
def services
|
|
85
|
+
@xrds.services.each {|s| s.yadis = self}
|
|
86
|
+
@xrds.services
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Returns a list of services, ordered by priority,
|
|
90
|
+
# that match the filter. filter is a Proc object that produces
|
|
91
|
+
# ServiceEnpoint objects, subclasses of ServiceEnpoint or nil.
|
|
92
|
+
# This method is useful for extracting several types of services while
|
|
93
|
+
# maintaining priority, for example you may write a filter Proc to extract
|
|
94
|
+
# OpenID and LID ServiceEnpoint objects.
|
|
95
|
+
def filter_services(filter)
|
|
96
|
+
# product a list of filtered ServiceEndpoint objects. filtered
|
|
97
|
+
# will contain a list of nil or ServiceEnpoint (subclasses) objects.
|
|
98
|
+
filtered = self.services.collect {|s| filter.call(s)}
|
|
99
|
+
|
|
100
|
+
# return all object in filtered that are not nil
|
|
101
|
+
return filtered.find_all {|s| s}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
data/test/test_discovery.rb
CHANGED
data/test/test_xrds.rb
CHANGED
|
@@ -5,26 +5,25 @@ class XRDSTestCase < Test::Unit::TestCase
|
|
|
5
5
|
|
|
6
6
|
def test_xrds_good
|
|
7
7
|
File.open('data/brian.xrds') do |f|
|
|
8
|
-
xrds = XRDS.
|
|
8
|
+
xrds = XRDS.new(f.read)
|
|
9
9
|
assert_not_nil(xrds)
|
|
10
10
|
assert_equal(xrds.services.length, 1)
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
|
|
15
14
|
def test_xrds_good_multi
|
|
16
15
|
File.open('data/brian.multi.xrds') do |f|
|
|
17
|
-
xrds = XRDS.
|
|
16
|
+
xrds = XRDS.new(f.read)
|
|
18
17
|
assert_not_nil(xrds)
|
|
19
18
|
assert_equal(1, xrds.services.length)
|
|
20
19
|
s = xrds.services[0]
|
|
21
|
-
|
|
20
|
+
assert s.service_types.member?('http://openid.net/signon/1.0')
|
|
22
21
|
end
|
|
23
22
|
end
|
|
24
23
|
|
|
25
24
|
def test_xrds_good_uri_multi
|
|
26
25
|
File.open('data/brian.multi_uri.xrds') do |f|
|
|
27
|
-
xrds = XRDS.
|
|
26
|
+
xrds = XRDS.new(f.read)
|
|
28
27
|
assert_not_nil(xrds)
|
|
29
28
|
assert_equal(2, xrds.services.length)
|
|
30
29
|
end
|
|
@@ -38,4 +37,13 @@ class XRDSTestCase < Test::Unit::TestCase
|
|
|
38
37
|
assert_nil(XRDS.parse('\000'))
|
|
39
38
|
end
|
|
40
39
|
|
|
40
|
+
def test_marshal
|
|
41
|
+
File.open('data/brian.xrds') do |f|
|
|
42
|
+
xrds = XRDS.new(f.read)
|
|
43
|
+
s = Marshal.dump(xrds)
|
|
44
|
+
xrds2 = Marshal.load(s)
|
|
45
|
+
assert_equal(xrds.services, xrds2.services)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
41
49
|
end
|
data/test/test_yadis.rb
CHANGED
|
@@ -3,44 +3,6 @@ require 'yadis'
|
|
|
3
3
|
|
|
4
4
|
class YADISTestCase < Test::Unit::TestCase
|
|
5
5
|
|
|
6
|
-
def test_yadis_openid
|
|
7
|
-
File.open('data/brian.xrds') do |f|
|
|
8
|
-
xrds = XRDS.parse(f.read)
|
|
9
|
-
|
|
10
|
-
assert_not_nil(xrds)
|
|
11
|
-
assert_equal(xrds.services.length, 1)
|
|
12
|
-
|
|
13
|
-
uri = 'http://brian.myopenid.com/'
|
|
14
|
-
xrds_uri = 'http://brian.myopenid.com/xrds'
|
|
15
|
-
y = YADIS.new(uri)
|
|
16
|
-
y.uri = uri
|
|
17
|
-
y.xrds_uri = xrds_uri
|
|
18
|
-
y.xrds_uri = xrds
|
|
19
|
-
|
|
20
|
-
servers = y.openid_servers
|
|
21
|
-
assert_equal(servers.length, 1)
|
|
22
|
-
|
|
23
|
-
myopenid = servers[0]
|
|
24
|
-
assert_equal(myopenid.service_type, 'http://openid.net/signon/1.0')
|
|
25
|
-
assert_equal(myopenid.uri, 'http://www.myopenid.com/server')
|
|
26
|
-
assert_equal(myopenid.other['openid:Delegate'], 'http://brian.myopenid.com/')
|
|
27
|
-
|
|
28
|
-
servers = y.openid_servers(['1.0'])
|
|
29
|
-
assert_equal(servers.length, 1)
|
|
30
|
-
|
|
31
|
-
myopenid = servers[0]
|
|
32
|
-
assert_equal(myopenid.service_type, 'http://openid.net/signon/1.0')
|
|
33
|
-
assert_equal(myopenid.uri, 'http://www.myopenid.com/server')
|
|
34
|
-
assert_equal(myopenid.other['openid:Delegate'], 'http://brian.myopenid.com/')
|
|
35
|
-
|
|
36
|
-
servers = y.openid_servers(['0.9'])
|
|
37
|
-
assert_equal(servers.length, 0)
|
|
38
|
-
|
|
39
|
-
servers = y.openid_servers(['0.9', '1.1'])
|
|
40
|
-
assert_equal(servers.length, 0)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
6
|
def test_yadis_lid
|
|
45
7
|
# need an xrds with lid stuff in it for this part
|
|
46
8
|
end
|
|
@@ -49,8 +11,8 @@ class YADISTestCase < Test::Unit::TestCase
|
|
|
49
11
|
xrds = XRDS.parse(File.open('data/brian_priority.xrds').read)
|
|
50
12
|
assert_equal(2, xrds.services.length)
|
|
51
13
|
assert_equal('http://www.myopenid.com/server', xrds.services[0].uri)
|
|
52
|
-
assert_equal('http://www.schtuff.com/?action=openid_server',
|
|
53
|
-
|
|
14
|
+
assert_equal('http://www.schtuff.com/?action=openid_server',
|
|
15
|
+
xrds.services[1].uri)
|
|
54
16
|
end
|
|
55
17
|
|
|
56
18
|
|
metadata
CHANGED
|
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
|
3
3
|
specification_version: 1
|
|
4
4
|
name: ruby-yadis
|
|
5
5
|
version: !ruby/object:Gem::Version
|
|
6
|
-
version: 0.
|
|
7
|
-
date: 2006-
|
|
6
|
+
version: "0.3"
|
|
7
|
+
date: 2006-05-10 00:00:00 -07:00
|
|
8
8
|
summary: A library for performing Yadis service discovery
|
|
9
9
|
require_paths:
|
|
10
10
|
- lib
|
|
@@ -31,11 +31,19 @@ files:
|
|
|
31
31
|
- examples/openid.rb
|
|
32
32
|
- lib/yadis.rb
|
|
33
33
|
- lib/yadis
|
|
34
|
+
- lib/yadis.rb~
|
|
34
35
|
- lib/yadis/parsehtml.rb
|
|
35
36
|
- lib/yadis/xrds.rb
|
|
36
37
|
- lib/yadis/yadis.rb
|
|
37
38
|
- lib/yadis/fetcher.rb
|
|
38
39
|
- lib/yadis/htmltokenizer.rb
|
|
40
|
+
- lib/yadis/manager.rb
|
|
41
|
+
- lib/yadis/yadis.rb~
|
|
42
|
+
- lib/yadis/service.rb
|
|
43
|
+
- lib/yadis/manager.rb~
|
|
44
|
+
- lib/yadis/service.rb~
|
|
45
|
+
- lib/yadis/xrds.rb~
|
|
46
|
+
- lib/yadis/fetcher.rb~
|
|
39
47
|
- test/test_parse.rb
|
|
40
48
|
- test/data
|
|
41
49
|
- test/test_discovery.rb
|