diff --git a/src/Exception/Http/Status304.php b/src/Exception/Http/Status304.php index a0c81c202..54096567d 100644 --- a/src/Exception/Http/Status304.php +++ b/src/Exception/Http/Status304.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 304 Not Modified responses @@ -29,5 +30,5 @@ final class Status304 extends Http { * * @var string */ - protected $reason = 'Not Modified'; + protected $reason = HttpStatus::TEXT_304; } diff --git a/src/Exception/Http/Status305.php b/src/Exception/Http/Status305.php index 52be5c482..4d4db10da 100644 --- a/src/Exception/Http/Status305.php +++ b/src/Exception/Http/Status305.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 305 Use Proxy responses @@ -29,5 +30,5 @@ final class Status305 extends Http { * * @var string */ - protected $reason = 'Use Proxy'; + protected $reason = HttpStatus::TEXT_305; } diff --git a/src/Exception/Http/Status306.php b/src/Exception/Http/Status306.php index 6dc6740c0..1711c8822 100644 --- a/src/Exception/Http/Status306.php +++ b/src/Exception/Http/Status306.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 306 Switch Proxy responses @@ -29,5 +30,5 @@ final class Status306 extends Http { * * @var string */ - protected $reason = 'Switch Proxy'; + protected $reason = HttpStatus::TEXT_306; } diff --git a/src/Exception/Http/Status400.php b/src/Exception/Http/Status400.php index bec772b18..f2c375c60 100644 --- a/src/Exception/Http/Status400.php +++ b/src/Exception/Http/Status400.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 400 Bad Request responses @@ -29,5 +30,5 @@ final class Status400 extends Http { * * @var string */ - protected $reason = 'Bad Request'; + protected $reason = HttpStatus::TEXT_400; } diff --git a/src/Exception/Http/Status401.php b/src/Exception/Http/Status401.php index 9e1129829..d1a1983ec 100644 --- a/src/Exception/Http/Status401.php +++ b/src/Exception/Http/Status401.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 401 Unauthorized responses @@ -29,5 +30,5 @@ final class Status401 extends Http { * * @var string */ - protected $reason = 'Unauthorized'; + protected $reason = HttpStatus::TEXT_401; } diff --git a/src/Exception/Http/Status402.php b/src/Exception/Http/Status402.php index d81606890..8816a3577 100644 --- a/src/Exception/Http/Status402.php +++ b/src/Exception/Http/Status402.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 402 Payment Required responses @@ -29,5 +30,5 @@ final class Status402 extends Http { * * @var string */ - protected $reason = 'Payment Required'; + protected $reason = HttpStatus::TEXT_402; } diff --git a/src/Exception/Http/Status403.php b/src/Exception/Http/Status403.php index 9884c5b07..453c08ca1 100644 --- a/src/Exception/Http/Status403.php +++ b/src/Exception/Http/Status403.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 403 Forbidden responses @@ -29,5 +30,5 @@ final class Status403 extends Http { * * @var string */ - protected $reason = 'Forbidden'; + protected $reason = HttpStatus::TEXT_403; } diff --git a/src/Exception/Http/Status404.php b/src/Exception/Http/Status404.php index c34b2f04f..0b205d64d 100644 --- a/src/Exception/Http/Status404.php +++ b/src/Exception/Http/Status404.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 404 Not Found responses @@ -29,5 +30,5 @@ final class Status404 extends Http { * * @var string */ - protected $reason = 'Not Found'; + protected $reason = HttpStatus::TEXT_404; } diff --git a/src/Exception/Http/Status405.php b/src/Exception/Http/Status405.php index 7d70f75ec..37c6a168b 100644 --- a/src/Exception/Http/Status405.php +++ b/src/Exception/Http/Status405.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 405 Method Not Allowed responses @@ -29,5 +30,5 @@ final class Status405 extends Http { * * @var string */ - protected $reason = 'Method Not Allowed'; + protected $reason = HttpStatus::TEXT_405; } diff --git a/src/Exception/Http/Status406.php b/src/Exception/Http/Status406.php index 726f43b8d..53be6099b 100644 --- a/src/Exception/Http/Status406.php +++ b/src/Exception/Http/Status406.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 406 Not Acceptable responses @@ -29,5 +30,5 @@ final class Status406 extends Http { * * @var string */ - protected $reason = 'Not Acceptable'; + protected $reason = HttpStatus::TEXT_406; } diff --git a/src/Exception/Http/Status407.php b/src/Exception/Http/Status407.php index 6682d9e2b..5a6cc63e6 100644 --- a/src/Exception/Http/Status407.php +++ b/src/Exception/Http/Status407.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 407 Proxy Authentication Required responses @@ -29,5 +30,5 @@ final class Status407 extends Http { * * @var string */ - protected $reason = 'Proxy Authentication Required'; + protected $reason = HttpStatus::TEXT_407; } diff --git a/src/Exception/Http/Status408.php b/src/Exception/Http/Status408.php index 4455ccd6d..269c2b323 100644 --- a/src/Exception/Http/Status408.php +++ b/src/Exception/Http/Status408.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 408 Request Timeout responses @@ -29,5 +30,5 @@ final class Status408 extends Http { * * @var string */ - protected $reason = 'Request Timeout'; + protected $reason = HttpStatus::TEXT_408; } diff --git a/src/Exception/Http/Status409.php b/src/Exception/Http/Status409.php index 9a19282e0..e8270bb1f 100644 --- a/src/Exception/Http/Status409.php +++ b/src/Exception/Http/Status409.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 409 Conflict responses @@ -29,5 +30,5 @@ final class Status409 extends Http { * * @var string */ - protected $reason = 'Conflict'; + protected $reason = HttpStatus::TEXT_409; } diff --git a/src/Exception/Http/Status410.php b/src/Exception/Http/Status410.php index 6ad0f6491..77a4fe953 100644 --- a/src/Exception/Http/Status410.php +++ b/src/Exception/Http/Status410.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 410 Gone responses @@ -29,5 +30,5 @@ final class Status410 extends Http { * * @var string */ - protected $reason = 'Gone'; + protected $reason = HttpStatus::TEXT_410; } diff --git a/src/Exception/Http/Status411.php b/src/Exception/Http/Status411.php index e6f2b3f0b..e41b6101d 100644 --- a/src/Exception/Http/Status411.php +++ b/src/Exception/Http/Status411.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 411 Length Required responses @@ -29,5 +30,5 @@ final class Status411 extends Http { * * @var string */ - protected $reason = 'Length Required'; + protected $reason = HttpStatus::TEXT_411; } diff --git a/src/Exception/Http/Status412.php b/src/Exception/Http/Status412.php index 6890641cf..b6445ed01 100644 --- a/src/Exception/Http/Status412.php +++ b/src/Exception/Http/Status412.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 412 Precondition Failed responses @@ -29,5 +30,5 @@ final class Status412 extends Http { * * @var string */ - protected $reason = 'Precondition Failed'; + protected $reason = HttpStatus::TEXT_412; } diff --git a/src/Exception/Http/Status413.php b/src/Exception/Http/Status413.php index 22ce30144..0156827d7 100644 --- a/src/Exception/Http/Status413.php +++ b/src/Exception/Http/Status413.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 413 Request Entity Too Large responses @@ -29,5 +30,5 @@ final class Status413 extends Http { * * @var string */ - protected $reason = 'Request Entity Too Large'; + protected $reason = HttpStatus::TEXT_413; } diff --git a/src/Exception/Http/Status414.php b/src/Exception/Http/Status414.php index 4170fd216..d038522b1 100644 --- a/src/Exception/Http/Status414.php +++ b/src/Exception/Http/Status414.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 414 Request-URI Too Large responses @@ -29,5 +30,5 @@ final class Status414 extends Http { * * @var string */ - protected $reason = 'Request-URI Too Large'; + protected $reason = HttpStatus::TEXT_414; } diff --git a/src/Exception/Http/Status415.php b/src/Exception/Http/Status415.php index 0052c9a89..e632127d4 100644 --- a/src/Exception/Http/Status415.php +++ b/src/Exception/Http/Status415.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 415 Unsupported Media Type responses @@ -29,5 +30,5 @@ final class Status415 extends Http { * * @var string */ - protected $reason = 'Unsupported Media Type'; + protected $reason = HttpStatus::TEXT_415; } diff --git a/src/Exception/Http/Status416.php b/src/Exception/Http/Status416.php index 69425413d..0fb470925 100644 --- a/src/Exception/Http/Status416.php +++ b/src/Exception/Http/Status416.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 416 Requested Range Not Satisfiable responses @@ -29,5 +30,5 @@ final class Status416 extends Http { * * @var string */ - protected $reason = 'Requested Range Not Satisfiable'; + protected $reason = HttpStatus::TEXT_416; } diff --git a/src/Exception/Http/Status417.php b/src/Exception/Http/Status417.php index b6408805e..cdf29b611 100644 --- a/src/Exception/Http/Status417.php +++ b/src/Exception/Http/Status417.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 417 Expectation Failed responses @@ -29,5 +30,5 @@ final class Status417 extends Http { * * @var string */ - protected $reason = 'Expectation Failed'; + protected $reason = HttpStatus::TEXT_417; } diff --git a/src/Exception/Http/Status418.php b/src/Exception/Http/Status418.php index 9c403126c..a0af622f3 100644 --- a/src/Exception/Http/Status418.php +++ b/src/Exception/Http/Status418.php @@ -10,6 +10,7 @@ namespace WpOrg\Requests\Exception\Http; use WpOrg\Requests\Exception\Http; +use WpOrg\Requests\Utility\HttpStatus; /** * Exception for 418 I'm A Teapot responses @@ -31,5 +32,5 @@ final class Status418 extends Http { * * @var string */ - protected $reason = "I'm A Teapot"; + protected $reason = HttpStatus::TEXT_418; } diff --git a/src/Exception/Http/Status421.php b/src/Exception/Http/Status421.php new file mode 100644 index 000000000..fdac2c742 --- /dev/null +++ b/src/Exception/Http/Status421.php @@ -0,0 +1,34 @@ + response element to avoid enumerating the internal members of multiple bindings to + * the same collection. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/208 + */ + const TEXT_208 = 'Already Reported'; + + /** + * HTTP response code 226 - IM Used (HTTP Delta encoding). + * + * This is mostly used for mirrors or backups of another resource. Except for that specific case, the 200 OK + * response is preferred to this status. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/226 + */ + const TEXT_226 = 'IM Used'; + + // Redirection messages (300 - 399) + + /** + * HTTP response code 300 - Multiple Choices. + * + * The request has more than one possible response. + * + * The user agent or user should choose one of them. (There is no standardized way of choosing one of the responses, + * but HTML links to the possibilities are recommended so the user can pick.) + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/300 + */ + const TEXT_300 = 'Multiple Choices'; + + /** + * HTTP response code 301 - Moved Permanently. + * + * The URL of the requested resource has been changed permanently. + * + * The new URL is given in the response. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301 + */ + const TEXT_301 = 'Moved Permanently'; + + /** + * HTTP response code 302 - Found. + * + * This response code means that the URI of requested resource has been changed temporarily. + * + * Further changes in the URI might be made in the future. Therefore, this same URI should be used by the client in + * future requests. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/302 + */ + const TEXT_302 = 'Found'; + + /** + * HTTP response code 303 - See Other. + * + * The server sent this response to direct the client to get the requested resource at another URI with a GET + * request. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303 + */ + const TEXT_303 = 'See Other'; + + /** + * HTTP response code 304 - Not Modified. + * + * This is used for caching purposes. It tells the client that the response has not been modified, so the client can + * continue to use the same cached version of the response. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304 + */ + const TEXT_304 = 'Not Modified'; + + /** + * HTTP response code 305 - Use Proxy (DEPRECATED!). + * + * Was defined in a previous version of the HTTP specification to indicate that a requested response must be + * accessed by a proxy. + * + * It has been deprecated due to security concerns regarding in-band configuration of a proxy. + * + * @deprecated + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/305 + */ + const TEXT_305 = 'Use Proxy'; + + /** + * HTTP response code 306 - Switch Proxy (DEPRECATED!). + * + * No longer used. Originally meant "Subsequent requests should use the specified proxy." + * + * @deprecated + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/306 + */ + const TEXT_306 = 'Switch Proxy'; + + /** + * HTTP response code 307 - Temporary Redirect. + * + * The server sends this response to direct the client to get the requested resource at another URI with same method + * that was used in the prior request. + * + * This has the same semantics as the 302 Found HTTP response code, with the exception that the user agent must not + * change the HTTP method used: If a POST was used in the first request, a POST must be used in the second request. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307 + */ + const TEXT_307 = 'Temporary Redirect'; + + /** + * HTTP response code 308 - Permanent Redirect. + * + * This means that the resource is now permanently located at another URI, specified by the Location: HTTP Response + * header. + * + * This has the same semantics as the 301 Moved Permanently HTTP response code, with the exception that the user + * agent must not change the HTTP method used: If a POST was used in the first request, a POST must be used in the + * second request. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308 + */ + const TEXT_308 = 'Permanent Redirect'; + + // Client error responses (400 - 499) + + /** + * HTTP response code 400 - Bad Request. + * + * The server cannot or will not process the request due to something that is perceived to be a client error (e.g., + * malformed request syntax, invalid request message framing, or deceptive request routing). + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400 + */ + const TEXT_400 = 'Bad Request'; + + /** + * HTTP response code 401 - Unauthorized. + * + * Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, + * the client must authenticate itself to get the requested response. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401 + */ + const TEXT_401 = 'Unauthorized'; + + /** + * HTTP response code 402 - Payment Required (Experimental). + * + * This response code is reserved for future use. The initial aim for creating this code was using it for digital + * payment systems, however this status code is used very rarely and no standard convention exists. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/402 + */ + const TEXT_402 = 'Payment Required'; + + /** + * HTTP response code 403 - Forbidden. + * + * The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to + * give the requested resource. + * + * Unlike 401 Unauthorized, the client's identity is known to the server. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403 + */ + const TEXT_403 = 'Forbidden'; + + /** + * HTTP response code 404 - Not Found. + * + * The server cannot find the requested resource. + * + * In the browser, this means the URL is not recognized. + * + * In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also + * send this response instead of 403 to hide the existence of a resource from an unauthorized client. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404 + */ + const TEXT_404 = 'Not Found'; + + /** + * HTTP response code 405 - Method Not Allowed. + * + * The request method is known by the server but is not supported by the target resource. For example, an API may + * not allow calling DELETE to remove a resource. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405 + */ + const TEXT_405 = 'Method Not Allowed'; + + /** + * HTTP response code 406 - Not Acceptable. + * + * This response is sent when the web server, after performing server-driven content negotiation, doesn't find any + * content that conforms to the criteria given by the user agent. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/406 + */ + const TEXT_406 = 'Not Acceptable'; + + /** + * HTTP response code 407 - Proxy Authentication Required. + * + * This is similar to 401 but authentication is needed to be done by a proxy. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/407 + */ + const TEXT_407 = 'Proxy Authentication Required'; + + /** + * HTTP response code 408 - Request Timeout. + * + * This response is sent on an idle connection by some servers, even without any previous request by the client. + * + * It means that the server would like to shut down this unused connection. This response is used much more since + * some browsers, like Chrome, Firefox 27+, or IE9, use HTTP pre-connection mechanisms to speed up surfing. + * + * Also note that some servers merely shut down the connection without sending this message. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408 + */ + const TEXT_408 = 'Request Timeout'; + + /** + * HTTP response code 409 - Conflict. + * + * This response is sent when a request conflicts with the current state of the server. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409 + */ + const TEXT_409 = 'Conflict'; + + /** + * HTTP response code 410 - Gone. + * + * This response is sent when the requested content has been permanently deleted from server, with no forwarding + * address. + * + * Clients are expected to remove their caches and links to the resource. + * The HTTP specification intends this status code to be used for "limited-time, promotional services". + * APIs should not feel compelled to indicate resources that have been deleted with this status code. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/410 + */ + const TEXT_410 = 'Gone'; + + /** + * HTTP response code 411 - Length Required. + * + * Server rejected the request because the Content-Length header field is not defined and the server requires it. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/411 + */ + const TEXT_411 = 'Length Required'; + + /** + * HTTP response code 412 - Precondition Failed. + * + * The client has indicated preconditions in its headers which the server does not meet. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/412 + */ + const TEXT_412 = 'Precondition Failed'; + + /** + * HTTP response code 413 - Payload Too Large. + * + * Request entity is larger than limits defined by server; the server might close the connection or return an + * Retry-After header field. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/413 + */ + const TEXT_413 = 'Payload Too Large'; + + /** + * HTTP response code 414 - URI Too Long. + * + * The URI requested by the client is longer than the server is willing to interpret. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414 + */ + const TEXT_414 = 'URI Too Long'; + + /** + * HTTP response code 415 - Unsupported Media Type. + * + * The media format of the requested data is not supported by the server, so the server is rejecting the request. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/415 + */ + const TEXT_415 = 'Unsupported Media Type'; + + /** + * HTTP response code 416 - Range Not Satisfiable. + * + * The range specified by the Range header field in the request can't be fulfilled; it's possible that the range is + * outside the size of the target URI's data. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416 + */ + const TEXT_416 = 'Requested Range Not Satisfiable'; + + /** + * HTTP response code 417 - Expectation Failed. + * + * This response code means the expectation indicated by the Expect request header field can't be met by the server. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/417 + */ + const TEXT_417 = 'Expectation Failed'; + + /** + * HTTP response code 418 - I'm a teapot. + * + * The server refuses the attempt to brew coffee with a teapot. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/418 + */ + const TEXT_418 = "I'm a teapot"; + + /** + * HTTP response code 421 - Misdirected Request. + * + * The request was directed at a server that is not able to produce a response. + * + * This can be sent by a server that is not configured to produce responses for the combination of scheme and + * authority that are included in the request URI. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/421 + */ + const TEXT_421 = 'Misdirected Request'; + + /** + * HTTP response code 422 - Unprocessable Entity (WebDAV). + * + * The request was well-formed but was unable to be followed due to semantic errors. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422 + */ + const TEXT_422 = 'Unprocessable Content'; + + /** + * HTTP response code 423 - Locked (WebDAV). + * + * The resource that is being accessed is locked. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/423 + */ + const TEXT_423 = 'Locked'; + + /** + * HTTP response code 424 - Failed Dependency (WebDAV). + * + * The request failed due to failure of a previous request. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/424 + */ + const TEXT_424 = 'Failed Dependency'; + + /** + * HTTP response code 425 - Too Early (Experimental). + * + * Indicates that the server is unwilling to risk processing a request that might be replayed. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/425 + */ + const TEXT_425 = 'Too Early'; + + /** + * HTTP response code 426 - Upgrade Required. + * + * The server refuses to perform the request using the current protocol but might be willing to do so after the + * client upgrades to a different protocol. + * + * The server sends an Upgrade header in a 426 response to indicate the required protocol(s). + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/426 + */ + const TEXT_426 = 'Upgrade Required'; + + /** + * HTTP response code 428 - Precondition Required. + * + * The origin server requires the request to be conditional. + * + * Intended to prevent the 'lost update' problem, where a client GETs a resource's state, modifies it, and PUTs it + * back to the server, when meanwhile a third party has modified the state on the server, leading to a conflict. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/428 + */ + const TEXT_428 = 'Precondition Required'; + + /** + * HTTP response code 429 - Too Many Requests. + * + * The user has sent too many requests in a given amount of time ("rate limiting"). + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429 + */ + const TEXT_429 = 'Too Many Requests'; + + /** + * HTTP response code 431 - Request Header Fields Too Large. + * + * The server is unwilling to process the request because its header fields are too large. + * + * The request may be resubmitted after reducing the size of the request header fields. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/431 + */ + const TEXT_431 = 'Request Header Fields Too Large'; + + /** + * HTTP response code 451 - Unavailable For Legal Reasons. + * + * The user-agent requested a resource that cannot legally be provided, such as a web page censored by a government. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/451 + */ + const TEXT_451 = 'Unavailable For Legal Reasons'; + + // Server error responses (500 - 599) + + /** + * HTTP response code 500 - Internal Server Error. + * + * The server has encountered a situation it doesn't know how to handle. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500 + */ + const TEXT_500 = 'Internal Server Error'; + + /** + * HTTP response code 501 - Not Implemented. + * + * The request method is not supported by the server and cannot be handled. + * + * The only methods that servers are required to support (and therefore that must not return this code) are GET and + * HEAD. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501 + */ + const TEXT_501 = 'Not Implemented'; + + /** + * HTTP response code 502 - Bad Gateway. + * + * This error response means that the server, while working as a gateway to get a response needed to handle the + * request, got an invalid response. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502 + */ + const TEXT_502 = 'Bad Gateway'; + + /** + * HTTP response code 503 - Service Unavailable. + * + * The server is not ready to handle the request. + * + * Common causes are a server that is down for maintenance or that is overloaded. + * + * Note that together with this response, a user-friendly page explaining the problem should be sent. + * + * This responses should be used for temporary conditions and the Retry-After: HTTP header should, if possible, + * contain the estimated time for the recovery of the service. The webmaster must also take care about the + * caching-related headers that are sent along with this response, as these temporary condition responses should + * usually not be cached. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503 + */ + const TEXT_503 = 'Service Unavailable'; + + /** + * HTTP response code 504 - Gateway Timeout. + * + * This error response is given when the server is acting as a gateway and cannot get a response in time. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504 + */ + const TEXT_504 = 'Gateway Timeout'; + + /** + * HTTP response code 505 - HTTP Version Not Supported. + * + * The HTTP version used in the request is not supported by the server. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/505 + */ + const TEXT_505 = 'HTTP Version Not Supported'; + + /** + * HTTP response code 506 - Variant Also Negotiates. + * + * The server has an internal configuration error: the chosen variant resource is configured to engage in + * transparent content negotiation itself, and is therefore not a proper end point in the negotiation process. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/506 + */ + const TEXT_506 = 'Variant Also Negotiates'; + + /** + * HTTP response code 507 - Insufficient Storage (WebDAV). + * + * The method could not be performed on the resource because the server is unable to store the representation needed + * to successfully complete the request. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/507 + */ + const TEXT_507 = 'Insufficient Storage'; + + /** + * HTTP response code 508 - Loop Detected (WebDAV). + * + * The server detected an infinite loop while processing the request. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508 + */ + const TEXT_508 = 'Loop Detected'; + + /** + * HTTP response code 510 - Not Extended. + * + * Further extensions to the request are required for the server to fulfill it. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/510 + */ + const TEXT_510 = 'Not Extended'; + + /** + * HTTP response code 511 - Network Authentication Required. + * + * The 511 status code indicates that the client needs to authenticate to gain network access. + * + * @var string + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/511 + */ + const TEXT_511 = 'Network Authentication Required'; + + + /** + * Map of status codes to their text. + * + * @var array + */ + const MAP = [ + 100 => self::TEXT_100, + 101 => self::TEXT_101, + 102 => self::TEXT_102, + 103 => self::TEXT_103, + 200 => self::TEXT_200, + 201 => self::TEXT_201, + 202 => self::TEXT_202, + 203 => self::TEXT_203, + 204 => self::TEXT_204, + 205 => self::TEXT_205, + 206 => self::TEXT_206, + 207 => self::TEXT_207, + 208 => self::TEXT_208, + 226 => self::TEXT_226, + 300 => self::TEXT_300, + 301 => self::TEXT_301, + 302 => self::TEXT_302, + 303 => self::TEXT_303, + 304 => self::TEXT_304, + 305 => self::TEXT_305, + 306 => self::TEXT_306, + 307 => self::TEXT_307, + 308 => self::TEXT_308, + 400 => self::TEXT_400, + 401 => self::TEXT_401, + 402 => self::TEXT_402, + 403 => self::TEXT_403, + 404 => self::TEXT_404, + 405 => self::TEXT_405, + 406 => self::TEXT_406, + 407 => self::TEXT_407, + 408 => self::TEXT_408, + 409 => self::TEXT_409, + 410 => self::TEXT_410, + 411 => self::TEXT_411, + 412 => self::TEXT_412, + 413 => self::TEXT_413, + 414 => self::TEXT_414, + 415 => self::TEXT_415, + 416 => self::TEXT_416, + 417 => self::TEXT_417, + 418 => self::TEXT_418, + 421 => self::TEXT_421, + 422 => self::TEXT_422, + 423 => self::TEXT_423, + 424 => self::TEXT_424, + 425 => self::TEXT_425, + 426 => self::TEXT_426, + 428 => self::TEXT_428, + 429 => self::TEXT_429, + 431 => self::TEXT_431, + 451 => self::TEXT_451, + 500 => self::TEXT_500, + 501 => self::TEXT_501, + 502 => self::TEXT_502, + 503 => self::TEXT_503, + 504 => self::TEXT_504, + 505 => self::TEXT_505, + 506 => self::TEXT_506, + 507 => self::TEXT_507, + 508 => self::TEXT_508, + 510 => self::TEXT_510, + 511 => self::TEXT_511, + ]; + + /** + * Get the status message from a status code. + * + * @param int|string $code Status code. + * @return string Status message. + * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $code argument is not a valid status code. + */ + public static function get_text($code) { + if (self::is_valid_code($code) === false) { + // When the type is correct, add the value to the error message to help debugging. + $type = gettype($code) . (is_scalar($code) ? " ($code)" : ''); + + throw InvalidArgument::create(1, '$code', 'a valid HTTP status code as an int or numeric string', $type); + } + + return self::MAP[$code]; + } + + /** + * Verify whether a status code is valid. + * + * @param int|string $code Status code to check. + * @return bool Whether the status code is valid. + */ + public static function is_valid_code($code) { + if (!is_int($code) && !is_string($code)) { + return false; + } + + return array_key_exists($code, self::MAP); + } +} diff --git a/tests/Exception/Http/HttpTest.php b/tests/Exception/Http/HttpTest.php index e5871d892..470437f19 100644 --- a/tests/Exception/Http/HttpTest.php +++ b/tests/Exception/Http/HttpTest.php @@ -96,8 +96,8 @@ public static function dataGetClass() { 'code' => '404', 'expected' => '\\' . Status404::class, ], - 'integer 422: class does not exist' => [ - 'code' => 422, + 'integer 460: class does not exist' => [ + 'code' => 460, 'expected' => $default, ], ]; diff --git a/tests/Exception/Http/StatusCodeTest.php b/tests/Exception/Http/StatusCodeTest.php new file mode 100644 index 000000000..28af67b78 --- /dev/null +++ b/tests/Exception/Http/StatusCodeTest.php @@ -0,0 +1,152 @@ +expectException(Http\StatusUnknown::class); + $this->expectExceptionCode($expected_code); + + throw new Http\StatusUnknown('testing-1-2-3', $data); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataUnknownStatusCodes() { + $response_with_status = new Response(); + $response_with_status->status_code = 12345; + + $response_without_status = new Response(); + + return [ + 'null (or not passed)' => [ + 'expectedCode' => 0, + ], + 'integer error code as data' => [ + 'expectedCode' => 0, + 'data' => 507, + ], + 'Response object with status code' => [ + 'expectedCode' => 12345, + 'data' => $response_with_status, + ], + 'Response object without status code' => [ + 'expectedCode' => 0, + 'data' => $response_without_status, + ], + ]; + } + + /** + * Test whether all HTTP exception classes can be instantiated for known status codes. + * + * We're making sure that if such an exception gets triggered, it will not + * fatal because of a broken exception class. + * + * @dataProvider dataKnownStatusCodes + * + * @param int status_code HTTP status code. + * @param string $expected_exception_class Exception class to expect. + * + * @return void + */ + public function testKnownStatusCodes($status_code, $expected_exception_class) { + $response_with_status = new Response(); + $response_with_status->status_code = $status_code; + + $exception_class = Http::get_class($status_code); + $exception_object = new $exception_class('testing-1-2-3'); + + $this->assertInstanceOf(Http::class, $exception_object); + $this->assertInstanceOf($expected_exception_class, $exception_object); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataKnownStatusCodes() { + $all_status_codes = array_keys(HttpStatus::MAP); + $non_exception_codes = [100, 101, 102, 103, 200, 201, 202, 203, 204, 205, 206, 207, 208, 226, 300, 301, 302, 303, 307, 308]; + + $data = []; + foreach ($all_status_codes as $status) { + $classname = in_array($status, $non_exception_codes, true) + ? Http\StatusUnknown::class + : Http::class . '\Status' . $status; + + $data['Status ' . $status] = [$status, $classname]; + } + + return $data; + } +} diff --git a/tests/Exception/Http/StatusUnknownTest.php b/tests/Exception/Http/StatusUnknownTest.php deleted file mode 100644 index d7bd9963a..000000000 --- a/tests/Exception/Http/StatusUnknownTest.php +++ /dev/null @@ -1,60 +0,0 @@ -expectException(StatusUnknown::class); - $this->expectExceptionCode($expected_code); - - throw new StatusUnknown('testing-1-2-3', $data); - } - - /** - * Data provider. - * - * @return array - */ - public static function dataException() { - $response_with_status = new Response(); - $response_with_status->status_code = 12345; - - $response_without_status = new Response(); - - return [ - 'null (or not passed)' => [ - 'expectedCode' => 0, - ], - 'integer error code as data' => [ - 'expectedCode' => 0, - 'data' => 507, - ], - 'Response object with status code' => [ - 'expectedCode' => 12345, - 'data' => $response_with_status, - ], - 'Response object without status code' => [ - 'expectedCode' => 0, - 'data' => $response_without_status, - ], - ]; - } -} diff --git a/tests/Fixtures/TransportMock.php b/tests/Fixtures/TransportMock.php index 8bcd38fbb..dfea35025 100644 --- a/tests/Fixtures/TransportMock.php +++ b/tests/Fixtures/TransportMock.php @@ -3,6 +3,7 @@ namespace WpOrg\Requests\Tests\Fixtures; use WpOrg\Requests\Transport; +use WpOrg\Requests\Utility\HttpStatus; final class TransportMock implements Transport { public $code = 200; @@ -10,58 +11,9 @@ final class TransportMock implements Transport { public $body = 'Test Body'; public $raw_headers = ''; - private static $messages = [ - 100 => '100 Continue', - 101 => '101 Switching Protocols', - 200 => '200 OK', - 201 => '201 Created', - 202 => '202 Accepted', - 203 => '203 Non-Authoritative Information', - 204 => '204 No Content', - 205 => '205 Reset Content', - 206 => '206 Partial Content', - 300 => '300 Multiple Choices', - 301 => '301 Moved Permanently', - 302 => '302 Found', - 303 => '303 See Other', - 304 => '304 Not Modified', - 305 => '305 Use Proxy', - 306 => '306 (Unused)', - 307 => '307 Temporary Redirect', - 400 => '400 Bad Request', - 401 => '401 Unauthorized', - 402 => '402 Payment Required', - 403 => '403 Forbidden', - 404 => '404 Not Found', - 405 => '405 Method Not Allowed', - 406 => '406 Not Acceptable', - 407 => '407 Proxy Authentication Required', - 408 => '408 Request Timeout', - 409 => '409 Conflict', - 410 => '410 Gone', - 411 => '411 Length Required', - 412 => '412 Precondition Failed', - 413 => '413 Request Entity Too Large', - 414 => '414 Request-URI Too Long', - 415 => '415 Unsupported Media Type', - 416 => '416 Requested Range Not Satisfiable', - 417 => '417 Expectation Failed', - 418 => '418 I\'m a teapot', - 428 => '428 Precondition Required', - 429 => '429 Too Many Requests', - 431 => '431 Request Header Fields Too Large', - 500 => '500 Internal Server Error', - 501 => '501 Not Implemented', - 502 => '502 Bad Gateway', - 503 => '503 Service Unavailable', - 504 => '504 Gateway Timeout', - 505 => '505 HTTP Version Not Supported', - 511 => '511 Network Authentication Required', - ]; - public function request($url, $headers = [], $data = [], $options = []) { - $status = isset(self::$messages[$this->code]) ? self::$messages[$this->code] : $this->code . ' unknown'; - $response = "HTTP/1.0 $status\r\n"; + $text = HttpStatus::is_valid_code($this->code) ? HttpStatus::get_text($this->code) : 'unknown'; + $response = "HTTP/1.0 {$this->code} {$text}\r\n"; $response .= "Content-Type: text/plain\r\n"; if ($this->chunked) { $response .= "Transfer-Encoding: chunked\r\n"; diff --git a/tests/Utility/HttpStatus/GetTextTest.php b/tests/Utility/HttpStatus/GetTextTest.php new file mode 100644 index 000000000..53914f8f3 --- /dev/null +++ b/tests/Utility/HttpStatus/GetTextTest.php @@ -0,0 +1,102 @@ +assertSame($text, HttpStatus::get_text($code)); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAccessValidEntry() { + return [ + 'integer key' => [404, 'Not Found'], + 'string key' => ['502', 'Bad Gateway'], + ]; + } + + /** + * Test retrieving a status code with an invalid type. + * + * @dataProvider dataAccessInvalidType + * + * @param mixed $code Status code value to test. + * + * @return void + */ + public function testAccessInvalidType($code) { + $this->expectException(InvalidArgument::class); + $this->expectExceptionMessage('a valid HTTP status code as an int or numeric string'); + HttpStatus::get_text($code); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAccessInvalidType() { + return TypeProviderHelper::getAllExcept(TypeProviderHelper::GROUP_INT, TypeProviderHelper::GROUP_STRING); + } + + /** + * Test retrieving a status code with a matching type but an invalid code. + * + * @dataProvider dataAccessInvalidCode + * + * @param mixed $code Status code value to test. + * + * @return void + */ + public function testAccessInvalidCode($code) { + $this->expectException(InvalidArgument::class); + $this->expectExceptionMessage( + sprintf( + 'a valid HTTP status code as an int or numeric string, %s (%s) given', + gettype($code), + $code + ) + ); + HttpStatus::get_text($code); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAccessInvalidCode() { + return [ + 'negative integer' => [-1], + 'zero integer' => [0], + 'too low integer' => [42], + 'too high integer' => [1000], + 'negative string' => ['-1'], + 'zero string' => ['0'], + 'too low string' => ['42'], + 'too high string' => ['1000'], + 'PHP_INT_MAX' => [PHP_INT_MAX], + ]; + } +} diff --git a/tests/Utility/HttpStatus/IsValidCodeTest.php b/tests/Utility/HttpStatus/IsValidCodeTest.php new file mode 100644 index 000000000..028d68a4c --- /dev/null +++ b/tests/Utility/HttpStatus/IsValidCodeTest.php @@ -0,0 +1,91 @@ +assertTrue(HttpStatus::is_valid_code($code)); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAccessValidEntry() { + return [ + 'integer key' => [404], + 'string key' => ['502'], + ]; + } + + /** + * Test retrieving a status code with an invalid type. + * + * @dataProvider dataAccessInvalidType + * + * @param mixed $code Status code value to test. + * + * @return void + */ + public function testAccessInvalidType($code) { + $this->assertFalse(HttpStatus::is_valid_code($code)); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAccessInvalidType() { + return TypeProviderHelper::getAllExcept(TypeProviderHelper::GROUP_INT, TypeProviderHelper::GROUP_STRING); + } + + /** + * Test retrieving a status code with a matching type but an invalid code. + * + * @dataProvider dataAccessInvalidCode + * + * @param mixed $code Status code value to test. + * + * @return void + */ + public function testAccessInvalidCode($code) { + $this->assertFalse(HttpStatus::is_valid_code($code)); + } + + /** + * Data provider. + * + * @return array + */ + public static function dataAccessInvalidCode() { + return [ + 'negative integer' => [-1], + 'zero integer' => [0], + 'too low integer' => [42], + 'too high integer' => [1000], + 'negative string' => ['-1'], + 'zero string' => ['0'], + 'too low string' => ['42'], + 'too high string' => ['1000'], + 'PHP_INT_MAX' => [PHP_INT_MAX], + ]; + } +}