/usr/lib/ruby/1.8/yadis/xrds.rb is in libyadis-ruby1.8 0.3.4-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | require 'rexml/document'
require 'yadis/service'
# Class that handles XRDS parsing and XRD Service element extraction.
module XRDSUtil
@@namespaces = {
'xrdsns' => 'xri://$xrds',
'xrdns' => 'xri://$xrd*($v*2.0)'
}
def last_xrd(root_element)
REXML::XPath.match(root_element, '/xrdsns:XRDS/xrdns:XRD',
@@namespaces)[-1]
end
end
class XRDS
include XRDSUtil
attr_reader :xml
# Method for producing a valid XRDS object. Accepts an XML
# String. Returns an XRDS object on success, or nil on failure.
# Same as calling XRDS.new, but does not raise ArgumentErrors.
def XRDS.parse(xml)
begin
return new(xml)
rescue
return nil
end
end
# Create a new XRDS object. Raises ArgumentError if xml_text is
# malformed or invalid XRDS.
def initialize(xml_text)
@xml_text = xml_text
parse_xml(xml_text)
end
def _dump(depth)
return @xml_text
end
def XRDS._load(s)
XRDS.new(s)
end
def parse_xml(xml_text)
begin
xml = @xml = REXML::Document.new(xml_text)
rescue
raise ArgumentError, "Can't parse XRDS"
end
if xml.root.nil?
raise ArgumentError, "No document root"
end
xrd = self.last_xrd(xml.root)
raise ArgumentError, "No XRD Elements found" if xrd.nil?
@services = {} # keyed by [service_priority, uri_priority]
REXML::XPath.each(xrd, 'xrdns:Service', @@namespaces) do |s|
_create_services(s)
end
REXML::XPath.each(xrd, 'xrdns:CanonicalID', @@namespaces) do |c|
canonical_id = c.text.strip
if canonical_id.length > 0
self.services.each {|s| s.canonical_id = canonical_id}
end
end
end
# Returns an Array of ServiceEndpoint objects, sorted by priority. Highest
# priority is at element 0.
def services
s = []
@services.keys.sort.each do |key|
services_list = @services[key].dup
# randomize services with the same priority
while services_list.length > 0
s << services_list.delete_at((rand * services_list.length).to_i)
end
end
return s
end
private
# create services objects
def _create_services(service_element)
service = ServiceEndpoint.new
service.element = service_element
service.uri = nil
service.service_types = []
REXML::XPath.each(service_element, 'xrdns:Type', @@namespaces) do |t|
# XXX: If the Type element is empty, should we add an empty element
# to our list, or none at all?
service.service_types << t.text.strip unless t.text.nil?
end
sp = service_element.attributes['priority']
service_priority = sp ? sp.to_i : -1
has_uri = false
REXML::XPath.each(service.element, 'xrdns:URI', @@namespaces) do |uri|
has_uri = true
_service = service.dup
_service.uri = uri.text.strip
up = uri.attributes['priority']
uri_priority = up ? up.to_i : -1
priority = [service_priority, uri_priority]
_add_service(priority, _service)
end
unless has_uri
priority = [service_priority, -1]
_add_service(priority, service)
end
end
def _add_service(priority, service)
unless @services.has_key?(priority)
@services[priority] = []
end
# services with the same priority are appended to the list
@services[priority] << service
end
end
|