Airship\Engine\Hail::postJSON PHP Method

postJSON() public method

Perform a POST request, get a decoded JSON response.
public postJSON ( string $url, array $params = [] ) : mixed
$url string
$params array
return mixed
    public function postJSON(string $url, array $params = [])
    {
        return \Airship\parseJSON($this->postReturnBody($url, $params), true);
    }

Usage Example

Example #1
0
 /**
  * Does this peer notary see the same Merkle root?
  *
  * @param Peer $peer
  * @param string $expectedRoot
  * @return bool
  * @throws CouldNotUpdate
  * @throws PeerSignatureFailed
  */
 protected function checkWithPeer(Peer $peer, string $expectedRoot) : bool
 {
     foreach ($peer->getAllURLs('/verify') as $url) {
         // Challenge nonce:
         $challenge = Base64UrlSafe::encode(\random_bytes(33));
         // Peer's response:
         $response = $this->hail->postJSON($url, ['challenge' => $challenge]);
         if ($response['status'] !== 'OK') {
             $this->log('Upstream error.', LogLevel::EMERGENCY, ['response' => $response]);
             return false;
         }
         // Decode then verify signature
         $message = Base64UrlSafe::decode($response['response']);
         $signature = Base64UrlSafe::decode($response['signature']);
         $isValid = AsymmetricCrypto::verify($message, $peer->getPublicKey(), $signature, true);
         if (!$isValid) {
             $this->log('Invalid digital signature (i.e. it was signed with an incorrect key).', LogLevel::EMERGENCY);
             throw new PeerSignatureFailed('Invalid digital signature (i.e. it was signed with an incorrect key).');
         }
         // Make sure our challenge was signed.
         $decoded = \json_decode($message, true);
         if (!\hash_equals($challenge, $decoded['challenge'])) {
             $this->log('Challenge-response authentication failed.', LogLevel::EMERGENCY);
             throw new CouldNotUpdate(\__('Challenge-response authentication failed.'));
         }
         // Make sure this was a recent signature (it *should* be).
         // The earliest timestamp we will accept from a peer:
         $min = (new \DateTime('now'))->sub(new \DateInterval('P01D'));
         // The timestamp the server provided:
         $time = new \DateTime($decoded['timestamp']);
         if ($time < $min) {
             throw new CouldNotUpdate(\__('Timestamp %s is far too old.', 'default', $decoded['timestamp']));
         }
         // Return TRUE if it matches the expected root.
         // Return FALSE if it matches.
         return \hash_equals($expectedRoot, $decoded['root']);
     }
     // When all else fails, throw a TransferException
     throw new TransferException();
 }