@@ -135,7 +135,7 @@ public actor WebPushManager: Sendable {
135135 }
136136
137137 deinit {
138- if !didShutdown, case let . httpClient( httpClient) = executor {
138+ if !didShutdown, case let . httpClient( httpClient, _ ) = executor {
139139 try ? httpClient. syncShutdown ( )
140140 }
141141 }
@@ -260,11 +260,12 @@ public actor WebPushManager: Sendable {
260260 logger: Logger ? = nil
261261 ) async throws {
262262 switch executor {
263- case . httpClient( let httpClient) :
263+ case . httpClient( let httpClient, let privateKey ) :
264264 var logger = logger ?? backgroundActivityLogger
265- logger [ metadataKey: " message " ] = " \( message) "
265+ logger [ metadataKey: " message " ] = " .data( \( message. base64URLEncodedString ( ) ) ) "
266266 try await execute (
267267 httpClient: httpClient,
268+ applicationServerECDHPrivateKey: privateKey,
268269 data: message,
269270 subscriber: subscriber,
270271 expiration: expiration,
@@ -345,9 +346,10 @@ public actor WebPushManager: Sendable {
345346 var logger = logger
346347 logger [ metadataKey: " message " ] = " \( message) "
347348 switch executor {
348- case . httpClient( let httpClient) :
349+ case . httpClient( let httpClient, let privateKey ) :
349350 try await execute (
350351 httpClient: httpClient,
352+ applicationServerECDHPrivateKey: privateKey,
351353 data: message. data,
352354 subscriber: subscriber,
353355 expiration: expiration,
@@ -367,13 +369,15 @@ public actor WebPushManager: Sendable {
367369 /// Send a message via HTTP Client, mocked or otherwise, encrypting it on the way.
368370 /// - Parameters:
369371 /// - httpClient: The protocol implementing HTTP-like functionality.
372+ /// - applicationServerECDHPrivateKey: The private key to use for the key exchange. If nil, one will be generated.
370373 /// - message: The message to send as raw data.
371374 /// - subscriber: The subscriber to sign the message against.
372375 /// - expiration: The expiration of the message.
373376 /// - urgency: The urgency of the message.
374377 /// - logger: The logger to use for status updates.
375378 func execute(
376379 httpClient: some HTTPClientProtocol ,
380+ applicationServerECDHPrivateKey: P256 . KeyAgreement . PrivateKey ? ,
377381 data message: some DataProtocol ,
378382 subscriber: some SubscriberProtocol ,
379383 expiration: Expiration ,
@@ -398,7 +402,7 @@ public actor WebPushManager: Sendable {
398402
399403 /// Prepare authorization, private keys, and payload ahead of time to bail early if they can't be created.
400404 let authorization = try loadCurrentVAPIDAuthorizationHeader ( endpoint: subscriber. endpoint, signingKey: signingKey)
401- let applicationServerECDHPrivateKey = P256 . KeyAgreement. PrivateKey ( )
405+ let applicationServerECDHPrivateKey = applicationServerECDHPrivateKey ?? P256 . KeyAgreement. PrivateKey ( )
402406
403407 /// Perform key exchange between the user agent's public key and our private key, deriving a shared secret.
404408 let userAgent = subscriber. userAgentKeyMaterial
@@ -511,7 +515,7 @@ extension WebPushManager: Service {
511515 } onCancelOrGracefulShutdown: { [ backgroundActivityLogger, executor] in
512516 backgroundActivityLogger. debug ( " Shutting down WebPushManager " )
513517 do {
514- if case let . httpClient( httpClient) = executor {
518+ if case let . httpClient( httpClient, _ ) = executor {
515519 try httpClient. syncShutdown ( )
516520 }
517521 } catch {
@@ -715,10 +719,17 @@ extension WebPushManager {
715719
716720 /// An internal type representing the executor for a push message.
717721 package enum Executor : Sendable {
722+ /// Use an HTTP client and optional private key to send an encrypted payload to a subscriber.
723+ ///
724+ /// This is used in tests to capture the encrypted request and make sure it is well-formed.
725+ case httpClient( any HTTPClientProtocol , P256 . KeyAgreement . PrivateKey ? )
726+
718727 /// Use an HTTP client to send an encrypted payload to a subscriber.
719728 ///
720729 /// This is used in tests to capture the encrypted request and make sure it is well-formed.
721- case httpClient( any HTTPClientProtocol )
730+ package static func httpClient( _ httpClient: any HTTPClientProtocol ) -> Self {
731+ . httpClient( httpClient, nil )
732+ }
722733
723734 /// Use a handler to capture the original message.
724735 ///
0 commit comments