diff options
author | friendica <info@friendica.com> | 2014-08-19 19:38:42 -0700 |
---|---|---|
committer | friendica <info@friendica.com> | 2014-08-19 19:38:42 -0700 |
commit | c7fe071a1fda1779ecb2a45016ea59b347695b67 (patch) | |
tree | 3f3ba14f84047b23e1550c86307d5399317ab95f | |
parent | 55d4ceb7e0c249eff337cb303c555bfa5d5bd2a0 (diff) | |
download | volse-hubzilla-c7fe071a1fda1779ecb2a45016ea59b347695b67.tar.gz volse-hubzilla-c7fe071a1fda1779ecb2a45016ea59b347695b67.tar.bz2 volse-hubzilla-c7fe071a1fda1779ecb2a45016ea59b347695b67.zip |
some work on network discovery
-rwxr-xr-x | include/diaspora.php | 91 | ||||
-rw-r--r-- | include/network.php | 244 |
2 files changed, 167 insertions, 168 deletions
diff --git a/include/diaspora.php b/include/diaspora.php index 02d479d95..dda552536 100755 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -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)) { - // 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); - } + // try webfinger. Make sure to distinguish between diaspora, + // redmatrix w/diaspora protocol and friendica w/diaspora protocol. -// 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)); + $result = discover_by_webbie($handle); + + + } - // 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; } diff --git a/include/network.php b/include/network.php index 66bba5b38..1a974a681 100644 --- a/include/network.php +++ b/include/network.php @@ -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; +}
\ No newline at end of file |