Skip to content

Commit 4a5cb90

Browse files
authored
Merge pull request #8186 from kenjis/fix-HTTP-verb-cases
fix: remove deprecated upper functionality in `Request::getMethod()`
2 parents 8b72997 + fe6babf commit 4a5cb90

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+439
-241
lines changed

app/Config/Filters.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class Filters extends BaseConfig
5050
* particular HTTP method (GET, POST, etc.).
5151
*
5252
* Example:
53-
* 'post' => ['foo', 'bar']
53+
* 'POST' => ['foo', 'bar']
5454
*
5555
* If you use this, you should disable auto-routing because auto-routing
5656
* permits any HTTP method to access a controller. Accessing the controller

app/Views/errors/html/error_exception.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@
205205
</tr>
206206
<tr>
207207
<td>HTTP Method</td>
208-
<td><?= esc(strtoupper($request->getMethod())) ?></td>
208+
<td><?= esc($request->getMethod()) ?></td>
209209
</tr>
210210
<tr>
211211
<td>IP Address</td>

phpstan-baseline.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,11 +1926,6 @@
19261926
'count' => 2,
19271927
'path' => __DIR__ . '/system/Filters/Filters.php',
19281928
];
1929-
$ignoreErrors[] = [
1930-
'message' => '#^Expression on left side of \\?\\? is not nullable\\.$#',
1931-
'count' => 1,
1932-
'path' => __DIR__ . '/system/Filters/Filters.php',
1933-
];
19341929
$ignoreErrors[] = [
19351930
'message' => '#^Only booleans are allowed in a negated boolean, array given\\.$#',
19361931
'count' => 1,

system/CodeIgniter.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use CodeIgniter\HTTP\DownloadResponse;
2222
use CodeIgniter\HTTP\Exceptions\RedirectException;
2323
use CodeIgniter\HTTP\IncomingRequest;
24+
use CodeIgniter\HTTP\Method;
2425
use CodeIgniter\HTTP\RedirectResponse;
2526
use CodeIgniter\HTTP\Request;
2627
use CodeIgniter\HTTP\ResponsableInterface;
@@ -1027,7 +1028,7 @@ public function storePreviousURL($uri)
10271028
public function spoofRequestMethod()
10281029
{
10291030
// Only works with POSTED forms
1030-
if (strtolower($this->request->getMethod()) !== 'post') {
1031+
if ($this->request->getMethod() !== Method::POST) {
10311032
return;
10321033
}
10331034

@@ -1038,7 +1039,7 @@ public function spoofRequestMethod()
10381039
}
10391040

10401041
// Only allows PUT, PATCH, DELETE
1041-
if (in_array(strtoupper($method), ['PUT', 'PATCH', 'DELETE'], true)) {
1042+
if (in_array($method, [Method::PUT, Method::PATCH, Method::DELETE], true)) {
10421043
$this->request = $this->request->setMethod($method);
10431044
}
10441045
}

system/Debug/Exceptions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public function exceptionHandler(Throwable $exception)
128128

129129
if ($this->config->log === true && ! in_array($statusCode, $this->config->ignoreCodes, true)) {
130130
$uri = $this->request->getPath() === '' ? '/' : $this->request->getPath();
131-
$routeInfo = '[Method: ' . strtoupper($this->request->getMethod()) . ', Route: ' . $uri . ']';
131+
$routeInfo = '[Method: ' . $this->request->getMethod() . ', Route: ' . $uri . ']';
132132

133133
log_message('critical', "{message}\n{routeInfo}\nin {exFile} on line {exLine}.\n{trace}", [
134134
'message' => $exception->getMessage(),

system/Debug/Toolbar.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public function run(float $startTime, float $totalTime, RequestInterface $reques
7979
$data = [];
8080
// Data items used within the view.
8181
$data['url'] = current_url();
82-
$data['method'] = strtoupper($request->getMethod());
82+
$data['method'] = $request->getMethod();
8383
$data['isAJAX'] = $request->isAJAX();
8484
$data['startTime'] = $startTime;
8585
$data['totalTime'] = $totalTime * 1000;

system/Filters/Filters.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -494,10 +494,28 @@ protected function processMethods()
494494
return;
495495
}
496496

497-
// Request method won't be set for CLI-based requests
498-
$method = strtolower($this->request->getMethod()) ?? 'cli';
497+
$method = $this->request->getMethod();
498+
499+
$found = false;
499500

500501
if (array_key_exists($method, $this->config->methods)) {
502+
$found = true;
503+
}
504+
// Checks lowercase HTTP method for backward compatibility.
505+
// @deprecated 4.5.0
506+
// @TODO remove this in the future.
507+
elseif (array_key_exists(strtolower($method), $this->config->methods)) {
508+
@trigger_error(
509+
'Setting lowercase HTTP method key "' . strtolower($method) . '" is deprecated.'
510+
. ' Use uppercase HTTP method like "' . strtoupper($method) . '".',
511+
E_USER_DEPRECATED
512+
);
513+
514+
$found = true;
515+
$method = strtolower($method);
516+
}
517+
518+
if ($found) {
501519
if (config(Feature::class)->oldFilterOrder) {
502520
$this->filters['before'] = array_merge($this->filters['before'], $this->config->methods[$method]);
503521
} else {

system/HTTP/CLIRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class CLIRequest extends Request
5656
*
5757
* @var string
5858
*/
59-
protected $method = 'cli';
59+
protected $method = 'CLI';
6060

6161
/**
6262
* Constructor

system/HTTP/CURLRequest.php

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public function __construct(App $config, URI $uri, ?ResponseInterface $response
112112
throw HTTPException::forMissingCurl(); // @codeCoverageIgnore
113113
}
114114

115-
parent::__construct('GET', $uri);
115+
parent::__construct(Method::GET, $uri);
116116

117117
$this->responseOrig = $response ?? new Response(config(App::class));
118118
$this->baseURI = $uri->useRawQueryString();
@@ -130,7 +130,7 @@ public function __construct(App $config, URI $uri, ?ResponseInterface $response
130130
* Sends an HTTP request to the specified $url. If this is a relative
131131
* URL, it will be merged with $this->baseURI to form a complete URL.
132132
*
133-
* @param string $method
133+
* @param string $method HTTP method
134134
*/
135135
public function request($method, string $url, array $options = []): ResponseInterface
136136
{
@@ -177,55 +177,55 @@ protected function resetOptions()
177177
*/
178178
public function get(string $url, array $options = []): ResponseInterface
179179
{
180-
return $this->request('get', $url, $options);
180+
return $this->request(Method::GET, $url, $options);
181181
}
182182

183183
/**
184184
* Convenience method for sending a DELETE request.
185185
*/
186186
public function delete(string $url, array $options = []): ResponseInterface
187187
{
188-
return $this->request('delete', $url, $options);
188+
return $this->request('DELETE', $url, $options);
189189
}
190190

191191
/**
192192
* Convenience method for sending a HEAD request.
193193
*/
194194
public function head(string $url, array $options = []): ResponseInterface
195195
{
196-
return $this->request('head', $url, $options);
196+
return $this->request('HEAD', $url, $options);
197197
}
198198

199199
/**
200200
* Convenience method for sending an OPTIONS request.
201201
*/
202202
public function options(string $url, array $options = []): ResponseInterface
203203
{
204-
return $this->request('options', $url, $options);
204+
return $this->request('OPTIONS', $url, $options);
205205
}
206206

207207
/**
208208
* Convenience method for sending a PATCH request.
209209
*/
210210
public function patch(string $url, array $options = []): ResponseInterface
211211
{
212-
return $this->request('patch', $url, $options);
212+
return $this->request('PATCH', $url, $options);
213213
}
214214

215215
/**
216216
* Convenience method for sending a POST request.
217217
*/
218218
public function post(string $url, array $options = []): ResponseInterface
219219
{
220-
return $this->request('post', $url, $options);
220+
return $this->request(Method::POST, $url, $options);
221221
}
222222

223223
/**
224224
* Convenience method for sending a PUT request.
225225
*/
226226
public function put(string $url, array $options = []): ResponseInterface
227227
{
228-
return $this->request('put', $url, $options);
228+
return $this->request(Method::PUT, $url, $options);
229229
}
230230

231231
/**
@@ -339,17 +339,6 @@ protected function prepareURL(string $url): string
339339
);
340340
}
341341

342-
/**
343-
* Get the request method. Overrides the Request class' method
344-
* since users expect a different answer here.
345-
*
346-
* @param bool|false $upper Whether to return in upper or lower case.
347-
*/
348-
public function getMethod(bool $upper = false): string
349-
{
350-
return ($upper) ? strtoupper($this->method) : strtolower($this->method);
351-
}
352-
353342
/**
354343
* Fires the actual cURL request.
355344
*
@@ -446,8 +435,6 @@ protected function applyRequestHeaders(array $curlOptions = []): array
446435
*/
447436
protected function applyMethod(string $method, array $curlOptions): array
448437
{
449-
$method = strtoupper($method);
450-
451438
$this->method = $method;
452439
$curlOptions[CURLOPT_CUSTOMREQUEST] = $method;
453440

@@ -458,7 +445,7 @@ protected function applyMethod(string $method, array $curlOptions): array
458445
return $this->applyBody($curlOptions);
459446
}
460447

461-
if ($method === 'PUT' || $method === 'POST') {
448+
if ($method === Method::PUT || $method === Method::POST) {
462449
// See http://tools.ietf.org/html/rfc7230#section-3.3.2
463450
if ($this->header('content-length') === null && ! isset($this->config['multipart'])) {
464451
$this->setHeader('Content-Length', '0');

system/HTTP/IncomingRequest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,17 +396,18 @@ public function negotiate(string $type, array $supported, bool $strictMatch = fa
396396
/**
397397
* Checks this request type.
398398
*
399-
* @param string $type HTTP verb or 'json' or 'ajax'
399+
* @param string $type HTTP verb or 'json' or 'ajax'.
400+
* HTTP verb should be case-sensitive, but this is case-insensitive.
400401
* @phpstan-param string|'get'|'post'|'put'|'delete'|'head'|'patch'|'options'|'json'|'ajax' $type
401402
*/
402403
public function is(string $type): bool
403404
{
404405
$valueUpper = strtoupper($type);
405406

406-
$httpMethods = ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH', 'OPTIONS'];
407+
$httpMethods = Method::all();
407408

408409
if (in_array($valueUpper, $httpMethods, true)) {
409-
return strtoupper($this->getMethod()) === $valueUpper;
410+
return $this->getMethod() === $valueUpper;
410411
}
411412

412413
if ($valueUpper === 'JSON') {

system/HTTP/Method.php

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
* HTTP Method List
16+
*/
17+
class Method
18+
{
19+
/**
20+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT
21+
*/
22+
public const CONNECT = 'CONNECT';
23+
24+
/**
25+
* Idempotent
26+
*
27+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE
28+
*/
29+
public const DELETE = 'DELETE';
30+
31+
/**
32+
* Safe, Idempotent, Cacheable
33+
*
34+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET
35+
*/
36+
public const GET = 'GET';
37+
38+
/**
39+
* Safe, Idempotent, Cacheable
40+
*
41+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD
42+
*/
43+
public const HEAD = 'HEAD';
44+
45+
/**
46+
* Safe, Idempotent
47+
*
48+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
49+
*/
50+
public const OPTIONS = 'OPTIONS';
51+
52+
/**
53+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PATCH
54+
*/
55+
public const PATCH = 'PATCH';
56+
57+
/**
58+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST
59+
*/
60+
public const POST = 'POST';
61+
62+
/**
63+
* Idempotent
64+
*
65+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT
66+
*/
67+
public const PUT = 'PUT';
68+
69+
/**
70+
* Safe, Idempotent
71+
*
72+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/TRACE
73+
*/
74+
public const TRACE = 'TRACE';
75+
76+
/**
77+
* Returns all HTTP methods.
78+
*
79+
* @return list<string>
80+
*/
81+
public static function all(): array
82+
{
83+
return [
84+
self::CONNECT,
85+
self::DELETE,
86+
self::GET,
87+
self::HEAD,
88+
self::OPTIONS,
89+
self::PATCH,
90+
self::POST,
91+
self::PUT,
92+
self::TRACE,
93+
];
94+
}
95+
}

system/HTTP/OutgoingRequest.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,13 @@ private function getHostFromUri(URI $uri): string
6666
}
6767

6868
/**
69-
* Get the request method.
69+
* Retrieves the HTTP method of the request.
7070
*
71-
* @param bool $upper Whether to return in upper or lower case.
72-
*
73-
* @deprecated The $upper functionality will be removed and this will revert to its PSR-7 equivalent
71+
* @return string Returns the request method (always uppercase)
7472
*/
75-
public function getMethod(bool $upper = false): string
73+
public function getMethod(): string
7674
{
77-
return ($upper) ? strtoupper($this->method) : strtolower($this->method);
75+
return $this->method;
7876
}
7977

8078
/**

system/HTTP/OutgoingRequestInterface.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,11 @@
2121
interface OutgoingRequestInterface extends MessageInterface
2222
{
2323
/**
24-
* Get the request method.
25-
* An extension of PSR-7's getMethod to allow casing.
24+
* Retrieves the HTTP method of the request.
2625
*
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
26+
* @return string Returns the request method.
3027
*/
31-
public function getMethod(bool $upper = false): string;
28+
public function getMethod(): string;
3229

3330
/**
3431
* Return an instance with the provided HTTP method.

0 commit comments

Comments
 (0)