Mercurial > hg > nginx
comparison src/http/ngx_http_parse.c @ 823:ccf3c59f8040
optimize the most frequent cases
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sat, 28 Oct 2006 12:04:43 +0000 |
parents | a908ba404078 |
children | f7491a59e736 |
comparison
equal
deleted
inserted
replaced
822:a908ba404078 | 823:ccf3c59f8040 |
---|---|
5 | 5 |
6 | 6 |
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_http.h> | 9 #include <ngx_http.h> |
10 | |
11 | |
12 static uint32_t usual[] = | |
13 { 0xffffdbfe, /* 1111 1111 1111 1111 1101 1011 1111 1110 */ | |
14 | |
15 /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ | |
16 0x7fff37d6, /* 0111 1111 1111 1111 0011 0111 1101 0110 */ | |
17 | |
18 /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ | |
19 0xefffffff, /* 1110 1111 1111 1111 1111 1111 1111 1111 */ | |
20 | |
21 /* ~}| {zyx wvut srqp onml kjih gfed cba` */ | |
22 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ | |
23 | |
24 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ | |
25 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ | |
26 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ | |
27 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ }; | |
10 | 28 |
11 | 29 |
12 /* gcc, icc, msvc and others compile these switches as an jump table */ | 30 /* gcc, icc, msvc and others compile these switches as an jump table */ |
13 | 31 |
14 ngx_int_t | 32 ngx_int_t |
223 break; | 241 break; |
224 | 242 |
225 /* check "/.", "//", "%", and "\" (Win32) in URI */ | 243 /* check "/.", "//", "%", and "\" (Win32) in URI */ |
226 case sw_after_slash_in_uri: | 244 case sw_after_slash_in_uri: |
227 | 245 |
228 c = (u_char) (ch | 0x20); | 246 if (usual[ch >> 5] & (1 << (ch & 0x1f))) { |
229 if (c >= 'a' && c <= 'z') { | |
230 state = sw_check_uri; | |
231 break; | |
232 } | |
233 | |
234 if (ch >= '0' && ch <= '9') { | |
235 state = sw_check_uri; | 247 state = sw_check_uri; |
236 break; | 248 break; |
237 } | 249 } |
238 | 250 |
239 switch (ch) { | 251 switch (ch) { |
289 break; | 301 break; |
290 | 302 |
291 /* check "/", "%" and "\" (Win32) in URI */ | 303 /* check "/", "%" and "\" (Win32) in URI */ |
292 case sw_check_uri: | 304 case sw_check_uri: |
293 | 305 |
294 c = (u_char) (ch | 0x20); | 306 if (usual[ch >> 5] & (1 << (ch & 0x1f))) { |
295 if (c >= 'a' && c <= 'z') { | |
296 break; | |
297 } | |
298 | |
299 if (ch >= '0' && ch <= '9') { | |
300 break; | 307 break; |
301 } | 308 } |
302 | 309 |
303 switch (ch) { | 310 switch (ch) { |
304 case '/': | 311 case '/': |
348 } | 355 } |
349 break; | 356 break; |
350 | 357 |
351 /* URI */ | 358 /* URI */ |
352 case sw_uri: | 359 case sw_uri: |
360 | |
361 if (usual[ch >> 5] & (1 << (ch & 0x1f))) { | |
362 break; | |
363 } | |
364 | |
353 switch (ch) { | 365 switch (ch) { |
354 case ' ': | 366 case ' ': |
355 r->uri_end = p; | 367 r->uri_end = p; |
356 state = sw_http_09; | 368 state = sw_http_09; |
357 break; | 369 break; |
791 "s:%d in:'%Xd:%c', out:'%c'", state, ch, ch, *u); | 803 "s:%d in:'%Xd:%c', out:'%c'", state, ch, ch, *u); |
792 | 804 |
793 switch (state) { | 805 switch (state) { |
794 | 806 |
795 case sw_usual: | 807 case sw_usual: |
808 | |
809 if (usual[ch >> 5] & (1 << (ch & 0x1f))) { | |
810 *u++ = ch; | |
811 ch = *p++; | |
812 break; | |
813 } | |
814 | |
796 switch(ch) { | 815 switch(ch) { |
797 #if (NGX_WIN32) | 816 #if (NGX_WIN32) |
798 case '\\': | 817 case '\\': |
799 r->uri_ext = NULL; | 818 r->uri_ext = NULL; |
800 | 819 |
834 r->plus_in_uri = 1; | 853 r->plus_in_uri = 1; |
835 default: | 854 default: |
836 *u++ = ch; | 855 *u++ = ch; |
837 break; | 856 break; |
838 } | 857 } |
858 | |
839 ch = *p++; | 859 ch = *p++; |
840 break; | 860 break; |
841 | 861 |
842 case sw_slash: | 862 case sw_slash: |
863 | |
864 if (usual[ch >> 5] & (1 << (ch & 0x1f))) { | |
865 state = sw_usual; | |
866 *u++ = ch; | |
867 ch = *p++; | |
868 break; | |
869 } | |
870 | |
843 switch(ch) { | 871 switch(ch) { |
844 #if (NGX_WIN32) | 872 #if (NGX_WIN32) |
845 case '\\': | 873 case '\\': |
846 #endif | 874 #endif |
847 case '/': | 875 case '/': |
864 default: | 892 default: |
865 state = sw_usual; | 893 state = sw_usual; |
866 *u++ = ch; | 894 *u++ = ch; |
867 break; | 895 break; |
868 } | 896 } |
897 | |
869 ch = *p++; | 898 ch = *p++; |
870 break; | 899 break; |
871 | 900 |
872 case sw_dot: | 901 case sw_dot: |
902 | |
903 if (usual[ch >> 5] & (1 << (ch & 0x1f))) { | |
904 state = sw_usual; | |
905 *u++ = ch; | |
906 ch = *p++; | |
907 break; | |
908 } | |
909 | |
873 switch(ch) { | 910 switch(ch) { |
874 #if (NGX_WIN32) | 911 #if (NGX_WIN32) |
875 case '\\': | 912 case '\\': |
876 #endif | 913 #endif |
877 case '/': | 914 case '/': |
896 default: | 933 default: |
897 state = sw_usual; | 934 state = sw_usual; |
898 *u++ = ch; | 935 *u++ = ch; |
899 break; | 936 break; |
900 } | 937 } |
938 | |
901 ch = *p++; | 939 ch = *p++; |
902 break; | 940 break; |
903 | 941 |
904 case sw_dot_dot: | 942 case sw_dot_dot: |
943 | |
944 if (usual[ch >> 5] & (1 << (ch & 0x1f))) { | |
945 state = sw_usual; | |
946 *u++ = ch; | |
947 ch = *p++; | |
948 break; | |
949 } | |
950 | |
905 switch(ch) { | 951 switch(ch) { |
906 #if (NGX_WIN32) | 952 #if (NGX_WIN32) |
907 case '\\': | 953 case '\\': |
908 #endif | 954 #endif |
909 case '/': | 955 case '/': |
936 default: | 982 default: |
937 state = sw_usual; | 983 state = sw_usual; |
938 *u++ = ch; | 984 *u++ = ch; |
939 break; | 985 break; |
940 } | 986 } |
987 | |
941 ch = *p++; | 988 ch = *p++; |
942 break; | 989 break; |
943 | 990 |
944 #if (NGX_WIN32) | 991 #if (NGX_WIN32) |
945 case sw_dot_dot_dot: | 992 case sw_dot_dot_dot: |
993 | |
994 if (usual[ch >> 5] & (1 << (ch & 0x1f))) { | |
995 state = sw_usual; | |
996 *u++ = ch; | |
997 ch = *p++; | |
998 break; | |
999 } | |
1000 | |
946 switch(ch) { | 1001 switch(ch) { |
947 case '\\': | 1002 case '\\': |
948 case '/': | 1003 case '/': |
949 state = sw_slash; | 1004 state = sw_slash; |
950 u -= 5; | 1005 u -= 5; |
975 default: | 1030 default: |
976 state = sw_usual; | 1031 state = sw_usual; |
977 *u++ = ch; | 1032 *u++ = ch; |
978 break; | 1033 break; |
979 } | 1034 } |
1035 | |
980 ch = *p++; | 1036 ch = *p++; |
981 break; | 1037 break; |
982 #endif | 1038 #endif |
983 | 1039 |
984 case sw_quoted: | 1040 case sw_quoted: |
1109 | 1165 |
1110 for ( /* void */ ; len; len--) { | 1166 for ( /* void */ ; len; len--) { |
1111 | 1167 |
1112 ch = *p++; | 1168 ch = *p++; |
1113 | 1169 |
1170 if (usual[ch >> 5] & (1 << (ch & 0x1f))) { | |
1171 continue; | |
1172 } | |
1173 | |
1114 if (ch == '?') { | 1174 if (ch == '?') { |
1115 args->len = len - 1; | 1175 args->len = len - 1; |
1116 args->data = p; | 1176 args->data = p; |
1117 uri->len -= len; | 1177 uri->len -= len; |
1118 | 1178 |
1122 if (ch == '\0') { | 1182 if (ch == '\0') { |
1123 *flags |= NGX_HTTP_ZERO_IN_URI; | 1183 *flags |= NGX_HTTP_ZERO_IN_URI; |
1124 continue; | 1184 continue; |
1125 } | 1185 } |
1126 | 1186 |
1127 if (ch != '/' | 1187 if (len > 2 && (ch == '/' |
1128 #if (NGX_WIN32) | 1188 #if (NGX_WIN32) |
1129 && ch != '\\' | 1189 || ch == '\\' |
1130 #endif | 1190 #endif |
1131 ) | 1191 )) |
1132 { | 1192 { |
1133 continue; | |
1134 } | |
1135 | |
1136 if (len > 2) { | |
1137 | |
1138 /* detect "/../" */ | 1193 /* detect "/../" */ |
1139 | 1194 |
1140 if (p[0] == '.' && p[1] == '.' && p[2] == '/') { | 1195 if (p[0] == '.' && p[1] == '.' && p[2] == '/') { |
1141 goto unsafe; | 1196 goto unsafe; |
1142 } | 1197 } |