Deleted
Added
nxt_http_parse.c (16:c382e548cbb6) | nxt_http_parse.c (19:385969e9f503) |
---|---|
1 2/* 3 * Copyright (C) NGINX, Inc. 4 * Copyright (C) Valentin V. Bartenev 5 */ 6 7#include <nxt_main.h> 8 | 1 2/* 3 * Copyright (C) NGINX, Inc. 4 * Copyright (C) Valentin V. Bartenev 5 */ 6 7#include <nxt_main.h> 8 |
9#ifdef __SSE4_2__ 10#include <x86intrin.h> 11#endif | |
12 | 9 |
13 | |
14typedef struct { 15 nxt_http_field_handler_t handler; 16 uintptr_t data; 17 union { 18 uint8_t str[8]; 19 uint64_t ui64; 20 } key[]; 21} nxt_http_fields_hash_entry_t; --- 101 unchanged lines hidden (view full) --- 123 } 124 125 *pos = p; 126 127 return trap; 128} 129 130 | 10typedef struct { 11 nxt_http_field_handler_t handler; 12 uintptr_t data; 13 union { 14 uint8_t str[8]; 15 uint64_t ui64; 16 } key[]; 17} nxt_http_fields_hash_entry_t; --- 101 unchanged lines hidden (view full) --- 119 } 120 121 *pos = p; 122 123 return trap; 124} 125 126 |
131#ifdef __SSE4_2__ 132 133nxt_inline nxt_http_target_traps_e 134nxt_http_parse_target_rest(u_char **pos, u_char *end) 135{ 136 int n; 137 u_char *p; 138 nxt_uint_t i; 139 140 static const u_char stop_chars[16] nxt_aligned(16) = " #\r\n"; 141 142 __m128i pattern = _mm_load_si128((__m128i *) stop_chars); 143 144 p = *pos; 145 146 for (n = (end - p) / 16; nxt_fast_path(n != 0); n--) { 147 148 __m128i test = _mm_loadu_si128((__m128i *) p); 149 150 i = _mm_cmpistri(pattern, test, _SIDD_LEAST_SIGNIFICANT 151 | _SIDD_CMP_EQUAL_ANY 152 | _SIDD_UBYTE_OPS); 153 154 p += i; 155 156 if (i != 16) { 157 *pos = p; 158 return nxt_http_target_chars[*p]; 159 } 160 } 161 162 *pos = p; 163 164 return nxt_http_parse_target(pos, end); 165} 166 167#else 168#define nxt_http_parse_target_rest nxt_http_parse_target 169#endif 170 171 | |
172nxt_int_t 173nxt_http_parse_request(nxt_http_request_parse_t *rp, nxt_buf_mem_t *b) 174{ 175 nxt_int_t rc; 176 177 if (rp->handler == NULL) { 178 rp->handler = &nxt_http_parse_request_line; 179 } --- 73 unchanged lines hidden (view full) --- 253 p++; 254 255 if (nxt_slow_path(p == end)) { 256 return NXT_AGAIN; 257 } 258 259 /* target */ 260 | 127nxt_int_t 128nxt_http_parse_request(nxt_http_request_parse_t *rp, nxt_buf_mem_t *b) 129{ 130 nxt_int_t rc; 131 132 if (rp->handler == NULL) { 133 rp->handler = &nxt_http_parse_request_line; 134 } --- 73 unchanged lines hidden (view full) --- 208 p++; 209 210 if (nxt_slow_path(p == end)) { 211 return NXT_AGAIN; 212 } 213 214 /* target */ 215 |
261 nxt_prefetch(&nxt_http_target_chars[' ']); 262 nxt_prefetch(&nxt_http_target_chars['@']); 263 nxt_prefetch(&nxt_http_target_chars['`']); 264 | |
265 ch = *p; 266 267 if (nxt_slow_path(ch != '/')) { 268 rc = nxt_http_parse_unusual_target(rp, &p, end); 269 270 if (nxt_slow_path(rc != NXT_OK)) { 271 return rc; 272 } --- 59 unchanged lines hidden (view full) --- 332 nxt_unreachable(); 333 } 334 335rest_of_target: 336 337 for ( ;; ) { 338 p++; 339 | 216 ch = *p; 217 218 if (nxt_slow_path(ch != '/')) { 219 rc = nxt_http_parse_unusual_target(rp, &p, end); 220 221 if (nxt_slow_path(rc != NXT_OK)) { 222 return rc; 223 } --- 59 unchanged lines hidden (view full) --- 283 nxt_unreachable(); 284 } 285 286rest_of_target: 287 288 for ( ;; ) { 289 p++; 290 |
340 trap = nxt_http_parse_target_rest(&p, end); | 291 trap = nxt_http_parse_target(&p, end); |
341 342 switch (trap) { 343 case NXT_HTTP_TARGET_SPACE: 344 rp->target_end = p; 345 goto space_after_target; 346 347 case NXT_HTTP_TARGET_HASH: 348 rp->complex_target = 1; --- 122 unchanged lines hidden (view full) --- 471 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 472 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 473 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 474 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 475 476 p = *pos; 477 478 size = end - p; | 292 293 switch (trap) { 294 case NXT_HTTP_TARGET_SPACE: 295 rp->target_end = p; 296 goto space_after_target; 297 298 case NXT_HTTP_TARGET_HASH: 299 rp->complex_target = 1; --- 122 unchanged lines hidden (view full) --- 422 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 423 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 424 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" 425 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 426 427 p = *pos; 428 429 size = end - p; |
430 i = rp->offset; |
|
479 | 431 |
480 for (i = rp->offset; i != size; i++) { | 432#define nxt_http_parse_field_name_step \ 433 { \ 434 ch = p[i]; \ 435 c = normal[ch]; \ 436 \ 437 if (nxt_slow_path(c == '\0')) { \ 438 goto name_end; \ 439 } \ 440 \ 441 rp->field_name_key.str[i % 32] = c; \ 442 i++; \ 443 } |
481 | 444 |
482 ch = p[i]; | 445 while (nxt_fast_path(size - i >= 8)) { 446 nxt_http_parse_field_name_step 447 nxt_http_parse_field_name_step 448 nxt_http_parse_field_name_step 449 nxt_http_parse_field_name_step |
483 | 450 |
484 c = normal[ch]; | 451 nxt_http_parse_field_name_step 452 nxt_http_parse_field_name_step 453 nxt_http_parse_field_name_step 454 nxt_http_parse_field_name_step 455 } |
485 | 456 |
486 if (nxt_fast_path(c != '\0')) { 487 rp->field_name_key.str[i % 32] = c; 488 continue; 489 } | 457 while (nxt_fast_path(i != size)) { 458 nxt_http_parse_field_name_step 459 } |
490 | 460 |
491 if (nxt_fast_path(ch == ':')) { 492 if (nxt_slow_path(i == 0)) { 493 return NXT_ERROR; 494 } | 461#undef nxt_http_parse_field_name_step |
495 | 462 |
496 *pos = &p[i] + 1; | 463 rp->offset = i; 464 rp->handler = &nxt_http_parse_field_name; |
497 | 465 |
498 rp->field_name.start = p; 499 rp->field_name.length = i; | 466 return NXT_AGAIN; |
500 | 467 |
501 rp->offset = 0; | 468name_end: |
502 | 469 |
503 return nxt_http_parse_field_value(rp, pos, end); | 470 if (nxt_fast_path(ch == ':')) { 471 if (nxt_slow_path(i == 0)) { 472 return NXT_ERROR; |
504 } 505 | 473 } 474 |
506 *pos = &p[i]; | 475 *pos = &p[i] + 1; |
507 | 476 |
508 rp->field_name.length = 0; | 477 rp->field_name.start = p; 478 rp->field_name.length = i; |
509 | 479 |
510 return nxt_http_parse_field_end(rp, pos, end); | 480 rp->offset = 0; 481 482 return nxt_http_parse_field_value(rp, pos, end); |
511 } 512 | 483 } 484 |
513 rp->offset = i; 514 rp->handler = &nxt_http_parse_field_name; | 485 *pos = &p[i]; |
515 | 486 |
516 return NXT_AGAIN; | 487 rp->field_name.length = 0; 488 489 return nxt_http_parse_field_end(rp, pos, end); |
517} 518 519 520static nxt_int_t 521nxt_http_parse_field_value(nxt_http_request_parse_t *rp, u_char **pos, 522 u_char *end) 523{ 524 u_char *p, ch; --- 54 unchanged lines hidden (view full) --- 579 return nxt_http_parse_field_end(rp, pos, end); 580} 581 582 583static u_char * 584nxt_http_lookup_field_end(u_char *p, u_char *end) 585{ 586 nxt_uint_t n; | 490} 491 492 493static nxt_int_t 494nxt_http_parse_field_value(nxt_http_request_parse_t *rp, u_char **pos, 495 u_char *end) 496{ 497 u_char *p, ch; --- 54 unchanged lines hidden (view full) --- 552 return nxt_http_parse_field_end(rp, pos, end); 553} 554 555 556static u_char * 557nxt_http_lookup_field_end(u_char *p, u_char *end) 558{ 559 nxt_uint_t n; |
587#ifdef __SSE4_2__ 588 nxt_uint_t i; | |
589 | 560 |
590 static const u_char end_chars[16] nxt_aligned(16) = "\r\n"; 591 592 __m128i pattern = _mm_load_si128((__m128i *) end_chars); 593 594 for (n = (end - p) / 16; nxt_fast_path(n != 0); n--) { 595 596 __m128i test = _mm_loadu_si128((__m128i *) p); 597 598 i = _mm_cmpistri(pattern, test, _SIDD_LEAST_SIGNIFICANT 599 | _SIDD_CMP_EQUAL_ANY 600 | _SIDD_UBYTE_OPS); 601 602 p += i; 603 604 if (i != 16) { 605 return p; 606 } 607 } 608#endif 609 | |
610#define nxt_http_lookup_field_end_step \ 611 { \ | 561#define nxt_http_lookup_field_end_step \ 562 { \ |
612 if (nxt_slow_path(*p <= '\r')) { \ | 563 if (nxt_slow_path(*p < 0x10)) { \ |
613 return p; \ 614 } \ 615 \ 616 p++; \ 617 } 618 | 564 return p; \ 565 } \ 566 \ 567 p++; \ 568 } 569 |
619 for (n = (end - p) / 8; nxt_fast_path(n != 0); n--) { | 570 for (n = (end - p) / 16; nxt_fast_path(n != 0); n--) { |
620 nxt_http_lookup_field_end_step 621 nxt_http_lookup_field_end_step 622 nxt_http_lookup_field_end_step 623 nxt_http_lookup_field_end_step 624 625 nxt_http_lookup_field_end_step 626 nxt_http_lookup_field_end_step 627 nxt_http_lookup_field_end_step 628 nxt_http_lookup_field_end_step | 571 nxt_http_lookup_field_end_step 572 nxt_http_lookup_field_end_step 573 nxt_http_lookup_field_end_step 574 nxt_http_lookup_field_end_step 575 576 nxt_http_lookup_field_end_step 577 nxt_http_lookup_field_end_step 578 nxt_http_lookup_field_end_step 579 nxt_http_lookup_field_end_step |
580 581 nxt_http_lookup_field_end_step 582 nxt_http_lookup_field_end_step 583 nxt_http_lookup_field_end_step 584 nxt_http_lookup_field_end_step 585 586 nxt_http_lookup_field_end_step 587 nxt_http_lookup_field_end_step 588 nxt_http_lookup_field_end_step 589 nxt_http_lookup_field_end_step |
|
629 } 630 | 590 } 591 |
631 switch (end - p) { 632 case 7: | 592 for (n = (end - p) / 4; nxt_fast_path(n != 0); n--) { |
633 nxt_http_lookup_field_end_step | 593 nxt_http_lookup_field_end_step |
634 case 6: | |
635 nxt_http_lookup_field_end_step | 594 nxt_http_lookup_field_end_step |
636 case 5: | |
637 nxt_http_lookup_field_end_step | 595 nxt_http_lookup_field_end_step |
638 case 4: | |
639 nxt_http_lookup_field_end_step | 596 nxt_http_lookup_field_end_step |
597 } 598 599 switch (end - p) { |
|
640 case 3: 641 nxt_http_lookup_field_end_step 642 case 2: 643 nxt_http_lookup_field_end_step 644 case 1: 645 nxt_http_lookup_field_end_step 646 case 0: 647 break; --- 26 unchanged lines hidden (view full) --- 674 } 675 } 676 677 if (nxt_fast_path(*p == '\n')) { 678 *pos = p + 1; 679 680 if (rp->field_name.length != 0) { 681 entry = nxt_http_fields_hash_lookup(rp->hash, | 600 case 3: 601 nxt_http_lookup_field_end_step 602 case 2: 603 nxt_http_lookup_field_end_step 604 case 1: 605 nxt_http_lookup_field_end_step 606 case 0: 607 break; --- 26 unchanged lines hidden (view full) --- 634 } 635 } 636 637 if (nxt_fast_path(*p == '\n')) { 638 *pos = p + 1; 639 640 if (rp->field_name.length != 0) { 641 entry = nxt_http_fields_hash_lookup(rp->hash, |
682 rp->field_name_key.ui64, 683 &rp->field_name); | 642 rp->field_name_key.ui64, 643 &rp->field_name); |
684 685 if (entry != NULL) { 686 rc = entry->handler(rp->ctx, &rp->field_name, &rp->field_value, 687 entry->data); 688 689 if (nxt_slow_path(rc != NXT_OK)) { 690 return NXT_ERROR; 691 } --- 198 unchanged lines hidden --- | 644 645 if (entry != NULL) { 646 rc = entry->handler(rp->ctx, &rp->field_name, &rp->field_value, 647 entry->data); 648 649 if (nxt_slow_path(rc != NXT_OK)) { 650 return NXT_ERROR; 651 } --- 198 unchanged lines hidden --- |