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);
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);
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[] = {
293 { nxt_string("X-Bad-Header"),
294 &nxt_http_test_header_return,
296 (uintptr_t) NXT_ERROR },
295 NXT_ERROR },
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 },
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 },
311 { nxt_string("Accept"),
312 &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 },
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 },
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 },
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 },
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 },
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 },
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 },
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;
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) {
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
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) {
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)
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)
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)
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
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)
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);
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)
773{
713 return (nxt_int_t) field->data;
774 return data;
775}