From 8b5ffe8cd8aa12137594f93f294f667513cc5538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gamez?= Date: Fri, 28 Jun 2024 15:02:53 +0200 Subject: [PATCH 1/2] Extract Messaging Request creation into a dedicated factory --- src/Firebase/Factory.php | 7 +++- src/Firebase/Messaging/ApiClient.php | 28 +------------- src/Firebase/Messaging/RequestFactory.php | 47 +++++++++++++++++++++++ 3 files changed, 54 insertions(+), 28 deletions(-) create mode 100644 src/Firebase/Messaging/RequestFactory.php diff --git a/src/Firebase/Factory.php b/src/Firebase/Factory.php index d6cfd00b..eeea2021 100644 --- a/src/Firebase/Factory.php +++ b/src/Firebase/Factory.php @@ -406,12 +406,15 @@ public function createMessaging(): Contract\Messaging $projectId = $this->getProjectId(); $errorHandler = new MessagingApiExceptionConverter($this->clock); + $requestFactory = new Messaging\RequestFactory( + requestFactory: $this->httpFactory, + streamFactory: $this->httpFactory, + ); $messagingApiClient = new Messaging\ApiClient( $this->createApiClient(), $projectId, - $this->httpFactory, - $this->httpFactory, + $requestFactory, ); $appInstanceApiClient = new AppInstanceApiClient( diff --git a/src/Firebase/Messaging/ApiClient.php b/src/Firebase/Messaging/ApiClient.php index c5ced7df..c95d6d76 100644 --- a/src/Firebase/Messaging/ApiClient.php +++ b/src/Firebase/Messaging/ApiClient.php @@ -4,14 +4,11 @@ namespace Kreait\Firebase\Messaging; -use Beste\Json; use GuzzleHttp\ClientInterface; use GuzzleHttp\Pool; use GuzzleHttp\Promise\PromiseInterface; use Iterator; -use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\StreamFactoryInterface; /** * @internal @@ -21,34 +18,13 @@ class ApiClient public function __construct( private readonly ClientInterface $client, private readonly string $projectId, - private readonly RequestFactoryInterface $requestFactory, - private readonly StreamFactoryInterface $streamFactory, + private readonly RequestFactory $requestFactory, ) { } public function createSendRequestForMessage(Message $message, bool $validateOnly): RequestInterface { - $request = $this->requestFactory - ->createRequest( - 'POST', - 'https://fcm.googleapis.com/v1/projects/'.$this->projectId.'/messages:send', - ) - ; - - $payload = ['message' => $message]; - - if ($validateOnly === true) { - $payload['validate_only'] = true; - } - - $body = $this->streamFactory->createStream(Json::encode($payload)); - - return $request - ->withProtocolVersion('2.0') - ->withBody($body) - ->withHeader('Content-Type', 'application/json; charset=UTF-8') - ->withHeader('Content-Length', (string) $body->getSize()) - ; + return $this->requestFactory->createRequest($message, $this->projectId, $validateOnly); } /** diff --git a/src/Firebase/Messaging/RequestFactory.php b/src/Firebase/Messaging/RequestFactory.php new file mode 100644 index 00000000..a4a83712 --- /dev/null +++ b/src/Firebase/Messaging/RequestFactory.php @@ -0,0 +1,47 @@ +requestFactory + ->createRequest( + 'POST', + 'https://fcm.googleapis.com/v1/projects/'.$projectId.'/messages:send', + ) + ; + + $payload = ['message' => $message]; + + if ($validateOnly === true) { + $payload['validate_only'] = true; + } + + $body = $this->streamFactory->createStream(Json::encode($payload)); + + return $request + ->withProtocolVersion('2.0') + ->withBody($body) + ->withHeader('Content-Type', 'application/json; charset=UTF-8') + ->withHeader('Content-Length', (string) $body->getSize()) + ; + } +} From 3dcd1c44fbe677981aaac7f6edd61bab290428d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gamez?= Date: Fri, 28 Jun 2024 15:03:06 +0200 Subject: [PATCH 2/2] Check if HTTP/2 is supported --- src/Firebase/Messaging/RequestFactory.php | 29 ++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/Firebase/Messaging/RequestFactory.php b/src/Firebase/Messaging/RequestFactory.php index a4a83712..74ba65d9 100644 --- a/src/Firebase/Messaging/RequestFactory.php +++ b/src/Firebase/Messaging/RequestFactory.php @@ -14,10 +14,13 @@ */ final class RequestFactory { + private bool $environmentSupportsHTTP2; + public function __construct( private readonly RequestFactoryInterface $requestFactory, private readonly StreamFactoryInterface $streamFactory, ) { + $this->environmentSupportsHTTP2 = self::environmentSupportsHTTP2(); } public function createRequest(Message $message, string $projectId, bool $validateOnly): RequestInterface @@ -29,6 +32,10 @@ public function createRequest(Message $message, string $projectId, bool $validat ) ; + if ($this->environmentSupportsHTTP2) { + $request = $request->withProtocolVersion('2.0'); + } + $payload = ['message' => $message]; if ($validateOnly === true) { @@ -38,10 +45,30 @@ public function createRequest(Message $message, string $projectId, bool $validat $body = $this->streamFactory->createStream(Json::encode($payload)); return $request - ->withProtocolVersion('2.0') ->withBody($body) ->withHeader('Content-Type', 'application/json; charset=UTF-8') ->withHeader('Content-Length', (string) $body->getSize()) ; } + + /** + * @see https://github.com/microsoftgraph/msgraph-sdk-php/issues/854 + * @see https://github.com/microsoftgraph/msgraph-sdk-php/pull/1120 + * + * @codeCoverageIgnore + */ + private static function environmentSupportsHTTP2(): bool + { + if (!extension_loaded('curl')) { + return false; + } + + if (!defined('CURL_VERSION_HTTP2')) { + return false; + } + + $features = curl_version()["features"] ?? null; + + return ($features & CURL_VERSION_HTTP2) === CURL_VERSION_HTTP2; + } }