nxt_http_parse_test.c (384:8f86d3ff3e29) nxt_http_parse_test.c (417:47366bb40f2c)
1
2/*
3 * Copyright (C) NGINX, Inc.
4 * Copyright (C) Valentin V. Bartenev
5 */
6
7#include <nxt_main.h>
8#include "nxt_tests.h"

--- 33 unchanged lines hidden (view full) ---

42
43 nxt_http_parse_test_data_t data;
44} nxt_http_parse_test_case_t;
45
46
47static nxt_int_t nxt_http_parse_test_run(nxt_http_request_parse_t *rp,
48 nxt_str_t *request);
49static nxt_int_t nxt_http_parse_test_bench(nxt_thread_t *thr,
1
2/*
3 * Copyright (C) NGINX, Inc.
4 * Copyright (C) Valentin V. Bartenev
5 */
6
7#include <nxt_main.h>
8#include "nxt_tests.h"

--- 33 unchanged lines hidden (view full) ---

42
43 nxt_http_parse_test_data_t data;
44} nxt_http_parse_test_case_t;
45
46
47static nxt_int_t nxt_http_parse_test_run(nxt_http_request_parse_t *rp,
48 nxt_str_t *request);
49static nxt_int_t nxt_http_parse_test_bench(nxt_thread_t *thr,
50 nxt_str_t *request, nxt_http_fields_hash_t *hash, const char *name,
51 nxt_uint_t n);
50 nxt_str_t *request, nxt_lvlhsh_t *hash, const char *name, nxt_uint_t n);
52static nxt_int_t nxt_http_parse_test_request_line(nxt_http_request_parse_t *rp,
53 nxt_http_parse_test_data_t *data,
54 nxt_str_t *request, nxt_log_t *log);
55static nxt_int_t nxt_http_parse_test_fields(nxt_http_request_parse_t *rp,
56 nxt_http_parse_test_data_t *data, nxt_str_t *request, nxt_log_t *log);
57
58
59static nxt_int_t nxt_http_test_header_return(void *ctx, nxt_http_field_t *field,
51static nxt_int_t nxt_http_parse_test_request_line(nxt_http_request_parse_t *rp,
52 nxt_http_parse_test_data_t *data,
53 nxt_str_t *request, nxt_log_t *log);
54static nxt_int_t nxt_http_parse_test_fields(nxt_http_request_parse_t *rp,
55 nxt_http_parse_test_data_t *data, nxt_str_t *request, nxt_log_t *log);
56
57
58static nxt_int_t nxt_http_test_header_return(void *ctx, nxt_http_field_t *field,
60 nxt_log_t *log);
59 uintptr_t data);
61
62
63static nxt_http_parse_test_case_t nxt_http_test_cases[] = {
64 {
65 nxt_string("GET / HTTP/1.0\r\n\r\n"),
66 NXT_DONE,
67 &nxt_http_parse_test_request_line,
68 { .request_line = {

--- 216 unchanged lines hidden (view full) ---

285 "X-Bad-Header: value\r\n\r\n"),
286 NXT_DONE,
287 &nxt_http_parse_test_fields,
288 { .result = NXT_ERROR }
289 },
290};
291
292
60
61
62static nxt_http_parse_test_case_t nxt_http_test_cases[] = {
63 {
64 nxt_string("GET / HTTP/1.0\r\n\r\n"),
65 NXT_DONE,
66 &nxt_http_parse_test_request_line,
67 { .request_line = {

--- 216 unchanged lines hidden (view full) ---

284 "X-Bad-Header: value\r\n\r\n"),
285 NXT_DONE,
286 &nxt_http_parse_test_fields,
287 { .result = NXT_ERROR }
288 },
289};
290
291
293static nxt_http_fields_hash_entry_t nxt_http_test_fields[] = {
292static nxt_http_field_proc_t nxt_http_test_fields[] = {
294 { nxt_string("X-Bad-Header"),
295 &nxt_http_test_header_return,
293 { nxt_string("X-Bad-Header"),
294 &nxt_http_test_header_return,
296 (uintptr_t) NXT_ERROR },
295 NXT_ERROR },
297
298 { nxt_string("X-Good-Header"),
299 &nxt_http_test_header_return,
296
297 { nxt_string("X-Good-Header"),
298 &nxt_http_test_header_return,
300 (uintptr_t) NXT_OK },
301
302 { nxt_null_string, NULL, 0 }
299 NXT_OK },
303};
304
305
300};
301
302
306static nxt_http_fields_hash_entry_t nxt_http_test_bench_fields[] = {
303static nxt_lvlhsh_t nxt_http_test_fields_hash;
304
305
306static nxt_http_field_proc_t nxt_http_test_bench_fields[] = {
307 { nxt_string("Host"),
308 &nxt_http_test_header_return, NXT_OK },
309 { nxt_string("User-Agent"),
310 &nxt_http_test_header_return, NXT_OK },
307 { nxt_string("Host"),
308 &nxt_http_test_header_return, NXT_OK },
309 { nxt_string("User-Agent"),
310 &nxt_http_test_header_return, NXT_OK },
311 { nxt_string("Accept"),
312 &nxt_http_test_header_return, NXT_OK },
311 { nxt_string("Accept-Encoding"),
312 &nxt_http_test_header_return, NXT_OK },
313 { nxt_string("Accept-Language"),
314 &nxt_http_test_header_return, NXT_OK },
315 { nxt_string("Connection"),
316 &nxt_http_test_header_return, NXT_OK },
317 { nxt_string("Content-Length"),
318 &nxt_http_test_header_return, NXT_OK },
313 { nxt_string("Accept-Encoding"),
314 &nxt_http_test_header_return, NXT_OK },
315 { nxt_string("Accept-Language"),
316 &nxt_http_test_header_return, NXT_OK },
317 { nxt_string("Connection"),
318 &nxt_http_test_header_return, NXT_OK },
319 { nxt_string("Content-Length"),
320 &nxt_http_test_header_return, NXT_OK },
321 { nxt_string("Content-Range"),
322 &nxt_http_test_header_return, NXT_OK },
319 { nxt_string("Content-Type"),
320 &nxt_http_test_header_return, NXT_OK },
323 { nxt_string("Content-Type"),
324 &nxt_http_test_header_return, NXT_OK },
325 { nxt_string("Cookie"),
326 &nxt_http_test_header_return, NXT_OK },
327 { nxt_string("Range"),
328 &nxt_http_test_header_return, NXT_OK },
329 { nxt_string("If-Range"),
330 &nxt_http_test_header_return, NXT_OK },
331 { nxt_string("Transfer-Encoding"),
332 &nxt_http_test_header_return, NXT_OK },
333 { nxt_string("Expect"),
334 &nxt_http_test_header_return, NXT_OK },
335 { nxt_string("Via"),
336 &nxt_http_test_header_return, NXT_OK },
321 { nxt_string("If-Modified-Since"),
322 &nxt_http_test_header_return, NXT_OK },
337 { nxt_string("If-Modified-Since"),
338 &nxt_http_test_header_return, NXT_OK },
339 { nxt_string("If-Unmodified-Since"),
340 &nxt_http_test_header_return, NXT_OK },
323 { nxt_string("If-Match"),
324 &nxt_http_test_header_return, NXT_OK },
341 { nxt_string("If-Match"),
342 &nxt_http_test_header_return, NXT_OK },
343 { nxt_string("If-None-Match"),
344 &nxt_http_test_header_return, NXT_OK },
345 { nxt_string("Referer"),
346 &nxt_http_test_header_return, NXT_OK },
325 { nxt_string("Date"),
326 &nxt_http_test_header_return, NXT_OK },
327 { nxt_string("Upgrade"),
328 &nxt_http_test_header_return, NXT_OK },
347 { nxt_string("Date"),
348 &nxt_http_test_header_return, NXT_OK },
349 { nxt_string("Upgrade"),
350 &nxt_http_test_header_return, NXT_OK },
351 { nxt_string("Authorization"),
352 &nxt_http_test_header_return, NXT_OK },
353 { nxt_string("Keep-Alive"),
354 &nxt_http_test_header_return, NXT_OK },
329 { nxt_string("X-Forwarded-For"),
330 &nxt_http_test_header_return, NXT_OK },
355 { nxt_string("X-Forwarded-For"),
356 &nxt_http_test_header_return, NXT_OK },
357 { nxt_string("X-Forwarded-Host"),
358 &nxt_http_test_header_return, NXT_OK },
359 { nxt_string("X-Forwarded-Proto"),
360 &nxt_http_test_header_return, NXT_OK },
361 { nxt_string("X-Http-Method-Override"),
362 &nxt_http_test_header_return, NXT_OK },
363 { nxt_string("X-Real-IP"),
364 &nxt_http_test_header_return, NXT_OK },
331 { nxt_string("X-Request-ID"),
332 &nxt_http_test_header_return, NXT_OK },
365 { nxt_string("X-Request-ID"),
366 &nxt_http_test_header_return, NXT_OK },
333
334 { nxt_null_string, NULL, 0 }
367 { nxt_string("TE"),
368 &nxt_http_test_header_return, NXT_OK },
369 { nxt_string("Pragma"),
370 &nxt_http_test_header_return, NXT_OK },
371 { nxt_string("Cache-Control"),
372 &nxt_http_test_header_return, NXT_OK },
373 { nxt_string("Origin"),
374 &nxt_http_test_header_return, NXT_OK },
375 { nxt_string("Upgrade-Insecure-Requests"),
376 &nxt_http_test_header_return, NXT_OK },
335};
336
337
338static nxt_str_t nxt_http_test_simple_request = nxt_string(
339 "GET /page HTTP/1.1\r\n"
340 "Host: example.com\r\n\r\n"
341);
342

--- 70 unchanged lines hidden (view full) ---

413);
414
415
416nxt_int_t
417nxt_http_parse_test(nxt_thread_t *thr)
418{
419 nxt_mp_t *mp, *mp_temp;
420 nxt_int_t rc;
377};
378
379
380static nxt_str_t nxt_http_test_simple_request = nxt_string(
381 "GET /page HTTP/1.1\r\n"
382 "Host: example.com\r\n\r\n"
383);
384

--- 70 unchanged lines hidden (view full) ---

455);
456
457
458nxt_int_t
459nxt_http_parse_test(nxt_thread_t *thr)
460{
461 nxt_mp_t *mp, *mp_temp;
462 nxt_int_t rc;
421 nxt_uint_t i;
422 nxt_http_fields_hash_t *hash;
463 nxt_uint_t i, colls, lvl_colls;
464 nxt_lvlhsh_t hash;
423 nxt_http_request_parse_t rp;
424 nxt_http_parse_test_case_t *test;
425
426 nxt_thread_time_update(thr);
427
428 mp = nxt_mp_create(1024, 128, 256, 32);
429 if (mp == NULL) {
430 return NXT_ERROR;
431 }
432
465 nxt_http_request_parse_t rp;
466 nxt_http_parse_test_case_t *test;
467
468 nxt_thread_time_update(thr);
469
470 mp = nxt_mp_create(1024, 128, 256, 32);
471 if (mp == NULL) {
472 return NXT_ERROR;
473 }
474
433 hash = nxt_http_fields_hash_create(nxt_http_test_fields, mp);
434 if (hash == NULL) {
475 rc = nxt_http_fields_hash(&nxt_http_test_fields_hash, mp,
476 nxt_http_test_fields,
477 nxt_nitems(nxt_http_test_fields));
478 if (rc != NXT_OK) {
435 return NXT_ERROR;
436 }
437
438 for (i = 0; i < nxt_nitems(nxt_http_test_cases); i++) {
439 test = &nxt_http_test_cases[i];
440
441 nxt_memzero(&rp, sizeof(nxt_http_request_parse_t));
442
443 mp_temp = nxt_mp_create(1024, 128, 256, 32);
444 if (mp_temp == NULL) {
445 return NXT_ERROR;
446 }
447
448 if (nxt_http_parse_request_init(&rp, mp_temp) != NXT_OK) {
449 return NXT_ERROR;
450 }
451
479 return NXT_ERROR;
480 }
481
482 for (i = 0; i < nxt_nitems(nxt_http_test_cases); i++) {
483 test = &nxt_http_test_cases[i];
484
485 nxt_memzero(&rp, sizeof(nxt_http_request_parse_t));
486
487 mp_temp = nxt_mp_create(1024, 128, 256, 32);
488 if (mp_temp == NULL) {
489 return NXT_ERROR;
490 }
491
492 if (nxt_http_parse_request_init(&rp, mp_temp) != NXT_OK) {
493 return NXT_ERROR;
494 }
495
452 rp.fields_hash = hash;
453
454 rc = nxt_http_parse_test_run(&rp, &test->request);
455
456 if (rc != test->result) {
457 nxt_log_alert(thr->log, "http parse test case failed:\n"
458 " - request:\n\"%V\"\n"
459 " - result: %i (expected: %i)",
460 &test->request, rc, test->result);
461 return NXT_ERROR;

--- 6 unchanged lines hidden (view full) ---

468 return NXT_ERROR;
469 }
470
471 nxt_mp_destroy(mp_temp);
472 }
473
474 nxt_log_error(NXT_LOG_NOTICE, thr->log, "http parse test passed");
475
496 rc = nxt_http_parse_test_run(&rp, &test->request);
497
498 if (rc != test->result) {
499 nxt_log_alert(thr->log, "http parse test case failed:\n"
500 " - request:\n\"%V\"\n"
501 " - result: %i (expected: %i)",
502 &test->request, rc, test->result);
503 return NXT_ERROR;

--- 6 unchanged lines hidden (view full) ---

510 return NXT_ERROR;
511 }
512
513 nxt_mp_destroy(mp_temp);
514 }
515
516 nxt_log_error(NXT_LOG_NOTICE, thr->log, "http parse test passed");
517
476 hash = nxt_http_fields_hash_create(nxt_http_test_bench_fields, mp);
477 if (hash == NULL) {
518 nxt_memzero(&hash, sizeof(nxt_lvlhsh_t));
519
520 colls = nxt_http_fields_hash_collisions(&hash, mp,
521 nxt_http_test_bench_fields,
522 nxt_nitems(nxt_http_test_bench_fields),
523 0);
524
525 nxt_memzero(&hash, sizeof(nxt_lvlhsh_t));
526
527 lvl_colls = nxt_http_fields_hash_collisions(&hash, mp,
528 nxt_http_test_bench_fields,
529 nxt_nitems(nxt_http_test_bench_fields),
530 1);
531
532 nxt_log_error(NXT_LOG_NOTICE, thr->log,
533 "http parse test hash collisions %ui out of %ui, level: %ui",
534 colls, nxt_nitems(nxt_http_test_bench_fields), lvl_colls);
535
536 nxt_memzero(&hash, sizeof(nxt_lvlhsh_t));
537
538 rc = nxt_http_fields_hash(&hash, mp, nxt_http_test_bench_fields,
539 nxt_nitems(nxt_http_test_bench_fields));
540 if (rc != NXT_OK) {
478 return NXT_ERROR;
479 }
480
481 if (nxt_http_parse_test_bench(thr, &nxt_http_test_simple_request,
541 return NXT_ERROR;
542 }
543
544 if (nxt_http_parse_test_bench(thr, &nxt_http_test_simple_request,
482 hash, "simple", 10000000)
545 &hash, "simple", 1000000)
483 != NXT_OK)
484 {
485 return NXT_ERROR;
486 }
487
488 if (nxt_http_parse_test_bench(thr, &nxt_http_test_big_request,
546 != NXT_OK)
547 {
548 return NXT_ERROR;
549 }
550
551 if (nxt_http_parse_test_bench(thr, &nxt_http_test_big_request,
489 hash, "big", 100000)
552 &hash, "big", 100000)
490 != NXT_OK)
491 {
492 return NXT_ERROR;
493 }
494
495 nxt_mp_destroy(mp);
496
497 return NXT_OK;

--- 18 unchanged lines hidden (view full) ---

516 } while (buf.free < buf.end && rc == NXT_AGAIN);
517
518 return rc;
519}
520
521
522static nxt_int_t
523nxt_http_parse_test_bench(nxt_thread_t *thr, nxt_str_t *request,
553 != NXT_OK)
554 {
555 return NXT_ERROR;
556 }
557
558 nxt_mp_destroy(mp);
559
560 return NXT_OK;

--- 18 unchanged lines hidden (view full) ---

579 } while (buf.free < buf.end && rc == NXT_AGAIN);
580
581 return rc;
582}
583
584
585static nxt_int_t
586nxt_http_parse_test_bench(nxt_thread_t *thr, nxt_str_t *request,
524 nxt_http_fields_hash_t *hash, const char *name, nxt_uint_t n)
587 nxt_lvlhsh_t *hash, const char *name, nxt_uint_t n)
525{
526 nxt_mp_t *mp;
527 nxt_nsec_t start, end;
528 nxt_uint_t i;
529 nxt_buf_mem_t buf;
530 nxt_http_request_parse_t rp;
531
532 nxt_log_error(NXT_LOG_NOTICE, thr->log,

--- 13 unchanged lines hidden (view full) ---

546 if (nxt_slow_path(mp == NULL)) {
547 return NXT_ERROR;
548 }
549
550 if (nxt_slow_path(nxt_http_parse_request_init(&rp, mp) != NXT_OK)) {
551 return NXT_ERROR;
552 }
553
588{
589 nxt_mp_t *mp;
590 nxt_nsec_t start, end;
591 nxt_uint_t i;
592 nxt_buf_mem_t buf;
593 nxt_http_request_parse_t rp;
594
595 nxt_log_error(NXT_LOG_NOTICE, thr->log,

--- 13 unchanged lines hidden (view full) ---

609 if (nxt_slow_path(mp == NULL)) {
610 return NXT_ERROR;
611 }
612
613 if (nxt_slow_path(nxt_http_parse_request_init(&rp, mp) != NXT_OK)) {
614 return NXT_ERROR;
615 }
616
554 rp.fields_hash = hash;
555
556 buf.pos = buf.start;
557 buf.free = buf.end;
558
559 if (nxt_slow_path(nxt_http_parse_request(&rp, &buf) != NXT_DONE)) {
560 nxt_log_alert(thr->log, "http parse %s request bench failed "
561 "while parsing", name);
562 return NXT_ERROR;
563 }
564
617 buf.pos = buf.start;
618 buf.free = buf.end;
619
620 if (nxt_slow_path(nxt_http_parse_request(&rp, &buf) != NXT_DONE)) {
621 nxt_log_alert(thr->log, "http parse %s request bench failed "
622 "while parsing", name);
623 return NXT_ERROR;
624 }
625
565 if (nxt_slow_path(nxt_http_fields_process(rp.fields, NULL, thr->log)
626 if (nxt_slow_path(nxt_http_fields_process(rp.fields, hash, NULL)
566 != NXT_OK))
567 {
568 nxt_log_alert(thr->log, "http parse %s request bench failed "
569 "while fields processing", name);
570 return NXT_ERROR;
571 }
572
573 nxt_mp_destroy(mp);

--- 114 unchanged lines hidden (view full) ---

688
689
690static nxt_int_t
691nxt_http_parse_test_fields(nxt_http_request_parse_t *rp,
692 nxt_http_parse_test_data_t *data, nxt_str_t *request, nxt_log_t *log)
693{
694 nxt_int_t rc;
695
627 != NXT_OK))
628 {
629 nxt_log_alert(thr->log, "http parse %s request bench failed "
630 "while fields processing", name);
631 return NXT_ERROR;
632 }
633
634 nxt_mp_destroy(mp);

--- 114 unchanged lines hidden (view full) ---

749
750
751static nxt_int_t
752nxt_http_parse_test_fields(nxt_http_request_parse_t *rp,
753 nxt_http_parse_test_data_t *data, nxt_str_t *request, nxt_log_t *log)
754{
755 nxt_int_t rc;
756
696 rc = nxt_http_fields_process(rp->fields, NULL, log);
757 rc = nxt_http_fields_process(rp->fields, &nxt_http_test_fields_hash, NULL);
697
698 if (rc != data->result) {
699 nxt_log_alert(log, "http parse test hash failed:\n"
700 " - request:\n\"%V\"\n"
701 " - result: %i (expected: %i)",
702 request, rc, data->result);
703 return NXT_ERROR;
704 }
705
706 return NXT_OK;
707}
708
709
710static nxt_int_t
758
759 if (rc != data->result) {
760 nxt_log_alert(log, "http parse test hash failed:\n"
761 " - request:\n\"%V\"\n"
762 " - result: %i (expected: %i)",
763 request, rc, data->result);
764 return NXT_ERROR;
765 }
766
767 return NXT_OK;
768}
769
770
771static nxt_int_t
711nxt_http_test_header_return(void *ctx, nxt_http_field_t *field, nxt_log_t *log)
772nxt_http_test_header_return(void *ctx, nxt_http_field_t *field, uintptr_t data)
712{
773{
713 return (nxt_int_t) field->data;
774 return data;
714}
775}