Completed
Push — master ( 0675a5...c513b3 )
by Maxence
03:29 queued 14s
created
lib/Vendor/GuzzleHttp/Psr7/AppendStream.php 3 patches
Indentation   +189 added lines, -189 removed lines patch added patch discarded remove patch
@@ -11,193 +11,193 @@
 block discarded – undo
11 11
  */
12 12
 final class AppendStream implements StreamInterface
13 13
 {
14
-    /** @var StreamInterface[] Streams being decorated */
15
-    private $streams = [];
16
-    /** @var bool */
17
-    private $seekable = \true;
18
-    /** @var int */
19
-    private $current = 0;
20
-    /** @var int */
21
-    private $pos = 0;
22
-    /**
23
-     * @param StreamInterface[] $streams Streams to decorate. Each stream must
24
-     *                                   be readable.
25
-     */
26
-    public function __construct(array $streams = [])
27
-    {
28
-        foreach ($streams as $stream) {
29
-            $this->addStream($stream);
30
-        }
31
-    }
32
-    public function __toString() : string
33
-    {
34
-        try {
35
-            $this->rewind();
36
-            return $this->getContents();
37
-        } catch (\Throwable $e) {
38
-            if (\PHP_VERSION_ID >= 70400) {
39
-                throw $e;
40
-            }
41
-            \trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string) $e), \E_USER_ERROR);
42
-            return '';
43
-        }
44
-    }
45
-    /**
46
-     * Add a stream to the AppendStream
47
-     *
48
-     * @param StreamInterface $stream Stream to append. Must be readable.
49
-     *
50
-     * @throws \InvalidArgumentException if the stream is not readable
51
-     */
52
-    public function addStream(StreamInterface $stream) : void
53
-    {
54
-        if (!$stream->isReadable()) {
55
-            throw new \InvalidArgumentException('Each stream must be readable');
56
-        }
57
-        // The stream is only seekable if all streams are seekable
58
-        if (!$stream->isSeekable()) {
59
-            $this->seekable = \false;
60
-        }
61
-        $this->streams[] = $stream;
62
-    }
63
-    public function getContents() : string
64
-    {
65
-        return Utils::copyToString($this);
66
-    }
67
-    /**
68
-     * Closes each attached stream.
69
-     */
70
-    public function close() : void
71
-    {
72
-        $this->pos = $this->current = 0;
73
-        $this->seekable = \true;
74
-        foreach ($this->streams as $stream) {
75
-            $stream->close();
76
-        }
77
-        $this->streams = [];
78
-    }
79
-    /**
80
-     * Detaches each attached stream.
81
-     *
82
-     * Returns null as it's not clear which underlying stream resource to return.
83
-     */
84
-    public function detach()
85
-    {
86
-        $this->pos = $this->current = 0;
87
-        $this->seekable = \true;
88
-        foreach ($this->streams as $stream) {
89
-            $stream->detach();
90
-        }
91
-        $this->streams = [];
92
-        return null;
93
-    }
94
-    public function tell() : int
95
-    {
96
-        return $this->pos;
97
-    }
98
-    /**
99
-     * Tries to calculate the size by adding the size of each stream.
100
-     *
101
-     * If any of the streams do not return a valid number, then the size of the
102
-     * append stream cannot be determined and null is returned.
103
-     */
104
-    public function getSize() : ?int
105
-    {
106
-        $size = 0;
107
-        foreach ($this->streams as $stream) {
108
-            $s = $stream->getSize();
109
-            if ($s === null) {
110
-                return null;
111
-            }
112
-            $size += $s;
113
-        }
114
-        return $size;
115
-    }
116
-    public function eof() : bool
117
-    {
118
-        return !$this->streams || $this->current >= \count($this->streams) - 1 && $this->streams[$this->current]->eof();
119
-    }
120
-    public function rewind() : void
121
-    {
122
-        $this->seek(0);
123
-    }
124
-    /**
125
-     * Attempts to seek to the given position. Only supports SEEK_SET.
126
-     */
127
-    public function seek($offset, $whence = \SEEK_SET) : void
128
-    {
129
-        if (!$this->seekable) {
130
-            throw new \RuntimeException('This AppendStream is not seekable');
131
-        } elseif ($whence !== \SEEK_SET) {
132
-            throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
133
-        }
134
-        $this->pos = $this->current = 0;
135
-        // Rewind each stream
136
-        foreach ($this->streams as $i => $stream) {
137
-            try {
138
-                $stream->rewind();
139
-            } catch (\Exception $e) {
140
-                throw new \RuntimeException('Unable to seek stream ' . $i . ' of the AppendStream', 0, $e);
141
-            }
142
-        }
143
-        // Seek to the actual position by reading from each stream
144
-        while ($this->pos < $offset && !$this->eof()) {
145
-            $result = $this->read(\min(8096, $offset - $this->pos));
146
-            if ($result === '') {
147
-                break;
148
-            }
149
-        }
150
-    }
151
-    /**
152
-     * Reads from all of the appended streams until the length is met or EOF.
153
-     */
154
-    public function read($length) : string
155
-    {
156
-        $buffer = '';
157
-        $total = \count($this->streams) - 1;
158
-        $remaining = $length;
159
-        $progressToNext = \false;
160
-        while ($remaining > 0) {
161
-            // Progress to the next stream if needed.
162
-            if ($progressToNext || $this->streams[$this->current]->eof()) {
163
-                $progressToNext = \false;
164
-                if ($this->current === $total) {
165
-                    break;
166
-                }
167
-                ++$this->current;
168
-            }
169
-            $result = $this->streams[$this->current]->read($remaining);
170
-            if ($result === '') {
171
-                $progressToNext = \true;
172
-                continue;
173
-            }
174
-            $buffer .= $result;
175
-            $remaining = $length - \strlen($buffer);
176
-        }
177
-        $this->pos += \strlen($buffer);
178
-        return $buffer;
179
-    }
180
-    public function isReadable() : bool
181
-    {
182
-        return \true;
183
-    }
184
-    public function isWritable() : bool
185
-    {
186
-        return \false;
187
-    }
188
-    public function isSeekable() : bool
189
-    {
190
-        return $this->seekable;
191
-    }
192
-    public function write($string) : int
193
-    {
194
-        throw new \RuntimeException('Cannot write to an AppendStream');
195
-    }
196
-    /**
197
-     * @return mixed
198
-     */
199
-    public function getMetadata($key = null)
200
-    {
201
-        return $key ? null : [];
202
-    }
14
+	/** @var StreamInterface[] Streams being decorated */
15
+	private $streams = [];
16
+	/** @var bool */
17
+	private $seekable = \true;
18
+	/** @var int */
19
+	private $current = 0;
20
+	/** @var int */
21
+	private $pos = 0;
22
+	/**
23
+	 * @param StreamInterface[] $streams Streams to decorate. Each stream must
24
+	 *                                   be readable.
25
+	 */
26
+	public function __construct(array $streams = [])
27
+	{
28
+		foreach ($streams as $stream) {
29
+			$this->addStream($stream);
30
+		}
31
+	}
32
+	public function __toString() : string
33
+	{
34
+		try {
35
+			$this->rewind();
36
+			return $this->getContents();
37
+		} catch (\Throwable $e) {
38
+			if (\PHP_VERSION_ID >= 70400) {
39
+				throw $e;
40
+			}
41
+			\trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string) $e), \E_USER_ERROR);
42
+			return '';
43
+		}
44
+	}
45
+	/**
46
+	 * Add a stream to the AppendStream
47
+	 *
48
+	 * @param StreamInterface $stream Stream to append. Must be readable.
49
+	 *
50
+	 * @throws \InvalidArgumentException if the stream is not readable
51
+	 */
52
+	public function addStream(StreamInterface $stream) : void
53
+	{
54
+		if (!$stream->isReadable()) {
55
+			throw new \InvalidArgumentException('Each stream must be readable');
56
+		}
57
+		// The stream is only seekable if all streams are seekable
58
+		if (!$stream->isSeekable()) {
59
+			$this->seekable = \false;
60
+		}
61
+		$this->streams[] = $stream;
62
+	}
63
+	public function getContents() : string
64
+	{
65
+		return Utils::copyToString($this);
66
+	}
67
+	/**
68
+	 * Closes each attached stream.
69
+	 */
70
+	public function close() : void
71
+	{
72
+		$this->pos = $this->current = 0;
73
+		$this->seekable = \true;
74
+		foreach ($this->streams as $stream) {
75
+			$stream->close();
76
+		}
77
+		$this->streams = [];
78
+	}
79
+	/**
80
+	 * Detaches each attached stream.
81
+	 *
82
+	 * Returns null as it's not clear which underlying stream resource to return.
83
+	 */
84
+	public function detach()
85
+	{
86
+		$this->pos = $this->current = 0;
87
+		$this->seekable = \true;
88
+		foreach ($this->streams as $stream) {
89
+			$stream->detach();
90
+		}
91
+		$this->streams = [];
92
+		return null;
93
+	}
94
+	public function tell() : int
95
+	{
96
+		return $this->pos;
97
+	}
98
+	/**
99
+	 * Tries to calculate the size by adding the size of each stream.
100
+	 *
101
+	 * If any of the streams do not return a valid number, then the size of the
102
+	 * append stream cannot be determined and null is returned.
103
+	 */
104
+	public function getSize() : ?int
105
+	{
106
+		$size = 0;
107
+		foreach ($this->streams as $stream) {
108
+			$s = $stream->getSize();
109
+			if ($s === null) {
110
+				return null;
111
+			}
112
+			$size += $s;
113
+		}
114
+		return $size;
115
+	}
116
+	public function eof() : bool
117
+	{
118
+		return !$this->streams || $this->current >= \count($this->streams) - 1 && $this->streams[$this->current]->eof();
119
+	}
120
+	public function rewind() : void
121
+	{
122
+		$this->seek(0);
123
+	}
124
+	/**
125
+	 * Attempts to seek to the given position. Only supports SEEK_SET.
126
+	 */
127
+	public function seek($offset, $whence = \SEEK_SET) : void
128
+	{
129
+		if (!$this->seekable) {
130
+			throw new \RuntimeException('This AppendStream is not seekable');
131
+		} elseif ($whence !== \SEEK_SET) {
132
+			throw new \RuntimeException('The AppendStream can only seek with SEEK_SET');
133
+		}
134
+		$this->pos = $this->current = 0;
135
+		// Rewind each stream
136
+		foreach ($this->streams as $i => $stream) {
137
+			try {
138
+				$stream->rewind();
139
+			} catch (\Exception $e) {
140
+				throw new \RuntimeException('Unable to seek stream ' . $i . ' of the AppendStream', 0, $e);
141
+			}
142
+		}
143
+		// Seek to the actual position by reading from each stream
144
+		while ($this->pos < $offset && !$this->eof()) {
145
+			$result = $this->read(\min(8096, $offset - $this->pos));
146
+			if ($result === '') {
147
+				break;
148
+			}
149
+		}
150
+	}
151
+	/**
152
+	 * Reads from all of the appended streams until the length is met or EOF.
153
+	 */
154
+	public function read($length) : string
155
+	{
156
+		$buffer = '';
157
+		$total = \count($this->streams) - 1;
158
+		$remaining = $length;
159
+		$progressToNext = \false;
160
+		while ($remaining > 0) {
161
+			// Progress to the next stream if needed.
162
+			if ($progressToNext || $this->streams[$this->current]->eof()) {
163
+				$progressToNext = \false;
164
+				if ($this->current === $total) {
165
+					break;
166
+				}
167
+				++$this->current;
168
+			}
169
+			$result = $this->streams[$this->current]->read($remaining);
170
+			if ($result === '') {
171
+				$progressToNext = \true;
172
+				continue;
173
+			}
174
+			$buffer .= $result;
175
+			$remaining = $length - \strlen($buffer);
176
+		}
177
+		$this->pos += \strlen($buffer);
178
+		return $buffer;
179
+	}
180
+	public function isReadable() : bool
181
+	{
182
+		return \true;
183
+	}
184
+	public function isWritable() : bool
185
+	{
186
+		return \false;
187
+	}
188
+	public function isSeekable() : bool
189
+	{
190
+		return $this->seekable;
191
+	}
192
+	public function write($string) : int
193
+	{
194
+		throw new \RuntimeException('Cannot write to an AppendStream');
195
+	}
196
+	/**
197
+	 * @return mixed
198
+	 */
199
+	public function getMetadata($key = null)
200
+	{
201
+		return $key ? null : [];
202
+	}
203 203
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare (strict_types=1);
3
+declare(strict_types=1);
4 4
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7;
5 5
 
6 6
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\StreamInterface;
@@ -38,7 +38,7 @@  discard block
 block discarded – undo
38 38
             if (\PHP_VERSION_ID >= 70400) {
39 39
                 throw $e;
40 40
             }
41
-            \trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string) $e), \E_USER_ERROR);
41
+            \trigger_error(\sprintf('%s::__toString exception: %s', self::class, (string)$e), \E_USER_ERROR);
42 42
             return '';
43 43
         }
44 44
     }
@@ -137,7 +137,7 @@  discard block
 block discarded – undo
137 137
             try {
138 138
                 $stream->rewind();
139 139
             } catch (\Exception $e) {
140
-                throw new \RuntimeException('Unable to seek stream ' . $i . ' of the AppendStream', 0, $e);
140
+                throw new \RuntimeException('Unable to seek stream '.$i.' of the AppendStream', 0, $e);
141 141
             }
142 142
         }
143 143
         // Seek to the actual position by reading from each stream
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -9,8 +9,7 @@
 block discarded – undo
9 9
  *
10 10
  * This is a read-only stream decorator.
11 11
  */
