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;
|
||||
$maxloops = 10;
|
||||
|
||||
do {
|
||||
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
|
||||
dbesc($handle)
|
||||
);
|
||||
if($r) {
|
||||
$person = $r[0];
|
||||
logger('find_diaspora_person_by handle: in cache ' . print_r($r,true), LOGGER_DEBUG);
|
||||
|
||||
$r = q("select * from xchan where xchan_addr = '%s' limit 1",
|
||||
dbesc($handle)
|
||||
);
|
||||
if($r) {
|
||||
$person = $r[0];
|
||||
logger('find_diaspora_person_by handle: in cache ' . print_r($r,true), LOGGER_DATA);
|
||||
|
||||
// update record occasionally so it doesn't get stale
|
||||
$d = strtotime($person['updated'] . ' +00:00');
|
||||
if($d < strtotime('now - 14 days'))
|
||||
$update = true;
|
||||
}
|
||||
// $d = strtotime($person['updated'] . ' +00:00');
|
||||
// if($d < strtotime('now - 14 days'))
|
||||
// $update = true;
|
||||
}
|
||||
|
||||
if((! $person) || ($update)) {
|
||||
|
||||
// try webfinger. Make sure to distinguish between diaspora,
|
||||
// redmatrix w/diaspora protocol and friendica w/diaspora protocol.
|
||||
|
||||
$result = discover_by_webbie($handle);
|
||||
|
||||
|
||||
// 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)) {
|
||||
// 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) {
|
||||
logger('find_diaspora_person_by_handle: create or refresh', LOGGER_DEBUG);
|
||||
require_once('include/Scrape.php');
|
||||
$r = probe_url($handle, PROBE_DIASPORA);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
@ -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
|
||||
// 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
|
||||
@ -912,3 +817,152 @@ function email_send($addr, $subject, $headers, $item) {
|
||||
logger('notifier: email delivery to ' . $addr);
|
||||
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