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..74ba65d9 --- /dev/null +++ b/src/Firebase/Messaging/RequestFactory.php @@ -0,0 +1,74 @@ +environmentSupportsHTTP2 = self::environmentSupportsHTTP2(); + } + + public function createRequest(Message $message, string $projectId, bool $validateOnly): RequestInterface + { + $request = $this->requestFactory + ->createRequest( + 'POST', + 'https://fcm.googleapis.com/v1/projects/'.$projectId.'/messages:send', + ) + ; + + if ($this->environmentSupportsHTTP2) { + $request = $request->withProtocolVersion('2.0'); + } + + $payload = ['message' => $message]; + + if ($validateOnly === true) { + $payload['validate_only'] = true; + } + + $body = $this->streamFactory->createStream(Json::encode($payload)); + + return $request + ->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; + } +}