Skip to content

Commit 949b622

Browse files
authored
Merge pull request #6698 from kenjis/add-OutgoingRequestInterface
feat: add OutgoingRequestInterface
2 parents 1abb1f4 + 583689c commit 949b622

File tree

10 files changed

+400
-40
lines changed

10 files changed

+400
-40
lines changed

app/Controllers/BaseController.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
namespace App\Controllers;
44

55
use CodeIgniter\Controller;
6-
use CodeIgniter\HTTP\CLIRequest;
7-
use CodeIgniter\HTTP\IncomingRequest;
86
use CodeIgniter\HTTP\RequestInterface;
97
use CodeIgniter\HTTP\ResponseInterface;
108
use Psr\Log\LoggerInterface;
@@ -24,7 +22,7 @@ abstract class BaseController extends Controller
2422
/**
2523
* Instance of the main Request object.
2624
*
27-
* @var CLIRequest|IncomingRequest
25+
* @var RequestInterface
2826
*/
2927
protected $request;
3028

phpstan-baseline.neon.dist

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,6 @@ parameters:
270270
count: 1
271271
path: system/HTTP/Request.php
272272

273-
-
274-
message: "#^Property CodeIgniter\\\\HTTP\\\\Request\\:\\:\\$uri \\(CodeIgniter\\\\HTTP\\\\URI\\) in empty\\(\\) is not falsy\\.$#"
275-
count: 1
276-
path: system/HTTP/Request.php
277-
278273
-
279274
message: "#^Property CodeIgniter\\\\HTTP\\\\URI\\:\\:\\$fragment \\(string\\) on left side of \\?\\? is not nullable\\.$#"
280275
count: 1
@@ -459,3 +454,8 @@ parameters:
459454
message: "#^Property Config\\\\View\\:\\:\\$plugins \\(array\\) on left side of \\?\\? is not nullable\\.$#"
460455
count: 1
461456
path: system/View/Parser.php
457+
458+
-
459+
message: "#^Constructor of class CodeIgniter\\\\HTTP\\\\CURLRequest has an unused parameter \\$config\\.$#"
460+
count: 1
461+
path: system/HTTP/CURLRequest.php

