function query($xri, $service_types, $filters = array()) { $services = array(); $canonicalID = null; foreach ($service_types as $service_type) { $url = $this->queryURL($xri, $service_type); $response = $this->fetcher->get($url); if ($response->status != 200) { continue; } $xrds = Services_Yadis_XRDS::parseXRDS($response->body); if (!$xrds) { continue; } $canonicalID = Services_Yadis_getCanonicalID($xri, $xrds); if ($canonicalID === false) { return null; } $some_services = $xrds->services($filters); $services = array_merge($services, $some_services); // TODO: // * If we do get hits for multiple service_types, we're // almost certainly going to have duplicated service // entries and broken priority ordering. } return array($canonicalID, $services); }
/** * This should be called statically and will build a Yadis * instance if the discovery process succeeds. This implements * Yadis discovery as specified in the Yadis specification. * * @param string $uri The URI on which to perform Yadis discovery. * * @param array $http_response An array reference where the HTTP * response object will be stored (see {@link * Services_Yadis_HTTPResponse}. * * @param Services_Yadis_HTTPFetcher $fetcher An instance of a * Services_Yadis_HTTPFetcher subclass. * * @param array $extra_ns_map An array which maps namespace names * to namespace URIs to be used when parsing the Yadis XRDS * document. * * @param integer $timeout An optional fetcher timeout, in seconds. * * @return mixed $obj Either null or an instance of * Services_Yadis_Yadis, depending on whether the discovery * succeeded. */ function discover($uri, &$http_response, &$fetcher, $extra_ns_map = null, $timeout = 20) { if (!$uri) { return null; } $request_uri = $uri; $headers = array("Accept: application/xrds+xml"); if (!$fetcher) { $fetcher = Services_Yadis_Yadis::getHTTPFetcher($timeout); } $response = $fetcher->get($uri, $headers); $http_response = $response; if (!$response) { return null; } if ($response->status != 200) { return null; } $xrds_uri = $response->final_url; $uri = $response->final_url; $body = $response->body; $xrds_header_uri = Services_Yadis_Yadis::_getHeader($response->headers, array('x-xrds-location', 'x-yadis-location')); $content_type = Services_Yadis_Yadis::_getHeader($response->headers, array('content-type')); if ($xrds_header_uri) { $xrds_uri = $xrds_header_uri; $response = $fetcher->get($xrds_uri); $http_response = $response; if (!$response) { return null; } else { $body = $response->body; $headers = $response->headers; $content_type = Services_Yadis_Yadis::_getHeader($headers, array('content-type')); } } if (Services_Yadis_Yadis::_getContentType($content_type) != 'application/xrds+xml') { // Treat the body as HTML and look for a META tag. $parser = new Services_Yadis_ParseHTML(); $new_uri = $parser->getHTTPEquiv($body); $xrds_uri = null; if ($new_uri) { $response = $fetcher->get($new_uri); if ($response->status != 200) { return null; } $http_response = $response; $body = $response->body; $xrds_uri = $new_uri; $content_type = Services_Yadis_Yadis::_getHeader($response->headers, array('content-type')); } } $xrds = Services_Yadis_XRDS::parseXRDS($body, $extra_ns_map); if ($xrds !== null) { $y = new Services_Yadis_Yadis(); $y->request_uri = $request_uri; $y->xrds = $xrds; $y->uri = $uri; $y->xrds_uri = $xrds_uri; $y->body = $body; $y->content_type = $content_type; return $y; } else { return null; } }
function test_services_filters() { // First, just be sure that service objects do the right // thing. $xml = Tests_Services_Yadis_readdata("brian_priority.xrds"); $xrds = Services_Yadis_XRDS::parseXRDS($xml, array('openid' => 'http://openid.net/xmlns/1.0')); $this->assertTrue($xrds !== null); // Get list of service objects. $services = $xrds->services(); $this->assertEquals(count($services), 2, "first service count"); // Query the two service objecs. $s1 = $services[0]; $this->assertEquals($s1->getPriority(), 1, "first priority check"); $types = $s1->getTypes(); $this->assertEquals(count($types), 1, "first type check"); $s2 = $services[1]; $this->assertEquals($s2->getPriority(), 2, "second priority check"); $types = $s2->getTypes(); $this->assertEquals(count($types), 1, "second type check"); function _DelegateFilter(&$service) { if ($service->getElements('openid:Delegate')) { return true; } return false; } // Make sure that a filter which matches both DOES match both. $this->assertEquals(count($xrds->services(array("_DelegateFilter"))), 2, "_DelegateFilter check"); // This filter should match all services in the document. function _HasTypeAndURI(&$service) { if ($service->getTypes() && $service->getURIs()) { return true; } return false; } // This filter should only match one. function _URIMatchesSchtuff(&$service) { $uris = $service->getURIs(); foreach ($uris as $uri) { if (preg_match("|schtuff|", $uri)) { return true; } } return false; } // This filter should only match one. function _URIMatchesMyOpenID(&$service) { $uris = $service->getURIs(); foreach ($uris as $uri) { if (preg_match("|myopenid|", $uri)) { return true; } } return false; } // Make sure a pair of filters in ALL mode only match one service. $this->assertEquals(count($xrds->services(array("_HasTypeAndURI", "_URIMatchesSchtuff"), SERVICES_YADIS_MATCH_ALL)), 1, "_HasTypeAndURI / _URIMatchesSchtuff check"); // Make sure a pair of filters in ALL mode only match one service. $this->assertEquals(count($xrds->services(array("_HasTypeAndURI", "_URIMatchesMyOpenID"), SERVICES_YADIS_MATCH_ALL)), 1, "_HasTypeAndURI / _URIMatchesMyOpenID check"); // Make sure a pair of filters in ANY mode matches both services. $this->assertEquals(count($xrds->services(array("_URIMatchesMyOpenID", "_URIMatchesSchtuff"))), 2, "_URIMatchesMyOpenID / _URIMatchesSchtuff check"); // Make sure the order of the services returned (when using // filters) is correct. $s = $xrds->services(array("_URIMatchesMyOpenID", "_URIMatchesSchtuff")); $this->assertTrue($s[0]->getPriority() === 1, "s[0] priority check"); $this->assertTrue($s[1]->getPriority() === 2, "s[1] priority check"); // Make sure a bad filter mode gets us a null service list. $this->assertTrue($xrds->services(array("_URIMatchesMyOpenID", "_URIMatchesSchtuff"), "bogus") === null, "bogus filter check"); }
function runTest() { // Parse into endpoint objects that we will check $xrds_object = Services_Yadis_XRDS::parseXRDS($this->xrds); $endpoints = array(); if ($xrds_object) { $endpoints = $xrds_object->services(array('filter_MatchesAnyOpenIDType')); $endpoints = Auth_OpenID_makeOpenIDEndpoints($this->yadis_url, $endpoints); } // make sure there are the same number of endpoints as // URIs. This assumes that the type_uris contains at least one // OpenID type. $this->assertEquals(count($this->uris), count($endpoints), "URI <-> Endpoint count"); // So that we can check equality on the endpoint types $type_uris = $this->type_uris; sort($type_uris); $seen_uris = array(); foreach ($endpoints as $endpoint) { $seen_uris[] = $endpoint->server_url; // All endpoints will have same yadis_url $this->assertEquals($this->yadis_url, $endpoint->identity_url); // and delegate $this->assertEquals($this->delegate, $endpoint->delegate); // and types $actual_types = $endpoint->type_uris; sort($actual_types); $this->assertEquals($actual_types, $type_uris); } // So that they will compare equal, because we don't care what // order they are in sort($seen_uris); $uris = $this->uris; sort($uris); // Make sure we saw all URIs, and saw each one once $this->assertEquals($uris, $seen_uris); }