public static function run($argc, $argv) { if ($argc < 2) { return; } logger('deliver: invoked: ' . print_r($argv, true), LOGGER_DATA); for ($x = 1; $x < $argc; $x++) { if (!$argv[$x]) { continue; } $dresult = null; $r = q("select * from outq where outq_hash = '%s' limit 1", dbesc($argv[$x])); if ($r) { $notify = json_decode($r[0]['outq_notify'], true); // Messages without an outq_msg will need to go via the web, even if it's a // local delivery. This includes conversation requests and refresh packets. if ($r[0]['outq_posturl'] === z_root() . '/post' && $r[0]['outq_msg']) { logger('deliver: local delivery', LOGGER_DEBUG); // local delivery // we should probably batch these and save a few delivery processes if ($r[0]['outq_msg']) { $m = json_decode($r[0]['outq_msg'], true); if (array_key_exists('message_list', $m)) { foreach ($m['message_list'] as $mm) { $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify, 'message' => $mm))))); zot_import($msg, z_root()); } } else { $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify, 'message' => $m))))); $dresult = zot_import($msg, z_root()); } remove_queue_item($r[0]['outq_hash']); if ($dresult && is_array($dresult)) { foreach ($dresult as $xx) { if (is_array($xx) && array_key_exists('message_id', $xx)) { if (delivery_report_is_storable($xx)) { q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ", dbesc($xx['message_id']), dbesc($xx['location']), dbesc($xx['recipient']), dbesc($xx['status']), dbesc(datetime_convert($xx['date'])), dbesc($xx['sender'])); } } } } q("delete from dreport where dreport_queue = '%s'", dbesc($argv[$x])); } } // otherwise it's a remote delivery - call queue_deliver() with the $immediate flag queue_deliver($r[0], true); } } }
function deliver_run($argv, $argc) { cli_startup(); $a = get_app(); if ($argc < 2) { return; } logger('deliver: invoked: ' . print_r($argv, true), LOGGER_DATA); for ($x = 1; $x < $argc; $x++) { $r = q("select * from outq where outq_hash = '%s' limit 1", dbesc($argv[$x])); if ($r) { if ($r[0]['outq_driver'] === 'post') { $result = z_post_url($r[0]['outq_posturl'], $r[0]['outq_msg']); if ($result['success'] && $result['return_code'] < 300) { logger('deliver: queue post success to ' . $r[0]['outq_posturl'], LOGGER_DEBUG); $y = q("delete from outq where outq_hash = '%s' limit 1", dbesc($argv[$x])); } else { logger('deliver: queue post returned ' . $result['return_code'] . ' from ' . $r[0]['outq_posturl'], LOGGER_DEBUG); $y = q("update outq set outq_updated = '%s' where outq_hash = '%s' limit 1", dbesc(datetime_convert()), dbesc($argv[$x])); } continue; } if ($r[0]['outq_posturl'] === z_root() . '/post') { logger('deliver: local delivery', LOGGER_DEBUG); // local delivery // we should probably batch these and save a few delivery processes // If there is no outq_msg, this is a refresh_all message which does not require local handling if ($r[0]['outq_msg']) { $msg = array('body' => json_encode(array('pickup' => array(array('notify' => json_decode($r[0]['outq_notify'], true), 'message' => json_decode($r[0]['outq_msg'], true)))))); zot_import($msg, z_root()); $r = q("delete from outq where outq_hash = '%s' limit 1", dbesc($argv[$x])); } } else { logger('deliver: dest: ' . $r[0]['outq_posturl'], LOGGER_DEBUG); $result = zot_zot($r[0]['outq_posturl'], $r[0]['outq_notify']); if ($result['success']) { zot_process_response($r[0]['outq_posturl'], $result, $r[0]); } else { $y = q("update outq set outq_updated = '%s' where outq_hash = '%s' limit 1", dbesc(datetime_convert()), dbesc($argv[$x])); } } } } }
/** * @brief * * We received a notification packet (in mod/post.php) that a message is waiting for us, and we've verified the sender. * Now send back a pickup message, using our message tracking ID ($arr['secret']), which we will sign with our site private key. * The entire pickup message is encrypted with the remote site's public key. * If everything checks out on the remote end, we will receive back a packet containing one or more messages, * which will be processed and delivered before this function ultimately returns. * * @see zot_import() * * @param array $arr * decrypted and json decoded notify packet from remote site * @return array from zot_import() */ function zot_fetch($arr) { logger('zot_fetch: ' . print_r($arr, true), LOGGER_DATA); $url = $arr['sender']['url'] . $arr['callback']; // set $multiple param on zot_gethub() to return all matching hubs // This allows us to recover from re-installs when a redundant (but invalid) hubloc for // this identity is widely dispersed throughout the network. $ret_hubs = zot_gethub($arr['sender'], true); if (!$ret_hubs) { logger('zot_fetch: no hub: ' . print_r($arr['sender'], true)); return; } foreach ($ret_hubs as $ret_hub) { $data = array('type' => 'pickup', 'url' => z_root(), 'callback_sig' => base64url_encode(rsa_sign(z_root() . '/post', get_config('system', 'prvkey'))), 'callback' => z_root() . '/post', 'secret' => $arr['secret'], 'secret_sig' => base64url_encode(rsa_sign($arr['secret'], get_config('system', 'prvkey')))); $datatosend = json_encode(crypto_encapsulate(json_encode($data), $ret_hub['hubloc_sitekey'])); $fetch = zot_zot($url, $datatosend); $result = zot_import($fetch, $arr['sender']['url']); if ($result) { return $result; } } return; }
function deliver_run($argv, $argc) { cli_startup(); $a = get_app(); if ($argc < 2) { return; } logger('deliver: invoked: ' . print_r($argv, true), LOGGER_DATA); for ($x = 1; $x < $argc; $x++) { $r = q("select * from outq where outq_hash = '%s' limit 1", dbesc($argv[$x])); if ($r) { /** * Check to see if we have any recent communications with this hub (in the last month). * If not, reduce the outq_priority. */ $h = parse_url($r[0]['outq_posturl']); if ($h) { $base = $h['scheme'] . '://' . $h['host'] . ($h['port'] ? ':' . $h['port'] : ''); if ($base !== z_root()) { $y = q("select site_update, site_dead from site where site_url = '%s' ", dbesc($base)); if ($y) { if (intval($y[0]['site_dead'])) { q("delete from outq where outq_posturl = '%s'", dbesc($r[0]['outq_posturl'])); logger('dead site ignored ' . $base); continue; } if ($y[0]['site_update'] < datetime_convert('UTC', 'UTC', 'now - 1 month')) { q("update outq set outq_priority = %d where outq_hash = '%s'", intval($r[0]['outq_priority'] + 10), dbesc($r[0]['outq_hash'])); logger('immediate delivery deferred for site ' . $base); continue; } } } } // "post" queue driver - used for diaspora and friendica-over-diaspora communications. if ($r[0]['outq_driver'] === 'post') { $result = z_post_url($r[0]['outq_posturl'], $r[0]['outq_msg']); if ($result['success'] && $result['return_code'] < 300) { logger('deliver: queue post success to ' . $r[0]['outq_posturl'], LOGGER_DEBUG); $y = q("delete from outq where outq_hash = '%s'", dbesc($argv[$x])); } else { logger('deliver: queue post returned ' . $result['return_code'] . ' from ' . $r[0]['outq_posturl'], LOGGER_DEBUG); $y = q("update outq set outq_updated = '%s' where outq_hash = '%s'", dbesc(datetime_convert()), dbesc($argv[$x])); } continue; } $notify = json_decode($r[0]['outq_notify'], true); // Check if this is a conversation request packet. It won't have outq_msg // but will be an encrypted packet - so will need to be handed off to // web delivery rather than processed inline. $sendtoweb = false; if (array_key_exists('iv', $notify) && !$r[0]['outq_msg']) { $sendtoweb = true; } if ($r[0]['outq_posturl'] === z_root() . '/post' && !$sendtoweb) { logger('deliver: local delivery', LOGGER_DEBUG); // local delivery // we should probably batch these and save a few delivery processes if ($r[0]['outq_msg']) { $m = json_decode($r[0]['outq_msg'], true); if (array_key_exists('message_list', $m)) { foreach ($m['message_list'] as $mm) { $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify, 'message' => $mm))))); zot_import($msg, z_root()); } } else { $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify, 'message' => $m))))); zot_import($msg, z_root()); } $r = q("delete from outq where outq_hash = '%s'", dbesc($argv[$x])); } } else { logger('deliver: dest: ' . $r[0]['outq_posturl'], LOGGER_DEBUG); $result = zot_zot($r[0]['outq_posturl'], $r[0]['outq_notify']); if ($result['success']) { logger('deliver: remote zot delivery succeeded to ' . $r[0]['outq_posturl']); zot_process_response($r[0]['outq_posturl'], $result, $r[0]); } else { logger('deliver: remote zot delivery failed to ' . $r[0]['outq_posturl']); $y = q("update outq set outq_updated = '%s' where outq_hash = '%s'", dbesc(datetime_convert()), dbesc($argv[$x])); } } } } }
function deliver_run($argv, $argc) { cli_startup(); $a = get_app(); if ($argc < 2) { return; } logger('deliver: invoked: ' . print_r($argv, true), LOGGER_DATA); for ($x = 1; $x < $argc; $x++) { $dresult = null; $r = q("select * from outq where outq_hash = '%s' limit 1", dbesc($argv[$x])); if ($r) { /** * Check to see if we have any recent communications with this hub (in the last month). * If not, reduce the outq_priority. */ $h = parse_url($r[0]['outq_posturl']); if ($h) { $base = $h['scheme'] . '://' . $h['host'] . ($h['port'] ? ':' . $h['port'] : ''); if ($base !== z_root()) { $y = q("select site_update, site_dead from site where site_url = '%s' ", dbesc($base)); if ($y) { if (intval($y[0]['site_dead'])) { q("delete from outq where outq_posturl = '%s'", dbesc($r[0]['outq_posturl'])); logger('dead site ignored ' . $base); continue; } if ($y[0]['site_update'] < datetime_convert('UTC', 'UTC', 'now - 1 month')) { q("update outq set outq_priority = %d where outq_hash = '%s'", intval($r[0]['outq_priority'] + 10), dbesc($r[0]['outq_hash'])); logger('immediate delivery deferred for site ' . $base); continue; } } else { // zot sites should all have a site record, unless they've been dead for as long as // your site has existed. Since we don't know for sure what these sites are, // call them unknown q("insert into site (site_url, site_update, site_dead, site_type) values ('%s','%s',0,%d) ", dbesc($base), dbesc(datetime_convert()), intval($r[0]['outq_driver'] === 'post' ? SITE_TYPE_NOTZOT : SITE_TYPE_UNKNOWN)); } } } // "post" queue driver - used for diaspora and friendica-over-diaspora communications. if ($r[0]['outq_driver'] === 'post') { $result = z_post_url($r[0]['outq_posturl'], $r[0]['outq_msg']); if ($result['success'] && $result['return_code'] < 300) { logger('deliver: queue post success to ' . $r[0]['outq_posturl'], LOGGER_DEBUG); q("update site set site_update = '%s', site_dead = 0 where site_url = '%s' ", dbesc(datetime_convert()), dbesc($site_url)); q("update dreport set status = '%s', dreport_time = '%s' where dreport_queue = '%s' limit 1", dbesc('accepted for delivery'), dbesc(datetime_convert()), dbesc($argv[$x])); $y = q("delete from outq where outq_hash = '%s'", dbesc($argv[$x])); } else { logger('deliver: queue post returned ' . $result['return_code'] . ' from ' . $r[0]['outq_posturl'], LOGGER_DEBUG); $y = q("update outq set outq_updated = '%s' where outq_hash = '%s'", dbesc(datetime_convert()), dbesc($argv[$x])); } continue; } $notify = json_decode($r[0]['outq_notify'], true); // Check if this is a conversation request packet. It won't have outq_msg // but will be an encrypted packet - so will need to be handed off to // web delivery rather than processed inline. $sendtoweb = false; if (array_key_exists('iv', $notify) && !$r[0]['outq_msg']) { $sendtoweb = true; } if ($r[0]['outq_posturl'] === z_root() . '/post' && !$sendtoweb) { logger('deliver: local delivery', LOGGER_DEBUG); // local delivery // we should probably batch these and save a few delivery processes if ($r[0]['outq_msg']) { $m = json_decode($r[0]['outq_msg'], true); if (array_key_exists('message_list', $m)) { foreach ($m['message_list'] as $mm) { $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify, 'message' => $mm))))); zot_import($msg, z_root()); } } else { $msg = array('body' => json_encode(array('success' => true, 'pickup' => array(array('notify' => $notify, 'message' => $m))))); $dresult = zot_import($msg, z_root()); } $r = q("delete from outq where outq_hash = '%s'", dbesc($argv[$x])); if ($dresult && is_array($dresult)) { foreach ($dresult as $xx) { if (is_array($xx) && array_key_exists('message_id', $xx)) { q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan ) values ( '%s', '%s','%s','%s','%s','%s' ) ", dbesc($xx['message_id']), dbesc($xx['location']), dbesc($xx['recipient']), dbesc($xx['status']), dbesc(datetime_convert($xx['date'])), dbesc($xx['sender'])); } } } q("delete from dreport where dreport_queue = '%s' limit 1", dbesc($argv[$x])); } } else { logger('deliver: dest: ' . $r[0]['outq_posturl'], LOGGER_DEBUG); $result = zot_zot($r[0]['outq_posturl'], $r[0]['outq_notify']); if ($result['success']) { logger('deliver: remote zot delivery succeeded to ' . $r[0]['outq_posturl']); zot_process_response($r[0]['outq_posturl'], $result, $r[0]); } else { logger('deliver: remote zot delivery failed to ' . $r[0]['outq_posturl']); $y = q("update outq set outq_updated = '%s' where outq_hash = '%s'", dbesc(datetime_convert()), dbesc($argv[$x])); } } } } }
/** * @brief * * We received a notification packet (in mod/post.php) that a message is waiting for us, and we've verified the sender. * Now send back a pickup message, using our message tracking ID ($arr['secret']), which we will sign with our site private key. * The entire pickup message is encrypted with the remote site's public key. * If everything checks out on the remote end, we will receive back a packet containing one or more messages, * which will be processed and delivered before this function ultimately returns. * * @see zot_import() * * @param array $arr * decrypted and json decoded notify packet from remote site * @return array from zot_import() */ function zot_fetch($arr) { logger('zot_fetch: ' . print_r($arr, true), LOGGER_DATA); $url = $arr['sender']['url'] . $arr['callback']; $ret_hub = zot_gethub($arr['sender']); if (!$ret_hub) { logger('zot_fetch: no hub: ' . print_r($arr['sender'], true)); return; } $data = array('type' => 'pickup', 'url' => z_root(), 'callback_sig' => base64url_encode(rsa_sign(z_root() . '/post', get_config('system', 'prvkey'))), 'callback' => z_root() . '/post', 'secret' => $arr['secret'], 'secret_sig' => base64url_encode(rsa_sign($arr['secret'], get_config('system', 'prvkey')))); $datatosend = json_encode(crypto_encapsulate(json_encode($data), $ret_hub['hubloc_sitekey'])); $fetch = zot_zot($url, $datatosend); $result = zot_import($fetch, $arr['sender']['url']); return $result; }