aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs/Lib/Zotfinger.php
blob: 2a16fc8cf46823a5635ab174bb47bc4c8e0e9bd4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?php

namespace Zotlabs\Lib;

use Zotlabs\Lib\Config;
use Zotlabs\Web\HTTPSig;

class Zotfinger {

	static function exec($resource, $channel = null, $verify = true, $recurse = true) {

		if(! $resource) {
			return false;
		}

		$m = parse_url($resource);

		$data = json_encode([ 'zot_token' => random_string() ]);

		if($channel && $m) {

			$headers = [
				'Accept'           => 'application/x-zot+json',
				'Content-Type'     => 'application/x-zot+json',
				'X-Zot-Token'      => random_string(),
				'Digest'           => HTTPSig::generate_digest_header($data),
				'Host'             => $m['host'],
				'(request-target)' => 'post ' . get_request_string($resource)
			];
			$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false);
		}
		else {
			$h = [ 'Accept: application/x-zot+json' ];
		}

		$result = [];

		$redirects = 0;

		$start_timestamp = microtime(true);
		$x = z_post_url($resource,$data,$redirects, [ 'headers' => $h  ] );
		logger('logger_stats_data cmd:Zotfinger' . ' start:' . $start_timestamp . ' ' . 'end:' . microtime(true) . ' meta:' . $resource . '#' . random_string(16));
		btlogger('Zotfinger');

		logger('fetch: ' . print_r($x,true), LOGGER_DATA);

        if (in_array(intval($x['return_code']), [ 404, 410 ]) && $recurse) {

            // The resource has been deleted or doesn't exist at this location.
            // Try to find another nomadic resource for this channel and return that.

            // First, see if there's a hubloc for this site. Fetch that record to
            // obtain the nomadic identity hash. Then use that to find any additional
            // nomadic locations.

            $h = Activity::get_actor_hublocs($resource, 'zot6');
            if ($h) {
                // mark this location deleted
                hubloc_delete($h[0]);
                $hubs = Activity::get_actor_hublocs($h[0]['hubloc_hash']);
                if ($hubs) {
                    foreach ($hubs as $hub) {
                        if ($hub['hubloc_id_url'] !== $resource && !$hub['hubloc_deleted']) {
                            return self::exec($hub['hubloc_id_url'], $channel, $verify);
                        }
                    }
                }
            }
        }

		if($x['success']) {
			if ($verify) {
				$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
			}

			$result['data'] = json_decode($x['body'],true);

			if($result['data'] && is_array($result['data']) && array_key_exists('encrypted',$result['data']) && $result['data']['encrypted']) {
				$result['data'] = json_decode(Crypto::unencapsulate($result['data'],Config::Get('system','prvkey')),true);
			}

			logger('decrypted: ' . print_r($result,true), LOGGER_DATA);

			return $result;
		}

		return false;
	}



}