Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Header
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
4 / 4
4
100.00% covered (success)
100.00%
1 / 1
 getName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMultilines
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
1
 isMultiline
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php declare(strict_types=1);
2/*
3 * This file is part of Aplus Framework HTTP Library.
4 *
5 * (c) Natan Felles <natanfelles@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10namespace Framework\HTTP;
11
12/**
13 * Class Header.
14 *
15 * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
16 *
17 * @package http
18 */
19class Header
20{
21    // -------------------------------------------------------------------------
22    // General headers (Request and Response)
23    // -------------------------------------------------------------------------
24    /**
25     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
26     *
27     * @var string
28     */
29    public const CACHE_CONTROL = 'Cache-Control';
30    /**
31     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection
32     *
33     * @var string
34     */
35    public const CONNECTION = 'Connection';
36    /**
37     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
38     *
39     * @var string
40     */
41    public const CONTENT_DISPOSITION = 'Content-Disposition';
42    /**
43     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Date
44     *
45     * @var string
46     */
47    public const DATE = 'Date';
48    /**
49     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive
50     *
51     * @var string
52     */
53    public const KEEP_ALIVE = 'Keep-Alive';
54    /**
55     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Pragma
56     *
57     * @var string
58     */
59    public const PRAGMA = 'Pragma';
60    /**
61     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Via
62     *
63     * @var string
64     */
65    public const VIA = 'Via';
66    /**
67     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Warning
68     *
69     * @var string
70     */
71    public const WARNING = 'Warning';
72    // -------------------------------------------------------------------------
73    // Representation headers (Request and Response)
74    // -------------------------------------------------------------------------
75    /**
76     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding
77     *
78     * @var string
79     */
80    public const CONTENT_ENCODING = 'Content-Encoding';
81    /**
82     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language
83     *
84     * @var string
85     */
86    public const CONTENT_LANGUAGE = 'Content-Language';
87    /**
88     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Location
89     *
90     * @var string
91     */
92    public const CONTENT_LOCATION = 'Content-Location';
93    /**
94     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
95     *
96     * @var string
97     */
98    public const CONTENT_TYPE = 'Content-Type';
99    // -------------------------------------------------------------------------
100    // Payload headers (Request and Response)
101    // -------------------------------------------------------------------------
102    /**
103     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length
104     *
105     * @var string
106     */
107    public const CONTENT_LENGTH = 'Content-Length';
108    /**
109     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range
110     *
111     * @var string
112     */
113    public const CONTENT_RANGE = 'Content-Range';
114    /**
115     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Link
116     *
117     * @var string
118     */
119    public const LINK = 'Link';
120    /**
121     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer
122     *
123     * @var string
124     */
125    public const TRAILER = 'Trailer';
126    /**
127     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding
128     *
129     * @var string
130     */
131    public const TRANSFER_ENCODING = 'Transfer-Encoding';
132    /**
133     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade
134     *
135     * @var string
136     */
137    public const UPGRADE = 'Upgrade';
138    // -------------------------------------------------------------------------
139    // Custom
140    // -------------------------------------------------------------------------
141    /**
142     * @see https://riptutorial.com/http-headers/topic/10581/x-request-id
143     *
144     * @var string
145     */
146    public const X_REQUEST_ID = 'X-Request-ID';
147    /**
148     * Header names.
149     *
150     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
151     *
152     * @var array<string,string>
153     */
154    protected static array $headers = [
155        // ---------------------------------------------------------------------
156        // General headers (Request and Response)
157        // ---------------------------------------------------------------------
158        'cache-control' => 'Cache-Control',
159        'connection' => 'Connection',
160        'content-disposition' => 'Content-Disposition',
161        'date' => 'Date',
162        'keep-alive' => 'Keep-Alive',
163        'link' => 'Link',
164        'pragma' => 'Pragma',
165        'via' => 'Via',
166        'warning' => 'Warning',
167        // ---------------------------------------------------------------------
168        // Representation headers (Request and Response)
169        // ---------------------------------------------------------------------
170        'content-encoding' => 'Content-Encoding',
171        'content-language' => 'Content-Language',
172        'content-location' => 'Content-Location',
173        'content-type' => 'Content-Type',
174        // ---------------------------------------------------------------------
175        // Payload headers (Request and Response)
176        // ---------------------------------------------------------------------
177        'content-length' => 'Content-Length',
178        'content-range' => 'Content-Range',
179        'trailer' => 'Trailer',
180        'transfer-encoding' => 'Transfer-Encoding',
181        // ---------------------------------------------------------------------
182        // Request headers
183        // ---------------------------------------------------------------------
184        'accept' => 'Accept',
185        'accept-charset' => 'Accept-Charset',
186        'accept-encoding' => 'Accept-Encoding',
187        'accept-language' => 'Accept-Language',
188        'access-control-request-headers' => 'Access-Control-Request-Headers',
189        'access-control-request-method' => 'Access-Control-Request-Method',
190        'authorization' => 'Authorization',
191        'cookie' => 'Cookie',
192        'dnt' => 'DNT',
193        'expect' => 'Expect',
194        'forwarded' => 'Forwarded',
195        'from' => 'From',
196        'host' => 'Host',
197        'if-match' => 'If-Match',
198        'if-modified-since' => 'If-Modified-Since',
199        'if-none-match' => 'If-None-Match',
200        'if-range' => 'If-Range',
201        'if-unmodified-since' => 'If-Unmodified-Since',
202        'origin' => 'Origin',
203        'proxy-authorization' => 'Proxy-Authorization',
204        'range' => 'Range',
205        'referer' => 'Referer',
206        'sec-fetch-dest' => 'Sec-Fetch-Dest',
207        'sec-fetch-mode' => 'Sec-Fetch-Mode',
208        'sec-fetch-site' => 'Sec-Fetch-Site',
209        'sec-fetch-user' => 'Sec-Fetch-User',
210        'te' => 'TE',
211        'upgrade-insecure-requests' => 'Upgrade-Insecure-Requests',
212        'user-agent' => 'User-Agent',
213        'x-forwarded-for' => 'X-Forwarded-For',
214        'x-forwarded-host' => 'X-Forwarded-Host',
215        'x-forwarded-proto' => 'X-Forwarded-Proto',
216        'x-real-ip' => 'X-Real-IP',
217        'x-requested-with' => 'X-Requested-With',
218        // ---------------------------------------------------------------------
219        // Response headers
220        // ---------------------------------------------------------------------
221        'accept-ranges' => 'Accept-Ranges',
222        'access-control-allow-credentials' => 'Access-Control-Allow-Credentials',
223        'access-control-allow-headers' => 'Access-Control-Allow-Headers',
224        'access-control-allow-methods' => 'Access-Control-Allow-Methods',
225        'access-control-allow-origin' => 'Access-Control-Allow-Origin',
226        'access-control-expose-headers' => 'Access-Control-Expose-Headers',
227        'access-control-max-age' => 'Access-Control-Max-Age',
228        'age' => 'Age',
229        'allow' => 'Allow',
230        'clear-site-data' => 'Clear-Site-Data',
231        'content-security-policy' => 'Content-Security-Policy',
232        'content-security-policy-report-only' => 'Content-Security-Policy-Report-Only',
233        'etag' => 'ETag',
234        'expect-ct' => 'Expect-CT',
235        'expires' => 'Expires',
236        'feature-policy' => 'Feature-Policy',
237        'last-modified' => 'Last-Modified',
238        'location' => 'Location',
239        'proxy-authenticate' => 'Proxy-Authenticate',
240        'public-key-pins' => 'Public-Key-Pins',
241        'public-key-pins-report-only' => 'Public-Key-Pins-Report-Only',
242        'referrer-policy' => 'Referrer-Policy',
243        'retry-after' => 'Retry-After',
244        'server' => 'Server',
245        'set-cookie' => 'Set-Cookie',
246        'sourcemap' => 'SourceMap',
247        'strict-transport-security' => 'Strict-Transport-Security',
248        'timing-allow-origin' => 'Timing-Allow-Origin',
249        'tk' => 'Tk',
250        'vary' => 'Vary',
251        'www-authenticate' => 'WWW-Authenticate',
252        'x-content-type-options' => 'X-Content-Type-Options',
253        'x-dns-prefetch-control' => 'X-DNS-Prefetch-Control',
254        'x-frame-options' => 'X-Frame-Options',
255        'x-xss-protection' => 'X-XSS-Protection',
256        // ---------------------------------------------------------------------
257        // Custom (Response)
258        // ---------------------------------------------------------------------
259        'x-request-id' => 'X-Request-ID',
260        'x-powered-by' => 'X-Powered-By',
261        // ---------------------------------------------------------------------
262        // WebSocket
263        // ---------------------------------------------------------------------
264        'sec-websocket-extensions' => 'Sec-WebSocket-Extensions',
265        'sec-websocket-key' => 'Sec-WebSocket-Key',
266        'sec-websocket-protocol' => 'Sec-WebSocket-Protocol',
267        'sec-websocket-version' => 'Sec-WebSocket-Version',
268    ];
269
270    public static function getName(string $name) : string
271    {
272        return static::$headers[\strtolower($name)] ?? $name;
273    }
274
275    public static function setName(string $name) : void
276    {
277        static::$headers[\strtolower($name)] = $name;
278    }
279
280    /**
281     * @return array<string>
282     */
283    public static function getMultilines() : array
284    {
285        return [
286            'date',
287            'expires',
288            'if-modified-since',
289            'if-range',
290            'if-unmodified-since',
291            'last-modified',
292            'proxy-authenticate',
293            'retry-after',
294            'set-cookie',
295            'www-authenticate',
296        ];
297    }
298
299    public static function isMultiline(string $name) : bool
300    {
301        return \in_array(\strtolower($name), static::getMultilines(), true);
302    }
303}