Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
Status
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
3 / 3
7
100.00% covered (success)
100.00%
1 / 1
 getReason
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 setStatus
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 validate
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
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
12use InvalidArgumentException;
13use LogicException;
14
15/**
16 * Class Status.
17 *
18 * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
19 *
20 * @package http
21 */
22class Status
23{
24    // -------------------------------------------------------------------------
25    // Informational responses
26    // -------------------------------------------------------------------------
27    /**
28     * 100 Continue.
29     *
30     * This interim response indicates that everything so far is OK and that the
31     * client should continue the request, or ignore the response if the request
32     * is already finished.
33     *
34     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100
35     *
36     * @var int
37     */
38    public const CONTINUE = 100;
39    /**
40     * 101 Switching Protocols.
41     *
42     * This code is sent in response to an Upgrade request header from the
43     * client, and indicates the protocol the server is switching to.
44     *
45     * @see Header::UPGRADE
46     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/101
47     *
48     * @var int
49     */
50    public const SWITCHING_PROTOCOLS = 101;
51    /**
52     * 102 Processing (WebDAV).
53     *
54     * This code indicates that the server has received and is processing the
55     * request, but no response is available yet.
56     *
57     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/102
58     *
59     * @var int
60     */
61    public const PROCESSING = 102;
62    /**
63     * 103 Early Hints.
64     *
65     * This status code is primarily intended to be used with the Link header,
66     * letting the user agent start preloading resources while the server
67     * prepares a response.
68     *
69     * @see Header::LINK
70     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103
71     *
72     * @var int
73     */
74    public const EARLY_HINTS = 103;
75    // -------------------------------------------------------------------------
76    // Successful responses
77    // -------------------------------------------------------------------------
78    /**
79     * 200 OK.
80     *
81     * The request has succeeded. The meaning of the success depends on the
82     * HTTP method:
83     *
84     * - GET: The resource has been fetched and is transmitted in the message
85     * body.
86     *
87     * - HEAD: The representation headers are included in the response without
88     * any message body.
89     *
90     * - PUT or POST: The resource describing the result of the action is
91     * transmitted in the message body.
92     *
93     * - TRACE: The message body contains the request message as received by the
94     * server.
95     *
96     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200
97     *
98     * @var int
99     */
100    public const OK = 200;
101    /**
102     * 201 Created.
103     *
104     * The request has succeeded and a new resource has been created as a
105     * result. This is typically the response sent after POST requests, or some
106     * PUT requests.
107     *
108     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201
109     *
110     * @var int
111     */
112    public const CREATED = 201;
113    /**
114     * 202 Accepted.
115     *
116     * The request has been received but not yet acted upon. It is noncommittal,
117     * since there is no way in HTTP to later send an asynchronous response
118     * indicating the outcome of the request. It is intended for cases where
119     * another process or server handles the request, or for batch processing.
120     *
121     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/202
122     *
123     * @var int
124     */
125    public const ACCEPTED = 202;
126    /**
127     * 203 Non-Authoritative Information.
128     *
129     * This response code means the returned meta-information is not exactly the
130     * same as is available from the origin server, but is collected from a
131     * local or a third-party copy. This is mostly used for mirrors or backups
132     * of another resource. Except for that specific case, the "200 OK" response
133     * is preferred to this status.
134     *
135     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/203
136     *
137     * @var int
138     */
139    public const NON_AUTHORITATIVE_INFORMATION = 203;
140    /**
141     * 204 No Content.
142     *
143     * There is no content to send for this request, but the headers may be
144     * useful. The user-agent may update its cached headers for this resource
145     * with the new ones.
146     *
147     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204
148     *
149     * @var int
150     */
151    public const NO_CONTENT = 204;
152    /**
153     * 205 Reset Content.
154     *
155     * Tells the user-agent to reset the document which sent this request.
156     *
157     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/205
158     *
159     * @var int
160     */
161    public const RESET_CONTENT = 205;
162    /**
163     * 206 Partial Content.
164     *
165     * This response code is used when the Range header is sent from the client
166     * to request only part of a resource.
167     *
168     * @see RequestHeader::RANGE
169     * @see Header::CONTENT_RANGE
170     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/206
171     *
172     * @var int
173     */
174    public const PARTIAL_CONTENT = 206;
175    /**
176     * 207 Multi-Status (WebDAV).
177     *
178     * Conveys information about multiple resources, for situations where
179     * multiple status codes might be appropriate.
180     *
181     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/207
182     *
183     * @var int
184     */
185    public const MULTI_STATUS = 207;
186    /**
187     * 208 Already Reported (WebDAV).
188     *
189     * Used inside a `<dav:propstat>` response element to avoid repeatedly
190     * enumerating the internal members of multiple bindings to the same
191     * collection.
192     *
193     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/208
194     *
195     * @var int
196     */
197    public const ALREADY_REPORTED = 208;
198    /**
199     * 226 IM Used (HTTP Delta encoding).
200     *
201     * The server has fulfilled a GET request for the resource, and the response
202     * is a representation of the result of one or more instance-manipulations
203     * applied to the current instance.
204     *
205     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/226
206     *
207     * @var int
208     */
209    public const IM_USED = 226;
210    // -------------------------------------------------------------------------
211    // Redirection messages
212    // -------------------------------------------------------------------------
213    /**
214     * 300 Multiple Choices.
215     *
216     * The request has more than one possible response. The user-agent or user
217     * should choose one of them. (There is no standardized way of choosing one
218     * of the responses, but HTML links to the possibilities are recommended so
219     * the user can pick.)
220     *
221     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/300
222     *
223     * @var int
224     */
225    public const MULTIPLE_CHOICES = 300;
226    /**
227     * 301 Moved Permanently.
228     *
229     * The URL of the requested resource has been changed permanently. The new
230     * URL is given in the response.
231     *
232     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301
233     *
234     * @var int
235     */
236    public const MOVED_PERMANENTLY = 301;
237    /**
238     * 302 Found.
239     *
240     * This response code means that the URI of requested resource has been
241     * changed temporarily. Further changes in the URI might be made in the
242     * future. Therefore, this same URI should be used by the client in future
243     * requests.
244     *
245     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302
246     *
247     * @var int
248     */
249    public const FOUND = 302;
250    /**
251     * 303 See Other.
252     *
253     * The server sent this response to direct the client to get the requested
254     * resource at another URI with a GET request.
255     *
256     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303
257     *
258     * @var int
259     */
260    public const SEE_OTHER = 303;
261    /**
262     * 304 Not Modified.
263     *
264     * This is used for caching purposes. It tells the client that the response
265     * has not been modified, so the client can continue to use the same cached
266     * version of the response.
267     *
268     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304
269     *
270     * @var int
271     */
272    public const NOT_MODIFIED = 304;
273    /**
274     * 305 Use Proxy.
275     *
276     * Defined in a previous version of the HTTP specification to indicate that
277     * a requested response must be accessed by a proxy. It has been deprecated
278     * due to security concerns regarding in-band configuration of a proxy.
279     *
280     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/305
281     *
282     * @var int
283     */
284    public const USE_PROXY = 305;
285    /**
286     * 306 unused.
287     *
288     * This response code is no longer used; it is just reserved. It was used in
289     * a previous version of the HTTP/1.1 specification.
290     *
291     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/306
292     *
293     * @var int
294     */
295    public const SWITCH_PROXY = 306;
296    /**
297     * 307 Temporary Redirect.
298     *
299     * The server sends this response to direct the client to get the requested
300     * resource at another URI with same method that was used in the prior
301     * request. This has the same semantics as the `302 Found` HTTP response
302     * code, with the exception that the user agent must not change the HTTP
303     * method used: If a `POST` was used in the first request, a `POST` must be
304     * used in the second request.
305     *
306     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307
307     *
308     * @var int
309     */
310    public const TEMPORARY_REDIRECT = 307;
311    /**
312     * 308 Permanent Redirect.
313     *
314     * This means that the resource is now permanently located at another URI,
315     * specified by the `Location:` HTTP Response header. This has the same
316     * semantics as the `301 Moved Permanently` HTTP response code, with the
317     * exception that the user agent must not change the HTTP method used: If a
318     * `POST` was used in the first request, a `POST` must be used in the second
319     * request.
320     *
321     * @see ResponseHeader::LOCATION
322     * @see Status::MOVED_PERMANENTLY
323     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308
324     *
325     * @var int
326     */
327    public const PERMANENT_REDIRECT = 308;
328    // -------------------------------------------------------------------------
329    // Client error responses
330    // -------------------------------------------------------------------------
331    /**
332     * 400 Bad Request.
333     *
334     * The server could not understand the request due to invalid syntax.
335     *
336     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400
337     *
338     * @var int
339     */
340    public const BAD_REQUEST = 400;
341    /**
342     * 401 Unauthorized.
343     *
344     * Although the HTTP standard specifies "unauthorized", semantically this
345     * response means "unauthenticated". That is, the client must authenticate
346     * itself to get the requested response.
347     *
348     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401
349     *
350     * @var int
351     */
352    public const UNAUTHORIZED = 401;
353    /**
354     * 402 Payment Required.
355     *
356     * This response code is reserved for future use. The initial aim for
357     * creating this code was using it for digital payment systems, however this
358     * status code is used very rarely and no standard convention exists.
359     *
360     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/402
361     *
362     * @var int
363     */
364    public const PAYMENT_REQUIRED = 402;
365    /**
366     * 403 Forbidden.
367     *
368     * The client does not have access rights to the content; that is, it is
369     * unauthorized, so the server is refusing to give the requested resource.
370     * Unlike 401, the client's identity is known to the server.
371     *
372     * @see Status::UNAUTHORIZED
373     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403
374     *
375     * @var int
376     */
377    public const FORBIDDEN = 403;
378    /**
379     * 404 Not Found.
380     *
381     * The server can not find the requested resource. In the browser, this
382     * means the URL is not recognized. In an API, this can also mean that the
383     * endpoint is valid but the resource itself does not exist. Servers may
384     * also send this response instead of 403 to hide the existence of a
385     * resource from an unauthorized client. This response code is probably the
386     * most famous one due to its frequent occurrence on the web.
387     *
388     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404
389     *
390     * @var int
391     */
392    public const NOT_FOUND = 404;
393    /**
394     * 405 Method Not Allowed.
395     *
396     * The request method is known by the server but is not supported by the
397     * target resource. For example, an API may forbid DELETE-ing a resource.
398     *
399     * @see ResponseHeader::ALLOW
400     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405
401     *
402     * @var int
403     */
404    public const METHOD_NOT_ALLOWED = 405;
405    /**
406     * 406 Not Acceptable.
407     *
408     * This response is sent when the web server, after performing server-driven
409     * content negotiation, doesn't find any content that conforms to the
410     * criteria given by the user agent.
411     *
412     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406
413     *
414     * @var int
415     */
416    public const NOT_ACCEPTABLE = 406;
417    /**
418     * 407 Proxy Authentication Required.
419     *
420     * This is similar to 401 but authentication is needed to be done by a
421     * proxy.
422     *
423     * @see Status::UNAUTHORIZED
424     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/407
425     *
426     * @var int
427     */
428    public const PROXY_AUTHENTICATION_REQUIRED = 407;
429    /**
430     * 408 Request Timeout.
431     *
432     * This response is sent on an idle connection by some servers, even without
433     * any previous request by the client. It means that the server would like
434     * to shut down this unused connection. This response is used much more
435     * since some browsers, like Chrome, Firefox 27+, or IE9, use HTTP
436     * pre-connection mechanisms to speed up surfing. Also note that some
437     * servers merely shut down the connection without sending this message.
438     *
439     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408
440     *
441     * @var int
442     */
443    public const REQUEST_TIMEOUT = 408;
444    /**
445     * 409 Conflict.
446     *
447     * This response is sent when a request conflicts with the current state of
448     * the server.
449     *
450     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409
451     *
452     * @var int
453     */
454    public const CONFLICT = 409;
455    /**
456     * 410 Gone.
457     *
458     * This response is sent when the requested content has been permanently
459     * deleted from server, with no forwarding address. Clients are expected to
460     * remove their caches and links to the resource. The HTTP specification
461     * intends this status code to be used for "limited-time, promotional
462     * services". APIs should not feel compelled to indicate resources that have
463     * been deleted with this status code.
464     *
465     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/410
466     *
467     * @var int
468     */
469    public const GONE = 410;
470    /**
471     * 411 Length Required.
472     *
473     * Server rejected the request because the Content-Length header field is
474     * not defined and the server requires it.
475     *
476     * @see Header::CONTENT_LENGTH
477     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/411
478     *
479     * @var int
480     */
481    public const LENGTH_REQUIRED = 411;
482    /**
483     * 412 Precondition Failed.
484     *
485     * The client has indicated preconditions in its headers which the server
486     * does not meet.
487     *
488     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412
489     *
490     * @var int
491     */
492    public const PRECONDITION_FAILED = 412;
493    /**
494     * 413 Payload Too Large.
495     *
496     * Request entity is larger than limits defined by server; the server might
497     * close the connection or return an `Retry-After` header field.
498     *
499     * @see ResponseHeader::RETRY_AFTER
500     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413
501     *
502     * @var int
503     */
504    public const PAYLOAD_TOO_LARGE = 413;
505    /**
506     * 414 URI Too Long.
507     *
508     * The URI requested by the client is longer than the server is willing to
509     * interpret.
510     *
511     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414
512     *
513     * @var int
514     */
515    public const URI_TOO_LARGE = 414;
516    /**
517     * 415 Unsupported Media Type.
518     *
519     * The media format of the requested data is not supported by the server,
520     * so the server is rejecting the request.
521     *
522     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/415
523     *
524     * @var int
525     */
526    public const UNSUPPORTED_MEDIA_TYPE = 415;
527    /**
528     * 416 Range Not Satisfiable.
529     *
530     * The range specified by the `Range` header field in the request can't be
531     * fulfilled; it's possible that the range is outside the size of the target
532     * URI's data.
533     *
534     * @see RequestHeader::RANGE
535     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416
536     *
537     * @var int
538     */
539    public const RANGE_NOT_SATISFIABLE = 416;
540    /**
541     * 417 Expectation Failed.
542     *
543     * This response code means the expectation indicated by the `Expect`
544     * request header field can't be met by the server.
545     *
546     * @see RequestHeader::EXPECT
547     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/417
548     *
549     * @var int
550     */
551    public const EXPECTATION_FAILED = 417;
552    /**
553     * 418 I'm a teapot.
554     *
555     * The server refuses the attempt to brew coffee with a teapot.
556     *
557     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/418
558     *
559     * @var int
560     */
561    public const IM_A_TEAPOT = 418;
562    /**
563     * 421 Misdirected Request.
564     *
565     * The request was directed at a server that is not able to produce a
566     * response. This can be sent by a server that is not configured to produce
567     * responses for the combination of scheme and authority that are included
568     * in the request URI.
569     *
570     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/421
571     *
572     * @var int
573     */
574    public const MISDIRECTED_REQUEST = 421;
575    /**
576     * 422 Unprocessable Entity (WebDAV).
577     *
578     * The request was well-formed but was unable to be followed due to semantic
579     * errors.
580     *
581     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
582     *
583     * @var int
584     */
585    public const UNPROCESSABLE_ENTITY = 422;
586    /**
587     * 423 Locked (WebDAV).
588     *
589     * The resource that is being accessed is locked.
590     *
591     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/423
592     *
593     * @var int
594     */
595    public const LOCKED = 423;
596    /**
597     * 424 Failed Dependency (WebDAV).
598     *
599     * The request failed due to failure of a previous request.
600     *
601     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/424
602     *
603     * @var int
604     */
605    public const FAILED_DEPENDENCY = 424;
606    /**
607     * 425 Too Early.
608     *
609     * Indicates that the server is unwilling to risk processing a request that
610     * might be replayed.
611     *
612     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/425
613     *
614     * @var int
615     */
616    public const TOO_EARLY = 425;
617    /**
618     * 426 Upgrade Required.
619     *
620     * The server refuses to perform the request using the current protocol but
621     * might be willing to do so after the client upgrades to a different
622     * protocol. The server sends an `Upgrade` header in a 426 response to
623     * indicate the required protocol(s).
624     *
625     * @see Header::UPGRADE
626     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/426
627     *
628     * @var int
629     */
630    public const UPGRADE_REQUIRED = 426;
631    /**
632     * 428 Precondition Required.
633     *
634     * The origin server requires the request to be conditional. This response
635     * is intended to prevent the 'lost update' problem, where a client GETs a
636     * resource's state, modifies it, and PUTs it back to the server, when
637     * meanwhile a third party has modified the state on the server, leading to
638     * a conflict.
639     *
640     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/428
641     *
642     * @var int
643     */
644    public const PRECONDITION_REQUIRED = 428;
645    /**
646     * 429 Too Many Requests.
647     *
648     * The user has sent too many requests in a given amount of time ("rate
649     * limiting").
650     *
651     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429
652     *
653     * @var int
654     */
655    public const TOO_MANY_REQUESTS = 429;
656    /**
657     * 431 Request Header Fields Too Large.
658     *
659     * The server is unwilling to process the request because its header fields
660     * are too large. The request may be resubmitted after reducing the size of
661     * the request header fields.
662     *
663     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431
664     *
665     * @var int
666     */
667    public const REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
668    /**
669     * 451 Unavailable For Legal Reasons.
670     *
671     * The user-agent requested a resource that cannot legally be provided, such
672     * as a web page censored by a government.
673     *
674     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/451
675     *
676     * @var int
677     */
678    public const UNAVAILABLE_FOR_LEGAL_REASONS = 451;
679    /**
680     * 499 Client Closed Request (nginx).
681     *
682     * A non-standard status code introduced by nginx for the case when a client
683     * closes the connection while nginx is processing the request.
684     *
685     * @see https://httpstatuses.com/499
686     *
687     * @var int
688     */
689    public const CLIENT_CLOSED_REQUEST = 499;
690    // -------------------------------------------------------------------------
691    // Server error responses
692    // -------------------------------------------------------------------------
693    /**
694     * 500 Internal Server Error.
695     *
696     * The server has encountered a situation it doesn't know how to handle.
697     *
698     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500
699     *
700     * @var int
701     */
702    public const INTERNAL_SERVER_ERROR = 500;
703    /**
704     * 501 Not Implemented.
705     *
706     * The request method is not supported by the server and cannot be handled.
707     * The only methods that servers are required to support (and therefore that
708     * must not return this code) are `GET` and `HEAD`.
709     *
710     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501
711     *
712     * @var int
713     */
714    public const NOT_IMPLEMENTED = 501;
715    /**
716     * 502 Bad Gateway.
717     *
718     * This error response means that the server, while working as a gateway to
719     * get a response needed to handle the request, got an invalid response.
720     *
721     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502
722     *
723     * @var int
724     */
725    public const BAD_GATEWAY = 502;
726    /**
727     * 503 Service Unavailable.
728     *
729     * The server is not ready to handle the request. Common causes are a server
730     * that is down for maintenance or that is overloaded. Note that together
731     * with this response, a user-friendly page explaining the problem should be
732     * sent. This response should be used for temporary conditions and the
733     * `Retry-After:` HTTP header should, if possible, contain the estimated
734     * time before the recovery of the service. The webmaster must also take
735     * care about the caching-related headers that are sent along with this
736     * response, as these temporary condition responses should usually not be
737     * cached.
738     *
739     * @see ResponseHeader::RETRY_AFTER
740     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503
741     *
742     * @var int
743     */
744    public const SERVICE_UNAVAILABLE = 503;
745    /**
746     * 504 Gateway Timeout.
747     *
748     * This error response is given when the server is acting as a gateway and
749     * cannot get a response in time.
750     *
751     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504
752     *
753     * @var int
754     */
755    public const GATEWAY_TIMEOUT = 504;
756    /**
757     * 505 HTTP Version Not Supported.
758     *
759     * The HTTP version used in the request is not supported by the server.
760     *
761     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/505
762     *
763     * @var int
764     */
765    public const HTTP_VERSION_NOT_SUPPORTED = 505;
766    /**
767     * 506 Variant Also Negotiates.
768     *
769     * The server has an internal configuration error: the chosen variant
770     * resource is configured to engage in transparent content negotiation
771     * itself, and is therefore not a proper end point in the negotiation
772     * process.
773     *
774     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/506
775     *
776     * @var int
777     */
778    public const VARIANT_ALSO_NEGOTIATES = 506;
779    /**
780     * 507 Insufficient Storage (WebDAV).
781     *
782     * The method could not be performed on the resource because the server is
783     * unable to store the representation needed to successfully complete the
784     * request.
785     *
786     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/507
787     *
788     * @var int
789     */
790    public const INSUFFICIENT_STORAGE = 507;
791    /**
792     * 508 Loop Detected (WebDAV).
793     *
794     * The server detected an infinite loop while processing the request.
795     *
796     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508
797     *
798     * @var int
799     */
800    public const LOOP_DETECTED = 508;
801    /**
802     * 510 Not Extended.
803     *
804     * Further extensions to the request are required for the server to fulfill
805     * it.
806     *
807     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/510
808     *
809     * @var int
810     */
811    public const NOT_EXTENDED = 510;
812    /**
813     * 511 Network Authentication Required.
814     *
815     * The 511 status code indicates that the client needs to authenticate to
816     * gain network access.
817     *
818     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/511
819     *
820     * @var int
821     */
822    public const NETWORK_AUTHENTICATION_REQUIRED = 511;
823    /**
824     * 599 Network Connect Timeout Error.
825     *
826     * This status code is not specified in any RFCs, but is used by some HTTP
827     * proxies to signal a network connect timeout behind the proxy to a client
828     * in front of the proxy.
829     *
830     * @see https://httpstatuses.com/599
831     *
832     * @var int
833     */
834    public const NETWORK_CONNECT_TIMEOUT_ERROR = 599;
835    /**
836     * Response status codes and reasons.
837     *
838     * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
839     *
840     * @var array<int,string>
841     */
842    protected static array $status = [
843        // ---------------------------------------------------------------------
844        // Informational responses
845        // ---------------------------------------------------------------------
846        100 => 'Continue',
847        101 => 'Switching Protocols',
848        102 => 'Processing',
849        103 => 'Early Hints',
850        // ---------------------------------------------------------------------
851        // Successful responses
852        // ---------------------------------------------------------------------
853        200 => 'OK',
854        201 => 'Created',
855        202 => 'Accepted',
856        203 => 'Non-Authoritative Information',
857        204 => 'No Content',
858        205 => 'Reset Content',
859        206 => 'Partial Content',
860        207 => 'Multi-Status',
861        208 => 'Already Reported',
862        226 => 'IM Used',
863        // ---------------------------------------------------------------------
864        // Redirection messages
865        // ---------------------------------------------------------------------
866        300 => 'Multiple Choices',
867        301 => 'Moved Permanently',
868        302 => 'Found',
869        303 => 'See Other',
870        304 => 'Not Modified',
871        305 => 'Use Proxy',
872        306 => 'Switch Proxy',
873        307 => 'Temporary Redirect',
874        308 => 'Permanent Redirect',
875        // ---------------------------------------------------------------------
876        // Client error responses
877        // ---------------------------------------------------------------------
878        400 => 'Bad Request',
879        401 => 'Unauthorized',
880        402 => 'Payment Required',
881        403 => 'Forbidden',
882        404 => 'Not Found',
883        405 => 'Method Not Allowed',
884        406 => 'Not Acceptable',
885        407 => 'Proxy Authentication Required',
886        408 => 'Request Timeout',
887        409 => 'Conflict',
888        410 => 'Gone',
889        411 => 'Length Required',
890        412 => 'Precondition Failed',
891        413 => 'Payload Too Large',
892        414 => 'URI Too Large',
893        415 => 'Unsupported Media Type',
894        416 => 'Range Not Satisfiable',
895        417 => 'Expectation Failed',
896        418 => "I'm a teapot",
897        421 => 'Misdirected Request',
898        422 => 'Unprocessable Entity',
899        423 => 'Locked',
900        424 => 'Failed Dependency',
901        425 => 'Too Early',
902        426 => 'Upgrade Required',
903        428 => 'Precondition Required',
904        429 => 'Too Many Requests',
905        431 => 'Request Header Fields Too Large',
906        451 => 'Unavailable For Legal Reasons',
907        499 => 'Client Closed Request',
908        // ---------------------------------------------------------------------
909        // Server error responses
910        // ---------------------------------------------------------------------
911        500 => 'Internal Server Error',
912        501 => 'Not Implemented',
913        502 => 'Bad Gateway',
914        503 => 'Service Unavailable',
915        504 => 'Gateway Timeout',
916        505 => 'HTTP Version Not Supported',
917        506 => 'Variant Also Negotiates',
918        507 => 'Insufficient Storage',
919        508 => 'Loop Detected',
920        510 => 'Not Extended',
921        511 => 'Network Authentication Required',
922        599 => 'Network Connect Timeout Error',
923    ];
924
925    /**
926     * @param int $code
927     * @param string|null $default
928     *
929     * @throws InvalidArgumentException for invalid code
930     * @throws LogicException for unknown code without a default reason
931     *
932     * @return string
933     */
934    public static function getReason(int $code, string $default = null) : string
935    {
936        $code = static::validate($code);
937        if (isset(static::$status[$code])) {
938            return static::$status[$code];
939        }
940        if ($default !== null) {
941            return $default;
942        }
943        throw new LogicException('Unknown status code must have a default reason: ' . $code);
944    }
945
946    public static function setStatus(int $code, string $reason) : void
947    {
948        static::$status[static::validate($code)] = $reason;
949    }
950
951    public static function validate(int $code) : int
952    {
953        if ($code < 100 || $code > 599) {
954            throw new InvalidArgumentException('Invalid response status code: ' . $code);
955        }
956        return $code;
957    }
958}