nxt_http_route.c (1473:e07d5b451423) nxt_http_route.c (1474:9af10e099d09)
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_router.h>
8#include <nxt_http.h>

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

34
35typedef enum {
36 NXT_HTTP_ROUTE_PATTERN_NOCASE = 0,
37 NXT_HTTP_ROUTE_PATTERN_LOWCASE,
38 NXT_HTTP_ROUTE_PATTERN_UPCASE,
39} nxt_http_route_pattern_case_t;
40
41
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_router.h>
8#include <nxt_http.h>

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

34
35typedef enum {
36 NXT_HTTP_ROUTE_PATTERN_NOCASE = 0,
37 NXT_HTTP_ROUTE_PATTERN_LOWCASE,
38 NXT_HTTP_ROUTE_PATTERN_UPCASE,
39} nxt_http_route_pattern_case_t;
40
41
42typedef enum {
43 NXT_HTTP_ROUTE_ENCODING_NONE = 0,
44 NXT_HTTP_ROUTE_ENCODING_URI,
45 NXT_HTTP_ROUTE_ENCODING_URI_PLUS
46} nxt_http_route_encoding_t;
47
48
42typedef struct {
43 nxt_conf_value_t *pass;
44 nxt_conf_value_t *ret;
45 nxt_str_t location;
46 nxt_conf_value_t *share;
47 nxt_conf_value_t *proxy;
48 nxt_conf_value_t *fallback;
49} nxt_http_route_action_conf_t;

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

