Skip to content

Commit bc465f7

Browse files
javiermarinrosMinishlink
authored andcommitted
VAPID header caching (#208)
* Implemented VAPID header caching As @ozgurhangisi suggested in #195 * Implemented VAPID header caching As @ozgurhangisi suggested in #195 * Docs updated
1 parent df7c5df commit bc465f7

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,14 @@ serviceWorkerRegistration.pushManager.subscribe({
156156
})
157157
```
158158

159+
#### Reusing VAPID headers
160+
161+
VAPID headers make use of a JSON Web Token (JWT) to verify your identity. That token payload includes the protocol and hostname of the endpoint included in the subscription and an expiration timestamp (usually between 12-24h), and it's signed using your public and private key. Given that, two notifications sent to the same push service will use the same token, so you can reuse them for the same flush session to boost performance using:
162+
163+
```php
164+
$webPush->setReuseVAPIDHeaders(true);
165+
```
166+
159167
### Notifications and default options
160168
Each notification can have a specific Time To Live, urgency, and topic.
161169
You can change the default options with `setDefaultOptions()` or in the constructor:

src/WebPush.php

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ class WebPush
4949
*/
5050
private $automaticPadding = Encryption::MAX_COMPATIBILITY_PAYLOAD_LENGTH;
5151

52+
/**
53+
* @var bool Reuse VAPID headers in the same flush session to improve performance
54+
*/
55+
private $reuseVAPIDHeaders = false;
56+
57+
/**
58+
* @var array Dictionary for VAPID headers cache
59+
*/
60+
private $vapidHeaders = [];
61+
5262
/**
5363
* WebPush constructor.
5464
*
@@ -173,6 +183,10 @@ public function flush(?int $batchSize = null) : iterable
173183
yield $result;
174184
}
175185
}
186+
187+
if ($this->reuseVAPIDHeaders) {
188+
$this->vapidHeaders = [];
189+
}
176190
}
177191

178192
/**
@@ -256,11 +270,26 @@ private function prepare(array $notifications): array
256270
throw new \ErrorException('Audience "'.$audience.'"" could not be generated.');
257271
}
258272

259-
if (!$contentEncoding) {
260-
throw new \ErrorException('Subscription should have a content encoding');
273+
$vapidHeaders = null;
274+
$cache_key = null;
275+
if ($this->reuseVAPIDHeaders) {
276+
$cache_key = implode('#', [$audience, $contentEncoding, crc32(serialize($vapid))]);
277+
if (array_key_exists($cache_key, $this->vapidHeaders)) {
278+
$vapidHeaders = $this->vapidHeaders[$cache_key];
279+
}
261280
}
262281

263-
$vapidHeaders = VAPID::getVapidHeaders($audience, $vapid['subject'], $vapid['publicKey'], $vapid['privateKey'], $contentEncoding);
282+
if (!$vapidHeaders) {
283+
if (!$contentEncoding) {
284+
throw new \ErrorException('Subscription should have a content encoding');
285+
}
286+
287+
$vapidHeaders = VAPID::getVapidHeaders($audience, $vapid['subject'], $vapid['publicKey'], $vapid['privateKey'], $contentEncoding);
288+
}
289+
290+
if ($this->reuseVAPIDHeaders) {
291+
$this->vapidHeaders[$cache_key] = $vapidHeaders;
292+
}
264293

265294
$headers['Authorization'] = $vapidHeaders['Authorization'];
266295

@@ -321,6 +350,22 @@ public function setAutomaticPadding($automaticPadding): WebPush
321350
return $this;
322351
}
323352

353+
/**
354+
* @return bool
355+
*/
356+
public function getReuseVAPIDHeaders()
357+
{
358+
return $this->reuseVAPIDHeaders;
359+
}
360+
361+
/**
362+
* Reuse VAPID headers in the same flush session to improve performance
363+
*/
364+
public function setReuseVAPIDHeaders($enabled)
365+
{
366+
$this->reuseVAPIDHeaders = $enabled;
367+
}
368+
324369
/**
325370
* @return array
326371
*/

0 commit comments

Comments
 (0)