1use crate::generate_responses_functions;
2use crate::responses::CustomResponse;
3use crate::traits::get_code_trait::GetCode;
4use strum_macros::EnumIter;
5
6generate_responses_functions! {
7 "Client errors",
8 ResponsesClientCodes,
9 BadRequest => (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).", 400, "Bad Request"),
10 Unauthorized => (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.", 401, "Unauthorized"),
11 PaymentRequired => (402, "Payment Required", "The initial purpose of this code was for digital payment systems, however this status code is rarely used and no standard convention exists.", 402, "Payment Required"),
12 Forbidden => (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.", 403, "Forbidden"),
13 NotFound => (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 Forbidden to hide the existence of a resource from an unauthorized client.", 404, "Not Found"),
14 MethodNotAllowed => (405, "Method Not Allowed", "The HTTP method is not supported for the target resource", 405, "Method Not Allowed"),
15 NotAcceptable => (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.", 406, "Not Acceptable"),
16 ProxyAuthenticationRequired => (407, "Proxy Authentication Required", "The client must authenticate with a proxy first", 407, "Proxy Authentication Required"),
17 RequestTimeout => (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 use HTTP pre-connection mechanisms to speed up browsing. Some servers may shut down a connection without sending this message.", 408, "Request Timeout"),
18 Conflict => (409, "Conflict", "This response is sent when a request conflicts with the current state of the server. In WebDAV remote web authoring, 409 responses are errors sent to the client so that a user might be able to resolve a conflict and resubmit the request.", 409, "Conflict"),
19 Gone => (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.", 410, "Gone"),
20 LengthRequired => (411, "Length Required", "Server rejected the request because the Content-Length header field is not defined and the server requires it.", 411, "Length Required"),
21 PreconditionFailed => (412, "Precondition Failed", "In conditional requests, the client has indicated preconditions in its headers which the server does not meet.", 412, "Precondition Failed"),
22 ContentTooLarge => (413, "Payload Too Large", "The request or resource is too large for the server to handle", 413, "Content Too Large"),
23 URITooLong => (414, "URI Too Long", "The URI requested by the client is longer than the server is willing to interpret.", 414, "URI Too Long"),
24 UnsupportedMediaType => (415, "Unsupported Media Type", "The media format of the requested data is not supported by the server, so the server is rejecting the request.", 415, "Unsupported Media Type"),
25 RangeNotSatisfiable => (416, "Range Not Satisfiable", "The range specified by the request's Range header field cannot be satisfied; the range may exceed the size of the data coming from the targeted URI.", 416, "Range Not Satisfiable"),
26 ExpectationFailed => (417, "Expectation Failed", "This response code means that the expectations indicated by the Expect request header field could not be met by the server.", 417, "Expectation Failed"),
27 ImATeapot => (418, "I'm a teapot", "The waiter refuses to brew coffee with a teapot, RFC 2324.", 418, "I'm a teapot"),
28 PageExpired => (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.", 419, "PageExpired"),
29 MethodFailure => (405, "Method Not Allowed", "The HTTP method is not supported for the target resource", 420, "MethodFailure"),
30 MisdirectedRequest => (421, "Misdirected Request", "The request was sent to a server unable to produce a response. This code may be sent by a server that has not been configured to produce responses subject to the combination of schemas and identities included in the request URI.", 421, "Misdirected Request"),
31 UnprocessableEntity => (422, "Unprocessable Entity", "The request was successfully created but could not be processed due to semantic errors, WebDAV RFC 4918.", 422, "Unprocessable Entity"),
32 Locked => (423, "Locked", "The resource that is currently being viewed is locked.", 423, "Locked"),
33 FailedDependency => (424, "Failed Dependency", "The query failed because a previous query failed.", 424, "Failed Dependency"),
34 TooEarly => (422, "Unprocessable Entity", "Indicate that the server does not want to process a request that could be replayed.", 425, "Too Early"),
35 UpgradeRequired => (426, "Upgrade Required", "The server refuses to process the request using the current protocol but may agree to do so if the client opts for another protocol. The server must send an Upgrade header in the 426 response to indicate the requested protocol(s) (Section 6.7 of [RFC7230]).", 426, "Upgrade Required"),
36 PreconditionRequired => (428, "Precondition Required", "The origin server requires the request to be conditional. This is intended to prevent the 'loss of update' problem, where a client retrieves the state of a resource with GET, modifies it, and returns it to the server with PUT while a third party modifies the state of the resource. server, which leads to a conflict.", 428, "Precondition Required"),
37 TooManyRequests => (429, "Too Many Requests", "The user has sent too many requests in a given amount of time (rate limiting).", 429, "Too Many Requests"),
38 RequestHeaderFieldsTooLarge => (431, "Request Header Fields Too Large", "The server is unwilling to process the request because the header fields are too long. The request can be returned after reducing the size of the headers.", 431, "Request Header Fields Too Large"),
39 LoginRequired => (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.", 432, "Login Required"),
40 OriginError => (400, "Bad Request", "The request was rejected due to an origin server/client IP issue", 433, "Origin Error"),
41 DestinationError => (400, "Bad Request", "The request was rejected due to a destination server/config issue", 434, "DestinationError"),
42 TooLarge => (413, "Payload Too Large", "The request or resource is too large for the server to handle", 435, "TooLarge"),
43 SSLCertificateError => (400, "Bad Request", "An invalid or untrusted SSL certificate was encountered", 436, "SSLCertificateError"),
44 SSLCertificateRequired => (400, "Bad Request", "The server requires a valid SSL certificate for secure connections", 437, "SSLCertificateRequired"),
45 NoCertificate => (400, "Bad Request", "No SSL certificate was provided by the client", 438, "NoCertificate"),
46 LoginTimeout => (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.", 440, "LoginTimeout"),
47 OverDataQuota => (413, "Payload Too Large", "The request or resource is too large for the server to handle", 441, "OverDataQuota"),
48 NoResponse => (400, "Bad Request", "The server closed the connection without sending a response", 444, "NoResponse"),
49 TooManyForwardedIPAddresses => (400, "Bad Request", "The request was rejected due to an origin server/client IP issue", 445, "TooManyForwardedIPAddresses"),
50 InternetSecurityError => (400, "Bad Request", "The request was rejected due to an origin server/client IP issue", 446, "InternetSecurityError"),
51 RetryWith => (428, "Precondition Required", "The user has sent too many requests in a given amount of time (rate limiting).", 449, "RetryWith"),
52 BlockedByWindowsParentalControls => (403, "Forbidden", "A Microsoft extension. This error is given when Windows Parental Controls are turned on and are blocking access to the given webpage.", 450, "BlockedByWindowsParentalControls"),
53 UnavailableForLegalReasons => (451, "Unavailable For Legal Reasons", "A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource.", 451, "UnavailableForLegalReasons"),
54 TooManyRecipients => (429, "Too Many Requests", "The user has sent too many requests in a given amount of time (rate limiting) or too many recipients or addresses used", 452, "TooManyRecipients"),
55 MethodNotValidInThisState => (405, "Method Not Allowed", "The HTTP method is not supported for the target resource", 453, "MethodNotValidInThisState"),
56 UnrecoverableError => (400, "Bad Request", "The server has encountered a situation it doesn't know how to handle.", 456, "UnrecoverableError"),
57 ClientClosedConnexionPrematurely => (400, "Bad Request", "The client closed the connection before the server could send a response.", 493, "ClientClosedConnexionPrematurely"),
58 RequestHeaderTooLarge => (431, "Request Header Fields Too Large", "The server is unwilling to process the request because the header fields are too long. The request can be returned after reducing the size of the headers.", 494, "RequestHeaderTooLarge"),
59 CertError => (400, "Bad Request", "The request was rejected due to an origin server/client IP issue", 495, "CertError"),
60 NoCert => (400, "Bad Request", "The request was rejected due to an origin server/client IP issue", 496, "NoCert"),
61 HTTPToHTTPS => (400, "Bad Request", "The request was rejected due to an origin server/client IP issue", 497, "HTTPToHTTPS"),
62 InvalidToken => (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.", 498, "InvalidToken"),
63 ClientClosedRequest => (400, "Bad Request", "The client closed the connection before the server could send a response.", 499, "ClientClosedRequest"),
64}
65
66#[cfg(test)]
67mod tests {
68 use crate::helpers::unified_tuple_helper::UnifiedTuple;
69 use crate::responses::ResponsesClientCodes;
70 use crate::traits::tuple_traits::IntoTwoFieldsTuple;
71 use serde_json::{json, to_value};
72
73 #[test]
74 fn test_get_code() {
75 assert_eq!(ResponsesClientCodes::BadRequest.get_code(), 400);
76 assert_eq!(ResponsesClientCodes::Unauthorized.get_code(), 401);
77 assert_eq!(ResponsesClientCodes::PaymentRequired.get_code(), 402);
78 assert_eq!(ResponsesClientCodes::Forbidden.get_code(), 403);
79 }
80
81 #[test]
82 fn test_client_codes_from_u16() {
83 assert_eq!(ResponsesClientCodes::from_u16(400), Some(ResponsesClientCodes::BadRequest));
84 assert_eq!(ResponsesClientCodes::from_u16(401), Some(ResponsesClientCodes::Unauthorized));
85 assert_eq!(ResponsesClientCodes::from_u16(441), Some(ResponsesClientCodes::OverDataQuota));
86 assert_eq!(ResponsesClientCodes::from_u16(9999), None);
87 }
88
89 #[test]
90 fn test_client_codes_from_internal_code() {
91 assert_eq!(
92 ResponsesClientCodes::from_internal_code(400),
93 Some(ResponsesClientCodes::BadRequest)
94 );
95 assert_eq!(
96 ResponsesClientCodes::from_internal_code(401),
97 Some(ResponsesClientCodes::Unauthorized)
98 );
99 assert_eq!(
100 ResponsesClientCodes::from_internal_code(441),
101 Some(ResponsesClientCodes::OverDataQuota)
102 );
103 assert_eq!(ResponsesClientCodes::from_internal_code(9999), None);
104 }
105
106 #[test]
107 fn test_client_closed_request_as_tuple() {
108 let code = ResponsesClientCodes::ClientClosedRequest;
109 let tuple = UnifiedTuple {
110 standard_code: 400,
111 standard_name: "Bad Request",
112 unified_description:
113 "The client closed the connection before the server could send a response.",
114 internal_code: Some(499),
115 internal_name: Option::from("ClientClosedRequest"),
116 };
117 let code_as_tuple = code.as_tuple();
118 assert_eq!(code_as_tuple, tuple);
119 }
120
121 #[test]
122 fn test_too_many_forward_ip_adresses_as_json() {
123 let response_code = ResponsesClientCodes::TooManyForwardedIPAddresses;
124 let json_result = response_code.as_json();
125 let expected_json = json!({
126 "type": "Client errors",
127 "details": {
128 "standard http code": {
129 "code": 400,
130 "name": "Bad Request"
131 },
132 "description": "The request was rejected due to an origin server/client IP issue",
133 "internal http code": {
134 "code": 445,
135 "name": "TooManyForwardedIPAddresses"
136 }
137 }
138 });
139
140 assert_eq!(json_result, expected_json);
141 }
142
143 #[test]
144 fn test_method_failure_into_two_fields_tuple() {
145 let response_code = ResponsesClientCodes::MethodFailure;
146 let tuple = response_code.into_two_fields_tuple();
147 let json_result = to_value(&tuple).unwrap();
148
149 let expected_json = json!({
150 "code": 405,
151 "name": "Method Not Allowed"
152 });
153
154 assert_eq!(json_result, expected_json);
155 }
156
157 #[test]
158 fn test_bad_request_duplicate_standard_codes() {
159 assert_eq!(ResponsesClientCodes::from_u16(444), Some(ResponsesClientCodes::NoResponse));
161 assert_eq!(ResponsesClientCodes::from_u16(438), Some(ResponsesClientCodes::NoCertificate));
162 }
163}