176static nxt_http_route_t *nxt_http_route_create(nxt_task_t *task,
177 nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
178static nxt_http_route_match_t *nxt_http_route_match_create(nxt_task_t *task,
179 nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
180static nxt_int_t nxt_http_route_action_create(nxt_router_temp_conf_t *tmcf,
181 nxt_conf_value_t *cv, nxt_http_action_t *action);
182static nxt_http_route_table_t *nxt_http_route_table_create(nxt_task_t *task,
183 nxt_mp_t *mp, nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
49typedef struct {
50 nxt_conf_value_t *pass;
51 nxt_conf_value_t *ret;
52 nxt_str_t location;
53 nxt_conf_value_t *share;
54 nxt_conf_value_t *proxy;
55 nxt_conf_value_t *fallback;
56} nxt_http_route_action_conf_t;

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

183static nxt_http_route_t *nxt_http_route_create(nxt_task_t *task,
184 nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
185static nxt_http_route_match_t *nxt_http_route_match_create(nxt_task_t *task,
186 nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
187static nxt_int_t nxt_http_route_action_create(nxt_router_temp_conf_t *tmcf,
188 nxt_conf_value_t *cv, nxt_http_action_t *action);
189static nxt_http_route_table_t *nxt_http_route_table_create(nxt_task_t *task,
190 nxt_mp_t *mp, nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
184 nxt_bool_t case_sensitive);
191 nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding);
185static nxt_http_route_ruleset_t *nxt_http_route_ruleset_create(nxt_task_t *task,
186 nxt_mp_t *mp, nxt_conf_value_t *ruleset_cv, nxt_http_route_object_t object,
192static nxt_http_route_ruleset_t *nxt_http_route_ruleset_create(nxt_task_t *task,
193 nxt_mp_t *mp, nxt_conf_value_t *ruleset_cv, nxt_http_route_object_t object,
187 nxt_bool_t case_sensitive);
194 nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding);
188static nxt_http_route_rule_t *nxt_http_route_rule_name_create(nxt_task_t *task,
189 nxt_mp_t *mp, nxt_conf_value_t *rule_cv, nxt_str_t *name,
195static nxt_http_route_rule_t *nxt_http_route_rule_name_create(nxt_task_t *task,
196 nxt_mp_t *mp, nxt_conf_value_t *rule_cv, nxt_str_t *name,
190 nxt_bool_t case_sensitive);
197 nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding);
191static nxt_http_route_addr_rule_t *nxt_http_route_addr_rule_create(
192 nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *cv);
193static nxt_http_route_rule_t *nxt_http_route_rule_create(nxt_task_t *task,
194 nxt_mp_t *mp, nxt_conf_value_t *cv, nxt_bool_t case_sensitive,
198static nxt_http_route_addr_rule_t *nxt_http_route_addr_rule_create(
199 nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *cv);
200static nxt_http_route_rule_t *nxt_http_route_rule_create(nxt_task_t *task,
201 nxt_mp_t *mp, nxt_conf_value_t *cv, nxt_bool_t case_sensitive,
195 nxt_http_route_pattern_case_t pattern_case);
202 nxt_http_route_pattern_case_t pattern_case,
203 nxt_http_route_encoding_t encoding);
196static int nxt_http_pattern_compare(const void *one, const void *two);
197static int nxt_http_addr_pattern_compare(const void *one, const void *two);
198static nxt_int_t nxt_http_route_pattern_create(nxt_task_t *task, nxt_mp_t *mp,
199 nxt_conf_value_t *cv, nxt_http_route_pattern_t *pattern,
204static int nxt_http_pattern_compare(const void *one, const void *two);
205static int nxt_http_addr_pattern_compare(const void *one, const void *two);
206static nxt_int_t nxt_http_route_pattern_create(nxt_task_t *task, nxt_mp_t *mp,
207 nxt_conf_value_t *cv, nxt_http_route_pattern_t *pattern,
200 nxt_http_route_pattern_case_t pattern_case);
208 nxt_http_route_pattern_case_t pattern_case,
209 nxt_http_route_encoding_t encoding);
210static nxt_int_t nxt_http_route_decode_str(nxt_str_t *str,
211 nxt_http_route_encoding_t encoding);
201static u_char *nxt_http_route_pattern_copy(nxt_mp_t *mp, nxt_str_t *test,
202 nxt_http_route_pattern_case_t pattern_case);
203
204static nxt_int_t nxt_http_route_resolve(nxt_task_t *task,
205 nxt_router_temp_conf_t *tmcf, nxt_http_route_t *route);
206static nxt_int_t nxt_http_action_resolve(nxt_task_t *task,
207 nxt_router_temp_conf_t *tmcf, nxt_http_action_t *action);
208static void nxt_http_route_find(nxt_http_routes_t *routes, nxt_str_t *name,

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

458 if (ret != NXT_OK) {
459 return NULL;
460 }
461
462 test = &match->test[0];
463
464 if (mtcf.scheme != NULL) {
465 rule = nxt_http_route_rule_create(task, mp, mtcf.scheme, 1,
212static u_char *nxt_http_route_pattern_copy(nxt_mp_t *mp, nxt_str_t *test,
213 nxt_http_route_pattern_case_t pattern_case);
214
215static nxt_int_t nxt_http_route_resolve(nxt_task_t *task,
216 nxt_router_temp_conf_t *tmcf, nxt_http_route_t *route);
217static nxt_int_t nxt_http_action_resolve(nxt_task_t *task,
218 nxt_router_temp_conf_t *tmcf, nxt_http_action_t *action);
219static void nxt_http_route_find(nxt_http_routes_t *routes, nxt_str_t *name,

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

469 if (ret != NXT_OK) {
470 return NULL;
471 }
472
473 test = &match->test[0];
474
475 if (mtcf.scheme != NULL) {
476 rule = nxt_http_route_rule_create(task, mp, mtcf.scheme, 1,
466 NXT_HTTP_ROUTE_PATTERN_NOCASE);
477 NXT_HTTP_ROUTE_PATTERN_NOCASE,
478 NXT_HTTP_ROUTE_ENCODING_NONE);
467 if (rule == NULL) {
468 return NULL;
469 }
470
471 rule->object = NXT_HTTP_ROUTE_SCHEME;
472 test->rule = rule;
473 test++;
474 }
475
476 if (mtcf.host != NULL) {
477 rule = nxt_http_route_rule_create(task, mp, mtcf.host, 1,
479 if (rule == NULL) {
480 return NULL;
481 }
482
483 rule->object = NXT_HTTP_ROUTE_SCHEME;
484 test->rule = rule;
485 test++;
486 }
487
488 if (mtcf.host != NULL) {
489 rule = nxt_http_route_rule_create(task, mp, mtcf.host, 1,
478 NXT_HTTP_ROUTE_PATTERN_LOWCASE);
490 NXT_HTTP_ROUTE_PATTERN_LOWCASE,
491 NXT_HTTP_ROUTE_ENCODING_NONE);
479 if (rule == NULL) {
480 return NULL;
481 }
482
483 rule->u.offset = offsetof(nxt_http_request_t, host);
484 rule->object = NXT_HTTP_ROUTE_STRING;
485 test->rule = rule;
486 test++;
487 }
488
489 if (mtcf.uri != NULL) {
490 rule = nxt_http_route_rule_create(task, mp, mtcf.uri, 1,
492 if (rule == NULL) {
493 return NULL;
494 }
495
496 rule->u.offset = offsetof(nxt_http_request_t, host);
497 rule->object = NXT_HTTP_ROUTE_STRING;
498 test->rule = rule;
499 test++;
500 }
501
502 if (mtcf.uri != NULL) {
503 rule = nxt_http_route_rule_create(task, mp, mtcf.uri, 1,
491 NXT_HTTP_ROUTE_PATTERN_NOCASE);
504 NXT_HTTP_ROUTE_PATTERN_NOCASE,
505 NXT_HTTP_ROUTE_ENCODING_URI);
492 if (rule == NULL) {
493 return NULL;
494 }
495
496 rule->u.offset = offsetof(nxt_http_request_t, path);
497 rule->object = NXT_HTTP_ROUTE_STRING_PTR;
498 test->rule = rule;
499 test++;
500 }
501
502 if (mtcf.method != NULL) {
503 rule = nxt_http_route_rule_create(task, mp, mtcf.method, 1,
506 if (rule == NULL) {
507 return NULL;
508 }
509
510 rule->u.offset = offsetof(nxt_http_request_t, path);
511 rule->object = NXT_HTTP_ROUTE_STRING_PTR;
512 test->rule = rule;
513 test++;
514 }
515
516 if (mtcf.method != NULL) {
517 rule = nxt_http_route_rule_create(task, mp, mtcf.method, 1,
504 NXT_HTTP_ROUTE_PATTERN_UPCASE);
518 NXT_HTTP_ROUTE_PATTERN_UPCASE,
519 NXT_HTTP_ROUTE_ENCODING_NONE);
505 if (rule == NULL) {
506 return NULL;
507 }
508
509 rule->u.offset = offsetof(nxt_http_request_t, method);
510 rule->object = NXT_HTTP_ROUTE_STRING_PTR;
511 test->rule = rule;
512 test++;
513 }
514
515 if (mtcf.headers != NULL) {
516 table = nxt_http_route_table_create(task, mp, mtcf.headers,
520 if (rule == NULL) {
521 return NULL;
522 }
523
524 rule->u.offset = offsetof(nxt_http_request_t, method);
525 rule->object = NXT_HTTP_ROUTE_STRING_PTR;
526 test->rule = rule;
527 test++;
528 }
529
530 if (mtcf.headers != NULL) {
531 table = nxt_http_route_table_create(task, mp, mtcf.headers,
517 NXT_HTTP_ROUTE_HEADER, 0);
532 NXT_HTTP_ROUTE_HEADER, 0,
533 NXT_HTTP_ROUTE_ENCODING_NONE);
518 if (table == NULL) {
519 return NULL;
520 }
521
522 test->table = table;
523 test++;
524 }
525
526 if (mtcf.arguments != NULL) {
527 table = nxt_http_route_table_create(task, mp, mtcf.arguments,
534 if (table == NULL) {
535 return NULL;
536 }
537
538 test->table = table;
539 test++;
540 }
541
542 if (mtcf.arguments != NULL) {
543 table = nxt_http_route_table_create(task, mp, mtcf.arguments,
528 NXT_HTTP_ROUTE_ARGUMENT, 1);
544 NXT_HTTP_ROUTE_ARGUMENT, 1,
545 NXT_HTTP_ROUTE_ENCODING_URI_PLUS);
529 if (table == NULL) {
530 return NULL;
531 }
532
533 test->table = table;
534 test++;
535 }
536
537 if (mtcf.cookies != NULL) {
538 table = nxt_http_route_table_create(task, mp, mtcf.cookies,
546 if (table == NULL) {
547 return NULL;
548 }
549
550 test->table = table;
551 test++;
552 }
553
554 if (mtcf.cookies != NULL) {
555 table = nxt_http_route_table_create(task, mp, mtcf.cookies,
539 NXT_HTTP_ROUTE_COOKIE, 1);
556 NXT_HTTP_ROUTE_COOKIE, 1,
557 NXT_HTTP_ROUTE_ENCODING_NONE);
540 if (table == NULL) {
541 return NULL;
542 }
543
544 test->table = table;
545 test++;
546 }
547

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

694
695 return NXT_OK;
696}
697
698
699static nxt_http_route_table_t *
700nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp,
701 nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
558 if (table == NULL) {
559 return NULL;
560 }
561
562 test->table = table;
563 test++;
564 }
565

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

712
713 return NXT_OK;
714}
715
716
717static nxt_http_route_table_t *
718nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp,
719 nxt_conf_value_t *table_cv, nxt_http_route_object_t object,
702 nxt_bool_t case_sensitive)
720 nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding)
703{
704 size_t size;
705 uint32_t i, n;
706 nxt_bool_t array;
707 nxt_conf_value_t *ruleset_cv;
708 nxt_http_route_table_t *table;
709 nxt_http_route_ruleset_t *ruleset;
710

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

717 if (nxt_slow_path(table == NULL)) {
718 return NULL;
719 }
720
721 table->items = n;
722 table->object = NXT_HTTP_ROUTE_TABLE;
723
724 if (!array) {
721{
722 size_t size;
723 uint32_t i, n;
724 nxt_bool_t array;
725 nxt_conf_value_t *ruleset_cv;
726 nxt_http_route_table_t *table;
727 nxt_http_route_ruleset_t *ruleset;
728

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

735 if (nxt_slow_path(table == NULL)) {
736 return NULL;
737 }
738
739 table->items = n;
740 table->object = NXT_HTTP_ROUTE_TABLE;
741
742 if (!array) {
725 ruleset = nxt_http_route_ruleset_create(task, mp, table_cv,
726 object, case_sensitive);
743 ruleset = nxt_http_route_ruleset_create(task, mp, table_cv, object,
744 case_sensitive, encoding);
727 if (nxt_slow_path(ruleset == NULL)) {
728 return NULL;
729 }
730
731 table->ruleset[0] = ruleset;
732
733 return table;
734 }
735
736 for (i = 0; i < n; i++) {
737 ruleset_cv = nxt_conf_get_array_element(table_cv, i);
738
745 if (nxt_slow_path(ruleset == NULL)) {
746 return NULL;
747 }
748
749 table->ruleset[0] = ruleset;
750
751 return table;
752 }
753
754 for (i = 0; i < n; i++) {
755 ruleset_cv = nxt_conf_get_array_element(table_cv, i);
756
739 ruleset = nxt_http_route_ruleset_create(task, mp, ruleset_cv,
740 object, case_sensitive);
757 ruleset = nxt_http_route_ruleset_create(task, mp, ruleset_cv, object,
758 case_sensitive, encoding);
741 if (nxt_slow_path(ruleset == NULL)) {
742 return NULL;
743 }
744
745 table->ruleset[i] = ruleset;
746 }
747
748 return table;
749}
750
751
752static nxt_http_route_ruleset_t *
753nxt_http_route_ruleset_create(nxt_task_t *task, nxt_mp_t *mp,
754 nxt_conf_value_t *ruleset_cv, nxt_http_route_object_t object,
759 if (nxt_slow_path(ruleset == NULL)) {
760 return NULL;
761 }
762
763 table->ruleset[i] = ruleset;
764 }
765
766 return table;
767}
768
769
770static nxt_http_route_ruleset_t *
771nxt_http_route_ruleset_create(nxt_task_t *task, nxt_mp_t *mp,
772 nxt_conf_value_t *ruleset_cv, nxt_http_route_object_t object,
755 nxt_bool_t case_sensitive)
773 nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding)
756{
757 size_t size;
758 uint32_t i, n, next;
759 nxt_str_t name;
760 nxt_conf_value_t *rule_cv;
761 nxt_http_route_rule_t *rule;
762 nxt_http_route_ruleset_t *ruleset;
763

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

773 ruleset->items = n;
774
775 next = 0;
776
777 for (i = 0; i < n; i++) {
778 rule_cv = nxt_conf_next_object_member(ruleset_cv, &name, &next);
779
780 rule = nxt_http_route_rule_name_create(task, mp, rule_cv, &name,
774{
775 size_t size;
776 uint32_t i, n, next;
777 nxt_str_t name;
778 nxt_conf_value_t *rule_cv;
779 nxt_http_route_rule_t *rule;
780 nxt_http_route_ruleset_t *ruleset;
781

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

791 ruleset->items = n;
792
793 next = 0;
794
795 for (i = 0; i < n; i++) {
796 rule_cv = nxt_conf_next_object_member(ruleset_cv, &name, &next);
797
798 rule = nxt_http_route_rule_name_create(task, mp, rule_cv, &name,
781 case_sensitive);
799 case_sensitive, encoding);
782 if (nxt_slow_path(rule == NULL)) {
783 return NULL;
784 }
785
786 rule->object = object;
787 ruleset->rule[i] = rule;
788 }
789
790 return ruleset;
791}
792
793
794static nxt_http_route_rule_t *
795nxt_http_route_rule_name_create(nxt_task_t *task, nxt_mp_t *mp,
800 if (nxt_slow_path(rule == NULL)) {
801 return NULL;
802 }
803
804 rule->object = object;
805 ruleset->rule[i] = rule;
806 }
807
808 return ruleset;
809}
810
811
812static nxt_http_route_rule_t *
813nxt_http_route_rule_name_create(nxt_task_t *task, nxt_mp_t *mp,
796 nxt_conf_value_t *rule_cv, nxt_str_t *name, nxt_bool_t case_sensitive)
814 nxt_conf_value_t *rule_cv, nxt_str_t *name, nxt_bool_t case_sensitive,
815 nxt_http_route_encoding_t encoding)
797{
816{
798 u_char c, *p;
817 u_char c, *p, *src, *start, *end, plus;
818 uint8_t d0, d1;
799 uint32_t hash;
800 nxt_uint_t i;
801 nxt_http_route_rule_t *rule;
802
803 rule = nxt_http_route_rule_create(task, mp, rule_cv, case_sensitive,
819 uint32_t hash;
820 nxt_uint_t i;
821 nxt_http_route_rule_t *rule;
822
823 rule = nxt_http_route_rule_create(task, mp, rule_cv, case_sensitive,
804 NXT_HTTP_ROUTE_PATTERN_NOCASE);
824 NXT_HTTP_ROUTE_PATTERN_NOCASE,
825 encoding);
805 if (nxt_slow_path(rule == NULL)) {
806 return NULL;
807 }
808
809 rule->u.name.length = name->length;
810
811 p = nxt_mp_nget(mp, name->length);
812 if (nxt_slow_path(p == NULL)) {
813 return NULL;
814 }
815
826 if (nxt_slow_path(rule == NULL)) {
827 return NULL;
828 }
829
830 rule->u.name.length = name->length;
831
832 p = nxt_mp_nget(mp, name->length);
833 if (nxt_slow_path(p == NULL)) {
834 return NULL;
835 }
836
837 hash = NXT_HTTP_FIELD_HASH_INIT;
816 rule->u.name.start = p;
817
838 rule->u.name.start = p;
839
818 hash = NXT_HTTP_FIELD_HASH_INIT;
840 if (encoding == NXT_HTTP_ROUTE_ENCODING_NONE) {
841 for (i = 0; i < name->length; i++) {
842 c = name->start[i];
843 *p++ = c;
819
844
820 for (i = 0; i < name->length; i++) {
821 c = name->start[i];
822 *p++ = c;
845 c = case_sensitive ? c : nxt_lowcase(c);
846 hash = nxt_http_field_hash_char(hash, c);
847 }
823
848
849 goto end;
850 }
851
852 plus = (encoding == NXT_HTTP_ROUTE_ENCODING_URI_PLUS) ? ' ' : '+';
853
854 start = name->start;
855 end = start + name->length;
856
857 for (src = start; src < end; src++) {
858 c = *src;
859
860 switch (c) {
861 case '%':
862 if (nxt_slow_path(end - src <= 2)) {
863 return NULL;
864 }
865
866 d0 = nxt_hex2int[src[1]];
867 d1 = nxt_hex2int[src[2]];
868 src += 2;
869
870 if (nxt_slow_path((d0 | d1) >= 16)) {
871 return NULL;
872 }
873
874 c = (d0 << 4) + d1;
875 *p++ = c;
876 break;
877
878 case '+':
879 c = plus;
880 *p++ = c;
881 break;
882
883 default:
884 *p++ = c;
885 break;
886 }
887
824 c = case_sensitive ? c : nxt_lowcase(c);
825 hash = nxt_http_field_hash_char(hash, c);
826 }
827
888 c = case_sensitive ? c : nxt_lowcase(c);
889 hash = nxt_http_field_hash_char(hash, c);
890 }
891
892 rule->u.name.length = p - rule->u.name.start;
893
894end:
895
828 rule->u.name.hash = nxt_http_field_hash_end(hash) & 0xFFFF;
829
830 return rule;
831}
832
833
834static nxt_http_route_rule_t *
835nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp,
836 nxt_conf_value_t *cv, nxt_bool_t case_sensitive,
896 rule->u.name.hash = nxt_http_field_hash_end(hash) & 0xFFFF;
897
898 return rule;
899}
900
901
902static nxt_http_route_rule_t *
903nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp,
904 nxt_conf_value_t *cv, nxt_bool_t case_sensitive,
837 nxt_http_route_pattern_case_t pattern_case)
905 nxt_http_route_pattern_case_t pattern_case,
906 nxt_http_route_encoding_t encoding)
838{
839 size_t size;
840 uint32_t i, n;
841 nxt_int_t ret;
842 nxt_bool_t string;
843 nxt_conf_value_t *value;
844 nxt_http_route_rule_t *rule;
845 nxt_http_route_pattern_t *pattern;

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

855
856 rule->items = n;
857
858 pattern = &rule->pattern[0];
859
860 if (string) {
861 pattern[0].case_sensitive = case_sensitive;
862 ret = nxt_http_route_pattern_create(task, mp, cv, &pattern[0],
907{
908 size_t size;
909 uint32_t i, n;
910 nxt_int_t ret;
911 nxt_bool_t string;
912 nxt_conf_value_t *value;
913 nxt_http_route_rule_t *rule;
914 nxt_http_route_pattern_t *pattern;

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

924
925 rule->items = n;
926
927 pattern = &rule->pattern[0];
928
929 if (string) {
930 pattern[0].case_sensitive = case_sensitive;
931 ret = nxt_http_route_pattern_create(task, mp, cv, &pattern[0],
863 pattern_case);
932 pattern_case, encoding);
864 if (nxt_slow_path(ret != NXT_OK)) {
865 return NULL;
866 }
867
868 return rule;
869 }
870
871 nxt_conf_array_qsort(cv, nxt_http_pattern_compare);
872
873 for (i = 0; i < n; i++) {
874 pattern[i].case_sensitive = case_sensitive;
875 value = nxt_conf_get_array_element(cv, i);
876
877 ret = nxt_http_route_pattern_create(task, mp, value, &pattern[i],
933 if (nxt_slow_path(ret != NXT_OK)) {
934 return NULL;
935 }
936
937 return rule;
938 }
939
940 nxt_conf_array_qsort(cv, nxt_http_pattern_compare);
941
942 for (i = 0; i < n; i++) {
943 pattern[i].case_sensitive = case_sensitive;
944 value = nxt_conf_get_array_element(cv, i);
945
946 ret = nxt_http_route_pattern_create(task, mp, value, &pattern[i],
878 pattern_case);
947 pattern_case, encoding);
879 if (nxt_slow_path(ret != NXT_OK)) {
880 return NULL;
881 }
882 }
883
884 return rule;
885}
886

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

967
968 return (p2->base.negative - p1->base.negative);
969}
970
971
972static nxt_int_t
973nxt_http_route_pattern_create(nxt_task_t *task, nxt_mp_t *mp,
974 nxt_conf_value_t *cv, nxt_http_route_pattern_t *pattern,
948 if (nxt_slow_path(ret != NXT_OK)) {
949 return NULL;
950 }
951 }
952
953 return rule;
954}
955

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

