mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
# Conflicts: # system/Autoloader/Autoloader.php # system/BaseModel.php # system/CLI/CLI.php # system/Database/MigrationRunner.php # system/Exceptions/PageNotFoundException.php # system/Router/RouteCollection.php # system/Validation/FileRules.php # tests/system/Autoloader/AutoloaderTest.php # tests/system/Filters/FiltersTest.php # tests/system/Test/ControllerTestTraitTest.php # tests/system/Test/FeatureTestTraitTest.php # tests/system/Validation/CreditCardRulesTest.php # tests/system/Validation/FileRulesTest.php # tests/system/Validation/StrictRules/DatabaseRelatedRulesTest.php # tests/system/Validation/StrictRules/FileRulesTest.php # tests/system/View/ViewTest.php
230 lines
7.7 KiB
PHP
230 lines
7.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* This file is part of CodeIgniter 4 framework.
|
|
*
|
|
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace CodeIgniter\HTTP;
|
|
|
|
use CodeIgniter\Cookie\Cookie;
|
|
use CodeIgniter\Cookie\CookieStore;
|
|
use CodeIgniter\HTTP\Exceptions\HTTPException;
|
|
use Config\App;
|
|
use Config\Cookie as CookieConfig;
|
|
|
|
/**
|
|
* Representation of an outgoing, server-side response.
|
|
*
|
|
* Per the HTTP specification, this interface includes properties for
|
|
* each of the following:
|
|
*
|
|
* - Protocol version
|
|
* - Status code and reason phrase
|
|
* - Headers
|
|
* - Message body
|
|
*
|
|
* @see \CodeIgniter\HTTP\ResponseTest
|
|
*/
|
|
class Response extends Message implements ResponseInterface
|
|
{
|
|
use ResponseTrait;
|
|
|
|
/**
|
|
* HTTP status codes
|
|
*
|
|
* @var array
|
|
*/
|
|
protected static $statusCodes = [
|
|
// 1xx: Informational
|
|
100 => 'Continue',
|
|
101 => 'Switching Protocols',
|
|
102 => 'Processing', // http://www.iana.org/go/rfc2518
|
|
103 => 'Early Hints', // http://www.ietf.org/rfc/rfc8297.txt
|
|
// 2xx: Success
|
|
200 => 'OK',
|
|
201 => 'Created',
|
|
202 => 'Accepted',
|
|
203 => 'Non-Authoritative Information', // 1.1
|
|
204 => 'No Content',
|
|
205 => 'Reset Content',
|
|
206 => 'Partial Content',
|
|
207 => 'Multi-Status', // http://www.iana.org/go/rfc4918
|
|
208 => 'Already Reported', // http://www.iana.org/go/rfc5842
|
|
226 => 'IM Used', // 1.1; http://www.ietf.org/rfc/rfc3229.txt
|
|
// 3xx: Redirection
|
|
300 => 'Multiple Choices',
|
|
301 => 'Moved Permanently',
|
|
302 => 'Found', // Formerly 'Moved Temporarily'
|
|
303 => 'See Other', // 1.1
|
|
304 => 'Not Modified',
|
|
305 => 'Use Proxy', // 1.1
|
|
306 => 'Switch Proxy', // No longer used
|
|
307 => 'Temporary Redirect', // 1.1
|
|
308 => 'Permanent Redirect', // 1.1; Experimental; http://www.ietf.org/rfc/rfc7238.txt
|
|
// 4xx: Client error
|
|
400 => 'Bad Request',
|
|
401 => 'Unauthorized',
|
|
402 => 'Payment Required',
|
|
403 => 'Forbidden',
|
|
404 => 'Not Found',
|
|
405 => 'Method Not Allowed',
|
|
406 => 'Not Acceptable',
|
|
407 => 'Proxy Authentication Required',
|
|
408 => 'Request Timeout',
|
|
409 => 'Conflict',
|
|
410 => 'Gone',
|
|
411 => 'Length Required',
|
|
412 => 'Precondition Failed',
|
|
413 => 'Content Too Large', // https://www.iana.org/assignments/http-status-codes/http-status-codes.xml
|
|
414 => 'URI Too Long', // https://www.iana.org/assignments/http-status-codes/http-status-codes.xml
|
|
415 => 'Unsupported Media Type',
|
|
416 => 'Requested Range Not Satisfiable',
|
|
417 => 'Expectation Failed',
|
|
418 => "I'm a teapot", // April's Fools joke; http://www.ietf.org/rfc/rfc2324.txt
|
|
// 419 (Authentication Timeout) is a non-standard status code with unknown origin
|
|
421 => 'Misdirected Request', // http://www.iana.org/go/rfc7540 Section 9.1.2
|
|
422 => 'Unprocessable Content', // https://www.iana.org/assignments/http-status-codes/http-status-codes.xml
|
|
423 => 'Locked', // http://www.iana.org/go/rfc4918
|
|
424 => 'Failed Dependency', // http://www.iana.org/go/rfc4918
|
|
425 => 'Too Early', // https://datatracker.ietf.org/doc/draft-ietf-httpbis-replay/
|
|
426 => 'Upgrade Required',
|
|
428 => 'Precondition Required', // 1.1; http://www.ietf.org/rfc/rfc6585.txt
|
|
429 => 'Too Many Requests', // 1.1; http://www.ietf.org/rfc/rfc6585.txt
|
|
431 => 'Request Header Fields Too Large', // 1.1; http://www.ietf.org/rfc/rfc6585.txt
|
|
451 => 'Unavailable For Legal Reasons', // http://tools.ietf.org/html/rfc7725
|
|
499 => 'Client Closed Request', // http://lxr.nginx.org/source/src/http/ngx_http_request.h#0133
|
|
// 5xx: Server error
|
|
500 => 'Internal Server Error',
|
|
501 => 'Not Implemented',
|
|
502 => 'Bad Gateway',
|
|
503 => 'Service Unavailable',
|
|
504 => 'Gateway Timeout',
|
|
505 => 'HTTP Version Not Supported',
|
|
506 => 'Variant Also Negotiates', // 1.1; http://www.ietf.org/rfc/rfc2295.txt
|
|
507 => 'Insufficient Storage', // http://www.iana.org/go/rfc4918
|
|
508 => 'Loop Detected', // http://www.iana.org/go/rfc5842
|
|
510 => 'Not Extended', // http://www.ietf.org/rfc/rfc2774.txt
|
|
511 => 'Network Authentication Required', // http://www.ietf.org/rfc/rfc6585.txt
|
|
599 => 'Network Connect Timeout Error', // https://httpstatuses.com/599
|
|
];
|
|
|
|
/**
|
|
* The current reason phrase for this response.
|
|
* If empty string, will use the default provided for the status code.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $reason = '';
|
|
|
|
/**
|
|
* The current status code for this response.
|
|
* The status code is a 3-digit integer result code of the server's attempt
|
|
* to understand and satisfy the request.
|
|
*
|
|
* @var int
|
|
*/
|
|
protected $statusCode = 200;
|
|
|
|
/**
|
|
* If true, will not write output. Useful during testing.
|
|
*
|
|
* @var bool
|
|
*
|
|
* @internal Used for framework testing, should not be relied on otherwise
|
|
*/
|
|
protected $pretend = false;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param App $config
|
|
*
|
|
* @todo Recommend removing reliance on config injection
|
|
*
|
|
* @deprecated 4.5.0 The param $config is no longer used.
|
|
*/
|
|
public function __construct($config) // @phpstan-ignore-line
|
|
{
|
|
// Default to a non-caching page.
|
|
// Also ensures that a Cache-control header exists.
|
|
$this->noCache();
|
|
|
|
// We need CSP object even if not enabled to avoid calls to non existing methods
|
|
$this->CSP = service('csp');
|
|
|
|
$this->cookieStore = new CookieStore([]);
|
|
|
|
$cookie = config(CookieConfig::class);
|
|
|
|
Cookie::setDefaults($cookie);
|
|
|
|
// Default to an HTML Content-Type. Devs can override if needed.
|
|
$this->setContentType('text/html');
|
|
}
|
|
|
|
/**
|
|
* Turns "pretend" mode on or off to aid in testing.
|
|
*
|
|
* Note that this is not a part of the interface so
|
|
* should not be relied on outside of internal testing.
|
|
*
|
|
* @return $this
|
|
*
|
|
* @internal For testing purposes only.
|
|
* @testTag only available to test code
|
|
*/
|
|
public function pretend(bool $pretend = true)
|
|
{
|
|
$this->pretend = $pretend;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Gets the response status code.
|
|
*
|
|
* The status code is a 3-digit integer result code of the server's attempt
|
|
* to understand and satisfy the request.
|
|
*
|
|
* @return int Status code.
|
|
*/
|
|
public function getStatusCode(): int
|
|
{
|
|
if (empty($this->statusCode)) {
|
|
throw HTTPException::forMissingResponseStatus();
|
|
}
|
|
|
|
return $this->statusCode;
|
|
}
|
|
|
|
/**
|
|
* Gets the response reason phrase associated with the status code.
|
|
*
|
|
* Because a reason phrase is not a required element in a response
|
|
* status line, the reason phrase value MAY be null. Implementations MAY
|
|
* choose to return the default RFC 7231 recommended reason phrase (or those
|
|
* listed in the IANA HTTP Status Code Registry) for the response's
|
|
* status code.
|
|
*
|
|
* @see http://tools.ietf.org/html/rfc7231#section-6
|
|
* @see http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
|
*
|
|
* @return string Reason phrase; must return an empty string if none present.
|
|
*/
|
|
public function getReasonPhrase()
|
|
{
|
|
if ($this->reason === '') {
|
|
return ! empty($this->statusCode) ? static::$statusCodes[$this->statusCode] : '';
|
|
}
|
|
|
|
return $this->reason;
|
|
}
|
|
}
|