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 }