1036
1037 return (p2->base.negative - p1->base.negative);
1038}
1039
1040
1041static nxt_int_t
1042nxt_http_route_pattern_create(nxt_task_t *task, nxt_mp_t *mp,
1043 nxt_conf_value_t *cv, nxt_http_route_pattern_t *pattern,
975 nxt_http_route_pattern_case_t pattern_case)
1044 nxt_http_route_pattern_case_t pattern_case,
1045 nxt_http_route_encoding_t encoding)
976{
977 u_char *start;
1046{
1047 u_char *start;
978 nxt_str_t test;
1048 nxt_str_t test, test2;
1049 nxt_int_t ret;
979 nxt_uint_t n, length;
980 nxt_http_route_pattern_type_t type;
981
982 /* Suppress warning about uninitialized variable. */
983 length = 0;
984
985 type = NXT_HTTP_ROUTE_PATTERN_EXACT;
986
987 nxt_conf_get_string(cv, &test);
988
989 pattern->negative = 0;
990 pattern->any = 1;
1050 nxt_uint_t n, length;
1051 nxt_http_route_pattern_type_t type;
1052
1053 /* Suppress warning about uninitialized variable. */
1054 length = 0;
1055
1056 type = NXT_HTTP_ROUTE_PATTERN_EXACT;
1057
1058 nxt_conf_get_string(cv, &test);
1059
1060 pattern->negative = 0;
1061 pattern->any = 1;
1062 pattern->min_length = 0;
991
992 if (test.length != 0) {
993
994 if (test.start[0] == '!') {
995 test.start++;
996 test.length--;
997
998 pattern->negative = 1;
999 pattern->any = 0;
1000 }
1001
1002 if (test.length != 0) {
1063
1064 if (test.length != 0) {
1065
1066 if (test.start[0] == '!') {
1067 test.start++;
1068 test.length--;
1069
1070 pattern->negative = 1;
1071 pattern->any = 0;
1072 }
1073
1074 if (test.length != 0) {
1003
1004 if (test.start[0] == '*') {
1005 test.start++;
1006 test.length--;
1007
1008 if (test.length != 0) {
1009 if (test.start[test.length - 1] == '*') {
1010 test.length--;
1011 type = NXT_HTTP_ROUTE_PATTERN_SUBSTRING;

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

1021 } else if (test.start[test.length - 1] == '*') {
1022 test.length--;
1023 type = NXT_HTTP_ROUTE_PATTERN_BEGIN;
1024
1025 } else {
1026 length = test.length - 1;
1027
1028 for (n = 1; n < length; n++) {
1075 if (test.start[0] == '*') {
1076 test.start++;
1077 test.length--;
1078
1079 if (test.length != 0) {
1080 if (test.start[test.length - 1] == '*') {
1081 test.length--;
1082 type = NXT_HTTP_ROUTE_PATTERN_SUBSTRING;

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

1092 } else if (test.start[test.length - 1] == '*') {
1093 test.length--;
1094 type = NXT_HTTP_ROUTE_PATTERN_BEGIN;
1095
1096 } else {
1097 length = test.length - 1;
1098
1099 for (n = 1; n < length; n++) {
1029 if (test.start[n] == '*') {
1030 test.length = n;
1031 type = NXT_HTTP_ROUTE_PATTERN_MIDDLE;
1032 break;
1100 if (test.start[n] != '*') {
1101 continue;
1033 }
1102 }
1103
1104 test.length = n;
1105
1106 test2.start = &test.start[n + 1];
1107 test2.length = length - n;
1108
1109 ret = nxt_http_route_decode_str(&test2, encoding);
1110 if (nxt_slow_path(ret != NXT_OK)) {
1111 return ret;
1112 }
1113
1114 type = NXT_HTTP_ROUTE_PATTERN_MIDDLE;
1115
1116 pattern->length2 = test2.length;
1117 pattern->min_length += test2.length;
1118
1119 start = nxt_http_route_pattern_copy(mp, &test2,
1120 pattern_case);
1121 if (nxt_slow_path(start == NULL)) {
1122 return NXT_ERROR;
1123 }
1124
1125 pattern->start2 = start;
1126 break;
1034 }
1035 }
1127 }
1128 }
1129
1130 ret = nxt_http_route_decode_str(&test, encoding);
1131 if (nxt_slow_path(ret != NXT_OK)) {
1132 return ret;
1133 }
1036 }
1037 }
1038
1039 pattern->type = type;
1134 }
1135 }
1136
1137 pattern->type = type;
1040 pattern->min_length = test.length;
1138 pattern->min_length += test.length;
1041 pattern->length1 = test.length;
1042
1043 start = nxt_http_route_pattern_copy(mp, &test, pattern_case);
1044 if (nxt_slow_path(start == NULL)) {
1045 return NXT_ERROR;
1046 }
1047
1048 pattern->start1 = start;
1049
1139 pattern->length1 = test.length;
1140
1141 start = nxt_http_route_pattern_copy(mp, &test, pattern_case);
1142 if (nxt_slow_path(start == NULL)) {
1143 return NXT_ERROR;
1144 }
1145
1146 pattern->start1 = start;
1147
1050 if (type == NXT_HTTP_ROUTE_PATTERN_MIDDLE) {
1051 length -= test.length;
1052 pattern->length2 = length;
1053 pattern->min_length += length;
1148 return NXT_OK;
1149}
1054
1150
1055 test.start = &test.start[test.length + 1];
1056 test.length = length;
1057
1151
1058 start = nxt_http_route_pattern_copy(mp, &test, pattern_case);
1059 if (nxt_slow_path(start == NULL)) {
1152static nxt_int_t
1153nxt_http_route_decode_str(nxt_str_t *str, nxt_http_route_encoding_t encoding)
1154{
1155 u_char *start, *end;
1156
1157 switch (encoding) {
1158 case NXT_HTTP_ROUTE_ENCODING_NONE:
1159 break;
1160
1161 case NXT_HTTP_ROUTE_ENCODING_URI:
1162 start = str->start;
1163
1164 end = nxt_decode_uri(start, start, str->length);
1165 if (nxt_slow_path(end == NULL)) {
1060 return NXT_ERROR;
1061 }
1062
1166 return NXT_ERROR;
1167 }
1168
1063 pattern->start2 = start;
1169 str->length = end - start;
1170 break;
1171
1172 case NXT_HTTP_ROUTE_ENCODING_URI_PLUS:
1173 start = str->start;
1174
1175 end = nxt_decode_uri_plus(start, start, str->length);
1176 if (nxt_slow_path(end == NULL)) {
1177 return NXT_ERROR;
1178 }
1179
1180 str->length = end - start;
1181 break;
1182
1183 default:
1184 nxt_unreachable();
1064 }
1065
1066 return NXT_OK;
1067}
1068
1069
1070static u_char *
1071nxt_http_route_pattern_copy(nxt_mp_t *mp, nxt_str_t *test,

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

1741 return nxt_http_route_test_argument(r, rule, arguments);
1742}
1743
1744
1745static nxt_array_t *
1746nxt_http_route_arguments_parse(nxt_http_request_t *r)
1747{
1748 size_t name_length;
1185 }
1186
1187 return NXT_OK;
1188}
1189
1190
1191static u_char *
1192nxt_http_route_pattern_copy(nxt_mp_t *mp, nxt_str_t *test,

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

1862 return nxt_http_route_test_argument(r, rule, arguments);
1863}
1864
1865
1866static nxt_array_t *
1867nxt_http_route_arguments_parse(nxt_http_request_t *r)
1868{
1869 size_t name_length;
1749 u_char c, *p, *start, *end, *name;
1870 u_char c, *p, *dst, *dst_start, *start, *end, *name;
1871 uint8_t d0, d1;
1750 uint32_t hash;
1751 nxt_bool_t valid;
1752 nxt_array_t *args;
1753 nxt_http_name_value_t *nv;
1754
1755 if (r->arguments != NULL) {
1756 return r->arguments;
1757 }
1758
1759 args = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t));
1760 if (nxt_slow_path(args == NULL)) {
1761 return NULL;
1762 }
1763
1764 hash = NXT_HTTP_FIELD_HASH_INIT;
1765 valid = 1;
1766 name = NULL;
1767 name_length = 0;
1768
1872 uint32_t hash;
1873 nxt_bool_t valid;
1874 nxt_array_t *args;
1875 nxt_http_name_value_t *nv;
1876
1877 if (r->arguments != NULL) {
1878 return r->arguments;
1879 }
1880
1881 args = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t));
1882 if (nxt_slow_path(args == NULL)) {
1883 return NULL;
1884 }
1885
1886 hash = NXT_HTTP_FIELD_HASH_INIT;
1887 valid = 1;
1888 name = NULL;
1889 name_length = 0;
1890
1891 dst_start = nxt_mp_nget(r->mem_pool, r->args->length);
1892 if (nxt_slow_path(dst_start == NULL)) {
1893 return NULL;
1894 }
1895
1769 start = r->args->start;
1770 end = start + r->args->length;
1771
1896 start = r->args->start;
1897 end = start + r->args->length;
1898
1772 for (p = start; p < end; p++) {
1899 for (p = start, dst = dst_start; p < end; p++, dst++) {
1773 c = *p;
1900 c = *p;
1901 *dst = c;
1774
1902
1775 if (c == '=') {
1776 name_length = p - start;
1777 name = start;
1778 start = p + 1;
1903 switch (c) {
1904 case '=':
1905 if (name != NULL) {
1906 break;
1907 }
1908
1909 name_length = dst - dst_start;
1779 valid = (name_length != 0);
1910 valid = (name_length != 0);
1911 name = dst_start;
1912 dst_start = dst + 1;
1780
1913
1781 } else if (c == '&') {
1914 continue;
1915
1916 case '&':
1782 if (valid) {
1783 nv = nxt_http_route_argument(args, name, name_length, hash,
1917 if (valid) {
1918 nv = nxt_http_route_argument(args, name, name_length, hash,
1784 start, p);
1919 dst_start, dst);
1785 if (nxt_slow_path(nv == NULL)) {
1786 return NULL;
1787 }
1788 }
1789
1790 hash = NXT_HTTP_FIELD_HASH_INIT;
1920 if (nxt_slow_path(nv == NULL)) {
1921 return NULL;
1922 }
1923 }
1924
1925 hash = NXT_HTTP_FIELD_HASH_INIT;
1926 name_length = 0;
1791 valid = 1;
1792 name = NULL;
1927 valid = 1;
1928 name = NULL;
1793 start = p + 1;
1929 dst_start = dst + 1;
1794
1930
1795 } else if (name == NULL) {
1931 continue;
1932
1933 case '+':
1934 c = ' ';
1935 *dst = ' ';
1936
1937 break;
1938
1939 case '%':
1940 if (nxt_slow_path(end - p <= 2)) {
1941 break;
1942 }
1943
1944 d0 = nxt_hex2int[p[1]];
1945 d1 = nxt_hex2int[p[2]];
1946
1947 if (nxt_slow_path((d0 | d1) >= 16)) {
1948 break;
1949 }
1950
1951 p += 2;
1952 c = (d0 << 4) + d1;
1953 *dst = c;
1954
1955 break;
1956 }
1957
1958 if (name == NULL) {
1796 hash = nxt_http_field_hash_char(hash, c);
1797 }
1798 }
1799
1800 if (valid) {
1959 hash = nxt_http_field_hash_char(hash, c);
1960 }
1961 }
1962
1963 if (valid) {
1801 nv = nxt_http_route_argument(args, name, name_length, hash, start, p);
1964 nv = nxt_http_route_argument(args, name, name_length, hash, dst_start,
1965 dst);
1802 if (nxt_slow_path(nv == NULL)) {
1803 return NULL;
1804 }
1805 }
1806
1807 r->arguments = args;
1808
1809 return args;

--- 350 unchanged lines hidden ---
1966 if (nxt_slow_path(nv == NULL)) {
1967 return NULL;
1968 }
1969 }
1970
1971 r->arguments = args;
1972
1973 return args;

--- 350 unchanged lines hidden ---