Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 74
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
HttpStatus
0.00% covered (danger)
0.00%
0 / 73
0.00% covered (danger)
0.00%
0 / 4
132
0.00% covered (danger)
0.00%
0 / 1
 registerHeadersSentCallback
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getMessage
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 1
2
 getHeader
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
30
 header
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2/**
3 * List of HTTP status codes.
4 *
5 * @license GPL-2.0-or-later
6 * @file
7 */
8
9namespace Wikimedia\Http;
10
11use InvalidArgumentException;
12
13/**
14 * @todo document
15 */
16class HttpStatus {
17
18    /**
19     * @var null|callable
20     */
21    private static $headersSentCallback = null;
22
23    public static function registerHeadersSentCallback( callable $callback ): ?callable {
24        $old = self::$headersSentCallback;
25        self::$headersSentCallback = $callback;
26
27        return $old;
28    }
29
30    /**
31     * Get the message associated with an HTTP response status code
32     *
33     * @param int $code Status code
34     * @return string|null Message, or null if $code is not known
35     */
36    public static function getMessage( $code ) {
37        static $statusMessage = [
38            100 => 'Continue',
39            101 => 'Switching Protocols',
40            102 => 'Processing',
41            200 => 'OK',
42            201 => 'Created',
43            202 => 'Accepted',
44            203 => 'Non-Authoritative Information',
45            204 => 'No Content',
46            205 => 'Reset Content',
47            206 => 'Partial Content',
48            207 => 'Multi-Status',
49            300 => 'Multiple Choices',
50            301 => 'Moved Permanently',
51            302 => 'Found',
52            303 => 'See Other',
53            304 => 'Not Modified',
54            305 => 'Use Proxy',
55            307 => 'Temporary Redirect',
56            400 => 'Bad Request',
57            401 => 'Unauthorized',
58            402 => 'Payment Required',
59            403 => 'Forbidden',
60            404 => 'Not Found',
61            405 => 'Method Not Allowed',
62            406 => 'Not Acceptable',
63            407 => 'Proxy Authentication Required',
64            408 => 'Request Timeout',
65            409 => 'Conflict',
66            410 => 'Gone',
67            411 => 'Length Required',
68            412 => 'Precondition Failed',
69            413 => 'Request Entity Too Large',
70            414 => 'Request-URI Too Large',
71            415 => 'Unsupported Media Type',
72            416 => 'Request Range Not Satisfiable',
73            417 => 'Expectation Failed',
74            422 => 'Unprocessable Entity',
75            423 => 'Locked',
76            424 => 'Failed Dependency',
77            428 => 'Precondition Required',
78            429 => 'Too Many Requests',
79            431 => 'Request Header Fields Too Large',
80            500 => 'Internal Server Error',
81            501 => 'Not Implemented',
82            502 => 'Bad Gateway',
83            503 => 'Service Unavailable',
84            504 => 'Gateway Timeout',
85            505 => 'HTTP Version Not Supported',
86            507 => 'Insufficient Storage',
87            511 => 'Network Authentication Required',
88        ];
89        return $statusMessage[$code] ?? null;
90    }
91
92    /**
93     * Construct an HTTP status code header
94     *
95     * @since 1.42
96     * @param int $code Status code
97     * @return string
98     */
99    public static function getHeader( $code ): string {
100        static $version = null;
101        $message = self::getMessage( $code );
102        if ( $message === null ) {
103            throw new InvalidArgumentException( "Unknown HTTP status code $code" );
104        }
105
106        if ( $version === null ) {
107            $version = isset( $_SERVER['SERVER_PROTOCOL'] ) &&
108            $_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.0' ?
109                '1.0' :
110                '1.1';
111        }
112
113        return "HTTP/$version $code $message";
114    }
115
116    /**
117     * Output an HTTP status code header
118     *
119     * @since 1.26
120     * @param int $code Status code
121     */
122    public static function header( $code ) {
123        if ( headers_sent() ) {
124            if ( self::$headersSentCallback ) {
125                ( self::$headersSentCallback )();
126                return;
127            }
128
129            // NOTE: If there is no custom callback, we continue normally and
130            //       rely on the implementation of header() to emit a warning.
131        }
132
133        try {
134            header( self::getHeader( $code ) );
135        } catch ( InvalidArgumentException ) {
136            trigger_error( "Unknown HTTP status code $code", E_USER_WARNING );
137        }
138    }
139
140}
141
142/** @deprecated class alias since 1.44 */
143class_alias( HttpStatus::class, 'HttpStatus' );