From a028eafeef66ffe0ff625d6170613a8fe88fa23f Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 16 May 2023 10:15:42 +0300 Subject: [PATCH] Cache webhook verification results Looks like `permission_callback` can be called multiple times in some cases/newer WP, resulting in difficult to read logs and other issues, such as slower request handling or possible lack of idempotence (first returned true, but then request failed and returned false). So now caching it in a variable. --- .../src/IncomingWebhookEndpoint.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php b/modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php index 4a7631572..b228139e0 100644 --- a/modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php +++ b/modules/ppcp-webhooks/src/IncomingWebhookEndpoint.php @@ -83,6 +83,14 @@ class IncomingWebhookEndpoint { */ private $last_webhook_event_storage; + /** + * Cached webhook verification results + * to avoid repeating requests when permission_callback is called multiple times. + * + * @var array + */ + private $verification_results = array(); + /** * IncomingWebhookEndpoint constructor. * @@ -160,7 +168,17 @@ class IncomingWebhookEndpoint { try { $event = $this->event_from_request( $request ); + } catch ( RuntimeException $exception ) { + $this->logger->error( 'Webhook parsing failed: ' . $exception->getMessage() ); + return false; + } + $cache_key = $event->id(); + if ( isset( $this->verification_results[ $cache_key ] ) ) { + return $this->verification_results[ $cache_key ]; + } + + try { if ( $this->simulation->is_simulation_event( $event ) ) { return true; } @@ -169,9 +187,11 @@ class IncomingWebhookEndpoint { if ( ! $result ) { $this->logger->error( 'Webhook verification failed.' ); } + $this->verification_results[ $cache_key ] = $result; return $result; } catch ( RuntimeException $exception ) { $this->logger->error( 'Webhook verification failed: ' . $exception->getMessage() ); + $this->verification_results[ $cache_key ] = false; return false; } }