// SPDX-License-Identifier: GPL-3.0-or-later #include "../libnetdata.h" ENUM_STR_MAP_DEFINE(HTTP_REQUEST_MODE) = { { .name = "OPTIONS", .id = HTTP_REQUEST_MODE_OPTIONS }, { .name = "GET", .id = HTTP_REQUEST_MODE_GET }, { .name = "FILECOPY", .id = HTTP_REQUEST_MODE_FILECOPY }, { .name = "POST", .id = HTTP_REQUEST_MODE_POST }, { .name = "PUT", .id = HTTP_REQUEST_MODE_PUT }, { .name = "DELETE", .id = HTTP_REQUEST_MODE_DELETE }, { .name = "STREAM", .id = HTTP_REQUEST_MODE_STREAM }, // terminator { .name = NULL, .id = 0 } }; ENUM_STR_DEFINE_FUNCTIONS(HTTP_REQUEST_MODE, 0, "UNKNOWN"); const char *http_response_code2string(int code) { switch(code) { case 100: return "Continue"; case 101: return "Switching Protocols"; case 102: return "Processing"; case 103: return "Early Hints"; case 200: return "OK"; case 201: return "Created"; case 202: return "Accepted"; case 203: return "Non-Authoritative Information"; case 204: return "No Content"; case 205: return "Reset Content"; case 206: return "Partial Content"; case 207: return "Multi-Status"; case 208: return "Already Reported"; case 226: return "IM Used"; case 300: return "Multiple Choices"; case 301: return "Moved Permanently"; case 302: return "Found"; case 303: return "See Other"; case 304: return "Not Modified"; case 305: return "Use Proxy"; case 306: return "Switch Proxy"; case 307: return "Temporary Redirect"; case 308: return "Permanent Redirect"; case 400: return "Bad Request"; case 401: return "Unauthorized"; case 402: return "Payment Required"; case 403: return "Forbidden"; case 404: return "Not Found"; case 405: return "Method Not Allowed"; case 406: return "Not Acceptable"; case 407: return "Proxy Authentication Required"; case 408: return "Request Timeout"; case 409: return "Conflict"; case 410: return "Gone"; case 411: return "Length Required"; case 412: return "Precondition Failed"; case 413: return "Payload Too Large"; case 414: return "URI Too Long"; case 415: return "Unsupported Media Type"; case 416: return "Range Not Satisfiable"; case 417: return "Expectation Failed"; case 418: return "I'm a teapot"; case 421: return "Misdirected Request"; case 422: return "Unprocessable Entity"; case 423: return "Locked"; case 424: return "Failed Dependency"; case 425: return "Too Early"; case 426: return "Upgrade Required"; case 428: return "Precondition Required"; case 429: return "Too Many Requests"; case 431: return "Request Header Fields Too Large"; case 451: return "Unavailable For Legal Reasons"; case 499: // nginx's extension to the standard return "Client Closed Request"; case 500: return "Internal Server Error"; case 501: return "Not Implemented"; case 502: return "Bad Gateway"; case 503: return "Service Unavailable"; case 504: return "Gateway Timeout"; case 505: return "HTTP Version Not Supported"; case 506: return "Variant Also Negotiates"; case 507: return "Insufficient Storage"; case 508: return "Loop Detected"; case 510: return "Not Extended"; case 511: return "Network Authentication Required"; default: if(code >= 100 && code < 200) return "Informational"; if(code >= 200 && code < 300) return "Successful"; if(code >= 300 && code < 400) return "Redirection"; if(code >= 400 && code < 500) return "Client Error"; if(code >= 500 && code < 600) return "Server Error"; return "Undefined Error"; } } static struct { const char *extension; uint32_t hash; HTTP_CONTENT_TYPE contenttype; } mime_types[] = { { "html" , 0 , CT_TEXT_HTML } , { "js" , 0 , CT_APPLICATION_X_JAVASCRIPT } , { "css" , 0 , CT_TEXT_CSS } , { "xml" , 0 , CT_TEXT_XML } , { "xsl" , 0 , CT_TEXT_XSL } , { "txt" , 0 , CT_TEXT_PLAIN } , { "svg" , 0 , CT_IMAGE_SVG_XML } , { "ttf" , 0 , CT_APPLICATION_X_FONT_TRUETYPE } , { "otf" , 0 , CT_APPLICATION_X_FONT_OPENTYPE } , { "woff2", 0 , CT_APPLICATION_FONT_WOFF2 } , { "woff" , 0 , CT_APPLICATION_FONT_WOFF } , { "eot" , 0 , CT_APPLICATION_VND_MS_FONTOBJ } , { "png" , 0 , CT_IMAGE_PNG } , { "jpg" , 0 , CT_IMAGE_JPG } , { "jpeg" , 0 , CT_IMAGE_JPG } , { "gif" , 0 , CT_IMAGE_GIF } , { "bmp" , 0 , CT_IMAGE_BMP } , { "ico" , 0 , CT_IMAGE_XICON } , { "icns" , 0 , CT_IMAGE_ICNS } // terminator , { NULL , 0 , 0 } }; HTTP_CONTENT_TYPE contenttype_for_filename(const char *filename) { // netdata_log_info("checking filename '%s'", filename); static int initialized = 0; int i; if(unlikely(!initialized)) { for (i = 0; mime_types[i].extension; i++) mime_types[i].hash = simple_hash(mime_types[i].extension); initialized = 1; } const char *s = filename, *last_dot = NULL; // find the last dot while(*s) { if(unlikely(*s == '.')) last_dot = s; s++; } if(unlikely(!last_dot || !*last_dot || !last_dot[1])) { // netdata_log_info("no extension for filename '%s'", filename); return CT_APPLICATION_OCTET_STREAM; } last_dot++; // netdata_log_info("extension for filename '%s' is '%s'", filename, last_dot); uint32_t hash = simple_hash(last_dot); for(i = 0; mime_types[i].extension ; i++) { if(unlikely(hash == mime_types[i].hash && !strcmp(last_dot, mime_types[i].extension))) { // netdata_log_info("matched extension for filename '%s': '%s'", filename, last_dot); return mime_types[i].contenttype; } } // netdata_log_info("not matched extension for filename '%s': '%s'", filename, last_dot); return CT_APPLICATION_OCTET_STREAM; }