Passed
Pull Request — master (#34)
by Anatoly
04:38
created
src/ServerRequestFactory.php 1 patch
Indentation   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -17,58 +17,58 @@
 block discarded – undo
17 17
 
18 18
 class ServerRequestFactory implements ServerRequestFactoryInterface
19 19
 {
20
-    /**
21
-     * @param array<array-key, mixed>|null $serverParams
22
-     * @param array<array-key, mixed>|null $queryParams
23
-     * @param array<array-key, mixed>|null $cookieParams
24
-     * @param array<array-key, mixed>|null $uploadedFiles
25
-     * @param array<array-key, mixed>|null $parsedBody
26
-     *
27
-     * @link http://php.net/manual/en/language.variables.superglobals.php
28
-     * @link https://www.php-fig.org/psr/psr-15/meta/
29
-     */
30
-    public static function fromGlobals(
31
-        ?array $serverParams = null,
32
-        ?array $queryParams = null,
33
-        ?array $cookieParams = null,
34
-        ?array $uploadedFiles = null,
35
-        ?array $parsedBody = null
36
-    ): ServerRequestInterface {
37
-        $serverParams ??= $_SERVER;
38
-        $queryParams ??= $_GET;
39
-        $cookieParams ??= $_COOKIE;
40
-        $uploadedFiles ??= $_FILES;
41
-        $parsedBody ??= $_POST;
20
+	/**
21
+	 * @param array<array-key, mixed>|null $serverParams
22
+	 * @param array<array-key, mixed>|null $queryParams
23
+	 * @param array<array-key, mixed>|null $cookieParams
24
+	 * @param array<array-key, mixed>|null $uploadedFiles
25
+	 * @param array<array-key, mixed>|null $parsedBody
26
+	 *
27
+	 * @link http://php.net/manual/en/language.variables.superglobals.php
28
+	 * @link https://www.php-fig.org/psr/psr-15/meta/
29
+	 */
30
+	public static function fromGlobals(
31
+		?array $serverParams = null,
32
+		?array $queryParams = null,
33
+		?array $cookieParams = null,
34
+		?array $uploadedFiles = null,
35
+		?array $parsedBody = null
36
+	): ServerRequestInterface {
37
+		$serverParams ??= $_SERVER;
38
+		$queryParams ??= $_GET;
39
+		$cookieParams ??= $_COOKIE;
40
+		$uploadedFiles ??= $_FILES;
41
+		$parsedBody ??= $_POST;
42 42
 
43
-        return new ServerRequest(
44
-            server_request_protocol_version($serverParams),
45
-            server_request_method($serverParams),
46
-            server_request_uri($serverParams),
47
-            server_request_headers($serverParams),
48
-            new PhpInputStream(),
49
-            $serverParams,
50
-            $queryParams,
51
-            $cookieParams,
52
-            server_request_files($uploadedFiles),
53
-            $parsedBody
54
-        );
55
-    }
43
+		return new ServerRequest(
44
+			server_request_protocol_version($serverParams),
45
+			server_request_method($serverParams),
46
+			server_request_uri($serverParams),
47
+			server_request_headers($serverParams),
48
+			new PhpInputStream(),
49
+			$serverParams,
50
+			$queryParams,
51
+			$cookieParams,
52
+			server_request_files($uploadedFiles),
53
+			$parsedBody
54
+		);
55
+	}
56 56
 
57
-    /**
58
-     * {@inheritDoc}
59
-     *
60
-     * @param mixed $uri
61
-     * @param array<array-key, mixed> $serverParams
62
-     */
63
-    public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
64
-    {
65
-        return new ServerRequest(
66
-            server_request_protocol_version($serverParams),
67
-            $method,
68
-            $uri,
69
-            server_request_headers($serverParams),
70
-            null, // body
71
-            $serverParams
72
-        );
73
-    }
57
+	/**
58
+	 * {@inheritDoc}
59
+	 *
60
+	 * @param mixed $uri
61
+	 * @param array<array-key, mixed> $serverParams
62
+	 */
63
+	public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface
64
+	{
65
+		return new ServerRequest(
66
+			server_request_protocol_version($serverParams),
67
+			$method,
68
+			$uri,
69
+			server_request_headers($serverParams),
70
+			null, // body
71
+			$serverParams
72
+		);
73
+	}
74 74
 }
Please login to merge, or discard this patch.
src/Message.php 1 patch
Indentation   +291 added lines, -291 removed lines patch added patch discarded remove patch
@@ -26,295 +26,295 @@
 block discarded – undo
26 26
 
27 27
 abstract class Message implements MessageInterface
28 28
 {
29
-    public const ALLOWED_HTTP_VERSIONS = ['1.0', '1.1', '2.0', '2'];
30
-
31
-    public const DEFAULT_HTTP_VERSION = self::ALLOWED_HTTP_VERSIONS[1];
32
-
33
-    private string $protocolVersion = self::DEFAULT_HTTP_VERSION;
34
-
35
-    /**
36
-     * @var array<string, list<string>>
37
-     */
38
-    private array $headers = [];
39
-
40
-    /**
41
-     * @var array<string, string>
42
-     */
43
-    private array $headerNames = [];
44
-
45
-    private ?StreamInterface $body = null;
46
-
47
-    /**
48
-     * @inheritDoc
49
-     */
50
-    public function getProtocolVersion(): string
51
-    {
52
-        return $this->protocolVersion;
53
-    }
54
-
55
-    /**
56
-     * @inheritDoc
57
-     *
58
-     * @throws InvalidArgumentException
59
-     */
60
-    public function withProtocolVersion($version): MessageInterface
61
-    {
62
-        $clone = clone $this;
63
-        $clone->setProtocolVersion($version);
64
-
65
-        return $clone;
66
-    }
67
-
68
-    /**
69
-     * @inheritDoc
70
-     */
71
-    public function getHeaders(): array
72
-    {
73
-        return $this->headers;
74
-    }
75
-
76
-    /**
77
-     * @inheritDoc
78
-     */
79
-    public function hasHeader($name): bool
80
-    {
81
-        $key = strtolower($name);
82
-
83
-        return isset($this->headerNames[$key]);
84
-    }
85
-
86
-    /**
87
-     * @inheritDoc
88
-     */
89
-    public function getHeader($name): array
90
-    {
91
-        $key = strtolower($name);
92
-
93
-        if (!isset($this->headerNames[$key])) {
94
-            return [];
95
-        }
96
-
97
-        return $this->headers[$this->headerNames[$key]];
98
-    }
99
-
100
-    /**
101
-     * @inheritDoc
102
-     */
103
-    public function getHeaderLine($name): string
104
-    {
105
-        $key = strtolower($name);
106
-
107
-        if (!isset($this->headerNames[$key])) {
108
-            return '';
109
-        }
110
-
111
-        return implode(',', $this->headers[$this->headerNames[$key]]);
112
-    }
113
-
114
-    /**
115
-     * @inheritDoc
116
-     */
117
-    public function withHeader($name, $value): MessageInterface
118
-    {
119
-        $clone = clone $this;
120
-        $clone->setHeader($name, $value, true);
121
-
122
-        return $clone;
123
-    }
124
-
125
-    /**
126
-     * @inheritDoc
127
-     */
128
-    public function withAddedHeader($name, $value): MessageInterface
129
-    {
130
-        $clone = clone $this;
131
-        $clone->setHeader($name, $value, false);
132
-
133
-        return $clone;
134
-    }
135
-
136
-    /**
137
-     * @inheritDoc
138
-     */
139
-    public function withoutHeader($name): MessageInterface
140
-    {
141
-        $clone = clone $this;
142
-        $clone->deleteHeader($name);
143
-
144
-        return $clone;
145
-    }
146
-
147
-    /**
148
-     * @inheritDoc
149
-     */
150
-    public function getBody(): StreamInterface
151
-    {
152
-        return $this->body ??= new PhpTempStream();
153
-    }
154
-
155
-    /**
156
-     * @inheritDoc
157
-     */
158
-    public function withBody(StreamInterface $body): MessageInterface
159
-    {
160
-        $clone = clone $this;
161
-        $clone->setBody($body);
162
-
163
-        return $clone;
164
-    }
165
-
166
-    /**
167
-     * Sets the given HTTP version to the message
168
-     *
169
-     * @param string $protocolVersion
170
-     *
171
-     * @throws InvalidArgumentException
172
-     */
173
-    final protected function setProtocolVersion($protocolVersion): void
174
-    {
175
-        $this->validateProtocolVersion($protocolVersion);
176
-
177
-        $this->protocolVersion = $protocolVersion;
178
-    }
179
-
180
-    /**
181
-     * Sets a new header to the message with the given name and value(s)
182
-     *
183
-     * @param string $name
184
-     * @param string|string[] $value
185
-     *
186
-     * @throws InvalidArgumentException
187
-     */
188
-    final protected function setHeader($name, $value, bool $replace = true): void
189
-    {
190
-        if (!is_array($value)) {
191
-            $value = [$value];
192
-        }
193
-
194
-        $this->validateHeaderName($name);
195
-        $this->validateHeaderValue($name, $value);
196
-
197
-        $replace and $this->deleteHeader($name);
198
-
199
-        $key = strtolower($name);
200
-
201
-        $this->headerNames[$key] ??= $name;
202
-        $this->headers[$this->headerNames[$key]] ??= [];
203
-
204
-        foreach ($value as $item) {
205
-            $this->headers[$this->headerNames[$key]][] = $item;
206
-        }
207
-    }
208
-
209
-    /**
210
-     * Sets the given headers to the message
211
-     *
212
-     * @param array<string, string|string[]> $headers
213
-     *
214
-     * @throws InvalidArgumentException
215
-     */
216
-    final protected function setHeaders(array $headers): void
217
-    {
218
-        foreach ($headers as $name => $value) {
219
-            $this->setHeader($name, $value, false);
220
-        }
221
-    }
222
-
223
-    /**
224
-     * Deletes a header from the message by the given name
225
-     *
226
-     * @param string $name
227
-     */
228
-    final protected function deleteHeader($name): void
229
-    {
230
-        $key = strtolower($name);
231
-
232
-        if (isset($this->headerNames[$key])) {
233
-            unset($this->headers[$this->headerNames[$key]]);
234
-            unset($this->headerNames[$key]);
235
-        }
236
-    }
237
-
238
-    /**
239
-     * Sets the given body to the message
240
-     */
241
-    final protected function setBody(StreamInterface $body): void
242
-    {
243
-        $this->body = $body;
244
-    }
245
-
246
-    /**
247
-     * Validates the given HTTP version
248
-     *
249
-     * @param mixed $protocolVersion
250
-     *
251
-     * @throws InvalidArgumentException
252
-     */
253
-    private function validateProtocolVersion($protocolVersion): void
254
-    {
255
-        if (!in_array($protocolVersion, self::ALLOWED_HTTP_VERSIONS, true)) {
256
-            throw new InvalidArgumentException('Unallowed HTTP version');
257
-        }
258
-    }
259
-
260
-    /**
261
-     * Validates the given header name
262
-     *
263
-     * @param mixed $name
264
-     *
265
-     * @throws InvalidArgumentException
266
-     */
267
-    private function validateHeaderName($name): void
268
-    {
269
-        if ($name === '') {
270
-            throw new InvalidArgumentException('HTTP header name cannot be an empty');
271
-        }
272
-
273
-        if (!is_string($name)) {
274
-            throw new InvalidArgumentException('HTTP header name must be a string');
275
-        }
276
-
277
-        if (!preg_match(HeaderInterface::RFC7230_TOKEN_REGEX, $name)) {
278
-            throw new InvalidArgumentException('HTTP header name is invalid');
279
-        }
280
-    }
281
-
282
-    /**
283
-     * Validates the given header value
284
-     *
285
-     * @param array<array-key, mixed> $value
286
-     *
287
-     * @throws InvalidArgumentException
288
-     */
289
-    private function validateHeaderValue(string $name, array $value): void
290
-    {
291
-        if ($value === []) {
292
-            throw new InvalidArgumentException(sprintf(
293
-                'The value of the HTTP header "%s" cannot be an empty array',
294
-                $name,
295
-            ));
296
-        }
297
-
298
-        foreach ($value as $key => $item) {
299
-            if ($item === '') {
300
-                continue;
301
-            }
302
-
303
-            if (!is_string($item)) {
304
-                throw new InvalidArgumentException(sprintf(
305
-                    'The value of the HTTP header "%s[%s]" must be a string',
306
-                    $name,
307
-                    $key
308
-                ));
309
-            }
310
-
311
-            if (!preg_match(HeaderInterface::RFC7230_FIELD_VALUE_REGEX, $item)) {
312
-                throw new InvalidArgumentException(sprintf(
313
-                    'The value of the HTTP header "%s[%s]" is invalid',
314
-                    $name,
315
-                    $key
316
-                ));
317
-            }
318
-        }
319
-    }
29
+	public const ALLOWED_HTTP_VERSIONS = ['1.0', '1.1', '2.0', '2'];
30
+
31
+	public const DEFAULT_HTTP_VERSION = self::ALLOWED_HTTP_VERSIONS[1];
32
+
33
+	private string $protocolVersion = self::DEFAULT_HTTP_VERSION;
34
+
35
+	/**
36
+	 * @var array<string, list<string>>
37
+	 */
38
+	private array $headers = [];
39
+
40
+	/**
41
+	 * @var array<string, string>
42
+	 */
43
+	private array $headerNames = [];
44
+
45
+	private ?StreamInterface $body = null;
46
+
47
+	/**
48
+	 * @inheritDoc
49
+	 */
50
+	public function getProtocolVersion(): string
51
+	{
52
+		return $this->protocolVersion;
53
+	}
54
+
55
+	/**
56
+	 * @inheritDoc
57
+	 *
58
+	 * @throws InvalidArgumentException
59
+	 */
60
+	public function withProtocolVersion($version): MessageInterface
61
+	{
62
+		$clone = clone $this;
63
+		$clone->setProtocolVersion($version);
64
+
65
+		return $clone;
66
+	}
67
+
68
+	/**
69
+	 * @inheritDoc
70
+	 */
71
+	public function getHeaders(): array
72
+	{
73
+		return $this->headers;
74
+	}
75
+
76
+	/**
77
+	 * @inheritDoc
78
+	 */
79
+	public function hasHeader($name): bool
80
+	{
81
+		$key = strtolower($name);
82
+
83
+		return isset($this->headerNames[$key]);
84
+	}
85
+
86
+	/**
87
+	 * @inheritDoc
88
+	 */
89
+	public function getHeader($name): array
90
+	{
91
+		$key = strtolower($name);
92
+
93
+		if (!isset($this->headerNames[$key])) {
94
+			return [];
95
+		}
96
+
97
+		return $this->headers[$this->headerNames[$key]];
98
+	}
99
+
100
+	/**
101
+	 * @inheritDoc
102
+	 */
103
+	public function getHeaderLine($name): string
104
+	{
105
+		$key = strtolower($name);
106
+
107
+		if (!isset($this->headerNames[$key])) {
108
+			return '';
109
+		}
110
+
111
+		return implode(',', $this->headers[$this->headerNames[$key]]);
112
+	}
113
+
114
+	/**
115
+	 * @inheritDoc
116
+	 */
117
+	public function withHeader($name, $value): MessageInterface
118
+	{
119
+		$clone = clone $this;
120
+		$clone->setHeader($name, $value, true);
121
+
122
+		return $clone;
123
+	}
124
+
125
+	/**
126
+	 * @inheritDoc
127
+	 */
128
+	public function withAddedHeader($name, $value): MessageInterface
129
+	{
130
+		$clone = clone $this;
131
+		$clone->setHeader($name, $value, false);
132
+
133
+		return $clone;
134
+	}
135
+
136
+	/**
137
+	 * @inheritDoc
138
+	 */
139
+	public function withoutHeader($name): MessageInterface
140
+	{
141
+		$clone = clone $this;
142
+		$clone->deleteHeader($name);
143
+
144
+		return $clone;
145
+	}
146
+
147
+	/**
148
+	 * @inheritDoc
149
+	 */
150
+	public function getBody(): StreamInterface
151
+	{
152
+		return $this->body ??= new PhpTempStream();
153
+	}
154
+
155
+	/**
156
+	 * @inheritDoc
157
+	 */
158
+	public function withBody(StreamInterface $body): MessageInterface
159
+	{
160
+		$clone = clone $this;
161
+		$clone->setBody($body);
162
+
163
+		return $clone;
164
+	}
165
+
166
+	/**
167
+	 * Sets the given HTTP version to the message
168
+	 *
169
+	 * @param string $protocolVersion
170
+	 *
171
+	 * @throws InvalidArgumentException
172
+	 */
173
+	final protected function setProtocolVersion($protocolVersion): void
174
+	{
175
+		$this->validateProtocolVersion($protocolVersion);
176
+
177
+		$this->protocolVersion = $protocolVersion;
178
+	}
179
+
180
+	/**
181
+	 * Sets a new header to the message with the given name and value(s)
182
+	 *
183
+	 * @param string $name
184
+	 * @param string|string[] $value
185
+	 *
186
+	 * @throws InvalidArgumentException
187
+	 */
188
+	final protected function setHeader($name, $value, bool $replace = true): void
189
+	{
190
+		if (!is_array($value)) {
191
+			$value = [$value];
192
+		}
193
+
194
+		$this->validateHeaderName($name);
195
+		$this->validateHeaderValue($name, $value);
196
+
197
+		$replace and $this->deleteHeader($name);
198
+
199
+		$key = strtolower($name);
200
+
201
+		$this->headerNames[$key] ??= $name;
202
+		$this->headers[$this->headerNames[$key]] ??= [];
203
+
204
+		foreach ($value as $item) {
205
+			$this->headers[$this->headerNames[$key]][] = $item;
206
+		}
207
+	}
208
+
209
+	/**
210
+	 * Sets the given headers to the message
211
+	 *
212
+	 * @param array<string, string|string[]> $headers
213
+	 *
214
+	 * @throws InvalidArgumentException
215
+	 */
216
+	final protected function setHeaders(array $headers): void
217
+	{
218
+		foreach ($headers as $name => $value) {
219
+			$this->setHeader($name, $value, false);
220
+		}
221
+	}
222
+
223
+	/**
224
+	 * Deletes a header from the message by the given name
225
+	 *
226
+	 * @param string $name
227
+	 */
228
+	final protected function deleteHeader($name): void
229
+	{
230
+		$key = strtolower($name);
231
+
232
+		if (isset($this->headerNames[$key])) {
233
+			unset($this->headers[$this->headerNames[$key]]);
234
+			unset($this->headerNames[$key]);
235
+		}
236
+	}
237
+
238
+	/**
239
+	 * Sets the given body to the message
240
+	 */
241
+	final protected function setBody(StreamInterface $body): void
242
+	{
243
+		$this->body = $body;
244
+	}
245
+
246
+	/**
247
+	 * Validates the given HTTP version
248
+	 *
249
+	 * @param mixed $protocolVersion
250
+	 *
251
+	 * @throws InvalidArgumentException
252
+	 */
253
+	private function validateProtocolVersion($protocolVersion): void
254
+	{
255
+		if (!in_array($protocolVersion, self::ALLOWED_HTTP_VERSIONS, true)) {
256
+			throw new InvalidArgumentException('Unallowed HTTP version');
257
+		}
258
+	}
259
+
260
+	/**
261
+	 * Validates the given header name
262
+	 *
263
+	 * @param mixed $name
264
+	 *
265
+	 * @throws InvalidArgumentException
266
+	 */
267
+	private function validateHeaderName($name): void
268
+	{
269
+		if ($name === '') {
270
+			throw new InvalidArgumentException('HTTP header name cannot be an empty');
271
+		}
272
+
273
+		if (!is_string($name)) {
274
+			throw new InvalidArgumentException('HTTP header name must be a string');
275
+		}
276
+
277
+		if (!preg_match(HeaderInterface::RFC7230_TOKEN_REGEX, $name)) {
278
+			throw new InvalidArgumentException('HTTP header name is invalid');
279
+		}
280
+	}
281
+
282
+	/**
283
+	 * Validates the given header value
284
+	 *
285
+	 * @param array<array-key, mixed> $value
286
+	 *
287
+	 * @throws InvalidArgumentException
288
+	 */
289
+	private function validateHeaderValue(string $name, array $value): void
290
+	{
291
+		if ($value === []) {
292
+			throw new InvalidArgumentException(sprintf(
293
+				'The value of the HTTP header "%s" cannot be an empty array',
294
+				$name,
295
+			));
296
+		}
297
+
298
+		foreach ($value as $key => $item) {
299
+			if ($item === '') {
300
+				continue;
301
+			}
302
+
303
+			if (!is_string($item)) {
304
+				throw new InvalidArgumentException(sprintf(
305
+					'The value of the HTTP header "%s[%s]" must be a string',
306
+					$name,
307
+					$key
308
+				));
309
+			}
310
+
311
+			if (!preg_match(HeaderInterface::RFC7230_FIELD_VALUE_REGEX, $item)) {
312
+				throw new InvalidArgumentException(sprintf(
313
+					'The value of the HTTP header "%s[%s]" is invalid',
314
+					$name,
315
+					$key
316
+				));
317
+			}
318
+		}
319
+	}
320 320
 }
Please login to merge, or discard this patch.
src/Request.php 1 patch
Indentation   +214 added lines, -214 removed lines patch added patch discarded remove patch
@@ -23,218 +23,218 @@
 block discarded – undo
23 23
 
24 24
 class Request extends Message implements RequestInterface, RequestMethodInterface
25 25
 {
26
-    private const RFC7230_REQUEST_TARGET_REGEX = '/^[\x21-\x7E\x80-\xFF]+$/';
27
-
28
-    private string $method = self::METHOD_GET;
29
-    private UriInterface $uri;
30
-    private ?string $requestTarget = null;
31
-
32
-    /**
33
-     * @param mixed $uri
34
-     * @param array<string, string|string[]>|null $headers
35
-     *
36
-     * @throws InvalidArgumentException
37
-     */
38
-    public function __construct(
39
-        ?string $method = null,
40
-        $uri = null,
41
-        ?array $headers = null,
42
-        ?StreamInterface $body = null
43
-    ) {
44
-        if ($method !== null) {
45
-            $this->setMethod($method);
46
-        }
47
-
48
-        $this->setUri($uri ?? '/');
49
-
50
-        if ($headers !== null) {
51
-            $this->setHeaders($headers);
52
-        }
53
-
54
-        if ($body !== null) {
55
-            $this->setBody($body);
56
-        }
57
-    }
58
-
59
-    /**
60
-     * @inheritDoc
61
-     */
62
-    public function getMethod(): string
63
-    {
64
-        return $this->method;
65
-    }
66
-
67
-    /**
68
-     * @inheritDoc
69
-     */
70
-    public function withMethod($method): RequestInterface
71
-    {
72
-        $clone = clone $this;
73
-        $clone->setMethod($method);
74
-
75
-        return $clone;
76
-    }
77
-
78
-    /**
79
-     * @inheritDoc
80
-     */
81
-    public function getUri(): UriInterface
82
-    {
83
-        return $this->uri;
84
-    }
85
-
86
-    /**
87
-     * @inheritDoc
88
-     */
89
-    public function withUri(UriInterface $uri, $preserveHost = false): RequestInterface
90
-    {
91
-        $clone = clone $this;
92
-        $clone->setUri($uri, $preserveHost);
93
-
94
-        return $clone;
95
-    }
96
-
97
-    /**
98
-     * @inheritDoc
99
-     */
100
-    public function getRequestTarget(): string
101
-    {
102
-        if ($this->requestTarget !== null) {
103
-            return $this->requestTarget;
104
-        }
105
-
106
-        $requestTarget = $this->uri->getPath();
107
-
108
-        // https://tools.ietf.org/html/rfc7230#section-5.3.1
109
-        // https://tools.ietf.org/html/rfc7230#section-2.7
110
-        //
111
-        // origin-form = absolute-path [ "?" query ]
112
-        // absolute-path = 1*( "/" segment )
113
-        if (strncmp($requestTarget, '/', 1) !== 0) {
114
-            return '/';
115
-        }
116
-
117
-        $queryString = $this->uri->getQuery();
118
-        if ($queryString !== '') {
119
-            $requestTarget .= '?' . $queryString;
120
-        }
121
-
122
-        return $requestTarget;
123
-    }
124
-
125
-    /**
126
-     * @inheritDoc
127
-     */
128
-    public function withRequestTarget($requestTarget): RequestInterface
129
-    {
130
-        $clone = clone $this;
131
-        $clone->setRequestTarget($requestTarget);
132
-
133
-        return $clone;
134
-    }
135
-
136
-    /**
137
-     * Sets the given method to the request
138
-     *
139
-     * @param string $method
140
-     *
141
-     * @throws InvalidArgumentException
142
-     */
143
-    final protected function setMethod($method): void
144
-    {
145
-        $this->validateMethod($method);
146
-
147
-        $this->method = $method;
148
-    }
149
-
150
-    /**
151
-     * Sets the given URI to the request
152
-     *
153
-     * @param mixed $uri
154
-     * @param bool $preserveHost
155
-     *
156
-     * @throws InvalidArgumentException
157
-     */
158
-    final protected function setUri($uri, $preserveHost = false): void
159
-    {
160
-        $this->uri = Uri::create($uri);
161
-
162
-        if ($preserveHost && $this->hasHeader('Host')) {
163
-            return;
164
-        }
165
-
166
-        $host = $this->uri->getHost();
167
-        if ($host === '') {
168
-            return;
169
-        }
170
-
171
-        $port = $this->uri->getPort();
172
-        if ($port !== null) {
173
-            $host .= ':' . $port;
174
-        }
175
-
176
-        $this->setHeader('Host', $host, true);
177
-    }
178
-
179
-    /**
180
-     * Sets the given request target to the request
181
-     *
182
-     * @param mixed $requestTarget
183
-     *
184
-     * @throws InvalidArgumentException
185
-     */
186
-    final protected function setRequestTarget($requestTarget): void
187
-    {
188
-        $this->validateRequestTarget($requestTarget);
189
-
190
-        /** @var string $requestTarget */
191
-
192
-        $this->requestTarget = $requestTarget;
193
-    }
194
-
195
-    /**
196
-     * Validates the given method
197
-     *
198
-     * @link https://tools.ietf.org/html/rfc7230#section-3.1.1
199
-     *
200
-     * @param mixed $method
201
-     *
202
-     * @throws InvalidArgumentException
203
-     */
204
-    private function validateMethod($method): void
205
-    {
206
-        if ($method === '') {
207
-            throw new InvalidArgumentException('HTTP method cannot be an empty');
208
-        }
209
-
210
-        if (!is_string($method)) {
211
-            throw new InvalidArgumentException('HTTP method must be a string');
212
-        }
213
-
214
-        if (!preg_match(HeaderInterface::RFC7230_TOKEN_REGEX, $method)) {
215
-            throw new InvalidArgumentException('Invalid HTTP method');
216
-        }
217
-    }
218
-
219
-    /**
220
-     * Validates the given request target
221
-     *
222
-     * @param mixed $requestTarget
223
-     *
224
-     * @throws InvalidArgumentException
225
-     */
226
-    private function validateRequestTarget($requestTarget): void
227
-    {
228
-        if ($requestTarget === '') {
229
-            throw new InvalidArgumentException('HTTP request target cannot be an empty');
230
-        }
231
-
232
-        if (!is_string($requestTarget)) {
233
-            throw new InvalidArgumentException('HTTP request target must be a string');
234
-        }
235
-
236
-        if (!preg_match(self::RFC7230_REQUEST_TARGET_REGEX, $requestTarget)) {
237
-            throw new InvalidArgumentException('Invalid HTTP request target');
238
-        }
239
-    }
26
+	private const RFC7230_REQUEST_TARGET_REGEX = '/^[\x21-\x7E\x80-\xFF]+$/';
27
+
28
+	private string $method = self::METHOD_GET;
29
+	private UriInterface $uri;
30
+	private ?string $requestTarget = null;
31
+
32
+	/**
33
+	 * @param mixed $uri
34
+	 * @param array<string, string|string[]>|null $headers
35
+	 *
36
+	 * @throws InvalidArgumentException
37
+	 */
38
+	public function __construct(
39
+		?string $method = null,
40
+		$uri = null,
41
+		?array $headers = null,
42
+		?StreamInterface $body = null
43
+	) {
44
+		if ($method !== null) {
45
+			$this->setMethod($method);
46
+		}
47
+
48
+		$this->setUri($uri ?? '/');
49
+
50
+		if ($headers !== null) {
51
+			$this->setHeaders($headers);
52
+		}
53
+
54
+		if ($body !== null) {
55
+			$this->setBody($body);
56
+		}
57
+	}
58
+
59
+	/**
60
+	 * @inheritDoc
61
+	 */
62
+	public function getMethod(): string
63
+	{
64
+		return $this->method;
65
+	}
66
+
67
+	/**
68
+	 * @inheritDoc
69
+	 */
70
+	public function withMethod($method): RequestInterface
71
+	{
72
+		$clone = clone $this;
73
+		$clone->setMethod($method);
74
+
75
+		return $clone;
76
+	}
77
+
78
+	/**
79
+	 * @inheritDoc
80
+	 */
81
+	public function getUri(): UriInterface
82
+	{
83
+		return $this->uri;
84
+	}
85
+
86
+	/**
87
+	 * @inheritDoc
88
+	 */
89
+	public function withUri(UriInterface $uri, $preserveHost = false): RequestInterface
90
+	{
91
+		$clone = clone $this;
92
+		$clone->setUri($uri, $preserveHost);
93
+
94
+		return $clone;
95
+	}
96
+
97
+	/**
98
+	 * @inheritDoc
99
+	 */
100
+	public function getRequestTarget(): string
101
+	{
102
+		if ($this->requestTarget !== null) {
103
+			return $this->requestTarget;
104
+		}
105
+
106
+		$requestTarget = $this->uri->getPath();
107
+
108
+		// https://tools.ietf.org/html/rfc7230#section-5.3.1
109
+		// https://tools.ietf.org/html/rfc7230#section-2.7
110
+		//
111
+		// origin-form = absolute-path [ "?" query ]
112
+		// absolute-path = 1*( "/" segment )
113
+		if (strncmp($requestTarget, '/', 1) !== 0) {
114
+			return '/';
115
+		}
116
+
117
+		$queryString = $this->uri->getQuery();
118
+		if ($queryString !== '') {
119
+			$requestTarget .= '?' . $queryString;
120
+		}
121
+
122
+		return $requestTarget;
123
+	}
124
+
125
+	/**
126
+	 * @inheritDoc
127
+	 */
128
+	public function withRequestTarget($requestTarget): RequestInterface
129
+	{
130
+		$clone = clone $this;
131
+		$clone->setRequestTarget($requestTarget);
132
+
133
+		return $clone;
134
+	}
135
+
136
+	/**
137
+	 * Sets the given method to the request
138
+	 *
139
+	 * @param string $method
140
+	 *
141
+	 * @throws InvalidArgumentException
142
+	 */
143
+	final protected function setMethod($method): void
144
+	{
145
+		$this->validateMethod($method);
146
+
147
+		$this->method = $method;
148
+	}
149
+
150
+	/**
151
+	 * Sets the given URI to the request
152
+	 *
153
+	 * @param mixed $uri
154
+	 * @param bool $preserveHost
155
+	 *
156
+	 * @throws InvalidArgumentException
157
+	 */
158
+	final protected function setUri($uri, $preserveHost = false): void
159
+	{
160
+		$this->uri = Uri::create($uri);
161
+
162
+		if ($preserveHost && $this->hasHeader('Host')) {
163
+			return;
164
+		}
165
+
166
+		$host = $this->uri->getHost();
167
+		if ($host === '') {
168
+			return;
169
+		}
170
+
171
+		$port = $this->uri->getPort();
172
+		if ($port !== null) {
173
+			$host .= ':' . $port;
174
+		}
175
+
176
+		$this->setHeader('Host', $host, true);
177
+	}
178
+
179
+	/**
180
+	 * Sets the given request target to the request
181
+	 *
182
+	 * @param mixed $requestTarget
183
+	 *
184
+	 * @throws InvalidArgumentException
185
+	 */
186
+	final protected function setRequestTarget($requestTarget): void
187
+	{
188
+		$this->validateRequestTarget($requestTarget);
189
+
190
+		/** @var string $requestTarget */
191
+
192
+		$this->requestTarget = $requestTarget;
193
+	}
194
+
195
+	/**
196
+	 * Validates the given method
197
+	 *
198
+	 * @link https://tools.ietf.org/html/rfc7230#section-3.1.1
199
+	 *
200
+	 * @param mixed $method
201
+	 *
202
+	 * @throws InvalidArgumentException
203
+	 */
204
+	private function validateMethod($method): void
205
+	{
206
+		if ($method === '') {
207
+			throw new InvalidArgumentException('HTTP method cannot be an empty');
208
+		}
209
+
210
+		if (!is_string($method)) {
211
+			throw new InvalidArgumentException('HTTP method must be a string');
212
+		}
213
+
214
+		if (!preg_match(HeaderInterface::RFC7230_TOKEN_REGEX, $method)) {
215
+			throw new InvalidArgumentException('Invalid HTTP method');
216
+		}
217
+	}
218
+
219
+	/**
220
+	 * Validates the given request target
221
+	 *
222
+	 * @param mixed $requestTarget
223
+	 *
224
+	 * @throws InvalidArgumentException
225
+	 */
226
+	private function validateRequestTarget($requestTarget): void
227
+	{
228
+		if ($requestTarget === '') {
229
+			throw new InvalidArgumentException('HTTP request target cannot be an empty');
230
+		}
231
+
232
+		if (!is_string($requestTarget)) {
233
+			throw new InvalidArgumentException('HTTP request target must be a string');
234
+		}
235
+
236
+		if (!preg_match(self::RFC7230_REQUEST_TARGET_REGEX, $requestTarget)) {
237
+			throw new InvalidArgumentException('Invalid HTTP request target');
238
+		}
239
+	}
240 240
 }
Please login to merge, or discard this patch.
src/StreamFactory.php 1 patch
Indentation   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -18,35 +18,35 @@
 block discarded – undo
18 18
 
19 19
 class StreamFactory implements StreamFactoryInterface
20 20
 {
21
-    /**
22
-     * @inheritDoc
23
-     */
24
-    public function createStream(string $content = ''): StreamInterface
25
-    {
26
-        $stream = new PhpTempStream();
27
-        if ($content === '') {
28
-            return $stream;
29
-        }
30
-
31
-        $stream->write($content);
32
-        $stream->rewind();
33
-
34
-        return $stream;
35
-    }
36
-
37
-    /**
38
-     * @inheritDoc
39
-     */
40
-    public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface
41
-    {
42
-        return new FileStream($filename, $mode);
43
-    }
44
-
45
-    /**
46
-     * @inheritDoc
47
-     */
48
-    public function createStreamFromResource($resource): StreamInterface
49
-    {
50
-        return new Stream($resource);
51
-    }
21
+	/**
22
+	 * @inheritDoc
23
+	 */
24
+	public function createStream(string $content = ''): StreamInterface
25
+	{
26
+		$stream = new PhpTempStream();
27
+		if ($content === '') {
28
+			return $stream;
29
+		}
30
+
31
+		$stream->write($content);
32
+		$stream->rewind();
33
+
34
+		return $stream;
35
+	}
36
+
37
+	/**
38
+	 * @inheritDoc
39
+	 */
40
+	public function createStreamFromFile(string $filename, string $mode = 'r'): StreamInterface
41
+	{
42
+		return new FileStream($filename, $mode);
43
+	}
44
+
45
+	/**
46
+	 * @inheritDoc
47
+	 */
48
+	public function createStreamFromResource($resource): StreamInterface
49
+	{
50
+		return new Stream($resource);
51
+	}
52 52
 }
Please login to merge, or discard this patch.
src/Uri.php 1 patch
Indentation   +370 added lines, -370 removed lines patch added patch discarded remove patch
@@ -28,374 +28,374 @@
 block discarded – undo
28 28
 
29 29
 class Uri implements UriInterface
30 30
 {
31
-    private string $scheme = '';
32
-    private string $userInfo = '';
33
-    private string $host = '';
34
-    private ?int $port = null;
35
-    private string $path = '';
36
-    private string $query = '';
37
-    private string $fragment = '';
38
-
39
-    /**
40
-     * @throws InvalidArgumentException
41
-     */
42
-    public function __construct(string $uri = '')
43
-    {
44
-        if ($uri === '') {
45
-            return;
46
-        }
47
-
48
-        $this->parseUri($uri);
49
-    }
50
-
51
-    /**
52
-     * @param mixed $uri
53
-     *
54
-     * @throws InvalidArgumentException
55
-     */
56
-    public static function create($uri): UriInterface
57
-    {
58
-        if ($uri instanceof UriInterface) {
59
-            return $uri;
60
-        }
61
-
62
-        if (!is_string($uri)) {
63
-            throw new InvalidArgumentException('URI should be a string');
64
-        }
65
-
66
-        return new self($uri);
67
-    }
68
-
69
-    /**
70
-     * @inheritDoc
71
-     */
72
-    public function withScheme($scheme): UriInterface
73
-    {
74
-        $clone = clone $this;
75
-        $clone->setScheme($scheme);
76
-
77
-        return $clone;
78
-    }
79
-
80
-    /**
81
-     * @inheritDoc
82
-     *
83
-     * @throws InvalidArgumentException
84
-     */
85
-    public function withUserInfo($user, $password = null): UriInterface
86
-    {
87
-        $clone = clone $this;
88
-        $clone->setUserInfo($user, $password);
89
-
90
-        return $clone;
91
-    }
92
-
93
-    /**
94
-     * @inheritDoc
95
-     */
96
-    public function withHost($host): UriInterface
97
-    {
98
-        $clone = clone $this;
99
-        $clone->setHost($host);
100
-
101
-        return $clone;
102
-    }
103
-
104
-    /**
105
-     * @inheritDoc
106
-     */
107
-    public function withPort($port): UriInterface
108
-    {
109
-        $clone = clone $this;
110
-        $clone->setPort($port);
111
-
112
-        return $clone;
113
-    }
114
-
115
-    /**
116
-     * @inheritDoc
117
-     */
118
-    public function withPath($path): UriInterface
119
-    {
120
-        $clone = clone $this;
121
-        $clone->setPath($path);
122
-
123
-        return $clone;
124
-    }
125
-
126
-    /**
127
-     * @inheritDoc
128
-     */
129
-    public function withQuery($query): UriInterface
130
-    {
131
-        $clone = clone $this;
132
-        $clone->setQuery($query);
133
-
134
-        return $clone;
135
-    }
136
-
137
-    /**
138
-     * @inheritDoc
139
-     *
140
-     * @throws InvalidArgumentException
141
-     */
142
-    public function withFragment($fragment): UriInterface
143
-    {
144
-        $clone = clone $this;
145
-        $clone->setFragment($fragment);
146
-
147
-        return $clone;
148
-    }
149
-
150
-    /**
151
-     * @inheritDoc
152
-     */
153
-    public function getScheme(): string
154
-    {
155
-        return $this->scheme;
156
-    }
157
-
158
-    /**
159
-     * @inheritDoc
160
-     */
161
-    public function getUserInfo(): string
162
-    {
163
-        return $this->userInfo;
164
-    }
165
-
166
-    /**
167
-     * @inheritDoc
168
-     */
169
-    public function getHost(): string
170
-    {
171
-        return $this->host;
172
-    }
173
-
174
-    /**
175
-     * @inheritDoc
176
-     */
177
-    public function getPort(): ?int
178
-    {
179
-        // The 80 is the default port number for the HTTP protocol.
180
-        if ($this->port === 80 && $this->scheme === 'http') {
181
-            return null;
182
-        }
183
-
184
-        // The 443 is the default port number for the HTTPS protocol.
185
-        if ($this->port === 443 && $this->scheme === 'https') {
186
-            return null;
187
-        }
188
-
189
-        return $this->port;
190
-    }
191
-
192
-    /**
193
-     * @inheritDoc
194
-     */
195
-    public function getPath(): string
196
-    {
197
-        // CVE-2015-3257
198
-        if (strncmp($this->path, '//', 2) === 0) {
199
-            return '/' . ltrim($this->path, '/');
200
-        }
201
-
202
-        return $this->path;
203
-    }
204
-
205
-    /**
206
-     * @inheritDoc
207
-     */
208
-    public function getQuery(): string
209
-    {
210
-        return $this->query;
211
-    }
212
-
213
-    /**
214
-     * @inheritDoc
215
-     */
216
-    public function getFragment(): string
217
-    {
218
-        return $this->fragment;
219
-    }
220
-
221
-    /**
222
-     * @inheritDoc
223
-     */
224
-    public function getAuthority(): string
225
-    {
226
-        // The host is the basic subcomponent.
227
-        if ($this->host === '') {
228
-            return '';
229
-        }
230
-
231
-        $authority = $this->host;
232
-        if ($this->userInfo !== '') {
233
-            $authority = $this->userInfo . '@' . $authority;
234
-        }
235
-
236
-        $port = $this->getPort();
237
-        if ($port !== null) {
238
-            $authority = $authority . ':' . $port;
239
-        }
240
-
241
-        return $authority;
242
-    }
243
-
244
-    /**
245
-     * @inheritDoc
246
-     */
247
-    public function __toString(): string
248
-    {
249
-        $uri = '';
250
-
251
-        $scheme = $this->scheme;
252
-        if ($scheme !== '') {
253
-            $uri .= $scheme . ':';
254
-        }
255
-
256
-        $authority = $this->getAuthority();
257
-        if ($authority !== '') {
258
-            $uri .= '//' . $authority;
259
-        }
260
-
261
-        $path = $this->path;
262
-        if ($path !== '') {
263
-            // https://github.com/sunrise-php/uri/issues/31
264
-            // https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
265
-            //
266
-            // If a URI contains an authority component,
267
-            // then the path component must either be empty
268
-            // or begin with a slash ("/") character.
269
-            if ($authority !== '' && strncmp($path, '/', 1) !== 0) {
270
-                $path = '/' . $path;
271
-            }
272
-
273
-            // https://github.com/sunrise-php/uri/issues/31
274
-            // https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
275
-            //
276
-            // If a URI does not contain an authority component,
277
-            // then the path cannot begin with two slash characters ("//").
278
-            if ($authority === '' && strncmp($path, '//', 2) === 0) {
279
-                $path = '/' . ltrim($path, '/');
280
-            }
281
-
282
-            $uri .= $path;
283
-        }
284
-
285
-        $query = $this->query;
286
-        if ($query !== '') {
287
-            $uri .= '?' . $query;
288
-        }
289
-
290
-        $fragment = $this->fragment;
291
-        if ($fragment !== '') {
292
-            $uri .= '#' . $fragment;
293
-        }
294
-
295
-        return $uri;
296
-    }
297
-
298
-    /**
299
-     * @param mixed $scheme
300
-     *
301
-     * @throws InvalidArgumentException
302
-     */
303
-    final protected function setScheme($scheme): void
304
-    {
305
-        $this->scheme = (new Scheme($scheme))->getValue();
306
-    }
307
-
308
-    /**
309
-     * @param mixed $user
310
-     * @param mixed $password
311
-     *
312
-     * @throws InvalidArgumentException
313
-     */
314
-    final protected function setUserInfo($user, $password): void
315
-    {
316
-        $this->userInfo = (new UserInfo($user, $password))->getValue();
317
-    }
318
-
319
-    /**
320
-     * @param mixed $host
321
-     *
322
-     * @throws InvalidArgumentException
323
-     */
324
-    final protected function setHost($host): void
325
-    {
326
-        $this->host = (new Host($host))->getValue();
327
-    }
328
-
329
-    /**
330
-     * @param mixed $port
331
-     *
332
-     * @throws InvalidArgumentException
333
-     */
334
-    final protected function setPort($port): void
335
-    {
336
-        $this->port = (new Port($port))->getValue();
337
-    }
338
-
339
-    /**
340
-     * @param mixed $path
341
-     *
342
-     * @throws InvalidArgumentException
343
-     */
344
-    final protected function setPath($path): void
345
-    {
346
-        $this->path = (new Path($path))->getValue();
347
-    }
348
-
349
-    /**
350
-     * @param mixed $query
351
-     *
352
-     * @throws InvalidArgumentException
353
-     */
354
-    final protected function setQuery($query): void
355
-    {
356
-        $this->query = (new Query($query))->getValue();
357
-    }
358
-
359
-    /**
360
-     * @param mixed $fragment
361
-     *
362
-     * @throws InvalidArgumentException
363
-     */
364
-    final protected function setFragment($fragment): void
365
-    {
366
-        $this->fragment = (new Fragment($fragment))->getValue();
367
-    }
368
-
369
-    /**
370
-     * @throws InvalidArgumentException
371
-     */
372
-    private function parseUri(string $uri): void
373
-    {
374
-        $components = parse_url($uri);
375
-        if ($components === false) {
376
-            throw new InvalidArgumentException('Invalid URI');
377
-        }
378
-
379
-        if (isset($components['scheme'])) {
380
-            $this->setScheme($components['scheme']);
381
-        }
382
-        if (isset($components['user'])) {
383
-            $this->setUserInfo($components['user'], $components['pass'] ?? null);
384
-        }
385
-        if (isset($components['host'])) {
386
-            $this->setHost($components['host']);
387
-        }
388
-        if (isset($components['port'])) {
389
-            $this->setPort($components['port']);
390
-        }
391
-        if (isset($components['path'])) {
392
-            $this->setPath($components['path']);
393
-        }
394
-        if (isset($components['query'])) {
395
-            $this->setQuery($components['query']);
396
-        }
397
-        if (isset($components['fragment'])) {
398
-            $this->setFragment($components['fragment']);
399
-        }
400
-    }
31
+	private string $scheme = '';
32
+	private string $userInfo = '';
33
+	private string $host = '';
34
+	private ?int $port = null;
35
+	private string $path = '';
36
+	private string $query = '';
37
+	private string $fragment = '';
38
+
39
+	/**
40
+	 * @throws InvalidArgumentException
41
+	 */
42
+	public function __construct(string $uri = '')
43
+	{
44
+		if ($uri === '') {
45
+			return;
46
+		}
47
+
48
+		$this->parseUri($uri);
49
+	}
50
+
51
+	/**
52
+	 * @param mixed $uri
53
+	 *
54
+	 * @throws InvalidArgumentException
55
+	 */
56
+	public static function create($uri): UriInterface
57
+	{
58
+		if ($uri instanceof UriInterface) {
59
+			return $uri;
60
+		}
61
+
62
+		if (!is_string($uri)) {
63
+			throw new InvalidArgumentException('URI should be a string');
64
+		}
65
+
66
+		return new self($uri);
67
+	}
68
+
69
+	/**
70
+	 * @inheritDoc
71
+	 */
72
+	public function withScheme($scheme): UriInterface
73
+	{
74
+		$clone = clone $this;
75
+		$clone->setScheme($scheme);
76
+
77
+		return $clone;
78
+	}
79
+
80
+	/**
81
+	 * @inheritDoc
82
+	 *
83
+	 * @throws InvalidArgumentException
84
+	 */
85
+	public function withUserInfo($user, $password = null): UriInterface
86
+	{
87
+		$clone = clone $this;
88
+		$clone->setUserInfo($user, $password);
89
+
90
+		return $clone;
91
+	}
92
+
93
+	/**
94
+	 * @inheritDoc
95
+	 */
96
+	public function withHost($host): UriInterface
97
+	{
98
+		$clone = clone $this;
99
+		$clone->setHost($host);
100
+
101
+		return $clone;
102
+	}
103
+
104
+	/**
105
+	 * @inheritDoc
106
+	 */
107
+	public function withPort($port): UriInterface
108
+	{
109
+		$clone = clone $this;
110
+		$clone->setPort($port);
111
+
112
+		return $clone;
113
+	}
114
+
115
+	/**
116
+	 * @inheritDoc
117
+	 */
118
+	public function withPath($path): UriInterface
119
+	{
120
+		$clone = clone $this;
121
+		$clone->setPath($path);
122
+
123
+		return $clone;
124
+	}
125
+
126
+	/**
127
+	 * @inheritDoc
128
+	 */
129
+	public function withQuery($query): UriInterface
130
+	{
131
+		$clone = clone $this;
132
+		$clone->setQuery($query);
133
+
134
+		return $clone;
135
+	}
136
+
137
+	/**
138
+	 * @inheritDoc
139
+	 *
140
+	 * @throws InvalidArgumentException
141
+	 */
142
+	public function withFragment($fragment): UriInterface
143
+	{
144
+		$clone = clone $this;
145
+		$clone->setFragment($fragment);
146
+
147
+		return $clone;
148
+	}
149
+
150
+	/**
151
+	 * @inheritDoc
152
+	 */
153
+	public function getScheme(): string
154
+	{
155
+		return $this->scheme;
156
+	}
157
+
158
+	/**
159
+	 * @inheritDoc
160
+	 */
161
+	public function getUserInfo(): string
162
+	{
163
+		return $this->userInfo;
164
+	}
165
+
166
+	/**
167
+	 * @inheritDoc
168
+	 */
169
+	public function getHost(): string
170
+	{
171
+		return $this->host;
172
+	}
173
+
174
+	/**
175
+	 * @inheritDoc
176
+	 */
177
+	public function getPort(): ?int
178
+	{
179
+		// The 80 is the default port number for the HTTP protocol.
180
+		if ($this->port === 80 && $this->scheme === 'http') {
181
+			return null;
182
+		}
183
+
184
+		// The 443 is the default port number for the HTTPS protocol.
185
+		if ($this->port === 443 && $this->scheme === 'https') {
186
+			return null;
187
+		}
188
+
189
+		return $this->port;
190
+	}
191
+
192
+	/**
193
+	 * @inheritDoc
194
+	 */
195
+	public function getPath(): string
196
+	{
197
+		// CVE-2015-3257
198
+		if (strncmp($this->path, '//', 2) === 0) {
199
+			return '/' . ltrim($this->path, '/');
200
+		}
201
+
202
+		return $this->path;
203
+	}
204
+
205
+	/**
206
+	 * @inheritDoc
207
+	 */
208
+	public function getQuery(): string
209
+	{
210
+		return $this->query;
211
+	}
212
+
213
+	/**
214
+	 * @inheritDoc
215
+	 */
216
+	public function getFragment(): string
217
+	{
218
+		return $this->fragment;
219
+	}
220
+
221
+	/**
222
+	 * @inheritDoc
223
+	 */
224
+	public function getAuthority(): string
225
+	{
226
+		// The host is the basic subcomponent.
227
+		if ($this->host === '') {
228
+			return '';
229
+		}
230
+
231
+		$authority = $this->host;
232
+		if ($this->userInfo !== '') {
233
+			$authority = $this->userInfo . '@' . $authority;
234
+		}
235
+
236
+		$port = $this->getPort();
237
+		if ($port !== null) {
238
+			$authority = $authority . ':' . $port;
239
+		}
240
+
241
+		return $authority;
242
+	}
243
+
244
+	/**
245
+	 * @inheritDoc
246
+	 */
247
+	public function __toString(): string
248
+	{
249
+		$uri = '';
250
+
251
+		$scheme = $this->scheme;
252
+		if ($scheme !== '') {
253
+			$uri .= $scheme . ':';
254
+		}
255
+
256
+		$authority = $this->getAuthority();
257
+		if ($authority !== '') {
258
+			$uri .= '//' . $authority;
259
+		}
260
+
261
+		$path = $this->path;
262
+		if ($path !== '') {
263
+			// https://github.com/sunrise-php/uri/issues/31
264
+			// https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
265
+			//
266
+			// If a URI contains an authority component,
267
+			// then the path component must either be empty
268
+			// or begin with a slash ("/") character.
269
+			if ($authority !== '' && strncmp($path, '/', 1) !== 0) {
270
+				$path = '/' . $path;
271
+			}
272
+
273
+			// https://github.com/sunrise-php/uri/issues/31
274
+			// https://datatracker.ietf.org/doc/html/rfc3986#section-3.3
275
+			//
276
+			// If a URI does not contain an authority component,
277
+			// then the path cannot begin with two slash characters ("//").
278
+			if ($authority === '' && strncmp($path, '//', 2) === 0) {
279
+				$path = '/' . ltrim($path, '/');
280
+			}
281
+
282
+			$uri .= $path;
283
+		}
284
+
285
+		$query = $this->query;
286
+		if ($query !== '') {
287
+			$uri .= '?' . $query;
288
+		}
289
+
290
+		$fragment = $this->fragment;
291
+		if ($fragment !== '') {
292
+			$uri .= '#' . $fragment;
293
+		}
294
+
295
+		return $uri;
296
+	}
297
+
298
+	/**
299
+	 * @param mixed $scheme
300
+	 *
301
+	 * @throws InvalidArgumentException
302
+	 */
303
+	final protected function setScheme($scheme): void
304
+	{
305
+		$this->scheme = (new Scheme($scheme))->getValue();
306
+	}
307
+
308
+	/**
309
+	 * @param mixed $user
310
+	 * @param mixed $password
311
+	 *
312
+	 * @throws InvalidArgumentException
313
+	 */
314
+	final protected function setUserInfo($user, $password): void
315
+	{
316
+		$this->userInfo = (new UserInfo($user, $password))->getValue();
317
+	}
318
+
319
+	/**
320
+	 * @param mixed $host
321
+	 *
322
+	 * @throws InvalidArgumentException
323
+	 */
324
+	final protected function setHost($host): void
325
+	{
326
+		$this->host = (new Host($host))->getValue();
327
+	}
328
+
329
+	/**
330
+	 * @param mixed $port
331
+	 *
332
+	 * @throws InvalidArgumentException
333
+	 */
334
+	final protected function setPort($port): void
335
+	{
336
+		$this->port = (new Port($port))->getValue();
337
+	}
338
+
339
+	/**
340
+	 * @param mixed $path
341
+	 *
342
+	 * @throws InvalidArgumentException
343
+	 */
344
+	final protected function setPath($path): void
345
+	{
346
+		$this->path = (new Path($path))->getValue();
347
+	}
348
+
349
+	/**
350
+	 * @param mixed $query
351
+	 *
352
+	 * @throws InvalidArgumentException
353
+	 */
354
+	final protected function setQuery($query): void
355
+	{
356
+		$this->query = (new Query($query))->getValue();
357
+	}
358
+
359
+	/**
360
+	 * @param mixed $fragment
361
+	 *
362
+	 * @throws InvalidArgumentException
363
+	 */
364
+	final protected function setFragment($fragment): void
365
+	{
366
+		$this->fragment = (new Fragment($fragment))->getValue();
367
+	}
368
+
369
+	/**
370
+	 * @throws InvalidArgumentException
371
+	 */
372
+	private function parseUri(string $uri): void
373
+	{
374
+		$components = parse_url($uri);
375
+		if ($components === false) {
376
+			throw new InvalidArgumentException('Invalid URI');
377
+		}
378
+
379
+		if (isset($components['scheme'])) {
380
+			$this->setScheme($components['scheme']);
381
+		}
382
+		if (isset($components['user'])) {
383
+			$this->setUserInfo($components['user'], $components['pass'] ?? null);
384
+		}
385
+		if (isset($components['host'])) {
386
+			$this->setHost($components['host']);
387
+		}
388
+		if (isset($components['port'])) {
389
+			$this->setPort($components['port']);
390
+		}
391
+		if (isset($components['path'])) {
392
+			$this->setPath($components['path']);
393
+		}
394
+		if (isset($components['query'])) {
395
+			$this->setQuery($components['query']);
396
+		}
397
+		if (isset($components['fragment'])) {
398
+			$this->setFragment($components['fragment']);
399
+		}
400
+	}
401 401
 }
Please login to merge, or discard this patch.
src/UriFactory.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -16,11 +16,11 @@
 block discarded – undo
16 16
 
17 17
 class UriFactory implements UriFactoryInterface
18 18
 {
19
-    /**
20
-     * @inheritDoc
21
-     */
22
-    public function createUri(string $uri = ''): UriInterface
23
-    {
24
-        return new Uri($uri);
25
-    }
19
+	/**
20
+	 * @inheritDoc
21
+	 */
22
+	public function createUri(string $uri = ''): UriInterface
23
+	{
24
+		return new Uri($uri);
25
+	}
26 26
 }
Please login to merge, or discard this patch.
src/Request/JsonRequest.php 1 patch
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -27,48 +27,48 @@
 block discarded – undo
27 27
  */
28 28
 final class JsonRequest extends Request
29 29
 {
30
-    /**
31
-     * @param mixed $uri
32
-     * @param mixed $data
33
-     * @param int<1, max> $depth
34
-     * @psalm-param int<1, 2147483647> $depth
35
-     *
36
-     * @throws InvalidArgumentException
37
-     */
38
-    public function __construct(string $method, $uri, $data, int $flags = 0, int $depth = 512)
39
-    {
40
-        parent::__construct($method, $uri);
30
+	/**
31
+	 * @param mixed $uri
32
+	 * @param mixed $data
33
+	 * @param int<1, max> $depth
34
+	 * @psalm-param int<1, 2147483647> $depth
35
+	 *
36
+	 * @throws InvalidArgumentException
37
+	 */
38
+	public function __construct(string $method, $uri, $data, int $flags = 0, int $depth = 512)
39
+	{
40
+		parent::__construct($method, $uri);
41 41
 
42
-        $this->setBody(self::createBody($data, $flags, $depth));
43
-        $this->setHeader('Content-Type', 'application/json; charset=utf-8');
44
-    }
42
+		$this->setBody(self::createBody($data, $flags, $depth));
43
+		$this->setHeader('Content-Type', 'application/json; charset=utf-8');
44
+	}
45 45
 
46
-    /**
47
-     * @param mixed $data
48
-     * @param int<1, max> $depth
49
-     * @psalm-param int<1, 2147483647> $depth
50
-     *
51
-     * @throws InvalidArgumentException
52
-     */
53
-    private static function createBody($data, int $flags, int $depth): StreamInterface
54
-    {
55
-        if ($data instanceof StreamInterface) {
56
-            return $data;
57
-        }
46
+	/**
47
+	 * @param mixed $data
48
+	 * @param int<1, max> $depth
49
+	 * @psalm-param int<1, 2147483647> $depth
50
+	 *
51
+	 * @throws InvalidArgumentException
52
+	 */
53
+	private static function createBody($data, int $flags, int $depth): StreamInterface
54
+	{
55
+		if ($data instanceof StreamInterface) {
56
+			return $data;
57
+		}
58 58
 
59
-        try {
60
-            $json = json_encode($data, $flags | JSON_THROW_ON_ERROR, $depth);
61
-        } catch (JsonException $e) {
62
-            throw new InvalidArgumentException(sprintf(
63
-                'Unable to create the JSON request due to an invalid data: %s',
64
-                $e->getMessage(),
65
-            ), 0, $e);
66
-        }
59
+		try {
60
+			$json = json_encode($data, $flags | JSON_THROW_ON_ERROR, $depth);
61
+		} catch (JsonException $e) {
62
+			throw new InvalidArgumentException(sprintf(
63
+				'Unable to create the JSON request due to an invalid data: %s',
64
+				$e->getMessage(),
65
+			), 0, $e);
66
+		}
67 67
 
68
-        $stream = new PhpTempStream('r+b');
69
-        $stream->write($json);
70
-        $stream->rewind();
68
+		$stream = new PhpTempStream('r+b');
69
+		$stream->write($json);
70
+		$stream->rewind();
71 71
 
72
-        return $stream;
73
-    }
72
+		return $stream;
73
+	}
74 74
 }
Please login to merge, or discard this patch.
src/Uri/Component/Port.php 1 patch
Indentation   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -20,40 +20,40 @@
 block discarded – undo
20 20
  */
21 21
 final class Port implements ComponentInterface
22 22
 {
23
-    private const MIN_VALUE = 1;
24
-    private const MAX_VALUE = (2 ** 16) - 1;
25
-
26
-    private ?int $value = null;
27
-
28
-    /**
29
-     * @param mixed $value
30
-     *
31
-     * @throws InvalidArgumentException
32
-     */
33
-    public function __construct($value)
34
-    {
35
-        if ($value === null) {
36
-            return;
37
-        }
38
-
39
-        if (!is_int($value)) {
40
-            throw new InvalidArgumentException('URI component "port" must be an integer');
41
-        }
42
-
43
-        if (!($value >= self::MIN_VALUE && $value <= self::MAX_VALUE)) {
44
-            throw new InvalidArgumentException('Invalid URI component "port"');
45
-        }
46
-
47
-        $this->value = $value;
48
-    }
49
-
50
-    /**
51
-     * {@inheritdoc}
52
-     *
53
-     * @return int|null
54
-     */
55
-    public function getValue(): ?int
56
-    {
57
-        return $this->value;
58
-    }
23
+	private const MIN_VALUE = 1;
24
+	private const MAX_VALUE = (2 ** 16) - 1;
25
+
26
+	private ?int $value = null;
27
+
28
+	/**
29
+	 * @param mixed $value
30
+	 *
31
+	 * @throws InvalidArgumentException
32
+	 */
33
+	public function __construct($value)
34
+	{
35
+		if ($value === null) {
36
+			return;
37
+		}
38
+
39
+		if (!is_int($value)) {
40
+			throw new InvalidArgumentException('URI component "port" must be an integer');
41
+		}
42
+
43
+		if (!($value >= self::MIN_VALUE && $value <= self::MAX_VALUE)) {
44
+			throw new InvalidArgumentException('Invalid URI component "port"');
45
+		}
46
+
47
+		$this->value = $value;
48
+	}
49
+
50
+	/**
51
+	 * {@inheritdoc}
52
+	 *
53
+	 * @return int|null
54
+	 */
55
+	public function getValue(): ?int
56
+	{
57
+		return $this->value;
58
+	}
59 59
 }
Please login to merge, or discard this patch.
src/Uri/Component/Query.php 1 patch
Indentation   +34 added lines, -34 removed lines patch added patch discarded remove patch
@@ -22,43 +22,43 @@
 block discarded – undo
22 22
  */
23 23
 final class Query implements ComponentInterface
24 24
 {
25
-    // phpcs:ignore Generic.Files.LineLength
26
-    private const NORMALIZATION_REGEX = '/(?:%[0-9A-Fa-f]{2}|[\x21\x24\x26-\x3b\x3d\x3f-\x5a\x5f\x61-\x7a\x7e]+)|(.?)/u';
25
+	// phpcs:ignore Generic.Files.LineLength
26
+	private const NORMALIZATION_REGEX = '/(?:%[0-9A-Fa-f]{2}|[\x21\x24\x26-\x3b\x3d\x3f-\x5a\x5f\x61-\x7a\x7e]+)|(.?)/u';
27 27
 
28
-    private string $value = '';
28
+	private string $value = '';
29 29
 
30
-    /**
31
-     * @param mixed $value
32
-     *
33
-     * @throws InvalidArgumentException
34
-     */
35
-    public function __construct($value)
36
-    {
37
-        if ($value === '') {
38
-            return;
39
-        }
30
+	/**
31
+	 * @param mixed $value
32
+	 *
33
+	 * @throws InvalidArgumentException
34
+	 */
35
+	public function __construct($value)
36
+	{
37
+		if ($value === '') {
38
+			return;
39
+		}
40 40
 
41
-        if (!is_string($value)) {
42
-            throw new InvalidArgumentException('URI component "query" must be a string');
43
-        }
41
+		if (!is_string($value)) {
42
+			throw new InvalidArgumentException('URI component "query" must be a string');
43
+		}
44 44
 
45
-        $this->value = (string) preg_replace_callback(
46
-            self::NORMALIZATION_REGEX,
47
-            static fn(array $matches): string => (
48
-                /** @var array{0: string, 1?: string} $matches */
49
-                isset($matches[1]) ? rawurlencode($matches[1]) : $matches[0]
50
-            ),
51
-            $value,
52
-        );
53
-    }
45
+		$this->value = (string) preg_replace_callback(
46
+			self::NORMALIZATION_REGEX,
47
+			static fn(array $matches): string => (
48
+				/** @var array{0: string, 1?: string} $matches */
49
+				isset($matches[1]) ? rawurlencode($matches[1]) : $matches[0]
50
+			),
51
+			$value,
52
+		);
53
+	}
54 54
 
55
-    /**
56
-     * {@inheritdoc}
57
-     *
58
-     * @return string
59
-     */
60
-    public function getValue(): string
61
-    {
62
-        return $this->value;
63
-    }
55
+	/**
56
+	 * {@inheritdoc}
57
+	 *
58
+	 * @return string
59
+	 */
60
+	public function getValue(): string
61
+	{
62
+		return $this->value;
63
+	}
64 64
 }
Please login to merge, or discard this patch.