Skip to content

Commit 7246088

Browse files
authored
Use Guzzle (#76)
* composer require guzzle instead of buzz * start transition from buzz to guzzle * implement guzzle batch * update readme for Guzzle
1 parent 6f440cb commit 7246088

File tree

3 files changed

+48
-96
lines changed

3 files changed

+48
-96
lines changed

README.md

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -210,31 +210,21 @@ $webPush->setAutomaticPadding(512); // enable automatic padding to 512 bytes (yo
210210
$webPush->setAutomaticPadding(true); // enable automatic padding to default maximum compatibility length
211211
```
212212

213-
### Changing the browser client
214-
By default, WebPush will use `MultiCurl`, allowing to send multiple notifications in parallel.
215-
You can change the client to any client extending `\Buzz\Client\AbstractClient`.
216-
Timeout is configurable in the constructor.
213+
### Customizing the HTTP client
214+
WebPush uses [Guzzle](https://github.com/guzzle/guzzle). It will use the most appropriate client it finds,
215+
and most of the time it will be `MultiCurl`, which allows to send multiple notifications in parallel.
217216

217+
You can customize the default request options and timeout when instantiating WebPush:
218218
```php
219219
<?php
220220

221221
use Minishlink\WebPush\WebPush;
222222

223-
$client = new \Buzz\Client\Curl();
224223
$timeout = 20; // seconds
225-
$webPush = new WebPush(array(), array(), $timeout, $client);
226-
```
227-
228-
You have access to the inner browser if you want to configure it further.
229-
```php
230-
<?php
231-
232-
use Minishlink\WebPush\WebPush;
233-
234-
$webPush = new WebPush();
235-
236-
/** @var $browser \Buzz\Browser */
237-
$browser = $webPush->getBrowser();
224+
$clientOptions = array(
225+
\GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => false,
226+
); // see \GuzzleHttp\RequestOptions
227+
$webPush = new WebPush(array(), array(), $timeout, $clientOptions);
238228
```
239229

240230
## Common questions

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
],
1515
"require": {
1616
"php": ">=5.6",
17-
"kriswallsmith/buzz": ">=0.6",
1817
"mdanter/ecc": "^0.4.0",
1918
"lib-openssl": "*",
2019
"spomky-labs/base64url": "^1.0",
2120
"spomky-labs/php-aes-gcm": "^1.0",
22-
"spomky-labs/jose": "^6.0"
21+
"spomky-labs/jose": "^6.0",
22+
"guzzlehttp/guzzle": "^6.2"
2323
},
2424
"require-dev": {
2525
"phpunit/phpunit": "4.8.*"

src/WebPush.php

Lines changed: 38 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,17 @@
1111

1212
namespace Minishlink\WebPush;
1313

14-
use Buzz\Browser;
15-
use Buzz\Client\AbstractClient;
16-
use Buzz\Client\MultiCurl;
17-
use Buzz\Exception\RequestException;
18-
use Buzz\Message\Response;
14+
use GuzzleHttp\Client;
15+
use GuzzleHttp\Exception\RequestException;
16+
use GuzzleHttp\Psr7\Request;
17+
use GuzzleHttp\Promise;
1918

2019
class WebPush
2120
{
2221
const GCM_URL = 'https://android.googleapis.com/gcm/send';
2322

24-
/** @var Browser */
25-
protected $browser;
23+
/** @var Client */
24+
protected $client;
2625

2726
/** @var array */
2827
protected $auth;
@@ -45,9 +44,9 @@ class WebPush
4544
* @param array $auth Some servers needs authentication
4645
* @param array $defaultOptions TTL, urgency, topic
4746
* @param int|null $timeout Timeout of POST request
48-
* @param AbstractClient|null $client
47+
* @param array $clientOptions
4948
*/
50-
public function __construct(array $auth = array(), $defaultOptions = array(), $timeout = 30, AbstractClient $client = null)
49+
public function __construct(array $auth = array(), $defaultOptions = array(), $timeout = 30, $clientOptions = array())
5150
{
5251
if (array_key_exists('VAPID', $auth)) {
5352
$auth['VAPID'] = VAPID::validate($auth['VAPID']);
@@ -57,9 +56,10 @@ public function __construct(array $auth = array(), $defaultOptions = array(), $t
5756

5857
$this->setDefaultOptions($defaultOptions);
5958

60-
$client = isset($client) ? $client : new MultiCurl();
61-
$client->setTimeout($timeout);
62-
$this->browser = new Browser($client);
59+
if (!array_key_exists('timeout', $clientOptions) && isset($timeout)) {
60+
$clientOptions['timeout'] = $timeout;
61+
}
62+
$this->client = new Client($clientOptions);
6363

6464
$this->nativePayloadEncryptionSupport = version_compare(phpversion(), '7.1', '>=');
6565
}
@@ -131,36 +131,36 @@ public function flush()
131131
}
132132

133133
// for each endpoint server type
134-
$responses = $this->prepareAndSend($this->notifications);
135-
136-
// if multi curl, flush
137-
if ($this->browser->getClient() instanceof MultiCurl) {
138-
/** @var MultiCurl $multiCurl */
139-
$multiCurl = $this->browser->getClient();
140-
$multiCurl->flush();
134+
$requests = $this->prepare($this->notifications);
135+
$promises = [];
136+
foreach ($requests as $request) {
137+
$promises[] = $this->client->sendAsync($request);
141138
}
139+
$results = Promise\settle($promises)->wait();
142140

143-
/** @var Response|null $response */
144141
$return = array();
145142
$completeSuccess = true;
146-
foreach ($responses as $i => $response) {
147-
if (!isset($response)) {
148-
$return[] = array(
149-
'success' => false,
150-
'endpoint' => $this->notifications[$i]->getEndpoint(),
151-
);
143+
foreach ($results as $result) {
144+
if ($result['state'] === "rejected") {
145+
/** @var RequestException $reason **/
146+
$reason = $result['reason'];
152147

153-
$completeSuccess = false;
154-
} elseif (!$response->isSuccessful()) {
155-
$return[] = array(
148+
$error = array(
156149
'success' => false,
157-
'endpoint' => $this->notifications[$i]->getEndpoint(),
158-
'statusCode' => $response->getStatusCode(),
159-
'headers' => $response->getHeaders(),
160-
'content' => $response->getContent(),
161-
'expired' => in_array($response->getStatusCode(), array(400, 404, 410)),
150+
'endpoint' => "".$reason->getRequest()->getUri(),
151+
'message' => $reason->getMessage(),
162152
);
163153

154+
$response = $reason->getResponse();
155+
if ($response !== null) {
156+
$statusCode = $response->getStatusCode();
157+
$error['statusCode'] = $statusCode;
158+
$error['expired'] = in_array($statusCode, array(400, 404, 410));
159+
$error['content'] = $response->getBody();
160+
$error['headers'] = $response->getHeaders();
161+
}
162+
163+
$return[] = $error;
164164
$completeSuccess = false;
165165
} else {
166166
$return[] = array(
@@ -175,9 +175,9 @@ public function flush()
175175
return $completeSuccess ? true : $return;
176176
}
177177

178-
private function prepareAndSend(array $notifications)
178+
private function prepare(array $notifications)
179179
{
180-
$responses = array();
180+
$requests = array();
181181
/** @var Notification $notification */
182182
foreach ($notifications as $notification) {
183183
$endpoint = $notification->getEndpoint();
@@ -247,48 +247,10 @@ private function prepareAndSend(array $notifications)
247247
}
248248
}
249249

250-
$responses[] = $this->sendRequest($endpoint, $headers, $content);
250+
$requests[] = new Request('POST', $endpoint, $headers, $content);
251251
}
252252

253-
return $responses;
254-
}
255-
256-
/**
257-
* @param string $url
258-
* @param array $headers
259-
* @param string $content
260-
*
261-
* @return \Buzz\Message\MessageInterface|null
262-
*/
263-
private function sendRequest($url, array $headers, $content)
264-
{
265-
try {
266-
$response = $this->browser->post($url, $headers, $content);
267-
} catch (RequestException $e) {
268-
$response = null;
269-
}
270-
271-
return $response;
272-
}
273-
274-
/**
275-
* @return Browser
276-
*/
277-
public function getBrowser()
278-
{
279-
return $this->browser;
280-
}
281-
282-
/**
283-
* @param Browser $browser
284-
*
285-
* @return WebPush
286-
*/
287-
public function setBrowser($browser)
288-
{
289-
$this->browser = $browser;
290-
291-
return $this;
253+
return $requests;
292254
}
293255

294256
/**

0 commit comments

Comments
 (0)