ruby-yadis 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
data/COPYING CHANGED
@@ -1,10 +1,13 @@
1
- Copyright (c) 2006, JanRain, Inc.
2
- All rights reserved.
3
-
4
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
-
6
- * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
- * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
- * Neither the name of the JanRain, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9
-
10
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1
+ Copyright 2006 JanRain, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License"); you
4
+ may not use this file except in compliance with the License. You may
5
+ obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
+ implied. See the License for the specific language governing
13
+ permissions and limitations under the License.
data/README CHANGED
@@ -9,6 +9,9 @@ Yadis Specification details:
9
9
 
10
10
  Please see the INSTALL, and have a look at the YADIS interface in yadis/yadis.rb
11
11
 
12
+ ==License
13
+ Apache Software License. For more information see the LICENSE file.
14
+
12
15
  ==Authors
13
16
  Brian Ellin. brian -at- janrain -dot- com
14
17
  JanRain, Inc. http://www.janrain.com/
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.3.3
7
- date: 2006-08-20 00:00:00 -07:00
6
+ version: 0.3.4
7
+ date: 2007-01-04 00:00:00 -08:00
8
8
  summary: A library for performing Yadis service discovery
9
9
  require_paths:
10
10
  - lib
@@ -31,19 +31,13 @@ files:
31
31
  - examples/openid.rb
32
32
  - lib/yadis.rb
33
33
  - lib/yadis
34
- - lib/yadis.rb~
35
34
  - lib/yadis/parsehtml.rb
36
35
  - lib/yadis/xrds.rb
37
36
  - lib/yadis/yadis.rb
38
37
  - lib/yadis/fetcher.rb
39
38
  - lib/yadis/htmltokenizer.rb
40
39
  - lib/yadis/manager.rb
41
- - lib/yadis/yadis.rb~
42
40
  - lib/yadis/service.rb
43
- - lib/yadis/manager.rb~
44
- - lib/yadis/service.rb~
45
- - lib/yadis/xrds.rb~
46
- - lib/yadis/fetcher.rb~
47
41
  - lib/yadis/xri.rb
48
42
  - lib/yadis/xrires.rb
49
43
  - test/test_parse.rb
@@ -55,12 +49,12 @@ files:
55
49
  - test/test_xri.rb
56
50
  - test/data/manifest.txt
57
51
  - test/data/brian.xrds
58
- - test/data/index.html
59
- - test/data/brian.multi.xrds
60
52
  - test/data/brian_priority.xrds
53
+ - test/data/brian.multi.xrds
54
+ - test/data/index.html
61
55
  - test/data/brian.multi_uri.xrds
62
- - test/data/index_xrds.html
63
56
  - test/data/index_yadis.html
57
+ - test/data/index_xrds.html
64
58
  - test/data/proxy-june1.xrds
65
59
  - test/data/weirdver.xrds
66
60
  - test/data/keturn.xrds
@@ -1 +0,0 @@
1
- require 'yadis/yadis'
@@ -1,79 +0,0 @@
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
@@ -1,138 +0,0 @@
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
-
@@ -1,24 +0,0 @@
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
@@ -1,128 +0,0 @@
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
-
@@ -1,104 +0,0 @@
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