@@ -28,6 +28,7 @@
Loading
28 28
use GuzzleHttp\HandlerStack;
29 29
use GuzzleHttp\MessageFormatter;
30 30
use function GuzzleHttp\Psr7\uri_for;
31 +
use GuzzleHttp\RequestOptions;
31 32
use Kreait\Clock;
32 33
use Kreait\Clock\SystemClock;
33 34
use Kreait\Firebase;
@@ -37,6 +38,7 @@
Loading
37 38
use Kreait\Firebase\Auth\IdTokenVerifier;
38 39
use Kreait\Firebase\Exception\InvalidArgumentException;
39 40
use Kreait\Firebase\Exception\RuntimeException;
41 +
use Kreait\Firebase\Http\HttpClientOptions;
40 42
use Kreait\Firebase\Http\Middleware;
41 43
use Kreait\Firebase\Project\ProjectId;
42 44
use Kreait\Firebase\Value\Email;
@@ -91,9 +93,6 @@
Loading
91 93
    /** @var bool */
92 94
    protected $guzzleDebugModeIsEnabled = false;
93 95
94 -
    /** @var string|null */
95 -
    protected $httpProxy;
96 -
97 96
    /** @var string */
98 97
    protected static $databaseUriPattern = 'https://%s.firebaseio.com';
99 98
@@ -109,11 +108,15 @@
Loading
109 108
    /** @var callable|null */
110 109
    protected $httpDebugLogMiddleware;
111 110
111 +
    /** @var HttpClientOptions */
112 +
    protected $httpClientOptions;
113 +
112 114
    public function __construct()
113 115
    {
114 116
        $this->clock = new SystemClock();
115 117
        $this->verifierCache = new InMemoryCache();
116 118
        $this->authTokenCache = new MemoryCacheItemPool();
119 +
        $this->httpClientOptions = HttpClientOptions::default();
117 120
    }
118 121
119 122
    /**
@@ -206,6 +209,14 @@
Loading
206 209
        return $factory;
207 210
    }
208 211
212 +
    public function withHttpClientOptions(HttpClientOptions $options): self
213 +
    {
214 +
        $factory = clone $this;
215 +
        $factory->httpClientOptions = $options;
216 +
217 +
        return $factory;
218 +
    }
219 +
209 220
    public function withHttpLogger(LoggerInterface $logger, ?MessageFormatter $formatter = null, ?string $logLevel = null, ?string $errorLogLevel = null): self
210 221
    {
211 222
        $formatter = $formatter ?: new MessageFormatter();
@@ -232,10 +243,9 @@
Loading
232 243
233 244
    public function withHttpProxy(string $proxy): self
234 245
    {
235 -
        $factory = clone $this;
236 -
        $factory->httpProxy = $proxy;
237 -
238 -
        return $factory;
246 +
        return $this->withHttpClientOptions(
247 +
            $this->httpClientOptions->withProxy($proxy)
248 +
        );
239 249
    }
240 250
241 251
    public function withClock(Clock $clock): self
@@ -545,14 +555,18 @@
Loading
545 555
546 556
        // @codeCoverageIgnoreStart
547 557
        if ($this->guzzleDebugModeIsEnabled) {
548 -
            $config['debug'] = true;
558 +
            $config[RequestOptions::DEBUG] = true;
549 559
        }
550 560
        // @codeCoverageIgnoreEnd
551 561
552 -
        if ($this->httpProxy) {
553 -
            $config['proxy'] = $this->httpProxy;
562 +
        if ($proxy = $this->httpClientOptions->proxy()) {
563 +
            $config[RequestOptions::PROXY] = $proxy;
554 564
        }
555 565
566 +
        $config[RequestOptions::CONNECT_TIMEOUT] = $this->httpClientOptions->connectTimeout();
567 +
        $config[RequestOptions::READ_TIMEOUT] = $this->httpClientOptions->readTimeout();
568 +
        $config[RequestOptions::TIMEOUT] = $this->httpClientOptions->timeout();
569 +
556 570
        $handler = $config['handler'] ?? null;
557 571
558 572
        if (!($handler instanceof HandlerStack)) {

@@ -0,0 +1,148 @@
Loading
1 +
<?php
2 +
3 +
declare(strict_types=1);
4 +
5 +
namespace Kreait\Firebase\Http;
6 +
7 +
use Kreait\Firebase\Exception\InvalidArgumentException;
8 +
9 +
final class HttpClientOptions
10 +
{
11 +
    /**
12 +
     * The amount of seconds to wait while connecting to a server.
13 +
     *
14 +
     * Defaults to indefinitely.
15 +
     *
16 +
     * @var float
17 +
     */
