static function getServiceDocument($remote) { $discovery = new Discovery(); $xrd = $discovery->lookup($remote); if (empty($xrd)) { // TRANS: Exception thrown when a service document could not be located account move. // TRANS: %s is the remote site. throw new Exception(sprintf(_("Cannot find XRD for %s."), $remote)); } $svcDocUrl = null; $username = null; foreach ($xrd->links as $link) { if ($link['rel'] == 'http://apinamespace.org/atom' && $link['type'] == 'application/atomsvc+xml') { $svcDocUrl = $link['href']; if (!empty($link['property'])) { foreach ($link['property'] as $property) { if ($property['type'] == 'http://apinamespace.org/atom/username') { $username = $property['value']; break; } } } break; } } if (empty($svcDocUrl)) { // TRANS: Exception thrown when an account could not be located when it should be moved. // TRANS: %s is the remote site. throw new Exception(sprintf(_("No AtomPub API service for %s."), $remote)); } return array($svcDocUrl, $username); }
public function getKeyPair($signer_uri) { $disco = new Discovery(); try { $xrd = $disco->lookup($signer_uri); } catch (Exception $e) { return false; } if ($xrd->links) { if ($link = Discovery::getService($xrd->links, Magicsig::PUBLICKEYREL)) { $keypair = false; $parts = explode(',', $link['href']); if (count($parts) == 2) { $keypair = $parts[1]; } else { // Backwards compatibility check for separator bug in 0.9.0 $parts = explode(';', $link['href']); if (count($parts) == 2) { $keypair = $parts[1]; } } if ($keypair) { return $keypair; } } } throw new Exception('Unable to locate signer public key'); }
static function getServiceDocument($remote) { $discovery = new Discovery(); $xrd = $discovery->lookup($remote); if (empty($xrd)) { // TRANS: Exception thrown when a service document could not be located account move. // TRANS: %s is the remote site. throw new Exception(sprintf(_("Cannot find XRD for %s."), $remote)); } $svcDocUrl = null; $username = null; $link = $xrd->links->get('http://apinamespace.org/atom', 'application/atomsvc+xml'); if (!is_null($link)) { $svcDocUrl = $link->href; if (isset($link['http://apinamespace.org/atom/username'])) { $username = $link['http://apinamespace.org/atom/username']; break; } } if (empty($svcDocUrl)) { // TRANS: Exception thrown when an account could not be located when it should be moved. // TRANS: %s is the remote site. throw new Exception(sprintf(_("No AtomPub API service for %s."), $remote)); } return array($svcDocUrl, $username); }
/** * For RFC6415 and HTTP URIs, fetch the host-meta file * and look for LRDD templates */ public function discover($uri) { // This is allowed for RFC6415 but not the 'WebFinger' RFC7033. $try_schemes = array('https', 'http'); $scheme = mb_strtolower(parse_url($uri, PHP_URL_SCHEME)); switch ($scheme) { case 'acct': if (!Discovery::isAcct($uri)) { throw new Exception('Bad resource URI: ' . $uri); } // We can't use parse_url data for this, since the 'host' // entry is only set if the scheme has '://' after it. list($user, $domain) = explode('@', parse_url($uri, PHP_URL_PATH)); break; case 'http': case 'https': $domain = mb_strtolower(parse_url($uri, PHP_URL_HOST)); $try_schemes = array($scheme); break; default: throw new Exception('Unable to discover resource descriptor endpoint.'); } foreach ($try_schemes as $scheme) { $url = $scheme . '://' . $domain . '/.well-known/host-meta'; try { $response = self::fetchUrl($url); $this->xrd->loadString($response->getBody()); } catch (Exception $e) { common_debug('LRDD could not load resource descriptor: ' . $url . ' (' . $e->getMessage() . ')'); continue; } return $this->xrd->links; } throw new Exception('Unable to retrieve resource descriptor links.'); }
/** * @description Service Discovery */ function discover() { using('lepton.net.httprequest'); using('lepton.web.discovery'); $d = Discovery::discover('http://127.0.0.1'); $this->assertNotNull($d); }
function prepare($args) { parent::prepare($args); $this->uri = $this->trimmed('uri'); $this->uri = Discovery::normalize($this->uri); if (Discovery::isWebfinger($this->uri)) { $parts = explode('@', substr(urldecode($this->uri), 5)); if (count($parts) == 2) { list($nick, $domain) = $parts; // @fixme confirm the domain too // @fixme if domain checking is added, ensure that it will not // cause problems with sites that have changed domains! $nick = common_canonical_nickname($nick); $this->user = User::staticGet('nickname', $nick); } } else { $this->user = User::staticGet('uri', $this->uri); if (empty($this->user)) { // try and get it by profile url $profile = Profile::staticGet('profileurl', $this->uri); if (!empty($profile)) { $this->user = User::staticGet('id', $profile->id); } } } if (!$this->user) { $this->clientError(_m('No such user.'), 404); return false; } return true; }
function connectWebfinger($acct) { $target_profile = $this->targetProfile(); $disco = new Discovery(); $xrd = $disco->lookup($acct); $link = $xrd->get('http://ostatus.org/schema/1.0/tag'); if (!is_null($link)) { // We found a URL - let's redirect! if (!empty($link->template)) { $url = Discovery::applyTemplate($link->template, $target_profile); } else { $url = $link->href; } common_log(LOG_INFO, "Sending remote subscriber {$acct} to {$url}"); common_redirect($url, 303); } // TRANS: Client error displayed when remote profile address could not be confirmed. $this->clientError(_m('Could not confirm remote profile address.')); }
function handle() { $nick = $this->user->nickname; $profile = $this->user->getProfile(); if (empty($this->xrd)) { $xrd = new XRD(); } else { $xrd = $this->xrd; } if (empty($xrd->subject)) { $xrd->subject = Discovery::normalize($this->uri); } // Possible aliases for the user $uris = array($this->user->uri, $profile->profileurl); // FIXME: Webfinger generation code should live somewhere on its own $path = common_config('site', 'path'); if (empty($path)) { $uris[] = sprintf('acct:%s@%s', $nick, common_config('site', 'server')); } foreach ($uris as $uri) { if ($uri != $xrd->subject) { $xrd->alias[] = $uri; } } $xrd->links[] = array('rel' => Discovery::PROFILEPAGE, 'type' => 'text/html', 'href' => $profile->profileurl); $xrd->links[] = array('rel' => Discovery::UPDATESFROM, 'href' => common_local_url('ApiTimelineUser', array('id' => $this->user->id, 'format' => 'atom')), 'type' => 'application/atom+xml'); // hCard $xrd->links[] = array('rel' => Discovery::HCARD, 'type' => 'text/html', 'href' => common_local_url('hcard', array('nickname' => $nick))); // XFN $xrd->links[] = array('rel' => 'http://gmpg.org/xfn/11', 'type' => 'text/html', 'href' => $profile->profileurl); // FOAF $xrd->links[] = array('rel' => 'describedby', 'type' => 'application/rdf+xml', 'href' => common_local_url('foaf', array('nickname' => $nick))); // Salmon $salmon_url = common_local_url('usersalmon', array('id' => $this->user->id)); $xrd->links[] = array('rel' => Salmon::REL_SALMON, 'href' => $salmon_url); // XXX : Deprecated - to be removed. $xrd->links[] = array('rel' => Salmon::NS_REPLIES, 'href' => $salmon_url); $xrd->links[] = array('rel' => Salmon::NS_MENTIONS, 'href' => $salmon_url); // Get this user's keypair $magickey = Magicsig::staticGet('user_id', $this->user->id); if (!$magickey) { // No keypair yet, let's generate one. $magickey = new Magicsig(); $magickey->generate($this->user->id); } $xrd->links[] = array('rel' => Magicsig::PUBLICKEYREL, 'href' => 'data:application/magic-public-key,' . $magickey->toString(false)); // TODO - finalize where the redirect should go on the publisher $url = common_local_url('ostatussub') . '?profile={uri}'; $xrd->links[] = array('rel' => 'http://ostatus.org/schema/1.0/subscribe', 'template' => $url); $url = common_local_url('tagprofile') . '?uri={uri}'; $xrd->links[] = array('rel' => 'http://ostatus.org/schema/1.0/tag', 'template' => $url); header('Content-type: application/xrd+xml'); print $xrd->toXML(); }
function connectWebfinger($acct) { $target_profile = $this->targetProfile(); $disco = new Discovery(); $result = $disco->lookup($acct); if (!$result) { // TRANS: Client error displayed when remote profile could not be looked up. $this->clientError(_m('Could not look up OStatus account profile.')); } foreach ($result->links as $link) { if ($link['rel'] == 'http://ostatus.org/schema/1.0/tag') { // We found a URL - let's redirect! $url = Discovery::applyTemplate($link['template'], $target_profile); common_log(LOG_INFO, "Sending remote subscriber {$acct} to {$url}"); common_redirect($url, 303); } } // TRANS: Client error displayed when remote profile address could not be confirmed. $this->clientError(_m('Could not confirm remote profile address.')); }
protected function setXRD() { parent::setXRD(); // Check to see if a $config['webfinger']['owner'] has been set // and then make sure 'subject' is set to that primary identity. if ($owner = common_config('webfinger', 'owner')) { $this->xrd->aliases[] = $this->xrd->subject; $this->xrd->subject = Discovery::normalize($owner); } else { $this->xrd->subject = $this->resource; } }
/** * Simply returns the WebFinger URL over HTTPS at the uri's domain: * https://{domain}/.well-known/webfinger?resource={uri} */ public function discover($uri) { if (!Discovery::isAcct($uri)) { throw new Exception('Bad resource URI: ' . $uri); } list($user, $domain) = explode('@', parse_url($uri, PHP_URL_PATH)); if (!filter_var($domain, FILTER_VALIDATE_IP) && !filter_var(gethostbyname($domain), FILTER_VALIDATE_IP)) { throw new Exception('Bad resource host.'); } $link = new XML_XRD_Element_Link(Discovery::LRDD_REL, 'https://' . $domain . '/.well-known/webfinger?resource={uri}', Discovery::JRD_MIMETYPE, true); //isTemplate return array($link); }
protected function prepare(array $args = array()) { parent::prepare($args); // throws exception if resource is empty $this->resource = Discovery::normalize($this->trimmed('resource')); try { if (Event::handle('StartGetWebFingerResource', array($this->resource, &$this->target, $this->args))) { Event::handle('EndGetWebFingerResource', array($this->resource, &$this->target, $this->args)); } } catch (NoSuchUserException $e) { throw new ServerException($e->getMessage(), 404); } if (!$this->target instanceof WebFingerResource) { // TRANS: Error message when an object URI which we cannot find was requested throw new ServerException(_m('Resource not found in local database.'), 404); } return true; }
function prepare($args) { $this->user = User::siteOwner(); if (!$this->user) { $this->clientError(_('No such user.'), 404); return false; } $nick = common_canonical_nickname($this->user->nickname); $acct = 'acct:' . $nick . '@' . common_config('site', 'server'); $this->xrd = new XRD(); // Check to see if a $config['webfinger']['owner'] has been set if ($owner = common_config('webfinger', 'owner')) { $this->xrd->subject = Discovery::normalize($owner); $this->xrd->alias[] = $acct; } else { $this->xrd->subject = $acct; } return true; }
function prepare($args) { parent::prepare($args); $this->uri = $this->trimmed('uri'); $this->uri = Discovery::normalize($this->uri); if (Discovery::isWebfinger($this->uri)) { $parts = explode('@', substr(urldecode($this->uri), 5)); if (count($parts) == 2) { list($nick, $domain) = $parts; // @fixme confirm the domain too $nick = common_canonical_nickname($nick); $this->user = User::staticGet('nickname', $nick); } } else { $this->user = User::staticGet('uri', $this->uri); } if (!$this->user) { $this->clientError(_('用户不存在'), 404); return false; } return true; }
function handle() { $nick = $this->user->nickname; if (empty($this->xrd)) { $xrd = new XRD(); } else { $xrd = $this->xrd; } if (empty($xrd->subject)) { $xrd->subject = Discovery::normalize($this->uri); } $xrd->alias[] = $this->user->uri; $xrd->links[] = array('rel' => Discovery::PROFILEPAGE, 'type' => 'text/html', 'href' => $this->user->uri); $xrd->links[] = array('rel' => Discovery::UPDATESFROM, 'href' => common_local_url('ApiTimelineUser', array('id' => $this->user->id, 'format' => 'atom')), 'type' => 'application/atom+xml'); // hCard $xrd->links[] = array('rel' => Discovery::HCARD, 'type' => 'text/html', 'href' => common_local_url('hcard', array('nickname' => $nick))); // XFN $xrd->links[] = array('rel' => 'http://gmpg.org/xfn/11', 'type' => 'text/html', 'href' => $this->user->uri); // FOAF $xrd->links[] = array('rel' => 'describedby', 'type' => 'application/rdf+xml', 'href' => common_local_url('foaf', array('nickname' => $nick))); // Salmon $salmon_url = common_local_url('usersalmon', array('id' => $this->user->id)); $xrd->links[] = array('rel' => Salmon::NS_REPLIES, 'href' => $salmon_url); $xrd->links[] = array('rel' => Salmon::NS_MENTIONS, 'href' => $salmon_url); // Get this user's keypair $magickey = Magicsig::staticGet('user_id', $this->user->id); if (!$magickey) { // No keypair yet, let's generate one. $magickey = new Magicsig(); $magickey->generate($this->user->id); } $xrd->links[] = array('rel' => Magicsig::PUBLICKEYREL, 'href' => 'data:application/magic-public-key,' . $magickey->toString(false)); // TODO - finalize where the redirect should go on the publisher $url = common_local_url('ostatussub') . '?profile={uri}'; $xrd->links[] = array('rel' => 'http://ostatus.org/schema/1.0/subscribe', 'template' => $url); header('Content-type: text/xml'); print $xrd->toXML(); }
public function onStartHostMetaLinks(array &$links) { foreach (Discovery::supportedMimeTypes() as $type) { $links[] = new XML_XRD_Element_Link(Discovery::LRDD_REL, common_local_url('webfinger') . '?resource={uri}', $type, true); // isTemplate } // OAuth connections $links[] = new XML_XRD_Element_link(self::OAUTH_ACCESS_TOKEN_REL, common_local_url('ApiOAuthAccessToken')); $links[] = new XML_XRD_Element_link(self::OAUTH_REQUEST_TOKEN_REL, common_local_url('ApiOAuthRequestToken')); $links[] = new XML_XRD_Element_link(self::OAUTH_AUTHORIZE_REL, common_local_url('ApiOAuthAuthorize')); }
/** * Get the Salmon keypair from a URI, uses XRD Discovery etc. Reasonably * you'll only get the public key ;) * * The string will (hopefully) be formatted as described in Magicsig specification: * https://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-magicsig-01.html#anchor13 * * @return string formatted as Magicsig keypair */ public function discoverKeyPair(Profile $profile) { $signer_uri = $profile->getUri(); if (empty($signer_uri)) { throw new ServerException(sprintf('Profile missing URI (id==%d)', $profile->id)); } $disco = new Discovery(); // Throws exception on lookup problems $xrd = $disco->lookup($signer_uri); $link = $xrd->get(Magicsig::PUBLICKEYREL); if (is_null($link)) { // TRANS: Exception. throw new Exception(_m('Unable to locate signer public key.')); } // We have a public key element, let's hope it has proper key data. $keypair = false; $parts = explode(',', $link->href); if (count($parts) == 2) { $keypair = $parts[1]; } else { // Backwards compatibility check for separator bug in 0.9.0 $parts = explode(';', $link->href); if (count($parts) == 2) { $keypair = $parts[1]; } } if ($keypair === false) { // For debugging clarity. Keypair did not pass count()-check above. // TRANS: Exception when public key was not properly formatted. throw new Exception(_m('Incorrectly formatted public key element.')); } return $keypair; }
function ensureProfiles() { try { $this->oprofile = Ostatus_profile::getActorProfile($this->activity); if (!$this->oprofile instanceof Ostatus_profile) { throw new UnknownUriException($this->activity->actor->id); } } catch (UnknownUriException $e) { // Apparently we didn't find the Profile object based on our URI, // so OStatus doesn't have it with this URI in ostatus_profile. // Try to look it up again, remote side may have changed from http to https // or maybe publish an acct: URI now instead of an http: URL. // // Steps: // 1. Check the newly received URI. Who does it say it is? // 2. Compare these alleged identities to our local database. // 3. If we found any locally stored identities, ask it about its aliases. // 4. Do any of the aliases from our known identity match the recently introduced one? // // Example: We have stored http://example.com/user/1 but this URI says https://example.com/user/1 common_debug('No local Profile object found for a magicsigned activity author URI: ' . $e->object_uri); $disco = new Discovery(); $xrd = $disco->lookup($e->object_uri); // Step 1: We got a bunch of discovery data for https://example.com/user/1 which includes // aliases https://example.com/user and hopefully our original http://example.com/user/1 too $all_ids = array_merge(array($xrd->subject), $xrd->aliases); if (!in_array($e->object_uri, $all_ids)) { common_debug('The activity author URI we got was not listed itself when doing discovery on it.'); throw $e; } // Go through each reported alias from lookup to see if we know this already foreach ($all_ids as $aliased_uri) { $oprofile = Ostatus_profile::getKV('uri', $aliased_uri); if (!$oprofile instanceof Ostatus_profile) { continue; // unknown locally, check the next alias } // Step 2: We found the alleged http://example.com/user/1 URI in our local database, // but this can't be trusted yet because anyone can publish any alias. common_debug('Found a local Ostatus_profile for "' . $e->object_uri . '" with this URI: ' . $aliased_uri); // We found an existing OStatus profile, but is it really the same? Do a callback to the URI's origin // Step 3: lookup our previously known http://example.com/user/1 webfinger etc. $xrd = $disco->lookup($oprofile->getUri()); // getUri returns ->uri, which we filtered on earlier $doublecheck_aliases = array_merge(array($xrd->subject), $xrd->aliases); common_debug('Trying to match known "' . $aliased_uri . '" against its returned aliases: ' . implode(' ', $doublecheck_aliases)); // if we find our original URI here, it is a legitimate alias // Step 4: Is the newly introduced https://example.com/user/1 URI in the list of aliases // presented by http://example.com/user/1 (i.e. do they both say they are the same identity?) if (in_array($e->object_uri, $doublecheck_aliases)) { $oprofile->updateUriKeys($e->object_uri, DiscoveryHints::fromXRD($xrd)); $this->oprofile = $oprofile; break; // don't iterate through aliases anymore } } // We might end up here after $all_ids is iterated through without a $this->oprofile value, if (!$this->oprofile instanceof Ostatus_profile) { common_debug("We do not have a local profile to connect to this activity's author. Let's create one."); // ensureActivityObjectProfile throws exception on failure $this->oprofile = Ostatus_profile::ensureActivityObjectProfile($this->activity->actor); } } assert($this->oprofile instanceof Ostatus_profile); $this->actor = $this->oprofile->localProfile(); }
public static function getProvider($url) { $discovery = new Discovery(); return $discovery->discover($url); }
/** * Look up, and if necessary create, an Ostatus_profile for the remote * entity with the given webfinger address. * This should never return null -- you will either get an object or * an exception will be thrown. * * @param string $addr webfinger address * @return Ostatus_profile * @throws Exception on error conditions * @throws OStatusShadowException if this reference would obscure a local user/group */ public static function updateWebfinger($addr) { $disco = new Discovery(); try { $xrd = $disco->lookup($addr); } catch (Exception $e) { // Save negative cache entry so we don't waste time looking it up again. // @fixme distinguish temporary failures? self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), null); // TRANS: Exception. throw new Exception(_m('Not a valid webfinger address.')); } $hints = array('webfinger' => $addr); $dhints = DiscoveryHints::fromXRD($xrd); $hints = array_merge($hints, $dhints); // If there's an Hcard, let's grab its info if (array_key_exists('hcard', $hints)) { if (!array_key_exists('profileurl', $hints) || $hints['hcard'] != $hints['profileurl']) { $hcardHints = DiscoveryHints::fromHcardUrl($hints['hcard']); $hints = array_merge($hcardHints, $hints); } } // If we got a feed URL, try that if (array_key_exists('feedurl', $hints)) { try { common_log(LOG_INFO, "Discovery on acct:{$addr} with feed URL " . $hints['feedurl']); $oprofile = self::ensureFeedURL($hints['feedurl'], $hints); self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri); return $oprofile; } catch (Exception $e) { common_log(LOG_WARNING, "Failed creating profile from feed URL '{$feedUrl}': " . $e->getMessage()); // keep looking } } // If we got a profile page, try that! if (array_key_exists('profileurl', $hints)) { try { common_log(LOG_INFO, "Discovery on acct:{$addr} with profile URL {$profileUrl}"); $oprofile = self::ensureProfileURL($hints['profileurl'], $hints); self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->uri); return $oprofile; } catch (OStatusShadowException $e) { // We've ended up with a remote reference to a local user or group. // @fixme ideally we should be able to say who it was so we can // go back and refer to it the regular way throw $e; } catch (Exception $e) { common_log(LOG_WARNING, "Failed creating profile from profile URL '{$profileUrl}': " . $e->getMessage()); // keep looking // // @fixme this means an error discovering from profile page // may give us a corrupt entry using the webfinger URI, which // will obscure the correct page-keyed profile later on. } } throw new Exception(sprintf(_m('Could not find a valid profile for "%s".'), $addr)); }
<?php //发现页面数据调用接口 require_once '../../models/Response.php'; require_once '../..//models/Discovery.php'; $style = new Response(); //$gender = isset($_GET['gender'])?$_GET['gender']:0; $pageId = isset($_GET['pageId']) ? $_GET['pageId'] : 1; $re = new Discovery(); $data = $re->presentForHuman2($pageId); echo $style->show('200', $data);
/** * Get the Salmon keypair from a URI, uses XRD Discovery etc. Reasonably * you'll only get the public key ;) * * The string will (hopefully) be formatted as described in Magicsig specification: * https://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-magicsig-01.html#anchor13 * * @return string formatted as Magicsig keypair */ public function discoverKeyPair(Profile $profile) { $signer_uri = $profile->getUri(); if (empty($signer_uri)) { throw new ServerException(sprintf('Profile missing URI (id==%d)', $profile->getID())); } $disco = new Discovery(); // Throws exception on lookup problems try { $xrd = $disco->lookup($signer_uri); } catch (Exception $e) { // Diaspora seems to require us to request the acct: uri $xrd = $disco->lookup($profile->getAcctUri()); } common_debug('Will try to find magic-public-key from XRD of profile id==' . $profile->getID()); $pubkey = null; if (Event::handle('MagicsigPublicKeyFromXRD', array($xrd, &$pubkey))) { $link = $xrd->get(Magicsig::PUBLICKEYREL); if (is_null($link)) { // TRANS: Exception. throw new Exception(_m('Unable to locate signer public key.')); } $pubkey = $link->href; } if (empty($pubkey)) { throw new ServerException('Empty Magicsig public key. A bug?'); } // We have a public key element, let's hope it has proper key data. $keypair = false; $parts = explode(',', $pubkey); if (count($parts) == 2) { $keypair = $parts[1]; } else { // Backwards compatibility check for separator bug in 0.9.0 $parts = explode(';', $pubkey); if (count($parts) == 2) { $keypair = $parts[1]; } } if ($keypair === false) { // For debugging clarity. Keypair did not pass count()-check above. // TRANS: Exception when public key was not properly formatted. throw new Exception(_m('Incorrectly formatted public key element.')); } return $keypair; }
<?php require_once '../..//models/Discovery.php'; require_once '../..//models/Response.php'; //获取发现页中的给爸/妈礼物数量 $re = new Discovery(); $data['father'] = $re->numForHuman(1); $data['mother'] = $re->numForHuman(0); echo Response::show('200', $data);
print "Re-running feed discovery for profile URL {$oprofile->uri}\n"; $feedurl = null; $salmonuri = null; // @fixme will bork where the URI isn't the profile URL for now $discover = new FeedDiscovery(); try { $feedurl = $discover->discoverFromURL($oprofile->uri); $salmonuri = $discover->getAtomLink(Salmon::REL_SALMON) ?: $discover->getAtomLink(Salmon::NS_REPLIES); // NS_REPLIES is deprecated if (empty($salmonuri)) { throw new FeedSubNoSalmonException('No salmon upstream URI was found'); } } catch (FeedSubException $e) { $acct = $oprofile->localProfile()->getAcctUri(); print "Could not discover feeds HTML response, trying reconstructed acct URI: {$acct}\n"; $disco = new Discovery(); $xrd = $disco->lookup($acct); $hints = DiscoveryHints::fromXRD($xrd); if (empty($feedurl) && !array_key_exists('feedurl', $hints)) { throw new FeedSubNoFeedException($acct); } $feedurl = $feedurl ?: $hints['feedurl']; $salmonuri = array_key_exists('salmon', $hints) ? $hints['salmon'] : $salmonuri; // get the hub data too and put it in the FeedDiscovery object $discover->discoverFromFeedUrl($feedurl); } $huburi = $discover->getHubLink(); print " Feed URL: {$feedurl}\n"; print " Hub URL: {$huburi}\n"; print " Salmon URL: {$salmonuri}\n"; if ($feedurl != $oprofile->feeduri || $salmonuri != $oprofile->salmonuri) {
<?php //发现页面数据调用接口 require_once '../../models/Response.php'; require_once '../..//models/Discovery.php'; $style = new Response(); $gender = isset($_GET['gender']) ? $_GET['gender'] : NULL; $pageId = isset($_GET['page']) ? $_GET['page'] : 1; $uid = isset($_GET['uid']) ? $_GET['uid'] : 1; $type = isset($_GET['type']) ? $_GET['type'] : NULL; $re = new Discovery(); $data = $re->presentForHuman($gender, $type, $pageId, $uid); echo $style->show('200', $data);
/** * Given a user ID, return the first available resource descriptor * * @param string $id User ID URI * * @return XML_XRD object for the resource descriptor of the id */ public function lookup($id) { // Normalize the incoming $id to make sure we have a uri $uri = self::normalize($id); foreach ($this->methods as $class) { try { $xrd = new XML_XRD(); common_debug("LRDD discovery method for '{$uri}': {$class}"); $lrdd = new $class(); $links = call_user_func(array($lrdd, 'discover'), $uri); $link = Discovery::getService($links, Discovery::LRDD_REL); // Load the LRDD XRD if (!empty($link->template)) { $xrd_uri = Discovery::applyTemplate($link->template, $uri); } elseif (!empty($link->href)) { $xrd_uri = $link->href; } else { throw new Exception('No resource descriptor URI in link.'); } $client = new HTTPClient(); $headers = array(); if (!is_null($link->type)) { $headers[] = "Accept: {$link->type}"; } $response = $client->get($xrd_uri, $headers); if ($response->getStatus() != 200) { throw new Exception('Unexpected HTTP status code.'); } $xrd->loadString($response->getBody()); return $xrd; } catch (Exception $e) { continue; } } // TRANS: Exception. %s is an ID. throw new Exception(sprintf(_('Unable to find services for %s.'), $id)); }
public function onEndDiscoveryMethodRegistration(Discovery $disco) { $disco->registerMethod('LRDDMethod_HostMeta'); $disco->registerMethod('LRDDMethod_LinkHeader'); $disco->registerMethod('LRDDMethod_LinkHTML'); }
public function discover($uri) { if (Discovery::isWebfinger($uri)) { // We have a webfinger acct: - start with host-meta list($name, $domain) = explode('@', $uri); } else { $domain = parse_url($uri, PHP_URL_HOST); } $url = 'http://' . $domain . '/.well-known/host-meta'; $xrd = Discovery::fetchXrd($url); if ($xrd) { if ($xrd->host != $domain) { return false; } return $xrd->links; } }
/** * Look up, and if necessary create, an Ostatus_profile for the remote * entity with the given webfinger address. * This should never return null -- you will either get an object or * an exception will be thrown. * * @param string $addr webfinger address * @return Ostatus_profile * @throws Exception on error conditions * @throws OStatusShadowException if this reference would obscure a local user/group */ public static function ensureWebfinger($addr) { // First, try the cache $uri = self::cacheGet(sprintf('ostatus_profile:webfinger:%s', $addr)); if ($uri !== false) { if (is_null($uri)) { // Negative cache entry // TRANS: Exception. throw new Exception(_m('Not a valid webfinger address.')); } $oprofile = Ostatus_profile::getKV('uri', $uri); if ($oprofile instanceof Ostatus_profile) { return $oprofile; } } // Try looking it up $oprofile = Ostatus_profile::getKV('uri', Discovery::normalize($addr)); if ($oprofile instanceof Ostatus_profile) { self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->getUri()); return $oprofile; } // Now, try some discovery $disco = new Discovery(); try { $xrd = $disco->lookup($addr); } catch (Exception $e) { // Save negative cache entry so we don't waste time looking it up again. // @todo FIXME: Distinguish temporary failures? self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), null); // TRANS: Exception. throw new Exception(_m('Not a valid webfinger address.')); } $hints = array_merge(array('webfinger' => $addr), DiscoveryHints::fromXRD($xrd)); // If there's an Hcard, let's grab its info if (array_key_exists('hcard', $hints)) { if (!array_key_exists('profileurl', $hints) || $hints['hcard'] != $hints['profileurl']) { $hcardHints = DiscoveryHints::fromHcardUrl($hints['hcard']); $hints = array_merge($hcardHints, $hints); } } // If we got a feed URL, try that $feedUrl = null; if (array_key_exists('feedurl', $hints)) { $feedUrl = $hints['feedurl']; try { common_log(LOG_INFO, "Discovery on acct:{$addr} with feed URL " . $hints['feedurl']); $oprofile = self::ensureFeedURL($hints['feedurl'], $hints); self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->getUri()); return $oprofile; } catch (Exception $e) { common_log(LOG_WARNING, "Failed creating profile from feed URL '{$feedUrl}': " . $e->getMessage()); // keep looking } } // If we got a profile page, try that! $profileUrl = null; if (array_key_exists('profileurl', $hints)) { $profileUrl = $hints['profileurl']; try { common_log(LOG_INFO, "Discovery on acct:{$addr} with profile URL {$profileUrl}"); $oprofile = self::ensureProfileURL($hints['profileurl'], $hints); self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->getUri()); return $oprofile; } catch (OStatusShadowException $e) { // We've ended up with a remote reference to a local user or group. // @todo FIXME: Ideally we should be able to say who it was so we can // go back and refer to it the regular way throw $e; } catch (Exception $e) { common_log(LOG_WARNING, "Failed creating profile from profile URL '{$profileUrl}': " . $e->getMessage()); // keep looking // // @todo FIXME: This means an error discovering from profile page // may give us a corrupt entry using the webfinger URI, which // will obscure the correct page-keyed profile later on. } } // XXX: try hcard // XXX: try FOAF if (array_key_exists('salmon', $hints)) { $salmonEndpoint = $hints['salmon']; // An account URL, a salmon endpoint, and a dream? Not much to go // on, but let's give it a try $uri = 'acct:' . $addr; $profile = new Profile(); $profile->nickname = self::nicknameFromUri($uri); $profile->created = common_sql_now(); if (!is_null($profileUrl)) { $profile->profileurl = $profileUrl; } $profile_id = $profile->insert(); if ($profile_id === false) { common_log_db_error($profile, 'INSERT', __FILE__); // TRANS: Exception. %s is a webfinger address. throw new Exception(sprintf(_m('Could not save profile for "%s".'), $addr)); } $oprofile = new Ostatus_profile(); $oprofile->uri = $uri; $oprofile->salmonuri = $salmonEndpoint; $oprofile->profile_id = $profile_id; $oprofile->created = common_sql_now(); if (!is_null($feedUrl)) { $oprofile->feeduri = $feedUrl; } $result = $oprofile->insert(); if ($result === false) { $profile->delete(); common_log_db_error($oprofile, 'INSERT', __FILE__); // TRANS: Exception. %s is a webfinger address. throw new Exception(sprintf(_m('Could not save OStatus profile for "%s".'), $addr)); } self::cacheSet(sprintf('ostatus_profile:webfinger:%s', $addr), $oprofile->getUri()); return $oprofile; } // TRANS: Exception. %s is a webfinger address. throw new Exception(sprintf(_m('Could not find a valid profile for "%s".'), $addr)); }
protected function checkAccept() { $type = null; $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : null; $useragent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null; if ($httpaccept !== null && $httpaccept != '*/*') { $can_serve = implode(',', Discovery::supportedMimeTypes()); $type = common_negotiate_type(common_accept_to_prefs($httpaccept), common_accept_to_prefs($can_serve)); } else { /* * HACK: for StatusNet to work against us, we must always serve an * XRD to at least versions <1.1.1 (at time of writing) since they * don't send Accept headers (in their 'Discovery::fetchXrd' calls) */ $matches = array(); preg_match('/(StatusNet)\\/(\\d+\\.\\d+(\\.\\d+)?)/', $useragent, $browser); if (count($browser) > 2 && $browser[1] === 'StatusNet' && version_compare($browser[2], '1.1.1') < 1) { return Discovery::XRD_MIMETYPE; } } if (empty($type)) { throw new Exception(_('No specified MIME type in Accept header.')); } return $type; }