Prechádzať zdrojové kódy

Check and simplify HTTP error code handling (Step 2/3)

bel 10 rokov pred
rodič
commit
0b3aa67fe1
1 zmenil súbory, kde vykonal 113 pridanie a 80 odobranie
  1. 113 80
      src/civetweb.c

+ 113 - 80
src/civetweb.c

@@ -1447,88 +1447,121 @@ static const char *suggest_connection_header(const struct mg_connection *conn)
 static void handle_file_based_request(struct mg_connection *conn, const char *path, struct file *filep);
 static int mg_stat(struct mg_connection *conn, const char *path, struct file *filep);
 
-static const char *mg_get_response_code_text(int response_code)
+static const char *mg_get_response_code_text(int response_code, struct mg_connection *conn)
 {
     switch (response_code)
     {
-    case 100: return "Continue"; // RFC2616 Section 10.1.1
-    case 101: return "Switching Protocols"; // RFC2616 Section 10.1.2
-    case 102: return "Processing"; // RFC2518 Section 10.1
-    case 200: return "OK"; // RFC2616 Section 10.2.1
-    case 201: return "Created"; // RFC2616 Section 10.2.2
-    case 202: return "Accepted"; // RFC2616 Section 10.2.3
-    case 203: return "Non-Authoritative Information"; // RFC2616 Section 10.2.4
-    case 204: return "No Content"; // RFC2616 Section 10.2.5
-    case 205: return "Reset Content"; // RFC2616 Section 10.2.6
-    case 206: return "Partial Content"; // RFC2616 Section 10.2.7
-    case 207: return "Multi-Status"; // RFC2518 Section 10.2, RFC4918 Section 11.1
-    case 208: return "Already Reported"; // RFC5842 Section 7.1
-    case 300: return "Multiple Choices"; // RFC2616 Section 10.3.1
-    case 301: return "Moved Permanently"; // RFC2616 Section 10.3.2
-    case 302: return "Found"; // RFC2616 Section 10.3.3
-    case 303: return "See Other"; // RFC2616 Section 10.3.4
-    case 304: return "Not Modified"; // RFC2616 Section 10.3.5
-    case 305: return "Use Proxy"; // RFC2616 Section 10.3.6
-    case 307: return "Temporary Redirect"; // RFC2616 Section 10.3.8
-    case 400: return "Bad Request"; // RFC2616 Section 10.4.1
-    case 401: return "Unauthorized"; // RFC2616 Section 10.4.2
-    case 402: return "Payment Required"; // RFC2616 Section 10.4.3
-    case 403: return "Forbidden"; // RFC2616 Section 10.4.4
-    case 404: return "Not Found"; // RFC2616 Section 10.4.5
-    case 405: return "Method Not Allowed"; // RFC2616 Section 10.4.6
-    case 406: return "Not Acceptable"; // RFC2616 Section 10.4.7
-    case 407: return "Proxy Authentication Required"; // RFC2616 Section 10.4.8
-    case 408: return "Request Time-out"; // RFC2616 Section 10.4.9
-    case 409: return "Conflict"; // RFC2616 Section 10.4.10
-    case 410: return "Gone"; // RFC2616 Section 10.4.11
-    case 411: return "Length Required"; // RFC2616 Section 10.4.12
-    case 412: return "Precondition Failed"; // RFC2616 Section 10.4.13
-    case 413: return "Request Entity Too Large"; // RFC2616 Section 10.4.14
-    case 414: return "Request-URI Too Large"; // RFC2616 Section 10.4.15
-    case 415: return "Unsupported Media Type"; // RFC2616 Section 10.4.16
-    case 416: return "Requested range not satisfiable"; // RFC2616 Section 10.4.17
-    case 417: return "Expectation Failed"; // RFC2616 Section 10.4.18
-    case 422: return "Unproccessable entity"; // RFC2518 Section 10.3, RFC4918 Section 11.2
-    case 423: return "Locked"; // RFC2518 Section 10.4, RFC4918 Section 11.3
-    case 424: return "Failed Dependency"; // RFC2518 Section 10.5, RFC4918 Section 11.4
-    case 500: return "Internal Server Error"; // RFC2616 Section 10.5.1
-    case 501: return "Not Implemented"; // RFC2616 Section 10.5.2
-    case 502: return "Bad Gateway"; // RFC2616 Section 10.5.3
-    case 503: return "Service Unavailable"; // RFC2616 Section 10.5.4
-    case 504: return "Gateway Time-out"; // RFC2616 Section 10.5.5
-    case 505: return "HTTP Version not supported"; // RFC2616 Section 10.5.6
-    case 507: return "Insufficient Storage"; // RFC2518 Section 10.6, , RFC4918 Section 11.5
-
-    /*
-    case 226: return "IM used"; // RFC3229 Section 10.4.1
-    case 308: return "Permanent Redirect"; // RFC7238 Section 3
-    case 418: return "I am a teapot"; // RFC2324 Section 2.3.2
-
-    case 419: return "Authentication Timeout"; // common use, no RFC
-
-    case 420: return "Method Failure"; // ??
-    case 425: return "Node code"; // ??
-    case 426: return "Upgrade Required"; // ??
-
-    case 428: return "Precondition Required"; // RFC 6585 ??
-    case 429: return "Too Many Requests"; // RFC 6585 ??
-    case 431: return "Request Header Fields Too Large"; // RFC 6585 ??
-
-    case 440: return "Login Timeout"; // ??
-    case 444: return "No Response"; // ??
-    case 449: return "Retry With"; // ??
-    case 450: return "Blocked by Windows Parental Controls"; // ??
-
-    case 451: return "Unavailable For Legal Reasons"; // Internet draft ??
-
-    case 506: return "Variant Also Negotiates"; // RFC 2295
-    case 508: return "Loop Detected"; // RFC 5842
-
-    case 510: return "Not Extended"; // RFC 2774
-    case 511: return "Network Authentication Required"; // RFC 6585
-    */
-
-    default: return "";
+    /* RFC2616 Section 10.1 - Informational 1xx */
+    case 100: return "Continue"; /* RFC2616 Section 10.1.1 */
+    case 101: return "Switching Protocols"; /* RFC2616 Section 10.1.2 */
+    case 102: return "Processing"; /* RFC2518 Section 10.1 */
+
+    /* RFC2616 Section 10.2 - Successful 2xx */
+    case 200: return "OK"; /* RFC2616 Section 10.2.1 */
+    case 201: return "Created"; /* RFC2616 Section 10.2.2 */
+    case 202: return "Accepted"; /* RFC2616 Section 10.2.3 */
+    case 203: return "Non-Authoritative Information"; /* RFC2616 Section 10.2.4 */
+    case 204: return "No Content"; /* RFC2616 Section 10.2.5 */
+    case 205: return "Reset Content"; /* RFC2616 Section 10.2.6 */
+    case 206: return "Partial Content"; /* RFC2616 Section 10.2.7 */
+    case 207: return "Multi-Status"; /* RFC2518 Section 10.2, RFC4918 Section 11.1 */
+
+    /* RFC2616 Section 10.3 - Redirection 3xx */
+    case 300: return "Multiple Choices"; /* RFC2616 Section 10.3.1 */
+    case 301: return "Moved Permanently"; /* RFC2616 Section 10.3.2 */
+    case 302: return "Found"; /* RFC2616 Section 10.3.3 */
+    case 303: return "See Other"; /* RFC2616 Section 10.3.4 */
+    case 304: return "Not Modified"; /* RFC2616 Section 10.3.5 */
+    case 305: return "Use Proxy"; /* RFC2616 Section 10.3.6 */
+    case 307: return "Temporary Redirect"; /* RFC2616 Section 10.3.8 */
+
+    /* RFC2616 Section 10.4 - Client Error 4xx */
+    case 400: return "Bad Request"; /* RFC2616 Section 10.4.1 */
+    case 401: return "Unauthorized"; /* RFC2616 Section 10.4.2 */
+    case 402: return "Payment Required"; /* RFC2616 Section 10.4.3 */
+    case 403: return "Forbidden"; /* RFC2616 Section 10.4.4 */
+    case 404: return "Not Found"; /* RFC2616 Section 10.4.5 */
+    case 405: return "Method Not Allowed"; /* RFC2616 Section 10.4.6 */
+    case 406: return "Not Acceptable"; /* RFC2616 Section 10.4.7 */
+    case 407: return "Proxy Authentication Required"; /* RFC2616 Section 10.4.8 */
+    case 408: return "Request Time-out"; /* RFC2616 Section 10.4.9 */
+    case 409: return "Conflict"; /* RFC2616 Section 10.4.10 */
+    case 410: return "Gone"; /* RFC2616 Section 10.4.11 */
+    case 411: return "Length Required"; /* RFC2616 Section 10.4.12 */
+    case 412: return "Precondition Failed"; /* RFC2616 Section 10.4.13 */
+    case 413: return "Request Entity Too Large"; /* RFC2616 Section 10.4.14 */
+    case 414: return "Request-URI Too Large"; /* RFC2616 Section 10.4.15 */
+    case 415: return "Unsupported Media Type"; /* RFC2616 Section 10.4.16 */
+    case 416: return "Requested range not satisfiable"; /* RFC2616 Section 10.4.17 */
+    case 417: return "Expectation Failed"; /* RFC2616 Section 10.4.18 */
+    case 422: return "Unproccessable entity"; /* RFC2518 Section 10.3, RFC4918 Section 11.2 */
+    case 423: return "Locked"; /* RFC2518 Section 10.4, RFC4918 Section 11.3 */
+    case 424: return "Failed Dependency"; /* RFC2518 Section 10.5, RFC4918 Section 11.4 */
+    case 428: return "Precondition Required"; /* RFC 6585, Section 3 */
+    case 429: return "Too Many Requests"; /* RFC 6585, Section 4 */
+    case 431: return "Request Header Fields Too Large"; /* RFC 6585, Section 5 */
+
+    /* RFC2616 Section 10.5 - Server Error 5xx */
+    case 500: return "Internal Server Error"; /* RFC2616 Section 10.5.1 */
+    case 501: return "Not Implemented"; /* RFC2616 Section 10.5.2 */
+    case 502: return "Bad Gateway"; /* RFC2616 Section 10.5.3 */
+    case 503: return "Service Unavailable"; /* RFC2616 Section 10.5.4 */
+    case 504: return "Gateway Time-out"; /* RFC2616 Section 10.5.5 */
+    case 505: return "HTTP Version not supported"; /* RFC2616 Section 10.5.6 */
+    case 507: return "Insufficient Storage"; /* RFC2518 Section 10.6, , RFC4918 Section 11.5 */
+    case 511: return "Network Authentication Required"; /* RFC 6585, Section 6 */
+
+    /* Return codes from non normative RFCs: */
+    /* Informative and experimental RFCs, "de facto" standards due to common use, ... */
+    case 208: return "Already Reported"; /* RFC5842 Section 7.1 */
+    case 226: return "IM used"; /* RFC3229 Section 10.4.1 */
+    case 308: return "Permanent Redirect"; /* RFC7238 Section 3 */
+    case 418: return "I am a teapot"; /* RFC2324 Section 2.3.2 */
+    case 419: return "Authentication Timeout"; /* common use */
+    case 451: return "Unavailable For Legal Reasons"; /* draft-tbray-http-legally-restricted-status-05, Section 3 */
+    case 506: return "Variant Also Negotiates"; /* RFC 2295, Section 8.1 */
+    case 508: return "Loop Detected"; /* RFC5842 Section 7.1 */
+    case 510: return "Not Extended"; /* RFC 2774, Section 7 */
+
+    /* according to hearsay (TODO: verify or delete) */
+    case 420: return "Method Failure";
+    case 425: return "Node code";
+    case 426: return "Upgrade Required";
+    case 440: return "Login Timeout";
+    case 444: return "No Response";
+    case 449: return "Retry With";
+    case 450: return "Blocked by Parental Controls";
+
+    default:
+        /* This error code is unknown. This should not happen. */
+        if (conn) {
+            mg_cry(conn, "Unknown HTTP response code: %u", response_code);
+        }
+
+        /* Return at least a category according to RFC 2616 Section 10. */
+        if (response_code>=100 && response_code<200) {
+            /* Unknown informational status code */
+            return "Information";
+        }
+        if (response_code>=200 && response_code<300) {
+            /* Unknown success code */
+            return "Success";
+        }
+        if (response_code>=300 && response_code<400) {
+            /* Unknown redirection code */
+            return "Redirection";
+        }
+        if (response_code>=400 && response_code<500) {
+            /* Unknown request error code */
+            return "Client Error";
+        }
+        if (response_code>=500 && response_code<600) {
+            /* Unknown server error code */
+            return "Server Error";
+        }
+
+        /* Response code not even within reasonable range */
+        return "";
     }
 }
 
@@ -1551,7 +1584,7 @@ static void send_http_error(struct mg_connection *conn, int status,
     const char *error_page_file_ext, *tstr;
 
     if (!reason) {
-        reason = mg_get_response_code_text(status);
+        reason = mg_get_response_code_text(status, conn);
     }
 
     conn->status_code = status;