some work on network discovery
This commit is contained in:
parent
55d4ceb7e0
commit
c7fe071a1f
@ -140,85 +140,30 @@ function find_diaspora_person_by_handle($handle) {
|
|||||||
$endlessloop = 0;
|
$endlessloop = 0;
|
||||||
$maxloops = 10;
|
$maxloops = 10;
|
||||||
|
|
||||||
do {
|
|
||||||
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
|
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
|
||||||
dbesc($handle)
|
dbesc($handle)
|
||||||
);
|
);
|
||||||
if($r) {
|
if($r) {
|
||||||
$person = $r[0];
|
$person = $r[0];
|
||||||
logger('find_diaspora_person_by handle: in cache ' . print_r($r,true), LOGGER_DEBUG);
|
logger('find_diaspora_person_by handle: in cache ' . print_r($r,true), LOGGER_DATA);
|
||||||
|
|
||||||
// update record occasionally so it doesn't get stale
|
// update record occasionally so it doesn't get stale
|
||||||
$d = strtotime($person['updated'] . ' +00:00');
|
// $d = strtotime($person['updated'] . ' +00:00');
|
||||||
if($d < strtotime('now - 14 days'))
|
// if($d < strtotime('now - 14 days'))
|
||||||
$update = true;
|
// $update = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FETCHING PERSON INFORMATION FROM REMOTE SERVER
|
|
||||||
//
|
|
||||||
// If the person isn't in our 'fcontact' table, or if he/she is but
|
|
||||||
// his/her information hasn't been updated for more than 14 days, then
|
|
||||||
// we want to fetch the person's information from the remote server.
|
|
||||||
//
|
|
||||||
// Note that $person isn't changed by this block of code unless the
|
|
||||||
// person's information has been successfully fetched from the remote
|
|
||||||
// server. So if $person was 'false' to begin with (because he/she wasn't
|
|
||||||
// in the local cache), it'll stay false, and if $person held the local
|
|
||||||
// cache information to begin with, it'll keep that information. That way
|
|
||||||
// if there's a problem with the remote fetch, we can at least use our
|
|
||||||
// cached information--it's better than nothing.
|
|
||||||
|
|
||||||
//fixme!!!
|
|
||||||
|
|
||||||
if((! $person) || ($update)) {
|
if((! $person) || ($update)) {
|
||||||
// Lock the function to prevent race conditions if multiple items
|
|
||||||
// come in at the same time from a person who doesn't exist in
|
|
||||||
// fcontact
|
|
||||||
//
|
|
||||||
// Don't loop forever. On the last loop, try to create the contact
|
|
||||||
// whether the function is locked or not. Maybe the locking thread
|
|
||||||
// has died or something. At any rate, a duplicate in 'fcontact'
|
|
||||||
// is a much smaller problem than a deadlocked thread
|
|
||||||
// $got_lock = lock_function('find_diaspora_person_by_handle', false);
|
|
||||||
if(($endlessloop + 1) >= $maxloops)
|
|
||||||
$got_lock = true;
|
|
||||||
|
|
||||||
if($got_lock) {
|
// try webfinger. Make sure to distinguish between diaspora,
|
||||||
logger('find_diaspora_person_by_handle: create or refresh', LOGGER_DEBUG);
|
// redmatrix w/diaspora protocol and friendica w/diaspora protocol.
|
||||||
require_once('include/Scrape.php');
|
|
||||||
$r = probe_url($handle, PROBE_DIASPORA);
|
$result = discover_by_webbie($handle);
|
||||||
|
|
||||||
|
|
||||||
// Note that Friendica contacts can return a "Diaspora person"
|
|
||||||
// if Diaspora connectivity is enabled on their server
|
|
||||||
if((count($r)) && ($r['network'] === NETWORK_DIASPORA)) {
|
|
||||||
add_fcontact($r,$update);
|
|
||||||
$person = ($r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unlock_function('find_diaspora_person_by_handle');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logger('find_diaspora_person_by_handle: couldn\'t lock function', LOGGER_DEBUG);
|
|
||||||
// if(! $person)
|
|
||||||
// block_on_function_lock('find_diaspora_person_by_handle');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while((! $person) && (! $got_lock) && (++$endlessloop < $maxloops));
|
|
||||||
|
|
||||||
// We need to try again if the person wasn't in 'fcontact' but the function was locked.
|
|
||||||
// The fact that the function was locked may mean that another process was creating the
|
|
||||||
// person's record. It could also mean another process was creating or updating an unrelated
|
|
||||||
// person.
|
|
||||||
//
|
|
||||||
// At any rate, we need to keep trying until we've either got the person or had a chance to
|
|
||||||
// try to fetch his/her remote information. But we don't want to block on locking the
|
|
||||||
// function, because if the other process is creating the record, then when we acquire the lock
|
|
||||||
// we'll dive right into creating another, duplicate record. We DO want to at least wait
|
|
||||||
// until the lock is released, so we don't flood the database with requests.
|
|
||||||
//
|
|
||||||
// If the person was in the 'fcontact' table, don't try again. It's not worth the time, since
|
|
||||||
// we do have some information for the person
|
|
||||||
|
|
||||||
return $person;
|
return $person;
|
||||||
}
|
}
|
||||||
|
@ -337,101 +337,6 @@ function convert_xml_element_to_array($xml_element, &$recursion_depth=0) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given an email style address, perform webfinger lookup and
|
|
||||||
// return the resulting DFRN profile URL, or if no DFRN profile URL
|
|
||||||
// is located, returns an OStatus subscription template (prefixed
|
|
||||||
// with the string 'stat:' to identify it as on OStatus template).
|
|
||||||
// If this isn't an email style address just return $s.
|
|
||||||
// Return an empty string if email-style addresses but webfinger fails,
|
|
||||||
// or if the resultant personal XRD doesn't contain a supported
|
|
||||||
// subscription/friend-request attribute.
|
|
||||||
|
|
||||||
// amended 7/9/2011 to return an hcard which could save potentially loading
|
|
||||||
// a lengthy content page to scrape dfrn attributes
|
|
||||||
|
|
||||||
|
|
||||||
function webfinger_dfrn($s,&$hcard) {
|
|
||||||
if(! strstr($s,'@')) {
|
|
||||||
return $s;
|
|
||||||
}
|
|
||||||
$profile_link = '';
|
|
||||||
|
|
||||||
$links = webfinger($s);
|
|
||||||
logger('webfinger_dfrn: ' . $s . ':' . print_r($links,true), LOGGER_DATA);
|
|
||||||
if(count($links)) {
|
|
||||||
foreach($links as $link) {
|
|
||||||
if($link['@attributes']['rel'] === NAMESPACE_DFRN)
|
|
||||||
$profile_link = $link['@attributes']['href'];
|
|
||||||
if($link['@attributes']['rel'] === NAMESPACE_OSTATUSSUB)
|
|
||||||
$profile_link = 'stat:' . $link['@attributes']['template'];
|
|
||||||
if($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard')
|
|
||||||
$hcard = $link['@attributes']['href'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $profile_link;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given an email style address, perform webfinger lookup and
|
|
||||||
// return the array of link attributes from the personal XRD file.
|
|
||||||
// On error/failure return an empty array.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function webfinger($s, $debug = false) {
|
|
||||||
$host = '';
|
|
||||||
if(strstr($s,'@')) {
|
|
||||||
$host = substr($s,strpos($s,'@') + 1);
|
|
||||||
}
|
|
||||||
if(strlen($host)) {
|
|
||||||
$tpl = fetch_lrdd_template($host);
|
|
||||||
logger('webfinger: lrdd template: ' . $tpl);
|
|
||||||
if(strlen($tpl)) {
|
|
||||||
$pxrd = str_replace('{uri}', urlencode('acct:' . $s), $tpl);
|
|
||||||
logger('webfinger: pxrd: ' . $pxrd);
|
|
||||||
$links = fetch_xrd_links($pxrd);
|
|
||||||
if(! count($links)) {
|
|
||||||
// try with double slashes
|
|
||||||
$pxrd = str_replace('{uri}', urlencode('acct://' . $s), $tpl);
|
|
||||||
logger('webfinger: pxrd: ' . $pxrd);
|
|
||||||
$links = fetch_xrd_links($pxrd);
|
|
||||||
}
|
|
||||||
return $links;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Given a host name, locate the LRDD template from that
|
|
||||||
// host. Returns the LRDD template or an empty string on
|
|
||||||
// error/failure.
|
|
||||||
|
|
||||||
|
|
||||||
function fetch_lrdd_template($host) {
|
|
||||||
$tpl = '';
|
|
||||||
|
|
||||||
$url1 = 'https://' . $host . '/.well-known/host-meta' ;
|
|
||||||
$url2 = 'http://' . $host . '/.well-known/host-meta' ;
|
|
||||||
$links = fetch_xrd_links($url1);
|
|
||||||
logger('fetch_lrdd_template from: ' . $url1);
|
|
||||||
logger('template (https): ' . print_r($links,true));
|
|
||||||
if(! count($links)) {
|
|
||||||
logger('fetch_lrdd_template from: ' . $url2);
|
|
||||||
$links = fetch_xrd_links($url2);
|
|
||||||
logger('template (http): ' . print_r($links,true));
|
|
||||||
}
|
|
||||||
if(count($links)) {
|
|
||||||
foreach($links as $link)
|
|
||||||
if($link['@attributes']['rel'] && $link['@attributes']['rel'] === 'lrdd')
|
|
||||||
$tpl = $link['@attributes']['template'];
|
|
||||||
}
|
|
||||||
if(! strpos($tpl,'{uri}'))
|
|
||||||
$tpl = '';
|
|
||||||
return $tpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take a URL from the wild, prepend http:// if necessary
|
// Take a URL from the wild, prepend http:// if necessary
|
||||||
// and check DNS to see if it's real (or check if is a valid IP address)
|
// and check DNS to see if it's real (or check if is a valid IP address)
|
||||||
// return true if it's OK, false if something is wrong with it
|
// return true if it's OK, false if something is wrong with it
|
||||||
@ -912,3 +817,152 @@ function email_send($addr, $subject, $headers, $item) {
|
|||||||
logger('notifier: email delivery to ' . $addr);
|
logger('notifier: email delivery to ' . $addr);
|
||||||
mail($addr, $subject, $body, $headers);
|
mail($addr, $subject, $body, $headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function discover_by_webbie($webbie) {
|
||||||
|
|
||||||
|
$x = webfinger_rfc7033($webbie);
|
||||||
|
if($x && array_key_exists('links',$x) && $x['links']) {
|
||||||
|
foreach($x['links'] as $link) {
|
||||||
|
if(array_key_exists('rel',$link) && $link['rel'] == 'http://purl.org/zot/protocol') {
|
||||||
|
logger('discover_by_webbie: zot found for ' . $webbie);
|
||||||
|
$z = z_fetch_url($link['href']);
|
||||||
|
if($z['success']) {
|
||||||
|
$j = json_decode($z['body'],true);
|
||||||
|
$i = import_xchan($j);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = old_webfinger($webbie);
|
||||||
|
if($x) {
|
||||||
|
logger('old_webfinger: ' . print_r($x,true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function webfinger_rfc7033($webbie) {
|
||||||
|
|
||||||
|
|
||||||
|
if(! strpos($webbie,'@'))
|
||||||
|
return false;
|
||||||
|
$lhs = substr($webbie,0,strpos($webbie,'@'));
|
||||||
|
$rhs = substr($webbie,strpos($webbie,'@')+1);
|
||||||
|
|
||||||
|
$resource = 'acct:' . $webbie;
|
||||||
|
|
||||||
|
$s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?resource=' . $resource);
|
||||||
|
|
||||||
|
if($s['success'])
|
||||||
|
$j = json_decode($s['body'],true);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
return($j);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function old_webfinger($webbie) {
|
||||||
|
|
||||||
|
$host = '';
|
||||||
|
if(strstr($webbie,'@'))
|
||||||
|
$host = substr($webbie,strpos($webbie,'@') + 1);
|
||||||
|
|
||||||
|
if(strlen($host)) {
|
||||||
|
$tpl = fetch_lrdd_template($host);
|
||||||
|
logger('old_webfinger: lrdd template: ' . $tpl,LOGGER_DATA);
|
||||||
|
if(strlen($tpl)) {
|
||||||
|
$pxrd = str_replace('{uri}', urlencode('acct:' . $webbie), $tpl);
|
||||||
|
logger('old_webfinger: pxrd: ' . $pxrd,LOGGER_DATA);
|
||||||
|
$links = fetch_xrd_links($pxrd);
|
||||||
|
if(! count($links)) {
|
||||||
|
// try with double slashes
|
||||||
|
$pxrd = str_replace('{uri}', urlencode('acct://' . $webbie), $tpl);
|
||||||
|
logger('old_webfinger: pxrd: ' . $pxrd,LOGGER_DATA);
|
||||||
|
$links = fetch_xrd_links($pxrd);
|
||||||
|
}
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function fetch_lrdd_template($host) {
|
||||||
|
$tpl = '';
|
||||||
|
|
||||||
|
$url1 = 'https://' . $host . '/.well-known/host-meta' ;
|
||||||
|
$url2 = 'http://' . $host . '/.well-known/host-meta' ;
|
||||||
|
$links = fetch_xrd_links($url1);
|
||||||
|
logger('fetch_lrdd_template from: ' . $url1, LOGGER_DEBUG);
|
||||||
|
logger('template (https): ' . print_r($links,true),LOGGER_DEBUG);
|
||||||
|
if(! count($links)) {
|
||||||
|
logger('fetch_lrdd_template from: ' . $url2);
|
||||||
|
$links = fetch_xrd_links($url2);
|
||||||
|
logger('template (http): ' . print_r($links,true),LOGGER_DEBUG);
|
||||||
|
}
|
||||||
|
if(count($links)) {
|
||||||
|
foreach($links as $link)
|
||||||
|
if($link['@attributes']['rel'] && $link['@attributes']['rel'] === 'lrdd' && (!$link['@attributes']['type'] || $link['@attributes']['type'] === 'application/xrd+xml'))
|
||||||
|
$tpl = $link['@attributes']['template'];
|
||||||
|
}
|
||||||
|
if(! strpos($tpl,'{uri}'))
|
||||||
|
$tpl = '';
|
||||||
|
return $tpl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function fetch_xrd_links($url) {
|
||||||
|
|
||||||
|
logger('fetch_xrd_links: ' . $url);
|
||||||
|
|
||||||
|
$redirects = 0;
|
||||||
|
$x = z_fetch_url($url,false,$redirects,array('timeout' => 20));
|
||||||
|
|
||||||
|
if(! $x['success'])
|
||||||
|
return array();
|
||||||
|
|
||||||
|
$xml = $x['body'];
|
||||||
|
logger('fetch_xrd_links: ' . $xml, LOGGER_DATA);
|
||||||
|
|
||||||
|
if ((! $xml) || (! stristr($xml,'<xrd')))
|
||||||
|
return array();
|
||||||
|
|
||||||
|
// fix diaspora's bad xml
|
||||||
|
$xml = str_replace(array('href="','"/>'),array('href="','"/>'),$xml);
|
||||||
|
|
||||||
|
$h = parse_xml_string($xml);
|
||||||
|
if(! $h)
|
||||||
|
return array();
|
||||||
|
|
||||||
|
$arr = convert_xml_element_to_array($h);
|
||||||
|
|
||||||
|
$links = array();
|
||||||
|
|
||||||
|
if(isset($arr['xrd']['link'])) {
|
||||||
|
$link = $arr['xrd']['link'];
|
||||||
|
|
||||||
|
if(! isset($link[0]))
|
||||||
|
$links = array($link);
|
||||||
|
else
|
||||||
|
$links = $link;
|
||||||
|
}
|
||||||
|
if(isset($arr['xrd']['alias'])) {
|
||||||
|
$alias = $arr['xrd']['alias'];
|
||||||
|
if(! isset($alias[0]))
|
||||||
|
$aliases = array($alias);
|
||||||
|
else
|
||||||
|
$aliases = $alias;
|
||||||
|
if(is_array($aliases) && count($aliases)) {
|
||||||
|
foreach($aliases as $alias) {
|
||||||
|
$links[]['@attributes'] = array('rel' => 'alias' , 'href' => $alias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger('fetch_xrd_links: ' . print_r($links,true), LOGGER_DATA);
|
||||||
|
|
||||||
|
return $links;
|
||||||
|
}
|
Reference in New Issue
Block a user