master
c 245 lines 7.04 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "../libnetdata.h"
4
5 ENUM_STR_MAP_DEFINE(HTTP_REQUEST_MODE) =
6 {
7 { .name = "OPTIONS", .id = HTTP_REQUEST_MODE_OPTIONS },
8 { .name = "GET", .id = HTTP_REQUEST_MODE_GET },
9 { .name = "POST", .id = HTTP_REQUEST_MODE_POST },
10 { .name = "PUT", .id = HTTP_REQUEST_MODE_PUT },
11 { .name = "DELETE", .id = HTTP_REQUEST_MODE_DELETE },
12 { .name = "STREAM", .id = HTTP_REQUEST_MODE_STREAM },
13
14 // terminator
15 { .name = NULL, .id = 0 }
16 };
17
18 ENUM_STR_DEFINE_FUNCTIONS(HTTP_REQUEST_MODE, 0, "UNKNOWN");
19
20 const char *http_response_code2string(int code) {
21 switch(code) {
22 case 100:
23 return "Continue";
24 case 101:
25 return "Switching Protocols";
26 case 102:
27 return "Processing";
28 case 103:
29 return "Early Hints";
30
31 case 200:
32 return "OK";
33 case 201:
34 return "Created";
35 case 202:
36 return "Accepted";
37 case 203:
38 return "Non-Authoritative Information";
39 case 204:
40 return "No Content";
41 case 205:
42 return "Reset Content";
43 case 206:
44 return "Partial Content";
45 case 207:
46 return "Multi-Status";
47 case 208:
48 return "Already Reported";
49 case 226:
50 return "IM Used";
51
52 case 300:
53 return "Multiple Choices";
54 case 301:
55 return "Moved Permanently";
56 case 302:
57 return "Found";
58 case 303:
59 return "See Other";
60 case 304:
61 return "Not Modified";
62 case 305:
63 return "Use Proxy";
64 case 306:
65 return "Switch Proxy";
66 case 307:
67 return "Temporary Redirect";
68 case 308:
69 return "Permanent Redirect";
70
71 case 400:
72 return "Bad Request";
73 case 401:
74 return "Unauthorized";
75 case 402:
76 return "Payment Required";
77 case 403:
78 return "Forbidden";
79 case 404:
80 return "Not Found";
81 case 405:
82 return "Method Not Allowed";
83 case 406:
84 return "Not Acceptable";
85 case 407:
86 return "Proxy Authentication Required";
87 case 408:
88 return "Request Timeout";
89 case 409:
90 return "Conflict";
91 case 410:
92 return "Gone";
93 case 411:
94 return "Length Required";
95 case 412:
96 return "Precondition Failed";
97 case 413:
98 return "Payload Too Large";
99 case 414:
100 return "URI Too Long";
101 case 415:
102 return "Unsupported Media Type";
103 case 416:
104 return "Range Not Satisfiable";
105 case 417:
106 return "Expectation Failed";
107 case 418:
108 return "I'm a teapot";
109 case 421:
110 return "Misdirected Request";
111 case 422:
112 return "Unprocessable Entity";
113 case 423:
114 return "Locked";
115 case 424:
116 return "Failed Dependency";
117 case 425:
118 return "Too Early";
119 case 426:
120 return "Upgrade Required";
121 case 428:
122 return "Precondition Required";
123 case 429:
124 return "Too Many Requests";
125 case 431:
126 return "Request Header Fields Too Large";
127 case 451:
128 return "Unavailable For Legal Reasons";
129 case 499: // nginx's extension to the standard
130 return "Client Closed Request";
131
132 case 500:
133 return "Internal Server Error";
134 case 501:
135 return "Not Implemented";
136 case 502:
137 return "Bad Gateway";
138 case 503:
139 return "Service Unavailable";
140 case 504:
141 return "Gateway Timeout";
142 case 505:
143 return "HTTP Version Not Supported";
144 case 506:
145 return "Variant Also Negotiates";
146 case 507:
147 return "Insufficient Storage";
148 case 508:
149 return "Loop Detected";
150 case 510:
151 return "Not Extended";
152 case 511:
153 return "Network Authentication Required";
154
155 default:
156 if(code >= 100 && code < 200)
157 return "Informational";
158
159 if(code >= 200 && code < 300)
160 return "Successful";
161
162 if(code >= 300 && code < 400)
163 return "Redirection";
164
165 if(code >= 400 && code < 500)
166 return "Client Error";
167
168 if(code >= 500 && code < 600)
169 return "Server Error";
170
171 return "Undefined Error";
172 }
173 }
174
175
176 static struct {
177 const char *extension;
178 uint32_t hash;
179 HTTP_CONTENT_TYPE contenttype;
180 } mime_types[] = {
181 { "html" , 0 , CT_TEXT_HTML }
182 , { "js" , 0 , CT_APPLICATION_X_JAVASCRIPT }
183 , { "css" , 0 , CT_TEXT_CSS }
184 , { "xml" , 0 , CT_TEXT_XML }
185 , { "xsl" , 0 , CT_TEXT_XSL }
186 , { "txt" , 0 , CT_TEXT_PLAIN }
187 , { "svg" , 0 , CT_IMAGE_SVG_XML }
188 , { "ttf" , 0 , CT_APPLICATION_X_FONT_TRUETYPE }
189 , { "otf" , 0 , CT_APPLICATION_X_FONT_OPENTYPE }
190 , { "woff2", 0 , CT_APPLICATION_FONT_WOFF2 }
191 , { "woff" , 0 , CT_APPLICATION_FONT_WOFF }
192 , { "eot" , 0 , CT_APPLICATION_VND_MS_FONTOBJ }
193 , { "png" , 0 , CT_IMAGE_PNG }
194 , { "jpg" , 0 , CT_IMAGE_JPG }
195 , { "jpeg" , 0 , CT_IMAGE_JPG }
196 , { "gif" , 0 , CT_IMAGE_GIF }
197 , { "bmp" , 0 , CT_IMAGE_BMP }
198 , { "ico" , 0 , CT_IMAGE_XICON }
199 , { "icns" , 0 , CT_IMAGE_ICNS }
200 , { "wasm" , 0 , CT_APPLICATION_WASM }
201
202 // terminator
203 , { NULL , 0 , 0 }
204 };
205
206 HTTP_CONTENT_TYPE contenttype_for_filename(const char *filename) {
207 // netdata_log_info("checking filename '%s'", filename);
208
209 static int initialized = 0;
210 int i;
211
212 if(unlikely(!initialized)) {
213 for (i = 0; mime_types[i].extension; i++)
214 mime_types[i].hash = simple_hash(mime_types[i].extension);
215
216 initialized = 1;
217 }
218
219 const char *s = filename, *last_dot = NULL;
220
221 // find the last dot
222 while(*s) {
223 if(unlikely(*s == '.')) last_dot = s;
224 s++;
225 }
226
227 if(unlikely(!last_dot || !*last_dot || !last_dot[1])) {
228 // netdata_log_info("no extension for filename '%s'", filename);
229 return CT_APPLICATION_OCTET_STREAM;
230 }
231 last_dot++;
232
233 // netdata_log_info("extension for filename '%s' is '%s'", filename, last_dot);
234
235 uint32_t hash = simple_hash(last_dot);
236 for(i = 0; mime_types[i].extension ; i++) {
237 if(unlikely(hash == mime_types[i].hash && !strcmp(last_dot, mime_types[i].extension))) {
238 // netdata_log_info("matched extension for filename '%s': '%s'", filename, last_dot);
239 return mime_types[i].contenttype;
240 }
241 }
242
243 // netdata_log_info("not matched extension for filename '%s': '%s'", filename, last_dot);
244 return CT_APPLICATION_OCTET_STREAM;
245 }