File: xrires.rb

package info (click to toggle)
ruby-openid 2.1.8debian-6
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,676 kB
  • sloc: ruby: 16,506; xml: 219; sh: 24; makefile: 2
file content (99 lines) | stat: -rw-r--r-- 2,569 bytes parent folder | download | duplicates (6)
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
require "cgi"
require "openid/yadis/xri"
require "openid/yadis/xrds"
require "openid/fetchers"

module OpenID

  module Yadis

    module XRI

      class XRIHTTPError < StandardError; end

      class ProxyResolver

        DEFAULT_PROXY = 'http://proxy.xri.net/'

        def initialize(proxy_url=nil)
          if proxy_url
            @proxy_url = proxy_url
          else
            @proxy_url = DEFAULT_PROXY
          end

          @proxy_url += '/' unless @proxy_url.match('/$')
        end

        def query_url(xri, service_type=nil)
          # URI normal form has a leading xri://, but we need to strip
          # that off again for the QXRI.  This is under discussion for
          # XRI Resolution WD 11.
          qxri = XRI.to_uri_normal(xri)[6..-1]
          hxri = @proxy_url + qxri
          args = {'_xrd_r' => 'application/xrds+xml'}
          if service_type
            args['_xrd_t'] = service_type
          else
            # don't perform service endpoint selection
            args['_xrd_r'] += ';sep=false'
          end

          return XRI.append_args(hxri, args)
        end

        def query(xri)
          # these can be query args or http headers, needn't be both.
          # headers = {'Accept' => 'application/xrds+xml;sep=true'}
          canonicalID = nil

          url = self.query_url(xri)
            begin
              response = OpenID.fetch(url)
            rescue
              raise XRIHTTPError, "Could not fetch #{xri}, #{$!}"
            end
            raise XRIHTTPError, "Could not fetch #{xri}" if response.nil?

            xrds = Yadis::parseXRDS(response.body)
            canonicalID = Yadis::get_canonical_id(xri, xrds)

          return canonicalID, Yadis::services(xrds)
          # TODO:
          #  * If we do get hits for multiple service_types, we're almost
          #    certainly going to have duplicated service entries and
          #    broken priority ordering.
        end
      end

      def self.urlencode(args)
        a = []
        args.each do |key, val|
          a << (CGI::escape(key) + "=" + CGI::escape(val))
        end
        a.join("&")
      end

      def self.append_args(url, args)
        return url if args.length == 0

        # rstrip question marks
        rstripped = url.dup
        while rstripped[-1].chr == '?'
          rstripped = rstripped[0...rstripped.length-1]
        end

        if rstripped.index('?')
          sep = '&'
        else
          sep = '?'
        end

        return url + sep + XRI.urlencode(args)
      end

    end

  end

end