18 +
    private $connectTimeout = \INF;
19 +
20 +
    /**
21 +
     * The amount of seconds to wait while reading a streamed body.
22 +
     *
23 +
     * Defaults to the value of the default_socket_timeout PHP ini setting.
24 +
     *
25 +
     * @var float
26 +
     */
27 +
    private $readTimeout;
28 +
29 +
    /**
30 +
     * The amount of seconds to wait for a full request (connect + transfer + read) to complete.
31 +
     *
32 +
     * Defaults to indefinitely.
33 +
     *
34 +
     * @var float
35 +
     */
36 +
    private $timeout = \INF;
37 +
38 +
    /**
39 +
     * The proxy that all requests should be passed through.
40 +
     *
41 +
     * @var string|null
42 +
     */
43 +
    private $proxy;
44 +
45 +
    private function __construct()
46 +
    {
47 +
        $this->readTimeout = ((float) \ini_get('default_socket_timeout')) ?: \INF;
48 +
    }
49 +
50 +
    public static function default(): self
51 +
    {
52 +
        return new self();
53 +
    }
54 +
55 +
    /**
56 +
     * The amount of seconds to wait while connecting to a server.
57 +
     *
58 +
     * Defaults to indefinitely.
59 +
     */
60 +
    public function connectTimeout(): float
61 +
    {
62 +
        return $this->connectTimeout;
63 +
    }
64 +
65 +
    /**
66 +
     * @param float $value the amount of seconds to wait while connecting to a server
67 +
     */
68 +
    public function withConnectTimeout(float $value): self
69 +
    {
70 +
        if ($value < 0) {
71 +
            throw new InvalidArgumentException('The connect timeout cannot be smaller than zero.');
72 +
        }
73 +
74 +
        $options = clone $this;
75 +
        $options->connectTimeout = $value;
76 +
77 +
        return $options;
78 +
    }
79 +
80 +
    /**
81 +
     * The amount of seconds to wait while reading a streamed body.
82 +
     *
83 +
     * Defaults to the value of the default_socket_timeout PHP ini setting.
84 +
     */
85 +
    public function readTimeout(): float
86 +
    {
87 +
        return $this->readTimeout;
88 +
    }
89 +
90 +
    /**
91 +
     * @param float $value the amount of seconds to wait while reading a streamed body
92 +
     */
93 +
    public function withReadTimeout(float $value): self
94 +
    {
95 +
        if ($value < 0) {
96 +
            throw new InvalidArgumentException('The read timeout cannot be smaller than zero.');
97 +
        }
98 +
99 +
        $options = clone $this;
100 +
        $options->readTimeout = $value;
101 +
102 +
        return $options;
103 +
    }
104 +
105 +
    /**
106 +
     * The amount of seconds to wait for a full request (connect + transfer + read) to complete.
107 +
     *
108 +
     * Defaults to indefinitely.
109 +
     */
110 +
    public function timeout(): float
111 +
    {
112 +
        return $this->timeout;
113 +
    }
114 +
115 +
    /**
116 +
     * @param float $value the amount of seconds to wait while reading a streamed body
117 +
     */
118 +
    public function withTimeout(float $value): self
119 +
    {
120 +
        if ($value < 0) {
121 +
            throw new InvalidArgumentException('The total timeout cannot be smaller than zero.');
122 +
        }
123 +
124 +
        $options = clone $this;
125 +
        $options->timeout = $value;
126 +
127 +
        return $options;
128 +
    }
129 +
130 +
    /**
131 +
     * The proxy that all requests should be passed through.
132 +
     */
133 +
    public function proxy(): ?string
134 +
    {
135 +
        return $this->proxy;
136 +
    }
137 +
138 +
    /**
139 +
     * @param string $value the proxy that all requests should be passed through
140 +
     */
141 +
    public function withProxy(string $value): self
142 +
    {
143 +
        $options = clone $this;
144 +
        $options->proxy = $value;
145 +
146 +
        return $options;
147 +
    }
148 +
}
Files Complexity Coverage
src/Firebase 1,400 95.99%
Project Totals (147 files) 1400 95.99%
1
comment:
2
  layout: "reach,diff"
3

4
coverage:
5
  status:
6
    project:
7
      default:
8
        informational: true
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading