From e29d5633b8d3a97cd1cb6cdb6f4ec2c1723f66a9 Mon Sep 17 00:00:00 2001 From: Jeremy Wadhams Date: Mon, 13 Jul 2026 13:04:44 -0500 Subject: [PATCH 1/2] fix: toGuzzle uses getHeaders() so auth headers can be computed at send-time Requests that need an auth header pulled from secrets or a compiled JWT couldn't set it in __construct(), since AbstractUseStaleRequest's background refresh clones and serializes the request before re-sending it off the queue -- construct-time state goes stale. Routing toGuzzle() through getHeaders() lets children override that method (the same pattern already used for getCacheTags()) to recompute headers fresh on every send, pre- and post-serialization. --- app/AbstractRequest.php | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/AbstractRequest.php b/app/AbstractRequest.php index cfeb09c..d74d1bc 100644 --- a/app/AbstractRequest.php +++ b/app/AbstractRequest.php @@ -247,7 +247,7 @@ public function toGuzzle(): Request $this->setAcceptHeaders(); $this->setOnStats(); - return new Request($this->method, $this->getURL(), $this->headers, $this->encodeBody()); + return new Request($this->method, $this->getURL(), $this->getHeaders(), $this->encodeBody()); } /** @@ -260,7 +260,25 @@ public function getArguments(): array } /** - * Simple readonly getter to read the headers so far. + * Getter for the headers to be sent with the request. Called by toGuzzle() immediately before send, + * so it is the preferred place to attach headers that must be computed freshly (e.g., pulled from a + * secrets store, or a compiled JWT) rather than set once in __construct(). + * + * This matters for AbstractUseStaleRequest: the background refresh job serializes/unserializes a clone + * of the request, so anything only set in __construct() (or otherwise stored as plain state) reflects + * whatever it was at the time of the *original* request, not a fresh value at refresh time. Overriding + * getHeaders() (the same pattern used by getCacheTags()) instead of relying on the $headers property + * ensures the value is recomputed every time the request is actually sent, both before and after + * serialization. + * + * @example + * public function getHeaders(): array + * { + * return array_merge(parent::getHeaders(), [ + * 'Authorization' => 'Bearer ' . $this->fetchToken(), + * ]); + * } + * * @return array */ public function getHeaders(): array From 91d15fd9a14a10fb7d2de80b39f077f0def20702 Mon Sep 17 00:00:00 2001 From: Jeremy Wadhams Date: Mon, 13 Jul 2026 13:05:59 -0500 Subject: [PATCH 2/2] docs: use array spread in getHeaders() override example Reads cleaner than array_merge, and string-key spread is fine on this repo's minimum supported PHP version (8.1+). --- app/AbstractRequest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/AbstractRequest.php b/app/AbstractRequest.php index d74d1bc..ec1259b 100644 --- a/app/AbstractRequest.php +++ b/app/AbstractRequest.php @@ -274,9 +274,10 @@ public function getArguments(): array * @example * public function getHeaders(): array * { - * return array_merge(parent::getHeaders(), [ + * return [ + * ...parent::getHeaders(), * 'Authorization' => 'Bearer ' . $this->fetchToken(), - * ]); + * ]; * } * * @return array