]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/test/public_func.c
buildsys: switch source download to quincy
[ceph.git] / ceph / src / civetweb / test / public_func.c
1 /* Copyright (c) 2015-2017 the Civetweb developers
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 * THE SOFTWARE.
20 */
21
22 #ifdef _MSC_VER
23 #ifndef _CRT_SECURE_NO_WARNINGS
24 #define _CRT_SECURE_NO_WARNINGS
25 #endif
26 #endif
27
28 #include <stdlib.h>
29 #include <stdio.h>
30
31 #include "public_func.h"
32 #include <civetweb.h>
33
34 /* This unit test file uses the excellent Check unit testing library.
35 * The API documentation is available here:
36 * http://check.sourceforge.net/doc/check_html/index.html
37 */
38
39 START_TEST(test_mg_version)
40 {
41 const char *ver = mg_version();
42 unsigned major = 0, minor = 0;
43 unsigned feature_files, feature_https, feature_cgi, feature_ipv6,
44 feature_websocket, feature_lua, feature_duktape, feature_caching;
45 unsigned expect_files = 0, expect_https = 0, expect_cgi = 0,
46 expect_ipv6 = 0, expect_websocket = 0, expect_lua = 0,
47 expect_duktape = 0, expect_caching = 0;
48 int ret, len;
49 char *buf;
50
51 ck_assert(ver != NULL);
52 ck_assert_str_eq(ver, CIVETWEB_VERSION);
53
54 /* check structure of version string */
55 ret = sscanf(ver, "%u.%u", &major, &minor);
56 ck_assert_int_eq(ret, 2);
57 ck_assert_uint_ge(major, 1);
58 if (major == 1) {
59 ck_assert_uint_ge(minor, 8); /* current version is 1.8 */
60 }
61
62 /* check feature */
63 feature_files = mg_check_feature(1);
64 feature_https = mg_check_feature(2);
65 feature_cgi = mg_check_feature(4);
66 feature_ipv6 = mg_check_feature(8);
67 feature_websocket = mg_check_feature(16);
68 feature_lua = mg_check_feature(32);
69 feature_duktape = mg_check_feature(64);
70 feature_caching = mg_check_feature(128);
71
72 #if !defined(NO_FILES)
73 expect_files = 1;
74 #endif
75 #if !defined(NO_SSL)
76 expect_https = 1;
77 #endif
78 #if !defined(NO_CGI)
79 expect_cgi = 1;
80 #endif
81 #if defined(USE_IPV6)
82 expect_ipv6 = 1;
83 #endif
84 #if defined(USE_WEBSOCKET)
85 expect_websocket = 1;
86 #endif
87 #if defined(USE_LUA)
88 expect_lua = 1;
89 #endif
90 #if defined(USE_DUKTAPE)
91 expect_duktape = 1;
92 #endif
93 #if !defined(NO_CACHING)
94 expect_caching = 1;
95 #endif
96
97 ck_assert_uint_eq(expect_files, !!feature_files);
98 ck_assert_uint_eq(expect_https, !!feature_https);
99 ck_assert_uint_eq(expect_cgi, !!feature_cgi);
100 ck_assert_uint_eq(expect_ipv6, !!feature_ipv6);
101 ck_assert_uint_eq(expect_websocket, !!feature_websocket);
102 ck_assert_uint_eq(expect_lua, !!feature_lua);
103 ck_assert_uint_eq(expect_duktape, !!feature_duktape);
104 ck_assert_uint_eq(expect_caching, !!feature_caching);
105
106 /* get system information */
107 len = mg_get_system_info(NULL, 0);
108 ck_assert_int_gt(len, 0);
109 buf = (char *)malloc((unsigned)len + 1);
110 ck_assert_ptr_ne(buf, NULL);
111 ret = mg_get_system_info(buf, len + 1);
112 ck_assert_int_eq(len, ret);
113 ret = (int)strlen(buf);
114 ck_assert_int_eq(len, ret);
115 free(buf);
116 }
117 END_TEST
118
119
120 START_TEST(test_mg_get_valid_options)
121 {
122 int i;
123 const struct mg_option *default_options = mg_get_valid_options();
124
125 ck_assert(default_options != NULL);
126
127 for (i = 0; default_options[i].name != NULL; i++) {
128 ck_assert(default_options[i].name != NULL);
129 ck_assert(strlen(default_options[i].name) > 0);
130 ck_assert(((int)default_options[i].type) > 0);
131 }
132
133 ck_assert(i > 0);
134 }
135 END_TEST
136
137
138 START_TEST(test_mg_get_builtin_mime_type)
139 {
140 ck_assert_str_eq(mg_get_builtin_mime_type("x.txt"), "text/plain");
141 ck_assert_str_eq(mg_get_builtin_mime_type("x.html"), "text/html");
142 ck_assert_str_eq(mg_get_builtin_mime_type("x.HTML"), "text/html");
143 ck_assert_str_eq(mg_get_builtin_mime_type("x.hTmL"), "text/html");
144 ck_assert_str_eq(mg_get_builtin_mime_type("/abc/def/ghi.htm"), "text/html");
145 ck_assert_str_eq(mg_get_builtin_mime_type("x.unknown_extention_xyz"),
146 "text/plain");
147 }
148 END_TEST
149
150
151 START_TEST(test_mg_strncasecmp)
152 {
153 ck_assert(mg_strncasecmp("abc", "abc", 3) == 0);
154 ck_assert(mg_strncasecmp("abc", "abcd", 3) == 0);
155 ck_assert(mg_strncasecmp("abc", "abcd", 4) != 0);
156 ck_assert(mg_strncasecmp("a", "A", 1) == 0);
157
158 ck_assert(mg_strncasecmp("A", "B", 1) < 0);
159 ck_assert(mg_strncasecmp("A", "b", 1) < 0);
160 ck_assert(mg_strncasecmp("a", "B", 1) < 0);
161 ck_assert(mg_strncasecmp("a", "b", 1) < 0);
162 ck_assert(mg_strncasecmp("b", "A", 1) > 0);
163 ck_assert(mg_strncasecmp("B", "A", 1) > 0);
164 ck_assert(mg_strncasecmp("b", "a", 1) > 0);
165 ck_assert(mg_strncasecmp("B", "a", 1) > 0);
166
167 ck_assert(mg_strncasecmp("xAx", "xBx", 3) < 0);
168 ck_assert(mg_strncasecmp("xAx", "xbx", 3) < 0);
169 ck_assert(mg_strncasecmp("xax", "xBx", 3) < 0);
170 ck_assert(mg_strncasecmp("xax", "xbx", 3) < 0);
171 ck_assert(mg_strncasecmp("xbx", "xAx", 3) > 0);
172 ck_assert(mg_strncasecmp("xBx", "xAx", 3) > 0);
173 ck_assert(mg_strncasecmp("xbx", "xax", 3) > 0);
174 ck_assert(mg_strncasecmp("xBx", "xax", 3) > 0);
175 }
176 END_TEST
177
178
179 START_TEST(test_mg_get_cookie)
180 {
181 char buf[32];
182 int ret;
183 const char *longcookie = "key1=1; key2=2; key3; key4=4; key5=; key6; "
184 "key7=this+is+it; key8=8; key9";
185
186 /* invalid result buffer */
187 ret = mg_get_cookie("", "notfound", NULL, 999);
188 ck_assert_int_eq(ret, -2);
189
190 /* zero size result buffer */
191 ret = mg_get_cookie("", "notfound", buf, 0);
192 ck_assert_int_eq(ret, -2);
193
194 /* too small result buffer */
195 ret = mg_get_cookie("key=toooooooooolong", "key", buf, 4);
196 ck_assert_int_eq(ret, -3);
197
198 /* key not found in string */
199 ret = mg_get_cookie("", "notfound", buf, sizeof(buf));
200 ck_assert_int_eq(ret, -1);
201
202 ret = mg_get_cookie(longcookie, "notfound", buf, sizeof(buf));
203 ck_assert_int_eq(ret, -1);
204
205 /* key not found in string */
206 ret = mg_get_cookie("key1=1; key2=2; key3=3", "notfound", buf, sizeof(buf));
207 ck_assert_int_eq(ret, -1);
208
209 /* keys are found as first, middle and last key */
210 memset(buf, 77, sizeof(buf));
211 ret = mg_get_cookie("key1=1; key2=2; key3=3", "key1", buf, sizeof(buf));
212 ck_assert_int_eq(ret, 1);
213 ck_assert_str_eq("1", buf);
214
215 memset(buf, 77, sizeof(buf));
216 ret = mg_get_cookie("key1=1; key2=2; key3=3", "key2", buf, sizeof(buf));
217 ck_assert_int_eq(ret, 1);
218 ck_assert_str_eq("2", buf);
219
220 memset(buf, 77, sizeof(buf));
221 ret = mg_get_cookie("key1=1; key2=2; key3=3", "key3", buf, sizeof(buf));
222 ck_assert_int_eq(ret, 1);
223 ck_assert_str_eq("3", buf);
224
225 /* longer value in the middle of a longer string */
226 memset(buf, 77, sizeof(buf));
227 ret = mg_get_cookie(longcookie, "key7", buf, sizeof(buf));
228 ck_assert_int_eq(ret, 10);
229 ck_assert_str_eq("this+is+it", buf);
230
231 /* key with = but without value in the middle of a longer string */
232 memset(buf, 77, sizeof(buf));
233 ret = mg_get_cookie(longcookie, "key5", buf, sizeof(buf));
234 ck_assert_int_eq(ret, 0);
235 ck_assert_str_eq("", buf);
236
237 /* key without = and without value in the middle of a longer string */
238 memset(buf, 77, sizeof(buf));
239 ret = mg_get_cookie(longcookie, "key6", buf, sizeof(buf));
240 ck_assert_int_eq(ret, -1);
241 /* TODO: mg_get_cookie and mg_get_var(2) should have the same behavior */
242 }
243 END_TEST
244
245
246 START_TEST(test_mg_get_var)
247 {
248 char buf[32];
249 int ret;
250 const char *shortquery = "key1=1&key2=2&key3=3";
251 const char *longquery = "key1=1&key2=2&key3&key4=4&key5=&key6&"
252 "key7=this+is+it&key8=8&key9&&key10=&&"
253 "key7=that+is+it&key12=12";
254
255 /* invalid result buffer */
256 ret = mg_get_var2("", 0, "notfound", NULL, 999, 0);
257 ck_assert_int_eq(ret, -2);
258
259 /* zero size result buffer */
260 ret = mg_get_var2("", 0, "notfound", buf, 0, 0);
261 ck_assert_int_eq(ret, -2);
262
263 /* too small result buffer */
264 ret = mg_get_var2("key=toooooooooolong", 19, "key", buf, 4, 0);
265 /* ck_assert_int_eq(ret, -3);
266 --> TODO: mg_get_cookie returns -3, mg_get_var -2. This should be
267 unified. */
268 ck_assert(ret < 0);
269
270 /* key not found in string */
271 ret = mg_get_var2("", 0, "notfound", buf, sizeof(buf), 0);
272 ck_assert_int_eq(ret, -1);
273
274 ret = mg_get_var2(
275 longquery, strlen(longquery), "notfound", buf, sizeof(buf), 0);
276 ck_assert_int_eq(ret, -1);
277
278 /* key not found in string */
279 ret = mg_get_var2(
280 shortquery, strlen(shortquery), "notfound", buf, sizeof(buf), 0);
281 ck_assert_int_eq(ret, -1);
282
283 /* key not found in string */
284 ret = mg_get_var2("key1=1&key2=2&key3=3&notfound=here",
285 strlen(shortquery),
286 "notfound",
287 buf,
288 sizeof(buf),
289 0);
290 ck_assert_int_eq(ret, -1);
291
292 /* key not found in string */
293 ret = mg_get_var2(
294 shortquery, strlen(shortquery), "key1", buf, sizeof(buf), 1);
295 ck_assert_int_eq(ret, -1);
296
297 /* keys are found as first, middle and last key */
298 memset(buf, 77, sizeof(buf));
299 ret = mg_get_var2(
300 shortquery, strlen(shortquery), "key1", buf, sizeof(buf), 0);
301 ck_assert_int_eq(ret, 1);
302 ck_assert_str_eq("1", buf);
303
304 memset(buf, 77, sizeof(buf));
305 ret = mg_get_var2(
306 shortquery, strlen(shortquery), "key2", buf, sizeof(buf), 0);
307 ck_assert_int_eq(ret, 1);
308 ck_assert_str_eq("2", buf);
309
310 memset(buf, 77, sizeof(buf));
311 ret = mg_get_var2(
312 shortquery, strlen(shortquery), "key3", buf, sizeof(buf), 0);
313 ck_assert_int_eq(ret, 1);
314 ck_assert_str_eq("3", buf);
315
316 /* mg_get_var call mg_get_var2 with last argument 0 */
317 memset(buf, 77, sizeof(buf));
318 ret = mg_get_var(shortquery, strlen(shortquery), "key1", buf, sizeof(buf));
319 ck_assert_int_eq(ret, 1);
320 ck_assert_str_eq("1", buf);
321
322 /* longer value in the middle of a longer string */
323 memset(buf, 77, sizeof(buf));
324 ret =
325 mg_get_var2(longquery, strlen(longquery), "key7", buf, sizeof(buf), 0);
326 ck_assert_int_eq(ret, 10);
327 ck_assert_str_eq("this is it", buf);
328
329 /* longer value in the middle of a longer string - seccond occurance of key
330 */
331 memset(buf, 77, sizeof(buf));
332 ret =
333 mg_get_var2(longquery, strlen(longquery), "key7", buf, sizeof(buf), 1);
334 ck_assert_int_eq(ret, 10);
335 ck_assert_str_eq("that is it", buf);
336
337 /* key with = but without value in the middle of a longer string */
338 memset(buf, 77, sizeof(buf));
339 ret =
340 mg_get_var2(longquery, strlen(longquery), "key5", buf, sizeof(buf), 0);
341 ck_assert_int_eq(ret, 0);
342 ck_assert_str_eq(buf, "");
343
344 /* key without = and without value in the middle of a longer string */
345 memset(buf, 77, sizeof(buf));
346 ret =
347 mg_get_var2(longquery, strlen(longquery), "key6", buf, sizeof(buf), 0);
348 ck_assert_int_eq(ret, -1);
349 ck_assert_str_eq(buf, "");
350 /* TODO: this is the same situation as with mg_get_value */
351 }
352 END_TEST
353
354
355 START_TEST(test_mg_md5)
356 {
357 char buf[33];
358 char *ret;
359 const char *long_str =
360 "_123456789A123456789B123456789C123456789D123456789E123456789F123456789"
361 "G123456789H123456789I123456789J123456789K123456789L123456789M123456789"
362 "N123456789O123456789P123456789Q123456789R123456789S123456789T123456789"
363 "U123456789V123456789W123456789X123456789Y123456789Z";
364
365 memset(buf, 77, sizeof(buf));
366 ret = mg_md5(buf, NULL);
367 ck_assert_str_eq(buf, "d41d8cd98f00b204e9800998ecf8427e");
368 ck_assert_str_eq(ret, "d41d8cd98f00b204e9800998ecf8427e");
369 ck_assert_ptr_eq(ret, buf);
370
371 memset(buf, 77, sizeof(buf));
372 ret = mg_md5(buf, "The quick brown fox jumps over the lazy dog.", NULL);
373 ck_assert_str_eq(buf, "e4d909c290d0fb1ca068ffaddf22cbd0");
374 ck_assert_str_eq(ret, "e4d909c290d0fb1ca068ffaddf22cbd0");
375 ck_assert_ptr_eq(ret, buf);
376
377 memset(buf, 77, sizeof(buf));
378 ret = mg_md5(buf,
379 "",
380 "The qu",
381 "ick bro",
382 "",
383 "wn fox ju",
384 "m",
385 "ps over the la",
386 "",
387 "",
388 "zy dog.",
389 "",
390 NULL);
391 ck_assert_str_eq(buf, "e4d909c290d0fb1ca068ffaddf22cbd0");
392 ck_assert_str_eq(ret, "e4d909c290d0fb1ca068ffaddf22cbd0");
393 ck_assert_ptr_eq(ret, buf);
394
395 memset(buf, 77, sizeof(buf));
396 ret = mg_md5(buf, long_str, NULL);
397 ck_assert_str_eq(buf, "1cb13cf9f16427807f081b2138241f08");
398 ck_assert_str_eq(ret, "1cb13cf9f16427807f081b2138241f08");
399 ck_assert_ptr_eq(ret, buf);
400
401 memset(buf, 77, sizeof(buf));
402 ret = mg_md5(buf, long_str + 1, NULL);
403 ck_assert_str_eq(buf, "cf62d3264334154f5779d3694cc5093f");
404 ck_assert_str_eq(ret, "cf62d3264334154f5779d3694cc5093f");
405 ck_assert_ptr_eq(ret, buf);
406 }
407 END_TEST
408
409
410 START_TEST(test_mg_url_encode)
411 {
412 char buf[20];
413 int ret;
414
415 memset(buf, 77, sizeof(buf));
416 ret = mg_url_encode("abc", buf, sizeof(buf));
417 ck_assert_int_eq(3, ret);
418 ck_assert_str_eq("abc", buf);
419
420 memset(buf, 77, sizeof(buf));
421 ret = mg_url_encode("a%b/c&d.e", buf, sizeof(buf));
422 ck_assert_int_eq(15, ret);
423 ck_assert_str_eq("a%25b%2fc%26d.e", buf);
424
425 memset(buf, 77, sizeof(buf));
426 ret = mg_url_encode("%%%", buf, 4);
427 ck_assert_int_eq(-1, ret);
428 ck_assert_str_eq("%25", buf);
429 }
430 END_TEST
431
432
433 START_TEST(test_mg_url_decode)
434 {
435 char buf[20];
436 int ret;
437
438 ret = mg_url_decode("abc", 3, buf, sizeof(buf), 0);
439 ck_assert_int_eq(ret, 3);
440 ck_assert_str_eq(buf, "abc");
441
442 ret = mg_url_decode("abcdef", 3, buf, sizeof(buf), 0);
443 ck_assert_int_eq(ret, 3);
444 ck_assert_str_eq(buf, "abc");
445
446 ret = mg_url_decode("x+y", 3, buf, sizeof(buf), 0);
447 ck_assert_int_eq(ret, 3);
448 ck_assert_str_eq(buf, "x+y");
449
450 ret = mg_url_decode("x+y", 3, buf, sizeof(buf), 1);
451 ck_assert_int_eq(ret, 3);
452 ck_assert_str_eq(buf, "x y");
453
454 ret = mg_url_decode("%25", 3, buf, sizeof(buf), 1);
455 ck_assert_int_eq(ret, 1);
456 ck_assert_str_eq(buf, "%");
457 }
458 END_TEST
459
460
461 START_TEST(test_mg_get_response_code_text)
462 {
463 int i;
464 size_t j, len;
465 const char *resp;
466
467 for (i = 100; i < 600; i++) {
468 resp = mg_get_response_code_text(NULL, i);
469 ck_assert_ptr_ne(resp, NULL);
470 len = strlen(resp);
471 ck_assert_uint_gt(len, 1);
472 ck_assert_uint_lt(len, 32);
473 for (j = 0; j < len; j++) {
474 if (resp[j] == ' ') {
475 /* space is valid */
476 } else if (resp[j] == '-') {
477 /* hyphen is valid */
478 } else if (resp[j] >= 'A' && resp[j] <= 'Z') {
479 /* A-Z is valid */
480 } else if (resp[j] >= 'a' && resp[j] <= 'z') {
481 /* a-z is valid */
482 } else {
483 ck_abort_msg("Found letter %c (%02xh) in %s",
484 resp[j],
485 resp[j],
486 resp);
487 }
488 }
489 }
490 }
491 END_TEST
492
493
494 #if !defined(REPLACE_CHECK_FOR_LOCAL_DEBUGGING)
495 Suite *
496 make_public_func_suite(void)
497 {
498 Suite *const suite = suite_create("PublicFunc");
499
500 TCase *const tcase_version = tcase_create("Version");
501 TCase *const tcase_get_valid_options = tcase_create("Options");
502 TCase *const tcase_get_builtin_mime_type = tcase_create("MIME types");
503 TCase *const tcase_strncasecmp = tcase_create("strcasecmp");
504 TCase *const tcase_urlencodingdecoding =
505 tcase_create("URL encoding decoding");
506 TCase *const tcase_cookies = tcase_create("Cookies and variables");
507 TCase *const tcase_md5 = tcase_create("MD5");
508 TCase *const tcase_aux = tcase_create("Aux functions");
509
510 tcase_add_test(tcase_version, test_mg_version);
511 tcase_set_timeout(tcase_version, civetweb_min_test_timeout);
512 suite_add_tcase(suite, tcase_version);
513
514 tcase_add_test(tcase_get_valid_options, test_mg_get_valid_options);
515 tcase_set_timeout(tcase_get_valid_options, civetweb_min_test_timeout);
516 suite_add_tcase(suite, tcase_get_valid_options);
517
518 tcase_add_test(tcase_get_builtin_mime_type, test_mg_get_builtin_mime_type);
519 tcase_set_timeout(tcase_get_builtin_mime_type, civetweb_min_test_timeout);
520 suite_add_tcase(suite, tcase_get_builtin_mime_type);
521
522 tcase_add_test(tcase_strncasecmp, test_mg_strncasecmp);
523 tcase_set_timeout(tcase_strncasecmp, civetweb_min_test_timeout);
524 suite_add_tcase(suite, tcase_strncasecmp);
525
526 tcase_add_test(tcase_urlencodingdecoding, test_mg_url_encode);
527 tcase_add_test(tcase_urlencodingdecoding, test_mg_url_decode);
528 tcase_set_timeout(tcase_urlencodingdecoding, civetweb_min_test_timeout);
529 suite_add_tcase(suite, tcase_urlencodingdecoding);
530
531 tcase_add_test(tcase_cookies, test_mg_get_cookie);
532 tcase_add_test(tcase_cookies, test_mg_get_var);
533 tcase_set_timeout(tcase_cookies, civetweb_min_test_timeout);
534 suite_add_tcase(suite, tcase_cookies);
535
536 tcase_add_test(tcase_md5, test_mg_md5);
537 tcase_set_timeout(tcase_md5, civetweb_min_test_timeout);
538 suite_add_tcase(suite, tcase_md5);
539
540 tcase_add_test(tcase_aux, test_mg_get_response_code_text);
541 tcase_set_timeout(tcase_aux, civetweb_min_test_timeout);
542 suite_add_tcase(suite, tcase_aux);
543
544 return suite;
545 }
546 #endif