12
-final class AppendStream implements StreamInterface
13
-{
12
+final class AppendStream implements StreamInterface {
14 13
     /** @var StreamInterface[] Streams being decorated */
15 14
     private $streams = [];
16 15
     /** @var bool */
Please login to merge, or discard this patch.
lib/Vendor/GuzzleHttp/Psr7/Request.php 3 patches
Indentation   +109 added lines, -109 removed lines patch added patch discarded remove patch
@@ -12,113 +12,113 @@
 block discarded – undo
12 12
  */
13 13
 class Request implements RequestInterface
14 14
 {
15
-    use MessageTrait;
16
-    /** @var string */
17
-    private $method;
18
-    /** @var string|null */
19
-    private $requestTarget;
20
-    /** @var UriInterface */
21
-    private $uri;
22
-    /**
23
-     * @param string                               $method  HTTP method
24
-     * @param string|UriInterface                  $uri     URI
25
-     * @param (string|string[])[]                  $headers Request headers
26
-     * @param string|resource|StreamInterface|null $body    Request body
27
-     * @param string                               $version Protocol version
28
-     */
29
-    public function __construct(string $method, $uri, array $headers = [], $body = null, string $version = '1.1')
30
-    {
31
-        $this->assertMethod($method);
32
-        if (!$uri instanceof UriInterface) {
33
-            $uri = new Uri($uri);
34
-        }
35
-        $this->method = \strtoupper($method);
36
-        $this->uri = $uri;
37
-        $this->setHeaders($headers);
38
-        $this->protocol = $version;
39
-        if (!isset($this->headerNames['host'])) {
40
-            $this->updateHostFromUri();
41
-        }
42
-        if ($body !== '' && $body !== null) {
43
-            $this->stream = Utils::streamFor($body);
44
-        }
45
-    }
46
-    public function getRequestTarget() : string
47
-    {
48
-        if ($this->requestTarget !== null) {
49
-            return $this->requestTarget;
50
-        }
51
-        $target = $this->uri->getPath();
52
-        if ($target === '') {
53
-            $target = '/';
54
-        }
55
-        if ($this->uri->getQuery() != '') {
56
-            $target .= '?' . $this->uri->getQuery();
57
-        }
58
-        return $target;
59
-    }
60
-    public function withRequestTarget($requestTarget) : RequestInterface
61
-    {
62
-        if (\preg_match('#\\s#', $requestTarget)) {
63
-            throw new InvalidArgumentException('Invalid request target provided; cannot contain whitespace');
64
-        }
65
-        $new = clone $this;
66
-        $new->requestTarget = $requestTarget;
67
-        return $new;
68
-    }
69
-    public function getMethod() : string
70
-    {
71
-        return $this->method;
72
-    }
73
-    public function withMethod($method) : RequestInterface
74
-    {
75
-        $this->assertMethod($method);
76
-        $new = clone $this;
77
-        $new->method = \strtoupper($method);
78
-        return $new;
79
-    }
80
-    public function getUri() : UriInterface
81
-    {
82
-        return $this->uri;
83
-    }
84
-    public function withUri(UriInterface $uri, $preserveHost = \false) : RequestInterface
85
-    {
86
-        if ($uri === $this->uri) {
87
-            return $this;
88
-        }
89
-        $new = clone $this;
90
-        $new->uri = $uri;
91
-        if (!$preserveHost || !isset($this->headerNames['host'])) {
92
-            $new->updateHostFromUri();
93
-        }
94
-        return $new;
95
-    }
96
-    private function updateHostFromUri() : void
97
-    {
98
-        $host = $this->uri->getHost();
99
-        if ($host == '') {
100
-            return;
101
-        }
102
-        if (($port = $this->uri->getPort()) !== null) {
103
-            $host .= ':' . $port;
104
-        }
105
-        if (isset($this->headerNames['host'])) {
106
-            $header = $this->headerNames['host'];
107
-        } else {
108
-            $header = 'Host';
109
-            $this->headerNames['host'] = 'Host';
110
-        }
111
-        // Ensure Host is the first header.
112
-        // See: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4
113
-        $this->headers = [$header => [$host]] + $this->headers;
114
-    }
115
-    /**
116
-     * @param mixed $method
117
-     */
118
-    private function assertMethod($method) : void
119
-    {
120
-        if (!\is_string($method) || $method === '') {
121
-            throw new InvalidArgumentException('Method must be a non-empty string.');
122
-        }
123
-    }
15
+	use MessageTrait;
16
+	/** @var string */
17
+	private $method;
18
+	/** @var string|null */
19
+	private $requestTarget;
20
+	/** @var UriInterface */
21
+	private $uri;
22
+	/**
23
+	 * @param string                               $method  HTTP method
24
+	 * @param string|UriInterface                  $uri     URI
25
+	 * @param (string|string[])[]                  $headers Request headers
26
+	 * @param string|resource|StreamInterface|null $body    Request body
27
+	 * @param string                               $version Protocol version
28
+	 */
29
+	public function __construct(string $method, $uri, array $headers = [], $body = null, string $version = '1.1')
30
+	{
31
+		$this->assertMethod($method);
32
+		if (!$uri instanceof UriInterface) {
33
+			$uri = new Uri($uri);
34
+		}
35
+		$this->method = \strtoupper($method);
36
+		$this->uri = $uri;
37
+		$this->setHeaders($headers);
38
+		$this->protocol = $version;
39
+		if (!isset($this->headerNames['host'])) {
40
+			$this->updateHostFromUri();
41
+		}
42
+		if ($body !== '' && $body !== null) {
43
+			$this->stream = Utils::streamFor($body);
44
+		}
45
+	}
46
+	public function getRequestTarget() : string
47
+	{
48
+		if ($this->requestTarget !== null) {
49
+			return $this->requestTarget;
50
+		}
51
+		$target = $this->uri->getPath();
52
+		if ($target === '') {
53
+			$target = '/';
54
+		}
55
+		if ($this->uri->getQuery() != '') {
56
+			$target .= '?' . $this->uri->getQuery();
57
+		}
58
+		return $target;
59
+	}
60
+	public function withRequestTarget($requestTarget) : RequestInterface
61
+	{
62
+		if (\preg_match('#\\s#', $requestTarget)) {
63
+			throw new InvalidArgumentException('Invalid request target provided; cannot contain whitespace');
64
+		}
65
+		$new = clone $this;
66
+		$new->requestTarget = $requestTarget;
67
+		return $new;
68
+	}
69
+	public function getMethod() : string
70
+	{
71
+		return $this->method;
72
+	}
73
+	public function withMethod($method) : RequestInterface
74
+	{
75
+		$this->assertMethod($method);
76
+		$new = clone $this;
77
+		$new->method = \strtoupper($method);
78
+		return $new;
79
+	}
80
+	public function getUri() : UriInterface
81
+	{
82
+		return $this->uri;
83
+	}
84
+	public function withUri(UriInterface $uri, $preserveHost = \false) : RequestInterface
85
+	{
86
+		if ($uri === $this->uri) {
87
+			return $this;
88
+		}
89
+		$new = clone $this;
90
+		$new->uri = $uri;
91
+		if (!$preserveHost || !isset($this->headerNames['host'])) {
92
+			$new->updateHostFromUri();
93
+		}
94
+		return $new;
95
+	}
96
+	private function updateHostFromUri() : void
97
+	{
98
+		$host = $this->uri->getHost();
99
+		if ($host == '') {
100
+			return;
101
+		}
102
+		if (($port = $this->uri->getPort()) !== null) {
103
+			$host .= ':' . $port;
104
+		}
105
+		if (isset($this->headerNames['host'])) {
106
+			$header = $this->headerNames['host'];
107
+		} else {
108
+			$header = 'Host';
109
+			$this->headerNames['host'] = 'Host';
110
+		}
111
+		// Ensure Host is the first header.
112
+		// See: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4
113
+		$this->headers = [$header => [$host]] + $this->headers;
114
+	}
115
+	/**
116
+	 * @param mixed $method
117
+	 */
118
+	private function assertMethod($method) : void
119
+	{
120
+		if (!\is_string($method) || $method === '') {
121
+			throw new InvalidArgumentException('Method must be a non-empty string.');
122
+		}
123
+	}
124 124
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare (strict_types=1);
3
+declare(strict_types=1);
4 4
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7;
5 5
 
6 6
 use InvalidArgumentException;
@@ -53,7 +53,7 @@  discard block
 block discarded – undo
53 53
             $target = '/';
54 54
         }
55 55
         if ($this->uri->getQuery() != '') {
56
-            $target .= '?' . $this->uri->getQuery();
56
+            $target .= '?'.$this->uri->getQuery();
57 57
         }
58 58
         return $target;
59 59
     }
@@ -100,7 +100,7 @@  discard block
 block discarded – undo
100 100
             return;
101 101
         }
102 102
         if (($port = $this->uri->getPort()) !== null) {
103
-            $host .= ':' . $port;
103
+            $host .= ':'.$port;
104 104
         }
