Class: XriResolver::AuthorityResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/xri_resolver.rb

Direct Known Subclasses

URIAuthorityResolver

Defined Under Namespace

Classes: Retn

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(xri, req, stack) ⇒ AuthorityResolver

Returns a new instance of AuthorityResolver.

Raises:



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
# File 'lib/xri_resolver.rb', line 28

def initialize(xri, req, stack)
  if XriParser::AuthorityParser === xri
    @xri = xri
  else
    begin
      @xri = XriParser::AuthorityParser.parse(xri)
    rescue Exception
      raise
    end
  end

  @req = req
  @stack = stack || Array.new

  if @req.saml
    sts = REXML::Element.new('Status')
    sts.add_attribute('code', code = '201')
    sts.text = 'SAML_NOT_IMPLEMENTED'
    xrd = REXML::Element.new('XRD')
    xrd << sts
    @xrd_array = Array.new
    @xrd_array << xrd
    return
  end
  
  raise UNKNOWN_ROOT, @xri.root unless Hash === XRIAuthorities[@xri.root]
  @client = HTTPClient.new
  @client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE unless XRIAuthorities[@xri.root][:verify_server_cert]
  @accept_header = 'application/xrds+xml'
  @accept_header << ';https=true' if @req.https
  
  @xrd_array = Array.new
  @resolved = "#{@xri.root}"
  @status_code = String.new ## status code of the last resolved subsegment
  subsegments_resolved = 0
  
  @authority_uris = XRIAuthorities[@xri.root][:authority_uris].map {|u| URI.parse(u)}

  errorcode = '220'
  errortext = ResponseStatus[errorcode]

  @xri.subsegments.each do |subsegment|
    begin
      @authority_uris = resolve_next(subsegment)
    rescue Exception => e
      errorcode = '220'
      errortext = e.message
      break
    end
    subsegments_resolved += 1
    if @authority_uris.empty? or !@authority_uris.all?{|r| URI === r}
      if subsegments_resolved < @xri.subsegments.length
        if ele = (@xrd_array.last.elements['Ref'] or @xrd_array.last.elements['Redirect'])
          @newreq = @req.clone
          @newreq.sep = true
          @newreq.nodefault_t = true
          @newreq.service_type = XRDType
          if ele.name == 'Ref'
            authsep = AuthorityResolver.resolve(ele.text, @newreq, @stack)
          else
            authsep = URIAuthorityResolver.new(@xri, @newreq, doappend(ele).text, @stack)
          end
          if authsep.resolved_successfully? and not authsep.to_urilist.empty?
            @xrd_array << authsep.to_xrds.root
            @authority_uris = authsep.to_urilist.collect { |uri| URI.parse(uri) }
          end
        else
          errorcode = @req.https ? '231' : '221'
          errortext = ResponseStatus[errorcode]
          break
        end
      end
    end
  end

  if subsegments_resolved < @xri.subsegments.length
    sts = REXML::Element.new('Status')
    sts.add_attribute('code', errorcode)
    sts.text = errortext
    qry = REXML::Element.new('Query')
    qry.text = unescape(@xri.subsegments[subsegments_resolved]).unpack('C*').pack('U*')
    xrd = REXML::Element.new('XRD')
    xrd << qry
    xrd << sts
    @xrd_array << xrd
  end

  serverstatus!
  completeuris!
  canonical!
  references!
  redirects!
  services!
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



26
27
28
# File 'lib/xri_resolver.rb', line 26

def client
  @client
end

#reqObject (readonly)

Returns the value of attribute req.



26
27
28
# File 'lib/xri_resolver.rb', line 26

def req
  @req
end

#resolvedObject (readonly)

Returns the value of attribute resolved.



26
27
28
# File 'lib/xri_resolver.rb', line 26

def resolved
  @resolved
end

#status_codeObject (readonly)

Returns the value of attribute status_code.



26
27
28
# File 'lib/xri_resolver.rb', line 26

def status_code
  @status_code
end

#xrd_arrayObject (readonly)

Returns the value of attribute xrd_array.



26
27
28
# File 'lib/xri_resolver.rb', line 26

def xrd_array
  @xrd_array
end

#xriObject (readonly)

Returns the value of attribute xri.



26
27
28
# File 'lib/xri_resolver.rb', line 26

def xri
  @xri
end

Class Method Details

.resolve(xri, req_obj = nil, stack = nil) ⇒ Object



19
20
21
22
23
# File 'lib/xri_resolver.rb', line 19

def resolve(xri, req_obj=nil, stack=nil) 
  ## create default ParseInputParameters object unless one is passed in
  req = (XriResolver::ParseInputParameters === req_obj) ? req_obj : XriResolver::ParseInputParameters.new
  self.new(xri, req, stack)
end

Instance Method Details

#doappend(uri, inplace = nil) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/xri_resolver.rb', line 165

def doappend(uri, inplace=nil)
  uri_txt = uri.text
  uri_app = uri.attribute('append').value rescue 'none'
  
  unless uri_app == 'none'
    uri_txt.slice!(/\/$/)
    uri_txt.insert(-1, '/')
  end
  
  case uri_app
  when 'local'
    uri_txt << @xri.local
  when 'authority'
    uri_txt << @xri.authority
  when 'path'
    uri_txt << @xri.path
  when 'query'
    uri_txt << @xri.appendable_query
  when 'qxri'
    uri_txt << @xri.qxri
  end
  
  if inplace
    uri.text = uri_txt
    uri.delete_attribute('append')
    uri
  else
    newuri = REXML::Element.new('URI')
    newuri.text = uri_txt
    newuri
  end
end

#last_xrdObject



142
143
144
145
146
147
148
# File 'lib/xri_resolver.rb', line 142

def last_xrd
  if @xrd_array.last.root.name == 'XRDS'
    REXML::XPath.match(@xrd_array.last.root, "//*[local-name()='XRD']", XRDNS).last
  else
    @xrd_array.last.root
  end
end

#last_xrd_docObject



150
151
152
# File 'lib/xri_resolver.rb', line 150

def last_xrd_doc
  REXML::Document.new(self.last_xrd.to_s.unpack('U*').pack('C*'))
end

#last_xrd_to_prettyObject



158
159
160
161
162
163
# File 'lib/xri_resolver.rb', line 158

def last_xrd_to_pretty
  output = ""
	doc = REXML::Document.new(last_xrd_to_s)
	doc.simple_write(output, 0)
	output
end

#last_xrd_to_sObject



154
155
156
# File 'lib/xri_resolver.rb', line 154

def last_xrd_to_s
  %Q{<?xml version='1.0' encoding='UTF-8'?>#{last_xrd.to_s.unpack('U*').pack('C*').gsub(/\n/, '')}}
end

#resolved_successfully?Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/xri_resolver.rb', line 123

def resolved_successfully?
  @resolved == unescape(@xri.fully_qualified) and @status_code === '100'
end

#to_prettyObject



131
132
133
134
135
136
# File 'lib/xri_resolver.rb', line 131

def	to_pretty
	output = ""
	doc = REXML::Document.new(self.to_s)
	doc.simple_write(output, 0) ## REXML::Document monkey-patched with simple_write at bottom of this file
	output
end

#to_sObject



127
128
129
# File 'lib/xri_resolver.rb', line 127

def to_s
  build_xrds(@xrd_array)
end

#to_urilistObject



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/xri_resolver.rb', line 198

def to_urilist
  if (code = get_xrd_status_code(self.last_xrd)) == '100'
    urilist = SEPSelector.select(self, self.last_xrd, @req).to_urilist
    if urilist.empty?
      code = '241'
      error = Array.new
      error << code
      error << ResponseStatus[code]
    else
      urilist
    end
  else
    text = get_xrd_status_text(self.last_xrd)
    error = Array.new
    error << code
    error << text unless text.empty?
  end
end

#to_xrdsObject



138
139
140
# File 'lib/xri_resolver.rb', line 138

def to_xrds
  REXML::Document.new(self.to_s)
end