1<?php
2
3/**
4 * Code for using a proxy XRI resolver.
5 */
6
7require_once 'Auth/Yadis/XRDS.php';
8require_once 'Auth/Yadis/XRI.php';
9
10class Auth_Yadis_ProxyResolver {
11
12    /** @var Auth_Yadis_HTTPFetcher */
13    protected $fetcher;
14
15    function __construct($fetcher, $proxy_url = null)
16    {
17        $this->fetcher = $fetcher;
18        $this->proxy_url = $proxy_url;
19        if (!$this->proxy_url) {
20            $this->proxy_url = Auth_Yadis_getDefaultProxy();
21        }
22    }
23
24    function queryURL($xri, $service_type = null)
25    {
26        // trim off the xri:// prefix
27        $qxri = substr(Auth_Yadis_toURINormal($xri), 6);
28        $hxri = $this->proxy_url . $qxri;
29        $args = [
30            '_xrd_r' => 'application/xrds+xml',
31        ];
32
33        if ($service_type) {
34            $args['_xrd_t'] = $service_type;
35        } else {
36            // Don't perform service endpoint selection.
37            $args['_xrd_r'] .= ';sep=false';
38        }
39
40        $query = Auth_Yadis_XRIAppendArgs($hxri, $args);
41        return $query;
42    }
43
44    function query($xri, $service_types, $filters = [])
45    {
46        $services = [];
47        $canonicalID = null;
48        foreach ($service_types as $service_type) {
49            $url = $this->queryURL($xri, $service_type);
50            $response = $this->fetcher->get($url);
51            if ($response->status != 200 and $response->status != 206) {
52                continue;
53            }
54            $xrds = Auth_Yadis_XRDS::parseXRDS($response->body);
55            if (!$xrds) {
56                continue;
57            }
58            $canonicalID = Auth_Yadis_getCanonicalID($xri,
59                                                         $xrds);
60
61            if ($canonicalID === false) {
62                return null;
63            }
64
65            $some_services = $xrds->services($filters);
66            $services = array_merge($services, $some_services);
67            // TODO:
68            //  * If we do get hits for multiple service_types, we're
69            //    almost certainly going to have duplicated service
70            //    entries and broken priority ordering.
71        }
72        return [$canonicalID, $services];
73    }
74}
75
76
77