system/HTTP/CURLRequest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
/**
2020
* A lightweight HTTP client for sending synchronous HTTP requests via cURL.
2121
*/
22-
class CURLRequest extends Request
22+
class CURLRequest extends OutgoingRequest
2323
{
2424
/**
2525
* The response object associated with this request
@@ -103,7 +103,7 @@ public function __construct(App $config, URI $uri, ?ResponseInterface $response
103103
throw HTTPException::forMissingCurl(); // @codeCoverageIgnore
104104
}
105105

106-
parent::__construct($config);
106+
parent::__construct('GET', $uri);
107107

108108
$this->response = $response;
109109
$this->baseURI = $uri->useRawQueryString();

system/HTTP/Message.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public function getBody()
6161
*
6262
* @deprecated Use Message::headers() to make room for PSR-7
6363
*
64+
* @TODO Incompatible return value with PSR-7
65+
*
6466
* @codeCoverageIgnore
6567
*/
6668
public function getHeaders(): array
@@ -76,6 +78,8 @@ public function getHeaders(): array
7678
*
7779
* @deprecated Use Message::header() to make room for PSR-7
7880
*
81+
* @TODO Incompatible return value with PSR-7
82+
*
7983
* @codeCoverageIgnore
8084
*/
8185
public function getHeader(string $name)

system/HTTP/OutgoingRequest.php

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CodeIgniter 4 framework.
5+
*
6+
* (c) CodeIgniter Foundation <[email protected]>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace CodeIgniter\HTTP;
13+
14+
/**
15+
* Representation of an outgoing, client-side request.
16+
*/
17+
class OutgoingRequest extends Message implements OutgoingRequestInterface
18+
{
19+
/**
20+
* Request method.
21+
*
22+
* @var string
23+
*/
24+
protected $method;
25+
26+
/**
27+
* A URI instance.
28+
*
29+
* @var URI|null
30+
*/
31+
protected $uri;
32+
33+
/**
34+
* @param string $method HTTP method
35+
* @param string|null $body
36+
*/
37+
public function __construct(
38+
string $method,
39+
?URI $uri = null,
40+
array $headers = [],
41+
$body = null,
42+
string $version = '1.1'
43+
) {
44+
$this->method = $method;
45+
$this->uri = $uri;
46+
47+
foreach ($headers as $header => $value) {
48+
$this->setHeader($header, $value);
49+
}
50+
51+
$this->body = $body;
52+
$this->protocolVersion = $version;
53+
54+
if (! $this->hasHeader('Host') && $this->uri->getHost() !== '') {
55+
$this->setHeader('Host', $this->getHostFromUri($this->uri));
56+
}
57+
}
58+
59+
private function getHostFromUri(URI $uri): string
60+
{
61+
$host = $uri->getHost();
62+
63+
return $host . ($uri->getPort() ? ':' . $uri->getPort() : '');
64+
}
65+
66+
/**
67+
* Get the request method.
68+
*
69+
* @param bool $upper Whether to return in upper or lower case.
70+
*
71+
* @deprecated The $upper functionality will be removed and this will revert to its PSR-7 equivalent
72+
*/
73+
public function getMethod(bool $upper = false): string
74+
{
75+
return ($upper) ? strtoupper($this->method) : strtolower($this->method);
76+
}
77+
78+
/**
79+
* Sets the request method. Used when spoofing the request.
80+
*
81+
* @return $this
82+
*
83+
* @deprecated Use withMethod() instead for immutability
84+
*/
85+
public function setMethod(string $method)
86+
{
87+
$this->method = $method;
88+
89+
return $this;
90+
}
91+
92+
/**
93+
* Returns an instance with the specified method.
94+
*
95+
* @param string $method
96+
*
97+
* @return static
98+
*/
99+
public function withMethod($method)
100+
{
101+
$request = clone $this;
102+
$request->method = $method;
103+
104+
return $request;
105+
}
106+
107+
/**
108+
* Retrieves the URI instance.
109+
*
110+
* @return URI|null
111+
*/
112+
public function getUri()
113+
{
114+
return $this->uri;
115+
}
116+
117+
/**
118+
* Returns an instance with the provided URI.
119+
*
120+
* @param URI $uri New request URI to use.
121+
* @param bool $preserveHost Preserve the original state of the Host header.
122+
*
123+
* @return static
124+
*/
125+
public function withUri(URI $uri, $preserveHost = false)
126+
{
127+
$request = clone $this;
128+
$request->uri = $uri;
129+
130+
if ($preserveHost) {
131+
if ($this->isHostHeaderMissingOrEmpty() && $uri->getHost() !== '') {
132+
$request->setHeader('Host', $this->getHostFromUri($uri));
133+
134+
return $request;
135+
}
136+
137+
if ($this->isHostHeaderMissingOrEmpty() && $uri->getHost() === '') {
138+
return $request;
139+
}
140+
141+
if (! $this->isHostHeaderMissingOrEmpty()) {
142+
return $request;
143+
}
144+
}
145+
146+
if ($uri->getHost() !== '') {
147+
$request->setHeader('Host', $this->getHostFromUri($uri));
148+
}
149+
150+
return $request;
151+
}
152+
153+
private function isHostHeaderMissingOrEmpty(): bool
154+
{
155+
if (! $this->hasHeader('Host')) {
156+
return true;
157+
}
158+
159+
return $this->header('Host')->getValue() === '';
160+
}
161+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CodeIgniter 4 framework.
5+
*
6+
* (c) CodeIgniter Foundation <[email protected]>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace CodeIgniter\HTTP;
13+
14+
use InvalidArgumentException;
15+
16+
/**
17+
* Representation of an outgoing, client-side request.
18+
*
19+
* Corresponds to Psr7\RequestInterface.
20+
*/
21+
interface OutgoingRequestInterface extends MessageInterface
22+
{
23+
/**
24+
* Get the request method.
25+
* An extension of PSR-7's getMethod to allow casing.
26+
*
27+
* @param bool $upper Whether to return in upper or lower case.
28+
*
29+
* @deprecated The $upper functionality will be removed and this will revert to its PSR-7 equivalent
30+
*/
31+
public function getMethod(bool $upper = false): string;
32+
33+
/**
34+
* Return an instance with the provided HTTP method.
35+
*
36+
* While HTTP method names are typically all uppercase characters, HTTP
37+
* method names are case-sensitive and thus implementations SHOULD NOT
38+
* modify the given string.
39+
*
40+
* This method MUST be implemented in such a way as to retain the
41+
* immutability of the message, and MUST return an instance that has the
42+
* changed request method.
43+
*
44+
* @param string $method Case-sensitive method.
45+
*
46+
* @return static
47+
*
48+
* @throws InvalidArgumentException for invalid HTTP methods.
49+
*/
50+
public function withMethod($method);
51+
52+
/**
53+
* Retrieves the URI instance.
54+
*
55+
* @see http://tools.ietf.org/html/rfc3986#section-4.3
56+
*
57+
* @return URI
58+
*/
59+
public function getUri();
60+
61+
/**
62+
* Returns an instance with the provided URI.
63+
*
64+
* This method MUST update the Host header of the returned request by
65+
* default if the URI contains a host component. If the URI does not
66+
* contain a host component, any pre-existing Host header MUST be carried
67+
* over to the returned request.
68+
*
69+
* You can opt-in to preserving the original state of the Host header by
70+
* setting `$preserveHost` to `true`. When `$preserveHost` is set to
71+
* `true`, this method interacts with the Host header in the following ways:
72+
*
73+
* - If the Host header is missing or empty, and the new URI contains
74+
* a host component, this method MUST update the Host header in the returned
75+
* request.
76+
* - If the Host header is missing or empty, and the new URI does not contain a
77+
* host component, this method MUST NOT update the Host header in the returned
78+
* request.
79+
* - If a Host header is present and non-empty, this method MUST NOT update
80+
* the Host header in the returned request.
81+
*
82+
* This method MUST be implemented in such a way as to retain the
83+
* immutability of the message, and MUST return an instance that has the
84+
* new UriInterface instance.
85+
*
86+
* @see http://tools.ietf.org/html/rfc3986#section-4.3
87+
*
88+
* @param URI $uri New request URI to use.
89+
* @param bool $preserveHost Preserve the original state of the Host header.
90+
*
91+
* @return static
92+
*/
93+
public function withUri(URI $uri, $preserveHost = false);
94+
}

system/HTTP/Request.php

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
namespace CodeIgniter\HTTP;
1313

1414
use CodeIgniter\Validation\FormatRules;
15+
use Config\App;
1516

1617
/**
17-
* Representation of an HTTP request.
18+
* Representation of an incoming, server-side HTTP request.
1819
*/
19-
class Request extends Message implements RequestInterface
20+
class Request extends OutgoingRequest implements RequestInterface
2021
{
2122
use RequestTrait;
2223

@@ -29,24 +30,10 @@ class Request extends Message implements RequestInterface
2930
*/
3031
protected $proxyIPs;
3132

32-
/**
33-
* Request method.
34-
*
35-
* @var string
36-
*/
37-
protected $method;
38-
39-
/**
40-
* A URI instance.
41-
*
42-
* @var URI
43-
*/
44-
protected $uri;
45-
4633
/**
4734
* Constructor.
4835
*
49-
* @param object $config
36+
* @param App $config
5037
*
5138
* @deprecated The $config is no longer needed and will be removed in a future version
5239
*/

0 commit comments

Comments
 (0)