105 105
         if (isset($this->headerNames['host'])) {
106 106
             $header = $this->headerNames['host'];
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -10,8 +10,7 @@
 block discarded – undo
10 10
 /**
11 11
  * PSR-7 request implementation.
12 12
  */
13
-class Request implements RequestInterface
14
-{
13
+class Request implements RequestInterface {
15 14
     use MessageTrait;
16 15
     /** @var string */
17 16
     private $method;
Please login to merge, or discard this patch.
lib/Vendor/GuzzleHttp/Psr7/Query.php 3 patches
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -3,8 +3,7 @@
 block discarded – undo
3 3
 declare (strict_types=1);
4 4
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7;
5 5
 
6
-final class Query
7
-{
6
+final class Query {
8 7
     /**
9 8
      * Parse a query string into an associative array.
10 9
      *
Please login to merge, or discard this patch.
Indentation   +104 added lines, -104 removed lines patch added patch discarded remove patch
@@ -5,108 +5,108 @@
 block discarded – undo
5 5
 
6 6
 final class Query
7 7
 {
8
-    /**
9
-     * Parse a query string into an associative array.
10
-     *
11
-     * If multiple values are found for the same key, the value of that key
12
-     * value pair will become an array. This function does not parse nested
13
-     * PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
14
-     * will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
15
-     *
16
-     * @param string   $str         Query string to parse
17
-     * @param int|bool $urlEncoding How the query string is encoded
18
-     */
19
-    public static function parse(string $str, $urlEncoding = \true) : array
20
-    {
21
-        $result = [];
22
-        if ($str === '') {
23
-            return $result;
24
-        }
25
-        if ($urlEncoding === \true) {
26
-            $decoder = function ($value) {
27
-                return \rawurldecode(\str_replace('+', ' ', (string) $value));
28
-            };
29
-        } elseif ($urlEncoding === \PHP_QUERY_RFC3986) {
30
-            $decoder = 'rawurldecode';
31
-        } elseif ($urlEncoding === \PHP_QUERY_RFC1738) {
32
-            $decoder = 'urldecode';
33
-        } else {
34
-            $decoder = function ($str) {
35
-                return $str;
36
-            };
37
-        }
38
-        foreach (\explode('&', $str) as $kvp) {
39
-            $parts = \explode('=', $kvp, 2);
40
-            $key = $decoder($parts[0]);
41
-            $value = isset($parts[1]) ? $decoder($parts[1]) : null;
42
-            if (!\array_key_exists($key, $result)) {
43
-                $result[$key] = $value;
44
-            } else {
45
-                if (!\is_array($result[$key])) {
46
-                    $result[$key] = [$result[$key]];
47
-                }
48
-                $result[$key][] = $value;
49
-            }
50
-        }
51
-        return $result;
52
-    }
53
-    /**
54
-     * Build a query string from an array of key value pairs.
55
-     *
56
-     * This function can use the return value of `parse()` to build a query
57
-     * string. This function does not modify the provided keys when an array is
58
-     * encountered (like `http_build_query()` would).
59
-     *
60
-     * @param array     $params           Query string parameters.
61
-     * @param int|false $encoding         Set to false to not encode,
62
-     *                                    PHP_QUERY_RFC3986 to encode using
63
-     *                                    RFC3986, or PHP_QUERY_RFC1738 to
64
-     *                                    encode using RFC1738.
65
-     * @param bool      $treatBoolsAsInts Set to true to encode as 0/1, and
66
-     *                                    false as false/true.
67
-     */
68
-    public static function build(array $params, $encoding = \PHP_QUERY_RFC3986, bool $treatBoolsAsInts = \true) : string
69
-    {
70
-        if (!$params) {
71
-            return '';
72
-        }
73
-        if ($encoding === \false) {
74
-            $encoder = function (string $str) : string {
75
-                return $str;
76
-            };
77
-        } elseif ($encoding === \PHP_QUERY_RFC3986) {
78
-            $encoder = 'rawurlencode';
79
-        } elseif ($encoding === \PHP_QUERY_RFC1738) {
80
-            $encoder = 'urlencode';
81
-        } else {
82
-            throw new \InvalidArgumentException('Invalid type');
83
-        }
84
-        $castBool = $treatBoolsAsInts ? static function ($v) {
85
-            return (int) $v;
86
-        } : static function ($v) {
87
-            return $v ? 'true' : 'false';
88
-        };
89
-        $qs = '';
90
-        foreach ($params as $k => $v) {
91
-            $k = $encoder((string) $k);
92
-            if (!\is_array($v)) {
93
-                $qs .= $k;
94
-                $v = \is_bool($v) ? $castBool($v) : $v;
95
-                if ($v !== null) {
96
-                    $qs .= '=' . $encoder((string) $v);
97
-                }
98
-                $qs .= '&';
99
-            } else {
100
-                foreach ($v as $vv) {
101
-                    $qs .= $k;
102
-                    $vv = \is_bool($vv) ? $castBool($vv) : $vv;
103
-                    if ($vv !== null) {
104
-                        $qs .= '=' . $encoder((string) $vv);
105
-                    }
106
-                    $qs .= '&';
107
-                }
108
-            }
109
-        }
110
-        return $qs ? (string) \substr($qs, 0, -1) : '';
111
-    }
8
+	/**
9
+	 * Parse a query string into an associative array.
10
+	 *
11
+	 * If multiple values are found for the same key, the value of that key
12
+	 * value pair will become an array. This function does not parse nested
13
+	 * PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2`
14
+	 * will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`.
15
+	 *
16
+	 * @param string   $str         Query string to parse
17
+	 * @param int|bool $urlEncoding How the query string is encoded
18
+	 */
19
+	public static function parse(string $str, $urlEncoding = \true) : array
20
+	{
21
+		$result = [];
22
+		if ($str === '') {
23
+			return $result;
24
+		}
25
+		if ($urlEncoding === \true) {
26
+			$decoder = function ($value) {
27
+				return \rawurldecode(\str_replace('+', ' ', (string) $value));
28
+			};
29
+		} elseif ($urlEncoding === \PHP_QUERY_RFC3986) {
30
+			$decoder = 'rawurldecode';
31
+		} elseif ($urlEncoding === \PHP_QUERY_RFC1738) {
32
+			$decoder = 'urldecode';
33
+		} else {
34
+			$decoder = function ($str) {
35
+				return $str;
36
+			};
37
+		}
38
+		foreach (\explode('&', $str) as $kvp) {
39
+			$parts = \explode('=', $kvp, 2);
40
+			$key = $decoder($parts[0]);
41
+			$value = isset($parts[1]) ? $decoder($parts[1]) : null;
42
+			if (!\array_key_exists($key, $result)) {
43
+				$result[$key] = $value;
44
+			} else {
45
+				if (!\is_array($result[$key])) {
46
+					$result[$key] = [$result[$key]];
47
+				}
48
+				$result[$key][] = $value;
49
+			}
50
+		}
51
+		return $result;
52
+	}
53
+	/**
54
+	 * Build a query string from an array of key value pairs.
55
+	 *
56
+	 * This function can use the return value of `parse()` to build a query
57
+	 * string. This function does not modify the provided keys when an array is
58
+	 * encountered (like `http_build_query()` would).
59
+	 *
60
+	 * @param array     $params           Query string parameters.
61
+	 * @param int|false $encoding         Set to false to not encode,
62
+	 *                                    PHP_QUERY_RFC3986 to encode using
63
+	 *                                    RFC3986, or PHP_QUERY_RFC1738 to
64
+	 *                                    encode using RFC1738.
65
+	 * @param bool      $treatBoolsAsInts Set to true to encode as 0/1, and
66
+	 *                                    false as false/true.
67
+	 */
68
+	public static function build(array $params, $encoding = \PHP_QUERY_RFC3986, bool $treatBoolsAsInts = \true) : string
69
+	{
70
+		if (!$params) {
71
+			return '';
72
+		}
73
+		if ($encoding === \false) {
74
+			$encoder = function (string $str) : string {
75
+				return $str;
76
+			};
77
+		} elseif ($encoding === \PHP_QUERY_RFC3986) {
78
+			$encoder = 'rawurlencode';
79
+		} elseif ($encoding === \PHP_QUERY_RFC1738) {
80
+			$encoder = 'urlencode';
81
+		} else {
82
+			throw new \InvalidArgumentException('Invalid type');
83
+		}
84
+		$castBool = $treatBoolsAsInts ? static function ($v) {
85
+			return (int) $v;
86
+		} : static function ($v) {
87
+			return $v ? 'true' : 'false';
88
+		};
89
+		$qs = '';
90
+		foreach ($params as $k => $v) {
91
+			$k = $encoder((string) $k);
92
+			if (!\is_array($v)) {
93
+				$qs .= $k;
94
+				$v = \is_bool($v) ? $castBool($v) : $v;
95
+				if ($v !== null) {
96
+					$qs .= '=' . $encoder((string) $v);
97
+				}
98
+				$qs .= '&';
99
+			} else {
100
+				foreach ($v as $vv) {
101
+					$qs .= $k;
102
+					$vv = \is_bool($vv) ? $castBool($vv) : $vv;
103
+					if ($vv !== null) {
104
+						$qs .= '=' . $encoder((string) $vv);
105
+					}
106
+					$qs .= '&';
107
+				}
108
+			}
109
+		}
110
+		return $qs ? (string) \substr($qs, 0, -1) : '';
111
+	}
112 112
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare (strict_types=1);
3
+declare(strict_types=1);
4 4
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7;
5 5
 
6 6
 final class Query
@@ -23,15 +23,15 @@  discard block
 block discarded – undo
23 23
             return $result;
24 24
         }
25 25
         if ($urlEncoding === \true) {
26
-            $decoder = function ($value) {
27
-                return \rawurldecode(\str_replace('+', ' ', (string) $value));
26
+            $decoder = function($value) {
27
+                return \rawurldecode(\str_replace('+', ' ', (string)$value));
28 28
             };
29 29
         } elseif ($urlEncoding === \PHP_QUERY_RFC3986) {
30 30
             $decoder = 'rawurldecode';
31 31
         } elseif ($urlEncoding === \PHP_QUERY_RFC1738) {
32 32
             $decoder = 'urldecode';
33 33
         } else {
34
-            $decoder = function ($str) {
34
+            $decoder = function($str) {
35 35
                 return $str;
36 36
             };
37 37
         }
@@ -71,7 +71,7 @@  discard block
 block discarded – undo
71 71
             return '';
72 72
         }
73 73
         if ($encoding === \false) {
74
-            $encoder = function (string $str) : string {
74
+            $encoder = function(string $str) : string {
75 75
                 return $str;
76 76
             };
77 77
         } elseif ($encoding === \PHP_QUERY_RFC3986) {
@@ -81,19 +81,19 @@  discard block
 block discarded – undo
81 81
         } else {
82 82
             throw new \InvalidArgumentException('Invalid type');
83 83
         }
84
-        $castBool = $treatBoolsAsInts ? static function ($v) {
85
-            return (int) $v;
86
-        } : static function ($v) {
84
+        $castBool = $treatBoolsAsInts ? static function($v) {
85
+            return (int)$v;
86
+        } : static function($v) {
87 87
             return $v ? 'true' : 'false';
88 88
         };
89 89
         $qs = '';
90 90
         foreach ($params as $k => $v) {
91
-            $k = $encoder((string) $k);
91
+            $k = $encoder((string)$k);
92 92
             if (!\is_array($v)) {
93 93
                 $qs .= $k;
94 94
                 $v = \is_bool($v) ? $castBool($v) : $v;
95 95
                 if ($v !== null) {
96
-                    $qs .= '=' . $encoder((string) $v);
96
+                    $qs .= '='.$encoder((string)$v);
97 97
                 }
98 98
                 $qs .= '&';
99 99
             } else {
@@ -101,12 +101,12 @@  discard block
 block discarded – undo
101 101
                     $qs .= $k;
102 102
                     $vv = \is_bool($vv) ? $castBool($vv) : $vv;
103 103
                     if ($vv !== null) {
104
-                        $qs .= '=' . $encoder((string) $vv);
104
+                        $qs .= '='.$encoder((string)$vv);
105 105
                     }
106 106
                     $qs .= '&';
107 107
                 }
108 108
             }
109 109
         }
110
-        return $qs ? (string) \substr($qs, 0, -1) : '';
110
+        return $qs ? (string)\substr($qs, 0, -1) : '';
111 111
     }
112 112
 }
Please login to merge, or discard this patch.
lib/Vendor/GuzzleHttp/Psr7/LazyOpenStream.php 3 patches
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -10,32 +10,32 @@
 block discarded – undo
10 10
  */
11 11
 final class LazyOpenStream implements StreamInterface
12 12
 {
13
-    use StreamDecoratorTrait;
14
-    /** @var string */
15
-    private $filename;
16
-    /** @var string */
17
-    private $mode;
18
-    /**
19
-     * @var StreamInterface
20
-     */
21
-    private $stream;
22
-    /**
23
-     * @param string $filename File to lazily open
24
-     * @param string $mode     fopen mode to use when opening the stream
25
-     */
26
-    public function __construct(string $filename, string $mode)
27
-    {
28
-        $this->filename = $filename;
29
-        $this->mode = $mode;
30
-        // unsetting the property forces the first access to go through
31
-        // __get().
32
-        unset($this->stream);
33
-    }
34
-    /**
35
-     * Creates the underlying stream lazily when required.
36
-     */
37
-    protected function createStream() : StreamInterface
38
-    {
39
-        return Utils::streamFor(Utils::tryFopen($this->filename, $this->mode));
40
-    }
13
+	use StreamDecoratorTrait;
14
+	/** @var string */
15
+	private $filename;
16
+	/** @var string */
17
+	private $mode;
18
+	/**
19
+	 * @var StreamInterface
20
+	 */
21
+	private $stream;
22
+	/**
23
+	 * @param string $filename File to lazily open
24
+	 * @param string $mode     fopen mode to use when opening the stream
25
+	 */
26
+	public function __construct(string $filename, string $mode)
27
+	{
28
+		$this->filename = $filename;
29
+		$this->mode = $mode;
30
+		// unsetting the property forces the first access to go through
31
+		// __get().
32
+		unset($this->stream);
33
+	}
34
+	/**
35
+	 * Creates the underlying stream lazily when required.
36
+	 */
37
+	protected function createStream() : StreamInterface
38
+	{
39
+		return Utils::streamFor(Utils::tryFopen($this->filename, $this->mode));
40
+	}
41 41
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -8,8 +8,7 @@
 block discarded – undo
8 8
  * Lazily reads or writes to a file that is opened only after an IO operation
9 9
  * take place on the stream.
10 10
  */
11
-final class LazyOpenStream implements StreamInterface
12
-{
11
+final class LazyOpenStream implements StreamInterface {
13 12
     use StreamDecoratorTrait;
14 13
     /** @var string */
15 14
     private $filename;
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare (strict_types=1);
3
+declare(strict_types=1);
4 4
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7;
5 5
 
6 6
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\StreamInterface;
Please login to merge, or discard this patch.
lib/Vendor/GuzzleHttp/Psr7/DroppingStream.php 3 patches
Indentation   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -10,31 +10,31 @@
 block discarded – undo
10 10
  */
11 11
 final class DroppingStream implements StreamInterface
12 12
 {
13
-    use StreamDecoratorTrait;
14
-    /** @var int */
15
-    private $maxLength;
16
-    /** @var StreamInterface */
17
-    private $stream;
18
-    /**
19
-     * @param StreamInterface $stream    Underlying stream to decorate.
20
-     * @param int             $maxLength Maximum size before dropping data.
21
-     */
22
-    public function __construct(StreamInterface $stream, int $maxLength)
23
-    {
24
-        $this->stream = $stream;
25
-        $this->maxLength = $maxLength;
26
-    }
27
-    public function write($string) : int
28
-    {
29
-        $diff = $this->maxLength - $this->stream->getSize();
30
-        // Begin returning 0 when the underlying stream is too large.
31
-        if ($diff <= 0) {
32
-            return 0;
33
-        }
34
-        // Write the stream or a subset of the stream if needed.
35
-        if (\strlen($string) < $diff) {
36
-            return $this->stream->write($string);
37
-        }
38
-        return $this->stream->write(\substr($string, 0, $diff));
39
-    }
13
+	use StreamDecoratorTrait;
14
+	/** @var int */
15
+	private $maxLength;
16
+	/** @var StreamInterface */
17
+	private $stream;
18
+	/**
19
+	 * @param StreamInterface $stream    Underlying stream to decorate.
20
+	 * @param int             $maxLength Maximum size before dropping data.
21
+	 */
22
+	public function __construct(StreamInterface $stream, int $maxLength)
23
+	{
24
+		$this->stream = $stream;
25
+		$this->maxLength = $maxLength;
26
+	}
27
+	public function write($string) : int
28
+	{
29
+		$diff = $this->maxLength - $this->stream->getSize();
30
+		// Begin returning 0 when the underlying stream is too large.
31
+		if ($diff <= 0) {
32
+			return 0;
33
+		}
34
+		// Write the stream or a subset of the stream if needed.
35
+		if (\strlen($string) < $diff) {
36
+			return $this->stream->write($string);
37
+		}
38
+		return $this->stream->write(\substr($string, 0, $diff));
39
+	}
40 40
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -8,8 +8,7 @@
 block discarded – undo
8 8
  * Stream decorator that begins dropping data once the size of the underlying
9 9
  * stream becomes too full.
10 10
  */
11
-final class DroppingStream implements StreamInterface
12
-{
11
+final class DroppingStream implements StreamInterface {
13 12
     use StreamDecoratorTrait;
14 13
     /** @var int */
15 14
     private $maxLength;
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare (strict_types=1);
3
+declare(strict_types=1);
4 4
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7;
5 5
 
6 6
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\StreamInterface;
Please login to merge, or discard this patch.
lib/Vendor/GuzzleHttp/Psr7/Utils.php 3 patches
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@  discard block
 block discarded – undo
1 1
 <?php
2 2
 
3
-declare (strict_types=1);
3
+declare(strict_types=1);
4 4
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7;
5 5
 
6 6
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\RequestInterface;
@@ -18,10 +18,10 @@  discard block
 block discarded – undo
18 18
     {
19 19
         $result = [];
20 20
         foreach ($keys as &$key) {
21
-            $key = \strtolower((string) $key);
21
+            $key = \strtolower((string)$key);
22 22
         }
23 23
         foreach ($data as $k => $v) {
24
-            if (!\in_array(\strtolower((string) $k), $keys)) {
24
+            if (!\in_array(\strtolower((string)$k), $keys)) {
25 25
                 $result[$k] = $v;
26 26
             }
27 27
         }
@@ -154,7 +154,7 @@  discard block
 block discarded – undo
154 154
                     $standardPorts = ['http' => 80, 'https' => 443];
155 155
                     $scheme = $changes['uri']->getScheme();
156 156
                     if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
157
-                        $changes['set_headers']['Host'] .= ':' . $port;
157
+                        $changes['set_headers']['Host'] .= ':'.$port;
158 158
                     }
159 159
                 }
160 160
             }
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
         if (\is_scalar($resource)) {
241 241
             $stream = self::tryFopen('php://temp', 'r+');
242 242
             if ($resource !== '') {
243
-                \fwrite($stream, (string) $resource);
243
+                \fwrite($stream, (string)$resource);
244 244
                 \fseek($stream, 0);
245 245
             }
246 246
             return new Stream($stream, $options);
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
                 if ($resource instanceof StreamInterface) {
265 265
                     return $resource;
266 266
                 } elseif ($resource instanceof \Iterator) {
267
-                    return new PumpStream(function () use($resource) {
267
+                    return new PumpStream(function() use($resource) {
268 268
                         if (!$resource->valid()) {
269 269
                             return \false;
270 270
                         }
@@ -273,7 +273,7 @@  discard block
 block discarded – undo
273 273
                         return $result;
274 274
                     }, $options);
275 275
                 } elseif (\method_exists($resource, '__toString')) {
276
-                    return self::streamFor((string) $resource, $options);
276
+                    return self::streamFor((string)$resource, $options);
277 277
                 }
278 278
                 break;
279 279
             case 'NULL':
@@ -282,7 +282,7 @@  discard block
 block discarded – undo
282 282
         if (\is_callable($resource)) {
283 283
             return new PumpStream($resource, $options);
284 284
         }
285
-        throw new \InvalidArgumentException('Invalid resource type: ' . \gettype($resource));
285
+        throw new \InvalidArgumentException('Invalid resource type: '.\gettype($resource));
286 286
     }
287 287
     /**
288 288
      * Safely opens a PHP stream resource using a filename.
@@ -300,7 +300,7 @@  discard block
 block discarded – undo
300 300
     public static function tryFopen(string $filename, string $mode)
301 301
     {
302 302
         $ex = null;
303
-        \set_error_handler(static function (int $errno, string $errstr) use($filename, $mode, &$ex) : bool {
303
+        \set_error_handler(static function(int $errno, string $errstr) use($filename, $mode, &$ex) : bool {
304 304
             $ex = new \RuntimeException(\sprintf('Unable to open "%s" using mode "%s": %s', $filename, $mode, $errstr));
305 305
             return \true;
306 306
         });
@@ -331,7 +331,7 @@  discard block
 block discarded – undo
331 331
     public static function tryGetContents($stream) : string
332 332
     {
333 333
         $ex = null;
334
-        \set_error_handler(static function (int $errno, string $errstr) use(&$ex) : bool {
334
+        \set_error_handler(static function(int $errno, string $errstr) use(&$ex) : bool {
335 335
             $ex = new \RuntimeException(\sprintf('Unable to read stream contents: %s', $errstr));
336 336
             return \true;
337 337
         });
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -7,8 +7,7 @@
 block discarded – undo
7 7
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\ServerRequestInterface;
8 8
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\StreamInterface;
9 9
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\UriInterface;
10
-final class Utils
11
-{
10
+final class Utils {
12 11
     /**
13 12
      * Remove the items given by the keys, case insensitively from the data.
14 13
      *
Please login to merge, or discard this patch.
Indentation   +371 added lines, -371 removed lines patch added patch discarded remove patch
@@ -9,378 +9,378 @@
 block discarded – undo
9 9
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\UriInterface;
10 10
 final class Utils
11 11
 {
12
-    /**
13
-     * Remove the items given by the keys, case insensitively from the data.
14
-     *
15
-     * @param (string|int)[] $keys
16
-     */
17
-    public static function caselessRemove(array $keys, array $data) : array
18
-    {
19
-        $result = [];
20
-        foreach ($keys as &$key) {
21
-            $key = \strtolower((string) $key);
22
-        }
23
-        foreach ($data as $k => $v) {
24
-            if (!\in_array(\strtolower((string) $k), $keys)) {
25
-                $result[$k] = $v;
26
-            }
27
-        }
28
-        return $result;
29
-    }
30
-    /**
31
-     * Copy the contents of a stream into another stream until the given number
32
-     * of bytes have been read.
33
-     *
34
-     * @param StreamInterface $source Stream to read from
35
-     * @param StreamInterface $dest   Stream to write to
36
-     * @param int             $maxLen Maximum number of bytes to read. Pass -1
37
-     *                                to read the entire stream.
38
-     *
39
-     * @throws \RuntimeException on error.
40
-     */
41
-    public static function copyToStream(StreamInterface $source, StreamInterface $dest, int $maxLen = -1) : void
42
-    {
43
-        $bufferSize = 8192;
44
-        if ($maxLen === -1) {
45
-            while (!$source->eof()) {
46
-                if (!$dest->write($source->read($bufferSize))) {
47
-                    break;
48
-                }
49
-            }
50
-        } else {
51
-            $remaining = $maxLen;
52
-            while ($remaining > 0 && !$source->eof()) {
53
-                $buf = $source->read(\min($bufferSize, $remaining));
54
-                $len = \strlen($buf);
55
-                if (!$len) {
56
-                    break;
57
-                }
58
-                $remaining -= $len;
59
-                $dest->write($buf);
60
-            }
61
-        }
62
-    }
63
-    /**
64
-     * Copy the contents of a stream into a string until the given number of
65
-     * bytes have been read.
66
-     *
67
-     * @param StreamInterface $stream Stream to read
68
-     * @param int             $maxLen Maximum number of bytes to read. Pass -1
69
-     *                                to read the entire stream.
70
-     *
71
-     * @throws \RuntimeException on error.
72
-     */
73
-    public static function copyToString(StreamInterface $stream, int $maxLen = -1) : string
74
-    {
75
-        $buffer = '';
76
-        if ($maxLen === -1) {
77
-            while (!$stream->eof()) {
78
-                $buf = $stream->read(1048576);
79
-                if ($buf === '') {
80
-                    break;
81
-                }
82
-                $buffer .= $buf;
83
-            }
84
-            return $buffer;
85
-        }
86
-        $len = 0;
87
-        while (!$stream->eof() && $len < $maxLen) {
88
-            $buf = $stream->read($maxLen - $len);
89
-            if ($buf === '') {
90
-                break;
91
-            }
92
-            $buffer .= $buf;
93
-            $len = \strlen($buffer);
94
-        }
95
-        return $buffer;
96
-    }
97
-    /**
98
-     * Calculate a hash of a stream.
99
-     *
100
-     * This method reads the entire stream to calculate a rolling hash, based
101
-     * on PHP's `hash_init` functions.
102
-     *
103
-     * @param StreamInterface $stream    Stream to calculate the hash for
104
-     * @param string          $algo      Hash algorithm (e.g. md5, crc32, etc)
105
-     * @param bool            $rawOutput Whether or not to use raw output
106
-     *
107
-     * @throws \RuntimeException on error.
108
-     */
109
-    public static function hash(StreamInterface $stream, string $algo, bool $rawOutput = \false) : string
110
-    {
111
-        $pos = $stream->tell();
112
-        if ($pos > 0) {
113
-            $stream->rewind();
114
-        }
115
-        $ctx = \hash_init($algo);
116
-        while (!$stream->eof()) {
117
-            \hash_update($ctx, $stream->read(1048576));
118
-        }
119
-        $out = \hash_final($ctx, $rawOutput);
120
-        $stream->seek($pos);
121
-        return $out;
122
-    }
123
-    /**
124
-     * Clone and modify a request with the given changes.
125
-     *
126
-     * This method is useful for reducing the number of clones needed to mutate
127
-     * a message.
128
-     *
129
-     * The changes can be one of:
130
-     * - method: (string) Changes the HTTP method.
131
-     * - set_headers: (array) Sets the given headers.
132
-     * - remove_headers: (array) Remove the given headers.
133
-     * - body: (mixed) Sets the given body.
134
-     * - uri: (UriInterface) Set the URI.
135
-     * - query: (string) Set the query string value of the URI.
136
-     * - version: (string) Set the protocol version.
137
-     *
138
-     * @param RequestInterface $request Request to clone and modify.
139
-     * @param array            $changes Changes to apply.
140
-     */
141
-    public static function modifyRequest(RequestInterface $request, array $changes) : RequestInterface
142
-    {
143
-        if (!$changes) {
144
-            return $request;
145
-        }
146
-        $headers = $request->getHeaders();
147
-        if (!isset($changes['uri'])) {
148
-            $uri = $request->getUri();
149
-        } else {
150
-            // Remove the host header if one is on the URI
151
-            if ($host = $changes['uri']->getHost()) {
152
-                $changes['set_headers']['Host'] = $host;
153
-                if ($port = $changes['uri']->getPort()) {
154
-                    $standardPorts = ['http' => 80, 'https' => 443];
155
-                    $scheme = $changes['uri']->getScheme();
156
-                    if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
157
-                        $changes['set_headers']['Host'] .= ':' . $port;
158
-                    }
159
-                }
160
-            }
161
-            $uri = $changes['uri'];
162
-        }
163
-        if (!empty($changes['remove_headers'])) {
164
-            $headers = self::caselessRemove($changes['remove_headers'], $headers);
165
-        }
166
-        if (!empty($changes['set_headers'])) {
167
-            $headers = self::caselessRemove(\array_keys($changes['set_headers']), $headers);
168
-            $headers = $changes['set_headers'] + $headers;
169
-        }
170
-        if (isset($changes['query'])) {
171
-            $uri = $uri->withQuery($changes['query']);
172
-        }
173
-        if ($request instanceof ServerRequestInterface) {
174
-            $new = (new ServerRequest($changes['method'] ?? $request->getMethod(), $uri, $headers, $changes['body'] ?? $request->getBody(), $changes['version'] ?? $request->getProtocolVersion(), $request->getServerParams()))->withParsedBody($request->getParsedBody())->withQueryParams($request->getQueryParams())->withCookieParams($request->getCookieParams())->withUploadedFiles($request->getUploadedFiles());
175
-            foreach ($request->getAttributes() as $key => $value) {
176
-                $new = $new->withAttribute($key, $value);
177
-            }
178
-            return $new;
179
-        }
180
-        return new Request($changes['method'] ?? $request->getMethod(), $uri, $headers, $changes['body'] ?? $request->getBody(), $changes['version'] ?? $request->getProtocolVersion());
181
-    }
182
-    /**
183
-     * Read a line from the stream up to the maximum allowed buffer length.
184
-     *
185
-     * @param StreamInterface $stream    Stream to read from
186
-     * @param int|null        $maxLength Maximum buffer length
187
-     */
188
-    public static function readLine(StreamInterface $stream, ?int $maxLength = null) : string
189
-    {
190
-        $buffer = '';
191
-        $size = 0;
192
-        while (!$stream->eof()) {
193
-            if ('' === ($byte = $stream->read(1))) {
194
-                return $buffer;
195
-            }
196
-            $buffer .= $byte;
197
-            // Break when a new line is found or the max length - 1 is reached
198
-            if ($byte === "\n" || ++$size === $maxLength - 1) {
199
-                break;
200
-            }
201
-        }
202
-        return $buffer;
203
-    }
204
-    /**
205
-     * Redact the password in the user info part of a URI.
206
-     */
207
-    public static function redactUserInfo(UriInterface $uri) : UriInterface
208
-    {
209
-        $userInfo = $uri->getUserInfo();
210
-        if (\false !== ($pos = \strpos($userInfo, ':'))) {
211
-            return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***');
212
-        }
213
-        return $uri;
214
-    }
215
-    /**
216
-     * Create a new stream based on the input type.
217
-     *
218
-     * Options is an associative array that can contain the following keys:
219
-     * - metadata: Array of custom metadata.
220
-     * - size: Size of the stream.
221
-     *
222
-     * This method accepts the following `$resource` types:
223
-     * - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
224
-     * - `string`: Creates a stream object that uses the given string as the contents.
225
-     * - `resource`: Creates a stream object that wraps the given PHP stream resource.
226
-     * - `Iterator`: If the provided value implements `Iterator`, then a read-only
227
-     *   stream object will be created that wraps the given iterable. Each time the
228
-     *   stream is read from, data from the iterator will fill a buffer and will be
229
-     *   continuously called until the buffer is equal to the requested read size.
230
-     *   Subsequent read calls will first read from the buffer and then call `next`
231
-     *   on the underlying iterator until it is exhausted.
232
-     * - `object` with `__toString()`: If the object has the `__toString()` method,
233
-     *   the object will be cast to a string and then a stream will be returned that
234
-     *   uses the string value.
235
-     * - `NULL`: When `null` is passed, an empty stream object is returned.
236
-     * - `callable` When a callable is passed, a read-only stream object will be
237
-     *   created that invokes the given callable. The callable is invoked with the
238
-     *   number of suggested bytes to read. The callable can return any number of
239
-     *   bytes, but MUST return `false` when there is no more data to return. The
240
-     *   stream object that wraps the callable will invoke the callable until the
241
-     *   number of requested bytes are available. Any additional bytes will be
242
-     *   buffered and used in subsequent reads.
243
-     *
244
-     * @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data
245
-     * @param array{size?: int, metadata?: array}                                    $options  Additional options
246
-     *
247
-     * @throws \InvalidArgumentException if the $resource arg is not valid.
248
-     */
249
-    public static function streamFor($resource = '', array $options = []) : StreamInterface
250
-    {
251
-        if (\is_scalar($resource)) {
252
-            $stream = self::tryFopen('php://temp', 'r+');
253
-            if ($resource !== '') {
254
-                \fwrite($stream, (string) $resource);
255
-                \fseek($stream, 0);
256
-            }
257
-            return new Stream($stream, $options);
258
-        }
259
-        switch (\gettype($resource)) {
260
-            case 'resource':
261
-                /*
12
+	/**
13
+	 * Remove the items given by the keys, case insensitively from the data.
14
+	 *
15
+	 * @param (string|int)[] $keys
16
+	 */
17
+	public static function caselessRemove(array $keys, array $data) : array
18
+	{
19
+		$result = [];
20
+		foreach ($keys as &$key) {
21
+			$key = \strtolower((string) $key);
22
+		}
23
+		foreach ($data as $k => $v) {
24
+			if (!\in_array(\strtolower((string) $k), $keys)) {
25
+				$result[$k] = $v;
26
+			}
27
+		}
28
+		return $result;
29
+	}
30
+	/**
31
+	 * Copy the contents of a stream into another stream until the given number
32
+	 * of bytes have been read.
33
+	 *
34
+	 * @param StreamInterface $source Stream to read from
35
+	 * @param StreamInterface $dest   Stream to write to
36
+	 * @param int             $maxLen Maximum number of bytes to read. Pass -1
37
+	 *                                to read the entire stream.
38
+	 *
39
+	 * @throws \RuntimeException on error.
40
+	 */
41
+	public static function copyToStream(StreamInterface $source, StreamInterface $dest, int $maxLen = -1) : void
42
+	{
43
+		$bufferSize = 8192;
44
+		if ($maxLen === -1) {
45
+			while (!$source->eof()) {
46
+				if (!$dest->write($source->read($bufferSize))) {
47
+					break;
48
+				}
49
+			}
50
+		} else {
51
+			$remaining = $maxLen;
52
+			while ($remaining > 0 && !$source->eof()) {
53
+				$buf = $source->read(\min($bufferSize, $remaining));
54
+				$len = \strlen($buf);
55
+				if (!$len) {
56
+					break;
57
+				}
58
+				$remaining -= $len;
59
+				$dest->write($buf);
60
+			}
61
+		}
62
+	}
63
+	/**
64
+	 * Copy the contents of a stream into a string until the given number of
65
+	 * bytes have been read.
66
+	 *
67
+	 * @param StreamInterface $stream Stream to read
68
+	 * @param int             $maxLen Maximum number of bytes to read. Pass -1
69
+	 *                                to read the entire stream.
70
+	 *
71
+	 * @throws \RuntimeException on error.
72
+	 */
73
+	public static function copyToString(StreamInterface $stream, int $maxLen = -1) : string
74
+	{
75
+		$buffer = '';
76
+		if ($maxLen === -1) {
77
+			while (!$stream->eof()) {
78
+				$buf = $stream->read(1048576);
79
+				if ($buf === '') {
80
+					break;
81
+				}
82
+				$buffer .= $buf;
83
+			}
84
+			return $buffer;
85
+		}
86
+		$len = 0;
87
+		while (!$stream->eof() && $len < $maxLen) {
88
+			$buf = $stream->read($maxLen - $len);
89
+			if ($buf === '') {
90
+				break;
91
+			}
92
+			$buffer .= $buf;
93
+			$len = \strlen($buffer);
94
+		}
95
+		return $buffer;
96
+	}
97
+	/**
98
+	 * Calculate a hash of a stream.
99
+	 *
100
+	 * This method reads the entire stream to calculate a rolling hash, based
101
+	 * on PHP's `hash_init` functions.
102
+	 *
103
+	 * @param StreamInterface $stream    Stream to calculate the hash for
104
+	 * @param string          $algo      Hash algorithm (e.g. md5, crc32, etc)
105
+	 * @param bool            $rawOutput Whether or not to use raw output
106
+	 *
107
+	 * @throws \RuntimeException on error.
108
+	 */
109
+	public static function hash(StreamInterface $stream, string $algo, bool $rawOutput = \false) : string
110
+	{
111
+		$pos = $stream->tell();
112
+		if ($pos > 0) {
113
+			$stream->rewind();
114
+		}
115
+		$ctx = \hash_init($algo);
116
+		while (!$stream->eof()) {
117
+			\hash_update($ctx, $stream->read(1048576));
118
+		}
119
+		$out = \hash_final($ctx, $rawOutput);
120
+		$stream->seek($pos);
121
+		return $out;
122
+	}
123
+	/**
124
+	 * Clone and modify a request with the given changes.
125
+	 *
126
+	 * This method is useful for reducing the number of clones needed to mutate
127
+	 * a message.
128
+	 *
129
+	 * The changes can be one of:
130
+	 * - method: (string) Changes the HTTP method.
131
+	 * - set_headers: (array) Sets the given headers.
132
+	 * - remove_headers: (array) Remove the given headers.
133
+	 * - body: (mixed) Sets the given body.
134
+	 * - uri: (UriInterface) Set the URI.
135
+	 * - query: (string) Set the query string value of the URI.
136
+	 * - version: (string) Set the protocol version.
137
+	 *
138
+	 * @param RequestInterface $request Request to clone and modify.
139
+	 * @param array            $changes Changes to apply.
140
+	 */
141
+	public static function modifyRequest(RequestInterface $request, array $changes) : RequestInterface
142
+	{
143
+		if (!$changes) {
144
+			return $request;
145
+		}
146
+		$headers = $request->getHeaders();
147
+		if (!isset($changes['uri'])) {
148
+			$uri = $request->getUri();
149
+		} else {
150
+			// Remove the host header if one is on the URI
151
+			if ($host = $changes['uri']->getHost()) {
152
+				$changes['set_headers']['Host'] = $host;
153
+				if ($port = $changes['uri']->getPort()) {
154
+					$standardPorts = ['http' => 80, 'https' => 443];
155
+					$scheme = $changes['uri']->getScheme();
156
+					if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) {
157
+						$changes['set_headers']['Host'] .= ':' . $port;
158
+					}
159
+				}
160
+			}
161
+			$uri = $changes['uri'];
162
+		}
163
+		if (!empty($changes['remove_headers'])) {
164
+			$headers = self::caselessRemove($changes['remove_headers'], $headers);
165
+		}
166
+		if (!empty($changes['set_headers'])) {
167
+			$headers = self::caselessRemove(\array_keys($changes['set_headers']), $headers);
168
+			$headers = $changes['set_headers'] + $headers;
169
+		}
170
+		if (isset($changes['query'])) {
171
+			$uri = $uri->withQuery($changes['query']);
172
+		}
173
+		if ($request instanceof ServerRequestInterface) {
174
+			$new = (new ServerRequest($changes['method'] ?? $request->getMethod(), $uri, $headers, $changes['body'] ?? $request->getBody(), $changes['version'] ?? $request->getProtocolVersion(), $request->getServerParams()))->withParsedBody($request->getParsedBody())->withQueryParams($request->getQueryParams())->withCookieParams($request->getCookieParams())->withUploadedFiles($request->getUploadedFiles());
175
+			foreach ($request->getAttributes() as $key => $value) {
176
+				$new = $new->withAttribute($key, $value);
177
+			}
178
+			return $new;
179
+		}
180
+		return new Request($changes['method'] ?? $request->getMethod(), $uri, $headers, $changes['body'] ?? $request->getBody(), $changes['version'] ?? $request->getProtocolVersion());
181
+	}
182
+	/**
183
+	 * Read a line from the stream up to the maximum allowed buffer length.
184
+	 *
185
+	 * @param StreamInterface $stream    Stream to read from
186
+	 * @param int|null        $maxLength Maximum buffer length
187
+	 */
188
+	public static function readLine(StreamInterface $stream, ?int $maxLength = null) : string
189
+	{
190
+		$buffer = '';
191
+		$size = 0;
192
+		while (!$stream->eof()) {
193
+			if ('' === ($byte = $stream->read(1))) {
194
+				return $buffer;
195
+			}
196
+			$buffer .= $byte;
197
+			// Break when a new line is found or the max length - 1 is reached
198
+			if ($byte === "\n" || ++$size === $maxLength - 1) {
199
+				break;
200
+			}
201
+		}
202
+		return $buffer;
203
+	}
204
+	/**
205
+	 * Redact the password in the user info part of a URI.
206
+	 */
207
+	public static function redactUserInfo(UriInterface $uri) : UriInterface
208
+	{
209
+		$userInfo = $uri->getUserInfo();
210
+		if (\false !== ($pos = \strpos($userInfo, ':'))) {
211
+			return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***');
212
+		}
213
+		return $uri;
214
+	}
215
+	/**
216
+	 * Create a new stream based on the input type.
217
+	 *
218
+	 * Options is an associative array that can contain the following keys:
219
+	 * - metadata: Array of custom metadata.
220
+	 * - size: Size of the stream.
221
+	 *
222
+	 * This method accepts the following `$resource` types:
223
+	 * - `Psr\Http\Message\StreamInterface`: Returns the value as-is.
224
+	 * - `string`: Creates a stream object that uses the given string as the contents.
225
+	 * - `resource`: Creates a stream object that wraps the given PHP stream resource.
226
+	 * - `Iterator`: If the provided value implements `Iterator`, then a read-only
227
+	 *   stream object will be created that wraps the given iterable. Each time the
228
+	 *   stream is read from, data from the iterator will fill a buffer and will be
229
+	 *   continuously called until the buffer is equal to the requested read size.
230
+	 *   Subsequent read calls will first read from the buffer and then call `next`
231
+	 *   on the underlying iterator until it is exhausted.
232
+	 * - `object` with `__toString()`: If the object has the `__toString()` method,
233
+	 *   the object will be cast to a string and then a stream will be returned that
234
+	 *   uses the string value.
235
+	 * - `NULL`: When `null` is passed, an empty stream object is returned.
236
+	 * - `callable` When a callable is passed, a read-only stream object will be
237
+	 *   created that invokes the given callable. The callable is invoked with the
238
+	 *   number of suggested bytes to read. The callable can return any number of
239
+	 *   bytes, but MUST return `false` when there is no more data to return. The
240
+	 *   stream object that wraps the callable will invoke the callable until the
241
+	 *   number of requested bytes are available. Any additional bytes will be
242
+	 *   buffered and used in subsequent reads.
243
+	 *
244
+	 * @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data
245
+	 * @param array{size?: int, metadata?: array}                                    $options  Additional options
246
+	 *
247
+	 * @throws \InvalidArgumentException if the $resource arg is not valid.
248
+	 */
249
+	public static function streamFor($resource = '', array $options = []) : StreamInterface
250
+	{
251
+		if (\is_scalar($resource)) {
252
+			$stream = self::tryFopen('php://temp', 'r+');
253
+			if ($resource !== '') {
254
+				\fwrite($stream, (string) $resource);
255
+				\fseek($stream, 0);
256
+			}
257
+			return new Stream($stream, $options);
258
+		}
259
+		switch (\gettype($resource)) {
260
+			case 'resource':
261
+				/*
262 262
                  * The 'php://input' is a special stream with quirks and inconsistencies.
263 263
                  * We avoid using that stream by reading it into php://temp
264 264
                  */
265
-                /** @var resource $resource */
266
-                if ((\stream_get_meta_data($resource)['uri'] ?? '') === 'php://input') {
267
-                    $stream = self::tryFopen('php://temp', 'w+');
268
-                    \stream_copy_to_stream($resource, $stream);
269
-                    \fseek($stream, 0);
270
-                    $resource = $stream;
271
-                }
272
-                return new Stream($resource, $options);
273
-            case 'object':
274
-                /** @var object $resource */
275
-                if ($resource instanceof StreamInterface) {
276
-                    return $resource;
277
-                } elseif ($resource instanceof \Iterator) {
278
-                    return new PumpStream(function () use($resource) {
279
-                        if (!$resource->valid()) {
280
-                            return \false;
281
-                        }
282
-                        $result = $resource->current();
283
-                        $resource->next();
284
-                        return $result;
285
-                    }, $options);
286
-                } elseif (\method_exists($resource, '__toString')) {
287
-                    return self::streamFor((string) $resource, $options);
288
-                }
289
-                break;
290
-            case 'NULL':
291
-                return new Stream(self::tryFopen('php://temp', 'r+'), $options);
292
-        }
293
-        if (\is_callable($resource)) {
294
-            return new PumpStream($resource, $options);
295
-        }
296
-        throw new \InvalidArgumentException('Invalid resource type: ' . \gettype($resource));
297
-    }
298
-    /**
299
-     * Safely opens a PHP stream resource using a filename.
300
-     *
301
-     * When fopen fails, PHP normally raises a warning. This function adds an
302
-     * error handler that checks for errors and throws an exception instead.
303
-     *
304
-     * @param string $filename File to open
305
-     * @param string $mode     Mode used to open the file
306
-     *
307
-     * @return resource
308
-     *
309
-     * @throws \RuntimeException if the file cannot be opened
310
-     */
311
-    public static function tryFopen(string $filename, string $mode)
312
-    {
313
-        $ex = null;
314
-        \set_error_handler(static function (int $errno, string $errstr) use($filename, $mode, &$ex) : bool {
315
-            $ex = new \RuntimeException(\sprintf('Unable to open "%s" using mode "%s": %s', $filename, $mode, $errstr));
316
-            return \true;
317
-        });
318
-        try {
319
-            /** @var resource $handle */
320
-            $handle = \fopen($filename, $mode);
321
-        } catch (\Throwable $e) {
322
-            $ex = new \RuntimeException(\sprintf('Unable to open "%s" using mode "%s": %s', $filename, $mode, $e->getMessage()), 0, $e);
323
-        }
324
-        \restore_error_handler();
325
-        if ($ex) {
326
-            /** @var $ex \RuntimeException */
327
-            throw $ex;
328
-        }
329
-        return $handle;
330
-    }
331
-    /**
332
-     * Safely gets the contents of a given stream.
333
-     *
334
-     * When stream_get_contents fails, PHP normally raises a warning. This
335
-     * function adds an error handler that checks for errors and throws an
336
-     * exception instead.
337
-     *
338
-     * @param resource $stream
339
-     *
340
-     * @throws \RuntimeException if the stream cannot be read
341
-     */
342
-    public static function tryGetContents($stream) : string
343
-    {
344
-        $ex = null;
345
-        \set_error_handler(static function (int $errno, string $errstr) use(&$ex) : bool {
346
-            $ex = new \RuntimeException(\sprintf('Unable to read stream contents: %s', $errstr));
347
-            return \true;
348
-        });
349
-        try {
350
-            /** @var string|false $contents */
351
-            $contents = \stream_get_contents($stream);
352
-            if ($contents === \false) {
353
-                $ex = new \RuntimeException('Unable to read stream contents');
354
-            }
355
-        } catch (\Throwable $e) {
356
-            $ex = new \RuntimeException(\sprintf('Unable to read stream contents: %s', $e->getMessage()), 0, $e);
357
-        }
358
-        \restore_error_handler();
359
-        if ($ex) {
360
-            /** @var $ex \RuntimeException */
361
-            throw $ex;
362
-        }
363
-        return $contents;
364
-    }
365
-    /**
366
-     * Returns a UriInterface for the given value.
367
-     *
368
-     * This function accepts a string or UriInterface and returns a
369
-     * UriInterface for the given value. If the value is already a
370
-     * UriInterface, it is returned as-is.
371
-     *
372
-     * @param string|UriInterface $uri
373
-     *
374
-     * @throws \InvalidArgumentException
375
-     */
376
-    public static function uriFor($uri) : UriInterface
377
-    {
378
-        if ($uri instanceof UriInterface) {
379
-            return $uri;
380
-        }
381
-        if (\is_string($uri)) {
382
-            return new Uri($uri);
383
-        }
384
-        throw new \InvalidArgumentException('URI must be a string or UriInterface');
385
-    }
265
+				/** @var resource $resource */
266
+				if ((\stream_get_meta_data($resource)['uri'] ?? '') === 'php://input') {
267
+					$stream = self::tryFopen('php://temp', 'w+');
268
+					\stream_copy_to_stream($resource, $stream);
269
+					\fseek($stream, 0);
270
+					$resource = $stream;
271
+				}
272
+				return new Stream($resource, $options);
273
+			case 'object':
274
+				/** @var object $resource */
275
+				if ($resource instanceof StreamInterface) {
276
+					return $resource;
277
+				} elseif ($resource instanceof \Iterator) {
278
+					return new PumpStream(function () use($resource) {
279
+						if (!$resource->valid()) {
280
+							return \false;
281
+						}
282
+						$result = $resource->current();
283
+						$resource->next();
284
+						return $result;
285
+					}, $options);
286
+				} elseif (\method_exists($resource, '__toString')) {
287
+					return self::streamFor((string) $resource, $options);
288
+				}
289
+				break;
290
+			case 'NULL':
291
+				return new Stream(self::tryFopen('php://temp', 'r+'), $options);
292
+		}
293
+		if (\is_callable($resource)) {
294
+			return new PumpStream($resource, $options);
295
+		}
296
+		throw new \InvalidArgumentException('Invalid resource type: ' . \gettype($resource));
297
+	}
298
+	/**
299
+	 * Safely opens a PHP stream resource using a filename.
300
+	 *
301
+	 * When fopen fails, PHP normally raises a warning. This function adds an
302
+	 * error handler that checks for errors and throws an exception instead.
303
+	 *
304
+	 * @param string $filename File to open
305
+	 * @param string $mode     Mode used to open the file
306
+	 *
307
+	 * @return resource
308
+	 *
309
+	 * @throws \RuntimeException if the file cannot be opened
310
+	 */
311
+	public static function tryFopen(string $filename, string $mode)
312
+	{
313
+		$ex = null;
314
+		\set_error_handler(static function (int $errno, string $errstr) use($filename, $mode, &$ex) : bool {
315
+			$ex = new \RuntimeException(\sprintf('Unable to open "%s" using mode "%s": %s', $filename, $mode, $errstr));
316
+			return \true;
317
+		});
318
+		try {
319
+			/** @var resource $handle */
320
+			$handle = \fopen($filename, $mode);
321
+		} catch (\Throwable $e) {
322
+			$ex = new \RuntimeException(\sprintf('Unable to open "%s" using mode "%s": %s', $filename, $mode, $e->getMessage()), 0, $e);
323
+		}
324
+		\restore_error_handler();
325
+		if ($ex) {
326
+			/** @var $ex \RuntimeException */
327
+			throw $ex;
328
+		}
329
+		return $handle;
330
+	}
331
+	/**
332
+	 * Safely gets the contents of a given stream.
333
+	 *
334
+	 * When stream_get_contents fails, PHP normally raises a warning. This
335
+	 * function adds an error handler that checks for errors and throws an
336
+	 * exception instead.
337
+	 *
338
+	 * @param resource $stream
339
+	 *
340
+	 * @throws \RuntimeException if the stream cannot be read
341
+	 */
342
+	public static function tryGetContents($stream) : string
343
+	{
344
+		$ex = null;
345
+		\set_error_handler(static function (int $errno, string $errstr) use(&$ex) : bool {
346
+			$ex = new \RuntimeException(\sprintf('Unable to read stream contents: %s', $errstr));
347
+			return \true;
348
+		});
349
+		try {
350
+			/** @var string|false $contents */
351
+			$contents = \stream_get_contents($stream);
352
+			if ($contents === \false) {
353
+				$ex = new \RuntimeException('Unable to read stream contents');
354
+			}
355
+		} catch (\Throwable $e) {
356
+			$ex = new \RuntimeException(\sprintf('Unable to read stream contents: %s', $e->getMessage()), 0, $e);
357
+		}
358
+		\restore_error_handler();
359
+		if ($ex) {
360
+			/** @var $ex \RuntimeException */
361
+			throw $ex;
362
+		}
363
+		return $contents;
364
+	}
365
+	/**
366
+	 * Returns a UriInterface for the given value.
367
+	 *
368
+	 * This function accepts a string or UriInterface and returns a
369
+	 * UriInterface for the given value. If the value is already a
370
+	 * UriInterface, it is returned as-is.
371
+	 *
372
+	 * @param string|UriInterface $uri
373
+	 *
374
+	 * @throws \InvalidArgumentException
375
+	 */
376
+	public static function uriFor($uri) : UriInterface
377
+	{
378
+		if ($uri instanceof UriInterface) {
379
+			return $uri;
380
+		}
381
+		if (\is_string($uri)) {
382
+			return new Uri($uri);
383
+		}
384
+		throw new \InvalidArgumentException('URI must be a string or UriInterface');
385
+	}
386 386
 }
Please login to merge, or discard this patch.
lib/Vendor/GuzzleHttp/Exception/GuzzleException.php 1 patch
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -3,6 +3,5 @@
 block discarded – undo
3 3
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Exception;
4 4
 
5 5
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Client\ClientExceptionInterface;
6
-interface GuzzleException extends ClientExceptionInterface
7
-{
6
+interface GuzzleException extends ClientExceptionInterface {
8 7
 }
Please login to merge, or discard this patch.
lib/Vendor/GuzzleHttp/Handler/CurlFactory.php 3 patches
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -16,8 +16,7 @@
 block discarded – undo
16 16
  *
17 17
  * @final
18 18
  */
19
-class CurlFactory implements CurlFactoryInterface
20
-{
19
+class CurlFactory implements CurlFactoryInterface {
21 20
     public const CURL_VERSION_STR = 'curl_version';
22 21
     /**
23 22
      * @deprecated
Please login to merge, or discard this patch.
Indentation   +541 added lines, -541 removed lines patch added patch discarded remove patch
@@ -19,545 +19,545 @@
 block discarded – undo
19 19
  */
20 20
 class CurlFactory implements CurlFactoryInterface
21 21
 {
22
-    public const CURL_VERSION_STR = 'curl_version';
23
-    /**
24
-     * @deprecated
25
-     */
26
-    public const LOW_CURL_VERSION_NUMBER = '7.21.2';
27
-    /**
28
-     * @var resource[]|\CurlHandle[]
29
-     */
30
-    private $handles = [];
31
-    /**
32
-     * @var int Total number of idle handles to keep in cache
33
-     */
34
-    private $maxHandles;
35
-    /**
36
-     * @param int $maxHandles Maximum number of idle handles.
37
-     */
38
-    public function __construct(int $maxHandles)
39
-    {
40
-        $this->maxHandles = $maxHandles;
41
-    }
42
-    public function create(RequestInterface $request, array $options) : EasyHandle
43
-    {
44
-        $protocolVersion = $request->getProtocolVersion();
45
-        if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
46
-            if (!self::supportsHttp2()) {
47
-                throw new ConnectException('HTTP/2 is supported by the cURL handler, however libcurl is built without HTTP/2 support.', $request);
48
-            }
49
-        } elseif ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
50
-            throw new ConnectException(\sprintf('HTTP/%s is not supported by the cURL handler.', $protocolVersion), $request);
51
-        }
52
-        if (isset($options['curl']['body_as_string'])) {
53
-            $options['_body_as_string'] = $options['curl']['body_as_string'];
54
-            unset($options['curl']['body_as_string']);
55
-        }
56
-        $easy = new EasyHandle();
57
-        $easy->request = $request;
58
-        $easy->options = $options;
59
-        $conf = $this->getDefaultConf($easy);
60
-        $this->applyMethod($easy, $conf);
61
-        $this->applyHandlerOptions($easy, $conf);
62
-        $this->applyHeaders($easy, $conf);
63
-        unset($conf['_headers']);
64
-        // Add handler options from the request configuration options
65
-        if (isset($options['curl'])) {
66
-            $conf = \array_replace($conf, $options['curl']);
67
-        }
68
-        $conf[\CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy);
69
-        $easy->handle = $this->handles ? \array_pop($this->handles) : \curl_init();
70
-        \curl_setopt_array($easy->handle, $conf);
71
-        return $easy;
72
-    }
73
-    private static function supportsHttp2() : bool
74
-    {
75
-        static $supportsHttp2 = null;
76
-        if (null === $supportsHttp2) {
77
-            $supportsHttp2 = self::supportsTls12() && \defined('CURL_VERSION_HTTP2') && \CURL_VERSION_HTTP2 & \curl_version()['features'];
78
-        }
79
-        return $supportsHttp2;
80
-    }
81
-    private static function supportsTls12() : bool
82
-    {
83
-        static $supportsTls12 = null;
84
-        if (null === $supportsTls12) {
85
-            $supportsTls12 = \CURL_SSLVERSION_TLSv1_2 & \curl_version()['features'];
86
-        }
87
-        return $supportsTls12;
88
-    }
89
-    private static function supportsTls13() : bool
90
-    {
91
-        static $supportsTls13 = null;
92
-        if (null === $supportsTls13) {
93
-            $supportsTls13 = \defined('CURL_SSLVERSION_TLSv1_3') && \CURL_SSLVERSION_TLSv1_3 & \curl_version()['features'];
94
-        }
95
-        return $supportsTls13;
96
-    }
97
-    public function release(EasyHandle $easy) : void
98
-    {
99
-        $resource = $easy->handle;
100
-        unset($easy->handle);
101
-        if (\count($this->handles) >= $this->maxHandles) {
102
-            \curl_close($resource);
103
-        } else {
104
-            // Remove all callback functions as they can hold onto references
105
-            // and are not cleaned up by curl_reset. Using curl_setopt_array
106
-            // does not work for some reason, so removing each one
107
-            // individually.
108
-            \curl_setopt($resource, \CURLOPT_HEADERFUNCTION, null);
109
-            \curl_setopt($resource, \CURLOPT_READFUNCTION, null);
110
-            \curl_setopt($resource, \CURLOPT_WRITEFUNCTION, null);
111
-            \curl_setopt($resource, \CURLOPT_PROGRESSFUNCTION, null);
112
-            \curl_reset($resource);
113
-            $this->handles[] = $resource;
114
-        }
115
-    }
116
-    /**
117
-     * Completes a cURL transaction, either returning a response promise or a
118
-     * rejected promise.
119
-     *
120
-     * @param callable(RequestInterface, array): PromiseInterface $handler
121
-     * @param CurlFactoryInterface                                $factory Dictates how the handle is released
122
-     */
123
-    public static function finish(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory) : PromiseInterface
124
-    {
125
-        if (isset($easy->options['on_stats'])) {
126
-            self::invokeStats($easy);
127
-        }
128
-        if (!$easy->response || $easy->errno) {
129
-            return self::finishError($handler, $easy, $factory);
130
-        }
131
-        // Return the response if it is present and there is no error.
132
-        $factory->release($easy);
133
-        // Rewind the body of the response if possible.
134
-        $body = $easy->response->getBody();
135
-        if ($body->isSeekable()) {
136
-            $body->rewind();
137
-        }
138
-        return new FulfilledPromise($easy->response);
139
-    }
140
-    private static function invokeStats(EasyHandle $easy) : void
141
-    {
142
-        $curlStats = \curl_getinfo($easy->handle);
143
-        $curlStats['appconnect_time'] = \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME);
144
-        $stats = new TransferStats($easy->request, $easy->response, $curlStats['total_time'], $easy->errno, $curlStats);
145
-        $easy->options['on_stats']($stats);
146
-    }
147
-    /**
148
-     * @param callable(RequestInterface, array): PromiseInterface $handler
149
-     */
150
-    private static function finishError(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory) : PromiseInterface
151
-    {
152
-        // Get error information and release the handle to the factory.
153
-        $ctx = ['errno' => $easy->errno, 'error' => \curl_error($easy->handle), 'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME)] + \curl_getinfo($easy->handle);
154
-        $ctx[self::CURL_VERSION_STR] = self::getCurlVersion();
155
-        $factory->release($easy);
156
-        // Retry when nothing is present or when curl failed to rewind.
157
-        if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) {
158
-            return self::retryFailedRewind($handler, $easy, $ctx);
159
-        }
160
-        return self::createRejection($easy, $ctx);
161
-    }
162
-    private static function getCurlVersion() : string
163
-    {
164
-        static $curlVersion = null;
165
-        if (null === $curlVersion) {
166
-            $curlVersion = \curl_version()['version'];
167
-        }
168
-        return $curlVersion;
169
-    }
170
-    private static function createRejection(EasyHandle $easy, array $ctx) : PromiseInterface
171
-    {
172
-        static $connectionErrors = [\CURLE_OPERATION_TIMEOUTED => \true, \CURLE_COULDNT_RESOLVE_HOST => \true, \CURLE_COULDNT_CONNECT => \true, \CURLE_SSL_CONNECT_ERROR => \true, \CURLE_GOT_NOTHING => \true];
173
-        if ($easy->createResponseException) {
174
-            return P\Create::rejectionFor(new RequestException('An error was encountered while creating the response', $easy->request, $easy->response, $easy->createResponseException, $ctx));
175
-        }
176
-        // If an exception was encountered during the onHeaders event, then
177
-        // return a rejected promise that wraps that exception.
178
-        if ($easy->onHeadersException) {
179
-            return P\Create::rejectionFor(new RequestException('An error was encountered during the on_headers event', $easy->request, $easy->response, $easy->onHeadersException, $ctx));
180
-        }
181
-        $uri = $easy->request->getUri();
182
-        $sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri);
183
-        $message = \sprintf('cURL error %s: %s (%s)', $ctx['errno'], $sanitizedError, 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html');
184
-        if ('' !== $sanitizedError) {
185
-            $redactedUriString = \OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($uri)->__toString();
186
-            if ($redactedUriString !== '' && \false === \strpos($sanitizedError, $redactedUriString)) {
187
-                $message .= \sprintf(' for %s', $redactedUriString);
188
-            }
189
-        }
190
-        // Create a connection exception if it was a specific error code.
191
-        $error = isset($connectionErrors[$easy->errno]) ? new ConnectException($message, $easy->request, null, $ctx) : new RequestException($message, $easy->request, $easy->response, null, $ctx);
192
-        return P\Create::rejectionFor($error);
193
-    }
194
-    private static function sanitizeCurlError(string $error, UriInterface $uri) : string
195
-    {
196
-        if ('' === $error) {
197
-            return $error;
198
-        }
199
-        $baseUri = $uri->withQuery('')->withFragment('');
200
-        $baseUriString = $baseUri->__toString();
201
-        if ('' === $baseUriString) {
202
-            return $error;
203
-        }
204
-        $redactedUriString = \OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString();
205
-        return \str_replace($baseUriString, $redactedUriString, $error);
206
-    }
207
-    /**
208
-     * @return array<int|string, mixed>
209
-     */
210
-    private function getDefaultConf(EasyHandle $easy) : array
211
-    {
212
-        $conf = ['_headers' => $easy->request->getHeaders(), \CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), \CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''), \CURLOPT_RETURNTRANSFER => \false, \CURLOPT_HEADER => \false, \CURLOPT_CONNECTTIMEOUT => 300];
213
-        if (\defined('CURLOPT_PROTOCOLS')) {
214
-            $conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS;
215
-        }
216
-        $version = $easy->request->getProtocolVersion();
217
-        if ('2' === $version || '2.0' === $version) {
218
-            $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0;
219
-        } elseif ('1.1' === $version) {
220
-            $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
221
-        } else {
222
-            $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0;
223
-        }
224
-        return $conf;
225
-    }
226
-    private function applyMethod(EasyHandle $easy, array &$conf) : void
227
-    {
228
-        $body = $easy->request->getBody();
229
-        $size = $body->getSize();
230
-        if ($size === null || $size > 0) {
231
-            $this->applyBody($easy->request, $easy->options, $conf);
232
-            return;
233
-        }
234
-        $method = $easy->request->getMethod();
235
-        if ($method === 'PUT' || $method === 'POST') {
236
-            // See https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2
237
-            if (!$easy->request->hasHeader('Content-Length')) {
238
-                $conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
239
-            }
240
-        } elseif ($method === 'HEAD') {
241
-            $conf[\CURLOPT_NOBODY] = \true;
242
-            unset($conf[\CURLOPT_WRITEFUNCTION], $conf[\CURLOPT_READFUNCTION], $conf[\CURLOPT_FILE], $conf[\CURLOPT_INFILE]);
243
-        }
244
-    }
245
-    private function applyBody(RequestInterface $request, array $options, array &$conf) : void
246
-    {
247
-        $size = $request->hasHeader('Content-Length') ? (int) $request->getHeaderLine('Content-Length') : null;
248
-        // Send the body as a string if the size is less than 1MB OR if the
249
-        // [curl][body_as_string] request value is set.
250
-        if ($size !== null && $size < 1000000 || !empty($options['_body_as_string'])) {
251
-            $conf[\CURLOPT_POSTFIELDS] = (string) $request->getBody();
252
-            // Don't duplicate the Content-Length header
253
-            $this->removeHeader('Content-Length', $conf);
254
-            $this->removeHeader('Transfer-Encoding', $conf);
255
-        } else {
256
-            $conf[\CURLOPT_UPLOAD] = \true;
257
-            if ($size !== null) {
258
-                $conf[\CURLOPT_INFILESIZE] = $size;
259
-                $this->removeHeader('Content-Length', $conf);
260
-            }
261
-            $body = $request->getBody();
262
-            if ($body->isSeekable()) {
263
-                $body->rewind();
264
-            }
265
-            $conf[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use($body) {
266
-                return $body->read($length);
267
-            };
268
-        }
269
-        // If the Expect header is not present, prevent curl from adding it
270
-        if (!$request->hasHeader('Expect')) {
271
-            $conf[\CURLOPT_HTTPHEADER][] = 'Expect:';
272
-        }
273
-        // cURL sometimes adds a content-type by default. Prevent this.
274
-        if (!$request->hasHeader('Content-Type')) {
275
-            $conf[\CURLOPT_HTTPHEADER][] = 'Content-Type:';
276
-        }
277
-    }
278
-    private function applyHeaders(EasyHandle $easy, array &$conf) : void
279
-    {
280
-        foreach ($conf['_headers'] as $name => $values) {
281
-            foreach ($values as $value) {
282
-                $value = (string) $value;
283
-                if ($value === '') {
284
-                    // cURL requires a special format for empty headers.
285
-                    // See https://github.com/guzzle/guzzle/issues/1882 for more details.
286
-                    $conf[\CURLOPT_HTTPHEADER][] = "{$name};";
287
-                } else {
288
-                    $conf[\CURLOPT_HTTPHEADER][] = "{$name}: {$value}";
289
-                }
290
-            }
291
-        }
292
-        // Remove the Accept header if one was not set
293
-        if (!$easy->request->hasHeader('Accept')) {
294
-            $conf[\CURLOPT_HTTPHEADER][] = 'Accept:';
295
-        }
296
-    }
297
-    /**
298
-     * Remove a header from the options array.
299
-     *
300
-     * @param string $name    Case-insensitive header to remove
301
-     * @param array  $options Array of options to modify
302
-     */
303
-    private function removeHeader(string $name, array &$options) : void
304
-    {
305
-        foreach (\array_keys($options['_headers']) as $key) {
306
-            if (!\strcasecmp($key, $name)) {
307
-                unset($options['_headers'][$key]);
308
-                return;
309
-            }
310
-        }
311
-    }
312
-    private function applyHandlerOptions(EasyHandle $easy, array &$conf) : void
313
-    {
314
-        $options = $easy->options;
315
-        if (isset($options['verify'])) {
316
-            if ($options['verify'] === \false) {
317
-                unset($conf[\CURLOPT_CAINFO]);
318
-                $conf[\CURLOPT_SSL_VERIFYHOST] = 0;
319
-                $conf[\CURLOPT_SSL_VERIFYPEER] = \false;
320
-            } else {
321
-                $conf[\CURLOPT_SSL_VERIFYHOST] = 2;
322
-                $conf[\CURLOPT_SSL_VERIFYPEER] = \true;
323
-                if (\is_string($options['verify'])) {
324
-                    // Throw an error if the file/folder/link path is not valid or doesn't exist.
325
-                    if (!\file_exists($options['verify'])) {
326
-                        throw new \InvalidArgumentException("SSL CA bundle not found: {$options['verify']}");
327
-                    }
328
-                    // If it's a directory or a link to a directory use CURLOPT_CAPATH.
329
-                    // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
330
-                    if (\is_dir($options['verify']) || \is_link($options['verify']) === \true && ($verifyLink = \readlink($options['verify'])) !== \false && \is_dir($verifyLink)) {
331
-                        $conf[\CURLOPT_CAPATH] = $options['verify'];
332
-                    } else {
333
-                        $conf[\CURLOPT_CAINFO] = $options['verify'];
334
-                    }
335
-                }
336
-            }
337
-        }
338
-        if (!isset($options['curl'][\CURLOPT_ENCODING]) && !empty($options['decode_content'])) {
339
-            $accept = $easy->request->getHeaderLine('Accept-Encoding');
340
-            if ($accept) {
341
-                $conf[\CURLOPT_ENCODING] = $accept;
342
-            } else {
343
-                // The empty string enables all available decoders and implicitly
344
-                // sets a matching 'Accept-Encoding' header.
345
-                $conf[\CURLOPT_ENCODING] = '';
346
-                // But as the user did not specify any encoding preference,
347
-                // let's leave it up to server by preventing curl from sending
348
-                // the header, which will be interpreted as 'Accept-Encoding: *'.
349
-                // https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding
350
-                $conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
351
-            }
352
-        }
353
-        if (!isset($options['sink'])) {
354
-            // Use a default temp stream if no sink was set.
355
-            $options['sink'] = \OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7\Utils::tryFopen('php://temp', 'w+');
356
-        }
357
-        $sink = $options['sink'];
358
-        if (!\is_string($sink)) {
359
-            $sink = \OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7\Utils::streamFor($sink);
360
-        } elseif (!\is_dir(\dirname($sink))) {
361
-            // Ensure that the directory exists before failing in curl.
362
-            throw new \RuntimeException(\sprintf('Directory %s does not exist for sink value of %s', \dirname($sink), $sink));
363
-        } else {
364
-            $sink = new LazyOpenStream($sink, 'w+');
365
-        }
366
-        $easy->sink = $sink;
367
-        $conf[\CURLOPT_WRITEFUNCTION] = static function ($ch, $write) use($sink) : int {
368
-            return $sink->write($write);
369
-        };
370
-        $timeoutRequiresNoSignal = \false;
371
-        if (isset($options['timeout'])) {
372
-            $timeoutRequiresNoSignal |= $options['timeout'] < 1;
373
-            $conf[\CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000;
374
-        }
375
-        // CURL default value is CURL_IPRESOLVE_WHATEVER
376
-        if (isset($options['force_ip_resolve'])) {
377
-            if ('v4' === $options['force_ip_resolve']) {
378
-                $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V4;
379
-            } elseif ('v6' === $options['force_ip_resolve']) {
380
-                $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V6;
381
-            }
382
-        }
383
-        if (isset($options['connect_timeout'])) {
384
-            $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1;
385
-            $conf[\CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000;
386
-        }
387
-        if ($timeoutRequiresNoSignal && \strtoupper(\substr(\PHP_OS, 0, 3)) !== 'WIN') {
388
-            $conf[\CURLOPT_NOSIGNAL] = \true;
389
-        }
390
-        if (isset($options['proxy'])) {
391
-            if (!\is_array($options['proxy'])) {
392
-                $conf[\CURLOPT_PROXY] = $options['proxy'];
393
-            } else {
394
-                $scheme = $easy->request->getUri()->getScheme();
395
-                if (isset($options['proxy'][$scheme])) {
396
-                    $host = $easy->request->getUri()->getHost();
397
-                    if (isset($options['proxy']['no']) && Utils::isHostInNoProxy($host, $options['proxy']['no'])) {
398
-                        unset($conf[\CURLOPT_PROXY]);
399
-                    } else {
400
-                        $conf[\CURLOPT_PROXY] = $options['proxy'][$scheme];
401
-                    }
402
-                }
403
-            }
404
-        }
405
-        if (isset($options['crypto_method'])) {
406
-            $protocolVersion = $easy->request->getProtocolVersion();
407
-            // If HTTP/2, upgrade TLS 1.0 and 1.1 to 1.2
408
-            if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
409
-                if (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
410
-                    $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
411
-                } elseif (\defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
412
-                    if (!self::supportsTls13()) {
413
-                        throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
414
-                    }
415
-                    $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
416
-                } else {
417
-                    throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
418
-                }
419
-            } elseif (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
420
-                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_0;
421
-            } elseif (\STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']) {
422
-                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_1;
423
-            } elseif (\STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
424
-                if (!self::supportsTls12()) {
425
-                    throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.2 not supported by your version of cURL');
426
-                }
427
-                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
428
-            } elseif (\defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
429
-                if (!self::supportsTls13()) {
430
-                    throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
431
-                }
432
-                $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
433
-            } else {
434
-                throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
435
-            }
436
-        }
437
-        if (isset($options['cert'])) {
438
-            $cert = $options['cert'];
439
-            if (\is_array($cert)) {
440
-                $conf[\CURLOPT_SSLCERTPASSWD] = $cert[1];
441
-                $cert = $cert[0];
442
-            }
443
-            if (!\file_exists($cert)) {
444
-                throw new \InvalidArgumentException("SSL certificate not found: {$cert}");
445
-            }
446
-            // OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files.
447
-            // see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
448
-            $ext = \pathinfo($cert, \PATHINFO_EXTENSION);
449
-            if (\preg_match('#^(der|p12)$#i', $ext)) {
450
-                $conf[\CURLOPT_SSLCERTTYPE] = \strtoupper($ext);
451
-            }
452
-            $conf[\CURLOPT_SSLCERT] = $cert;
453
-        }
454
-        if (isset($options['ssl_key'])) {
455
-            if (\is_array($options['ssl_key'])) {
456
-                if (\count($options['ssl_key']) === 2) {
457
-                    [$sslKey, $conf[\CURLOPT_SSLKEYPASSWD]] = $options['ssl_key'];
458
-                } else {
459
-                    [$sslKey] = $options['ssl_key'];
460
-                }
461
-            }
462
-            $sslKey = $sslKey ?? $options['ssl_key'];
463
-            if (!\file_exists($sslKey)) {
464
-                throw new \InvalidArgumentException("SSL private key not found: {$sslKey}");
465
-            }
466
-            $conf[\CURLOPT_SSLKEY] = $sslKey;
467
-        }
468
-        if (isset($options['progress'])) {
469
-            $progress = $options['progress'];
470
-            if (!\is_callable($progress)) {
471
-                throw new \InvalidArgumentException('progress client option must be callable');
472
-            }
473
-            $conf[\CURLOPT_NOPROGRESS] = \false;
474
-            $conf[\CURLOPT_PROGRESSFUNCTION] = static function ($resource, int $downloadSize, int $downloaded, int $uploadSize, int $uploaded) use($progress) {
475
-                $progress($downloadSize, $downloaded, $uploadSize, $uploaded);
476
-            };
477
-        }
478
-        if (!empty($options['debug'])) {
479
-            $conf[\CURLOPT_STDERR] = Utils::debugResource($options['debug']);
480
-            $conf[\CURLOPT_VERBOSE] = \true;
481
-        }
482
-    }
483
-    /**
484
-     * This function ensures that a response was set on a transaction. If one
485
-     * was not set, then the request is retried if possible. This error
486
-     * typically means you are sending a payload, curl encountered a
487
-     * "Connection died, retrying a fresh connect" error, tried to rewind the
488
-     * stream, and then encountered a "necessary data rewind wasn't possible"
489
-     * error, causing the request to be sent through curl_multi_info_read()
490
-     * without an error status.
491
-     *
492
-     * @param callable(RequestInterface, array): PromiseInterface $handler
493
-     */
494
-    private static function retryFailedRewind(callable $handler, EasyHandle $easy, array $ctx) : PromiseInterface
495
-    {
496
-        try {
497
-            // Only rewind if the body has been read from.
498
-            $body = $easy->request->getBody();
499
-            if ($body->tell() > 0) {
500
-                $body->rewind();
501
-            }
502
-        } catch (\RuntimeException $e) {
503
-            $ctx['error'] = 'The connection unexpectedly failed without ' . 'providing an error. The request would have been retried, ' . 'but attempting to rewind the request body failed. ' . 'Exception: ' . $e;
504
-            return self::createRejection($easy, $ctx);
505
-        }
506
-        // Retry no more than 3 times before giving up.
507
-        if (!isset($easy->options['_curl_retries'])) {
508
-            $easy->options['_curl_retries'] = 1;
509
-        } elseif ($easy->options['_curl_retries'] == 2) {
510
-            $ctx['error'] = 'The cURL request was retried 3 times ' . 'and did not succeed. The most likely reason for the failure ' . 'is that cURL was unable to rewind the body of the request ' . 'and subsequent retries resulted in the same error. Turn on ' . 'the debug option to see what went wrong. See ' . 'https://bugs.php.net/bug.php?id=47204 for more information.';
511
-            return self::createRejection($easy, $ctx);
512
-        } else {
513
-            ++$easy->options['_curl_retries'];
514
-        }
515
-        return $handler($easy->request, $easy->options);
516
-    }
517
-    private function createHeaderFn(EasyHandle $easy) : callable
518
-    {
519
-        if (isset($easy->options['on_headers'])) {
520
-            $onHeaders = $easy->options['on_headers'];
521
-            if (!\is_callable($onHeaders)) {
522
-                throw new \InvalidArgumentException('on_headers must be callable');
523
-            }
524
-        } else {
525
-            $onHeaders = null;
526
-        }
527
-        return static function ($ch, $h) use($onHeaders, $easy, &$startingResponse) {
528
-            $value = \trim($h);
529
-            if ($value === '') {
530
-                $startingResponse = \true;
531
-                try {
532
-                    $easy->createResponse();
533
-                } catch (\Exception $e) {
534
-                    $easy->createResponseException = $e;
535
-                    return -1;
536
-                }
537
-                if ($onHeaders !== null) {
538
-                    try {
539
-                        $onHeaders($easy->response);
540
-                    } catch (\Exception $e) {
541
-                        // Associate the exception with the handle and trigger
542
-                        // a curl header write error by returning 0.
543
-                        $easy->onHeadersException = $e;
544
-                        return -1;
545
-                    }
546
-                }
547
-            } elseif ($startingResponse) {
548
-                $startingResponse = \false;
549
-                $easy->headers = [$value];
550
-            } else {
551
-                $easy->headers[] = $value;
552
-            }
553
-            return \strlen($h);
554
-        };
555
-    }
556
-    public function __destruct()
557
-    {
558
-        foreach ($this->handles as $id => $handle) {
559
-            \curl_close($handle);
560
-            unset($this->handles[$id]);
561
-        }
562
-    }
22
+	public const CURL_VERSION_STR = 'curl_version';
23
+	/**
24
+	 * @deprecated
25
+	 */
26
+	public const LOW_CURL_VERSION_NUMBER = '7.21.2';
27
+	/**
28
+	 * @var resource[]|\CurlHandle[]
29
+	 */
30
+	private $handles = [];
31
+	/**
32
+	 * @var int Total number of idle handles to keep in cache
33
+	 */
34
+	private $maxHandles;
35
+	/**
36
+	 * @param int $maxHandles Maximum number of idle handles.
37
+	 */
38
+	public function __construct(int $maxHandles)
39
+	{
40
+		$this->maxHandles = $maxHandles;
41
+	}
42
+	public function create(RequestInterface $request, array $options) : EasyHandle
43
+	{
44
+		$protocolVersion = $request->getProtocolVersion();
45
+		if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
46
+			if (!self::supportsHttp2()) {
47
+				throw new ConnectException('HTTP/2 is supported by the cURL handler, however libcurl is built without HTTP/2 support.', $request);
48
+			}
49
+		} elseif ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) {
50
+			throw new ConnectException(\sprintf('HTTP/%s is not supported by the cURL handler.', $protocolVersion), $request);
51
+		}
52
+		if (isset($options['curl']['body_as_string'])) {
53
+			$options['_body_as_string'] = $options['curl']['body_as_string'];
54
+			unset($options['curl']['body_as_string']);
55
+		}
56
+		$easy = new EasyHandle();
57
+		$easy->request = $request;
58
+		$easy->options = $options;
59
+		$conf = $this->getDefaultConf($easy);
60
+		$this->applyMethod($easy, $conf);
61
+		$this->applyHandlerOptions($easy, $conf);
62
+		$this->applyHeaders($easy, $conf);
63
+		unset($conf['_headers']);
64
+		// Add handler options from the request configuration options
65
+		if (isset($options['curl'])) {
66
+			$conf = \array_replace($conf, $options['curl']);
67
+		}
68
+		$conf[\CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy);
69
+		$easy->handle = $this->handles ? \array_pop($this->handles) : \curl_init();
70
+		\curl_setopt_array($easy->handle, $conf);
71
+		return $easy;
72
+	}
73
+	private static function supportsHttp2() : bool
74
+	{
75
+		static $supportsHttp2 = null;
76
+		if (null === $supportsHttp2) {
77
+			$supportsHttp2 = self::supportsTls12() && \defined('CURL_VERSION_HTTP2') && \CURL_VERSION_HTTP2 & \curl_version()['features'];
78
+		}
79
+		return $supportsHttp2;
80
+	}
81
+	private static function supportsTls12() : bool
82
+	{
83
+		static $supportsTls12 = null;
84
+		if (null === $supportsTls12) {
85
+			$supportsTls12 = \CURL_SSLVERSION_TLSv1_2 & \curl_version()['features'];
86
+		}
87
+		return $supportsTls12;
88
+	}
89
+	private static function supportsTls13() : bool
90
+	{
91
+		static $supportsTls13 = null;
92
+		if (null === $supportsTls13) {
93
+			$supportsTls13 = \defined('CURL_SSLVERSION_TLSv1_3') && \CURL_SSLVERSION_TLSv1_3 & \curl_version()['features'];
94
+		}
95
+		return $supportsTls13;
96
+	}
97
+	public function release(EasyHandle $easy) : void
98
+	{
99
+		$resource = $easy->handle;
100
+		unset($easy->handle);
101
+		if (\count($this->handles) >= $this->maxHandles) {
102
+			\curl_close($resource);
103
+		} else {
104
+			// Remove all callback functions as they can hold onto references
105
+			// and are not cleaned up by curl_reset. Using curl_setopt_array
106
+			// does not work for some reason, so removing each one
107
+			// individually.
108
+			\curl_setopt($resource, \CURLOPT_HEADERFUNCTION, null);
109
+			\curl_setopt($resource, \CURLOPT_READFUNCTION, null);
110
+			\curl_setopt($resource, \CURLOPT_WRITEFUNCTION, null);
111
+			\curl_setopt($resource, \CURLOPT_PROGRESSFUNCTION, null);
112
+			\curl_reset($resource);
113
+			$this->handles[] = $resource;
114
+		}
115
+	}
116
+	/**
117
+	 * Completes a cURL transaction, either returning a response promise or a
118
+	 * rejected promise.
119
+	 *
120
+	 * @param callable(RequestInterface, array): PromiseInterface $handler
121
+	 * @param CurlFactoryInterface                                $factory Dictates how the handle is released
122
+	 */
123
+	public static function finish(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory) : PromiseInterface
124
+	{
125
+		if (isset($easy->options['on_stats'])) {
126
+			self::invokeStats($easy);
127
+		}
128
+		if (!$easy->response || $easy->errno) {
129
+			return self::finishError($handler, $easy, $factory);
130
+		}
131
+		// Return the response if it is present and there is no error.
132
+		$factory->release($easy);
133
+		// Rewind the body of the response if possible.
134
+		$body = $easy->response->getBody();
135
+		if ($body->isSeekable()) {
136
+			$body->rewind();
137
+		}
138
+		return new FulfilledPromise($easy->response);
139
+	}
140
+	private static function invokeStats(EasyHandle $easy) : void
141
+	{
142
+		$curlStats = \curl_getinfo($easy->handle);
143
+		$curlStats['appconnect_time'] = \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME);
144
+		$stats = new TransferStats($easy->request, $easy->response, $curlStats['total_time'], $easy->errno, $curlStats);
145
+		$easy->options['on_stats']($stats);
146
+	}
147
+	/**
148
+	 * @param callable(RequestInterface, array): PromiseInterface $handler
149
+	 */
150
+	private static function finishError(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory) : PromiseInterface
151
+	{
152
+		// Get error information and release the handle to the factory.
153
+		$ctx = ['errno' => $easy->errno, 'error' => \curl_error($easy->handle), 'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME)] + \curl_getinfo($easy->handle);
154
+		$ctx[self::CURL_VERSION_STR] = self::getCurlVersion();
155
+		$factory->release($easy);
156
+		// Retry when nothing is present or when curl failed to rewind.
157
+		if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) {
158
+			return self::retryFailedRewind($handler, $easy, $ctx);
159
+		}
160
+		return self::createRejection($easy, $ctx);
161
+	}
162
+	private static function getCurlVersion() : string
163
+	{
164
+		static $curlVersion = null;
165
+		if (null === $curlVersion) {
166
+			$curlVersion = \curl_version()['version'];
167
+		}
168
+		return $curlVersion;
169
+	}
170
+	private static function createRejection(EasyHandle $easy, array $ctx) : PromiseInterface
171
+	{
172
+		static $connectionErrors = [\CURLE_OPERATION_TIMEOUTED => \true, \CURLE_COULDNT_RESOLVE_HOST => \true, \CURLE_COULDNT_CONNECT => \true, \CURLE_SSL_CONNECT_ERROR => \true, \CURLE_GOT_NOTHING => \true];
173
+		if ($easy->createResponseException) {
174
+			return P\Create::rejectionFor(new RequestException('An error was encountered while creating the response', $easy->request, $easy->response, $easy->createResponseException, $ctx));
175
+		}
176
+		// If an exception was encountered during the onHeaders event, then
177
+		// return a rejected promise that wraps that exception.
178
+		if ($easy->onHeadersException) {
179
+			return P\Create::rejectionFor(new RequestException('An error was encountered during the on_headers event', $easy->request, $easy->response, $easy->onHeadersException, $ctx));
180
+		}
181
+		$uri = $easy->request->getUri();
182
+		$sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri);
183
+		$message = \sprintf('cURL error %s: %s (%s)', $ctx['errno'], $sanitizedError, 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html');
184
+		if ('' !== $sanitizedError) {
185
+			$redactedUriString = \OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($uri)->__toString();
186
+			if ($redactedUriString !== '' && \false === \strpos($sanitizedError, $redactedUriString)) {
187
+				$message .= \sprintf(' for %s', $redactedUriString);
188
+			}
189
+		}
190
+		// Create a connection exception if it was a specific error code.
191
+		$error = isset($connectionErrors[$easy->errno]) ? new ConnectException($message, $easy->request, null, $ctx) : new RequestException($message, $easy->request, $easy->response, null, $ctx);
192
+		return P\Create::rejectionFor($error);
193
+	}
194
+	private static function sanitizeCurlError(string $error, UriInterface $uri) : string
195
+	{
196
+		if ('' === $error) {
197
+			return $error;
198
+		}
199
+		$baseUri = $uri->withQuery('')->withFragment('');
200
+		$baseUriString = $baseUri->__toString();
201
+		if ('' === $baseUriString) {
202
+			return $error;
203
+		}
204
+		$redactedUriString = \OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString();
205
+		return \str_replace($baseUriString, $redactedUriString, $error);
206
+	}
207
+	/**
208
+	 * @return array<int|string, mixed>
209
+	 */
210
+	private function getDefaultConf(EasyHandle $easy) : array
211
+	{
212
+		$conf = ['_headers' => $easy->request->getHeaders(), \CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), \CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''), \CURLOPT_RETURNTRANSFER => \false, \CURLOPT_HEADER => \false, \CURLOPT_CONNECTTIMEOUT => 300];
213
+		if (\defined('CURLOPT_PROTOCOLS')) {
214
+			$conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS;
215
+		}
216
+		$version = $easy->request->getProtocolVersion();
217
+		if ('2' === $version || '2.0' === $version) {
218
+			$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0;
219
+		} elseif ('1.1' === $version) {
220
+			$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1;
221
+		} else {
222
+			$conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0;
223
+		}
224
+		return $conf;
225
+	}
226
+	private function applyMethod(EasyHandle $easy, array &$conf) : void
227
+	{
228
+		$body = $easy->request->getBody();
229
+		$size = $body->getSize();
230
+		if ($size === null || $size > 0) {
231
+			$this->applyBody($easy->request, $easy->options, $conf);
232
+			return;
233
+		}
234
+		$method = $easy->request->getMethod();
235
+		if ($method === 'PUT' || $method === 'POST') {
236
+			// See https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2
237
+			if (!$easy->request->hasHeader('Content-Length')) {
238
+				$conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
239
+			}
240
+		} elseif ($method === 'HEAD') {
241
+			$conf[\CURLOPT_NOBODY] = \true;
242
+			unset($conf[\CURLOPT_WRITEFUNCTION], $conf[\CURLOPT_READFUNCTION], $conf[\CURLOPT_FILE], $conf[\CURLOPT_INFILE]);
243
+		}
244
+	}
245
+	private function applyBody(RequestInterface $request, array $options, array &$conf) : void
246
+	{
247
+		$size = $request->hasHeader('Content-Length') ? (int) $request->getHeaderLine('Content-Length') : null;
248
+		// Send the body as a string if the size is less than 1MB OR if the
249
+		// [curl][body_as_string] request value is set.
250
+		if ($size !== null && $size < 1000000 || !empty($options['_body_as_string'])) {
251
+			$conf[\CURLOPT_POSTFIELDS] = (string) $request->getBody();
252
+			// Don't duplicate the Content-Length header
253
+			$this->removeHeader('Content-Length', $conf);
254
+			$this->removeHeader('Transfer-Encoding', $conf);
255
+		} else {
256
+			$conf[\CURLOPT_UPLOAD] = \true;
257
+			if ($size !== null) {
258
+				$conf[\CURLOPT_INFILESIZE] = $size;
259
+				$this->removeHeader('Content-Length', $conf);
260
+			}
261
+			$body = $request->getBody();
262
+			if ($body->isSeekable()) {
263
+				$body->rewind();
264
+			}
265
+			$conf[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use($body) {
266
+				return $body->read($length);
267
+			};
268
+		}
269
+		// If the Expect header is not present, prevent curl from adding it
270
+		if (!$request->hasHeader('Expect')) {
271
+			$conf[\CURLOPT_HTTPHEADER][] = 'Expect:';
272
+		}
273
+		// cURL sometimes adds a content-type by default. Prevent this.
274
+		if (!$request->hasHeader('Content-Type')) {
275
+			$conf[\CURLOPT_HTTPHEADER][] = 'Content-Type:';
276
+		}
277
+	}
278
+	private function applyHeaders(EasyHandle $easy, array &$conf) : void
279
+	{
280
+		foreach ($conf['_headers'] as $name => $values) {
281
+			foreach ($values as $value) {
282
+				$value = (string) $value;
283
+				if ($value === '') {
284
+					// cURL requires a special format for empty headers.
285
+					// See https://github.com/guzzle/guzzle/issues/1882 for more details.
286
+					$conf[\CURLOPT_HTTPHEADER][] = "{$name};";
287
+				} else {
288
+					$conf[\CURLOPT_HTTPHEADER][] = "{$name}: {$value}";
289
+				}
290
+			}
291
+		}
292
+		// Remove the Accept header if one was not set
293
+		if (!$easy->request->hasHeader('Accept')) {
294
+			$conf[\CURLOPT_HTTPHEADER][] = 'Accept:';
295
+		}
296
+	}
297
+	/**
298
+	 * Remove a header from the options array.
299
+	 *
300
+	 * @param string $name    Case-insensitive header to remove
301
+	 * @param array  $options Array of options to modify
302
+	 */
303
+	private function removeHeader(string $name, array &$options) : void
304
+	{
305
+		foreach (\array_keys($options['_headers']) as $key) {
306
+			if (!\strcasecmp($key, $name)) {
307
+				unset($options['_headers'][$key]);
308
+				return;
309
+			}
310
+		}
311
+	}
312
+	private function applyHandlerOptions(EasyHandle $easy, array &$conf) : void
313
+	{
314
+		$options = $easy->options;
315
+		if (isset($options['verify'])) {
316
+			if ($options['verify'] === \false) {
317
+				unset($conf[\CURLOPT_CAINFO]);
318
+				$conf[\CURLOPT_SSL_VERIFYHOST] = 0;
319
+				$conf[\CURLOPT_SSL_VERIFYPEER] = \false;
320
+			} else {
321
+				$conf[\CURLOPT_SSL_VERIFYHOST] = 2;
322
+				$conf[\CURLOPT_SSL_VERIFYPEER] = \true;
323
+				if (\is_string($options['verify'])) {
324
+					// Throw an error if the file/folder/link path is not valid or doesn't exist.
325
+					if (!\file_exists($options['verify'])) {
326
+						throw new \InvalidArgumentException("SSL CA bundle not found: {$options['verify']}");
327
+					}
328
+					// If it's a directory or a link to a directory use CURLOPT_CAPATH.
329
+					// If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO.
330
+					if (\is_dir($options['verify']) || \is_link($options['verify']) === \true && ($verifyLink = \readlink($options['verify'])) !== \false && \is_dir($verifyLink)) {
331
+						$conf[\CURLOPT_CAPATH] = $options['verify'];
332
+					} else {
333
+						$conf[\CURLOPT_CAINFO] = $options['verify'];
334
+					}
335
+				}
336
+			}
337
+		}
338
+		if (!isset($options['curl'][\CURLOPT_ENCODING]) && !empty($options['decode_content'])) {
339
+			$accept = $easy->request->getHeaderLine('Accept-Encoding');
340
+			if ($accept) {
341
+				$conf[\CURLOPT_ENCODING] = $accept;
342
+			} else {
343
+				// The empty string enables all available decoders and implicitly
344
+				// sets a matching 'Accept-Encoding' header.
345
+				$conf[\CURLOPT_ENCODING] = '';
346
+				// But as the user did not specify any encoding preference,
347
+				// let's leave it up to server by preventing curl from sending
348
+				// the header, which will be interpreted as 'Accept-Encoding: *'.
349
+				// https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding
350
+				$conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:';
351
+			}
352
+		}
353
+		if (!isset($options['sink'])) {
354
+			// Use a default temp stream if no sink was set.
355
+			$options['sink'] = \OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7\Utils::tryFopen('php://temp', 'w+');
356
+		}
357
+		$sink = $options['sink'];
358
+		if (!\is_string($sink)) {
359
+			$sink = \OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Psr7\Utils::streamFor($sink);
360
+		} elseif (!\is_dir(\dirname($sink))) {
361
+			// Ensure that the directory exists before failing in curl.
362
+			throw new \RuntimeException(\sprintf('Directory %s does not exist for sink value of %s', \dirname($sink), $sink));
363
+		} else {
364
+			$sink = new LazyOpenStream($sink, 'w+');
365
+		}
366
+		$easy->sink = $sink;
367
+		$conf[\CURLOPT_WRITEFUNCTION] = static function ($ch, $write) use($sink) : int {
368
+			return $sink->write($write);
369
+		};
370
+		$timeoutRequiresNoSignal = \false;
371
+		if (isset($options['timeout'])) {
372
+			$timeoutRequiresNoSignal |= $options['timeout'] < 1;
373
+			$conf[\CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000;
374
+		}
375
+		// CURL default value is CURL_IPRESOLVE_WHATEVER
376
+		if (isset($options['force_ip_resolve'])) {
377
+			if ('v4' === $options['force_ip_resolve']) {
378
+				$conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V4;
379
+			} elseif ('v6' === $options['force_ip_resolve']) {
380
+				$conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V6;
381
+			}
382
+		}
383
+		if (isset($options['connect_timeout'])) {
384
+			$timeoutRequiresNoSignal |= $options['connect_timeout'] < 1;
385
+			$conf[\CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000;
386
+		}
387
+		if ($timeoutRequiresNoSignal && \strtoupper(\substr(\PHP_OS, 0, 3)) !== 'WIN') {
388
+			$conf[\CURLOPT_NOSIGNAL] = \true;
389
+		}
390
+		if (isset($options['proxy'])) {
391
+			if (!\is_array($options['proxy'])) {
392
+				$conf[\CURLOPT_PROXY] = $options['proxy'];
393
+			} else {
394
+				$scheme = $easy->request->getUri()->getScheme();
395
+				if (isset($options['proxy'][$scheme])) {
396
+					$host = $easy->request->getUri()->getHost();
397
+					if (isset($options['proxy']['no']) && Utils::isHostInNoProxy($host, $options['proxy']['no'])) {
398
+						unset($conf[\CURLOPT_PROXY]);
399
+					} else {
400
+						$conf[\CURLOPT_PROXY] = $options['proxy'][$scheme];
401
+					}
402
+				}
403
+			}
404
+		}
405
+		if (isset($options['crypto_method'])) {
406
+			$protocolVersion = $easy->request->getProtocolVersion();
407
+			// If HTTP/2, upgrade TLS 1.0 and 1.1 to 1.2
408
+			if ('2' === $protocolVersion || '2.0' === $protocolVersion) {
409
+				if (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
410
+					$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
411
+				} elseif (\defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
412
+					if (!self::supportsTls13()) {
413
+						throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
414
+					}
415
+					$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
416
+				} else {
417
+					throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
418
+				}
419
+			} elseif (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) {
420
+				$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_0;
421
+			} elseif (\STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']) {
422
+				$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_1;
423
+			} elseif (\STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) {
424
+				if (!self::supportsTls12()) {
425
+					throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.2 not supported by your version of cURL');
426
+				}
427
+				$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2;
428
+			} elseif (\defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) {
429
+				if (!self::supportsTls13()) {
430
+					throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL');
431
+				}
432
+				$conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3;
433
+			} else {
434
+				throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided');
435
+			}
436
+		}
437
+		if (isset($options['cert'])) {
438
+			$cert = $options['cert'];
439
+			if (\is_array($cert)) {
440
+				$conf[\CURLOPT_SSLCERTPASSWD] = $cert[1];
441
+				$cert = $cert[0];
442
+			}
443
+			if (!\file_exists($cert)) {
444
+				throw new \InvalidArgumentException("SSL certificate not found: {$cert}");
445
+			}
446
+			// OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files.
447
+			// see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html
448
+			$ext = \pathinfo($cert, \PATHINFO_EXTENSION);
449
+			if (\preg_match('#^(der|p12)$#i', $ext)) {
450
+				$conf[\CURLOPT_SSLCERTTYPE] = \strtoupper($ext);
451
+			}
452
+			$conf[\CURLOPT_SSLCERT] = $cert;
453
+		}
454
+		if (isset($options['ssl_key'])) {
455
+			if (\is_array($options['ssl_key'])) {
456
+				if (\count($options['ssl_key']) === 2) {
457
+					[$sslKey, $conf[\CURLOPT_SSLKEYPASSWD]] = $options['ssl_key'];
458
+				} else {
459
+					[$sslKey] = $options['ssl_key'];
460
+				}
461
+			}
462
+			$sslKey = $sslKey ?? $options['ssl_key'];
463
+			if (!\file_exists($sslKey)) {
464
+				throw new \InvalidArgumentException("SSL private key not found: {$sslKey}");
465
+			}
466
+			$conf[\CURLOPT_SSLKEY] = $sslKey;
467
+		}
468
+		if (isset($options['progress'])) {
469
+			$progress = $options['progress'];
470
+			if (!\is_callable($progress)) {
471
+				throw new \InvalidArgumentException('progress client option must be callable');
472
+			}
473
+			$conf[\CURLOPT_NOPROGRESS] = \false;
474
+			$conf[\CURLOPT_PROGRESSFUNCTION] = static function ($resource, int $downloadSize, int $downloaded, int $uploadSize, int $uploaded) use($progress) {
475
+				$progress($downloadSize, $downloaded, $uploadSize, $uploaded);
476
+			};
477
+		}
478
+		if (!empty($options['debug'])) {
479
+			$conf[\CURLOPT_STDERR] = Utils::debugResource($options['debug']);
480
+			$conf[\CURLOPT_VERBOSE] = \true;
481
+		}
482
+	}
483
+	/**
484
+	 * This function ensures that a response was set on a transaction. If one
485
+	 * was not set, then the request is retried if possible. This error
486
+	 * typically means you are sending a payload, curl encountered a
487
+	 * "Connection died, retrying a fresh connect" error, tried to rewind the
488
+	 * stream, and then encountered a "necessary data rewind wasn't possible"
489
+	 * error, causing the request to be sent through curl_multi_info_read()
490
+	 * without an error status.
491
+	 *
492
+	 * @param callable(RequestInterface, array): PromiseInterface $handler
493
+	 */
494
+	private static function retryFailedRewind(callable $handler, EasyHandle $easy, array $ctx) : PromiseInterface
495
+	{
496
+		try {
497
+			// Only rewind if the body has been read from.
498
+			$body = $easy->request->getBody();
499
+			if ($body->tell() > 0) {
500
+				$body->rewind();
501
+			}
502
+		} catch (\RuntimeException $e) {
503
+			$ctx['error'] = 'The connection unexpectedly failed without ' . 'providing an error. The request would have been retried, ' . 'but attempting to rewind the request body failed. ' . 'Exception: ' . $e;
504
+			return self::createRejection($easy, $ctx);
505
+		}
506
+		// Retry no more than 3 times before giving up.
507
+		if (!isset($easy->options['_curl_retries'])) {
508
+			$easy->options['_curl_retries'] = 1;
509
+		} elseif ($easy->options['_curl_retries'] == 2) {
510
+			$ctx['error'] = 'The cURL request was retried 3 times ' . 'and did not succeed. The most likely reason for the failure ' . 'is that cURL was unable to rewind the body of the request ' . 'and subsequent retries resulted in the same error. Turn on ' . 'the debug option to see what went wrong. See ' . 'https://bugs.php.net/bug.php?id=47204 for more information.';
511
+			return self::createRejection($easy, $ctx);
512
+		} else {
513
+			++$easy->options['_curl_retries'];
514
+		}
515
+		return $handler($easy->request, $easy->options);
516
+	}
517
+	private function createHeaderFn(EasyHandle $easy) : callable
518
+	{
519
+		if (isset($easy->options['on_headers'])) {
520
+			$onHeaders = $easy->options['on_headers'];
521
+			if (!\is_callable($onHeaders)) {
522
+				throw new \InvalidArgumentException('on_headers must be callable');
523
+			}
524
+		} else {
525
+			$onHeaders = null;
526
+		}
527
+		return static function ($ch, $h) use($onHeaders, $easy, &$startingResponse) {
528
+			$value = \trim($h);
529
+			if ($value === '') {
530
+				$startingResponse = \true;
531
+				try {
532
+					$easy->createResponse();
533
+				} catch (\Exception $e) {
534
+					$easy->createResponseException = $e;
535
+					return -1;
536
+				}
537
+				if ($onHeaders !== null) {
538
+					try {
539
+						$onHeaders($easy->response);
540
+					} catch (\Exception $e) {
541
+						// Associate the exception with the handle and trigger
542
+						// a curl header write error by returning 0.
543
+						$easy->onHeadersException = $e;
544
+						return -1;
545
+					}
546
+				}
547
+			} elseif ($startingResponse) {
548
+				$startingResponse = \false;
549
+				$easy->headers = [$value];
550
+			} else {
551
+				$easy->headers[] = $value;
552
+			}
553
+			return \strlen($h);
554
+		};
555
+	}
556
+	public function __destruct()
557
+	{
558
+		foreach ($this->handles as $id => $handle) {
559
+			\curl_close($handle);
560
+			unset($this->handles[$id]);
561
+		}
562
+	}
563 563
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
      */
210 210
     private function getDefaultConf(EasyHandle $easy) : array
211 211
     {
212
-        $conf = ['_headers' => $easy->request->getHeaders(), \CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), \CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''), \CURLOPT_RETURNTRANSFER => \false, \CURLOPT_HEADER => \false, \CURLOPT_CONNECTTIMEOUT => 300];
212
+        $conf = ['_headers' => $easy->request->getHeaders(), \CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), \CURLOPT_URL => (string)$easy->request->getUri()->withFragment(''), \CURLOPT_RETURNTRANSFER => \false, \CURLOPT_HEADER => \false, \CURLOPT_CONNECTTIMEOUT => 300];
213 213
         if (\defined('CURLOPT_PROTOCOLS')) {
214 214
             $conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS;
215 215
         }
@@ -244,11 +244,11 @@  discard block
 block discarded – undo
244 244
     }
245 245
     private function applyBody(RequestInterface $request, array $options, array &$conf) : void
246 246
     {
247
-        $size = $request->hasHeader('Content-Length') ? (int) $request->getHeaderLine('Content-Length') : null;
247
+        $size = $request->hasHeader('Content-Length') ? (int)$request->getHeaderLine('Content-Length') : null;
248 248
         // Send the body as a string if the size is less than 1MB OR if the
249 249
         // [curl][body_as_string] request value is set.
250 250
         if ($size !== null && $size < 1000000 || !empty($options['_body_as_string'])) {
251
-            $conf[\CURLOPT_POSTFIELDS] = (string) $request->getBody();
251
+            $conf[\CURLOPT_POSTFIELDS] = (string)$request->getBody();
252 252
             // Don't duplicate the Content-Length header
253 253
             $this->removeHeader('Content-Length', $conf);
254 254
             $this->removeHeader('Transfer-Encoding', $conf);
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
             if ($body->isSeekable()) {
263 263
                 $body->rewind();
264 264
             }
265
-            $conf[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use($body) {
265
+            $conf[\CURLOPT_READFUNCTION] = static function($ch, $fd, $length) use($body) {
266 266
                 return $body->read($length);
267 267
             };
268 268
         }
@@ -279,7 +279,7 @@  discard block
 block discarded – undo
279 279
     {
280 280
         foreach ($conf['_headers'] as $name => $values) {
281 281
             foreach ($values as $value) {
282
-                $value = (string) $value;
282
+                $value = (string)$value;
283 283
                 if ($value === '') {
284 284
                     // cURL requires a special format for empty headers.
285 285
                     // See https://github.com/guzzle/guzzle/issues/1882 for more details.
@@ -364,7 +364,7 @@  discard block
 block discarded – undo
364 364
             $sink = new LazyOpenStream($sink, 'w+');
365 365
         }
366 366
         $easy->sink = $sink;
367
-        $conf[\CURLOPT_WRITEFUNCTION] = static function ($ch, $write) use($sink) : int {
367
+        $conf[\CURLOPT_WRITEFUNCTION] = static function($ch, $write) use($sink) : int {
368 368
             return $sink->write($write);
369 369
         };
370 370
         $timeoutRequiresNoSignal = \false;
@@ -471,7 +471,7 @@  discard block
 block discarded – undo
471 471
                 throw new \InvalidArgumentException('progress client option must be callable');
472 472
             }
473 473
             $conf[\CURLOPT_NOPROGRESS] = \false;
474
-            $conf[\CURLOPT_PROGRESSFUNCTION] = static function ($resource, int $downloadSize, int $downloaded, int $uploadSize, int $uploaded) use($progress) {
474
+            $conf[\CURLOPT_PROGRESSFUNCTION] = static function($resource, int $downloadSize, int $downloaded, int $uploadSize, int $uploaded) use($progress) {
475 475
                 $progress($downloadSize, $downloaded, $uploadSize, $uploaded);
476 476
             };
477 477
         }
@@ -500,14 +500,14 @@  discard block
 block discarded – undo
500 500
                 $body->rewind();
501 501
             }
502 502
         } catch (\RuntimeException $e) {
503
-            $ctx['error'] = 'The connection unexpectedly failed without ' . 'providing an error. The request would have been retried, ' . 'but attempting to rewind the request body failed. ' . 'Exception: ' . $e;
503
+            $ctx['error'] = 'The connection unexpectedly failed without '.'providing an error. The request would have been retried, '.'but attempting to rewind the request body failed. '.'Exception: '.$e;
504 504
             return self::createRejection($easy, $ctx);
505 505
         }
506 506
         // Retry no more than 3 times before giving up.
507 507
         if (!isset($easy->options['_curl_retries'])) {
508 508
             $easy->options['_curl_retries'] = 1;
509 509
         } elseif ($easy->options['_curl_retries'] == 2) {
510
-            $ctx['error'] = 'The cURL request was retried 3 times ' . 'and did not succeed. The most likely reason for the failure ' . 'is that cURL was unable to rewind the body of the request ' . 'and subsequent retries resulted in the same error. Turn on ' . 'the debug option to see what went wrong. See ' . 'https://bugs.php.net/bug.php?id=47204 for more information.';
510
+            $ctx['error'] = 'The cURL request was retried 3 times '.'and did not succeed. The most likely reason for the failure '.'is that cURL was unable to rewind the body of the request '.'and subsequent retries resulted in the same error. Turn on '.'the debug option to see what went wrong. See '.'https://bugs.php.net/bug.php?id=47204 for more information.';
511 511
             return self::createRejection($easy, $ctx);
512 512
         } else {
513 513
             ++$easy->options['_curl_retries'];
@@ -524,7 +524,7 @@  discard block
 block discarded – undo
524 524
         } else {
525 525
             $onHeaders = null;
526 526
         }
527
-        return static function ($ch, $h) use($onHeaders, $easy, &$startingResponse) {
527
+        return static function($ch, $h) use($onHeaders, $easy, &$startingResponse) {
528 528
             $value = \trim($h);
529 529
             if ($value === '') {
530 530
                 $startingResponse = \true;
Please login to merge, or discard this patch.
lib/Vendor/GuzzleHttp/Handler/CurlFactoryInterface.php 2 patches
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -5,19 +5,19 @@
 block discarded – undo
5 5
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\RequestInterface;
6 6
 interface CurlFactoryInterface
7 7
 {
8
-    /**
9
-     * Creates a cURL handle resource.
10
-     *
11
-     * @param RequestInterface $request Request
12
-     * @param array            $options Transfer options
13
-     *
14
-     * @throws \RuntimeException when an option cannot be applied
15
-     */
16
-    public function create(RequestInterface $request, array $options) : EasyHandle;
17
-    /**
18
-     * Release an easy handle, allowing it to be reused or closed.
19
-     *
20
-     * This function must call unset on the easy handle's "handle" property.
21
-     */
22
-    public function release(EasyHandle $easy) : void;
8
+	/**
9
+	 * Creates a cURL handle resource.
10
+	 *
11
+	 * @param RequestInterface $request Request
12
+	 * @param array            $options Transfer options
13
+	 *
14
+	 * @throws \RuntimeException when an option cannot be applied
15
+	 */
16
+	public function create(RequestInterface $request, array $options) : EasyHandle;
17
+	/**
18
+	 * Release an easy handle, allowing it to be reused or closed.
19
+	 *
20
+	 * This function must call unset on the easy handle's "handle" property.
21
+	 */
22
+	public function release(EasyHandle $easy) : void;
23 23
 }
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -3,8 +3,7 @@
 block discarded – undo
3 3
 namespace OCA\FullTextSearch_Elasticsearch\Vendor\GuzzleHttp\Handler;
4 4
 
5 5
 use OCA\FullTextSearch_Elasticsearch\Vendor\Psr\Http\Message\RequestInterface;
6
-interface CurlFactoryInterface
7
-{
6
+interface CurlFactoryInterface {
8 7
     /**
9 8
      * Creates a cURL handle resource.
10 9
      *
Please login to merge, or discard this patch.