comparison src/http/ngx_http_parse.c @ 10:46833bd150cb NGINX_0_1_5

nginx 0.1.5 *) Bugfix: on Solaris and Linux there may be too many "recvmsg() returned not enough data" alerts. *) Bugfix: there were the "writev() failed (22: Invalid argument)" errors on Solaris in proxy mode without sendfile. On other platforms that do not support sendfile at all the process got caught in an endless loop. *) Bugfix: segmentation fault on Solaris in proxy mode and using sendfile. *) Bugfix: segmentation fault on Solaris. *) Bugfix: on-line upgrade did not work on Linux. *) Bugfix: the ngx_http_autoindex_module module did not escape the spaces, the quotes, and the percent signs in the directory listing. *) Change: the decrease of the copy operations. *) Feature: the userid_p3p directive.
author Igor Sysoev <http://sysoev.ru>
date Thu, 11 Nov 2004 00:00:00 +0300
parents cc9f381affaa
children 6f8b0dc0f8dd
comparison
equal deleted inserted replaced
9:77eee314ddbd 10:46833bd150cb
197 } 197 }
198 break; 198 break;
199 } 199 }
200 break; 200 break;
201 201
202 /* check "/.", "//", and "%" in URI */ 202 /* check "/.", "//", "%", and "\" (Win32) in URI */
203 case sw_after_slash_in_uri: 203 case sw_after_slash_in_uri:
204 switch (ch) { 204 switch (ch) {
205 case CR: 205 case CR:
206 r->uri_end = p - 1; 206 r->uri_end = p - 1;
207 r->http_minor = 9; 207 r->http_minor = 9;
222 break; 222 break;
223 case '%': 223 case '%':
224 r->quoted_uri = 1; 224 r->quoted_uri = 1;
225 state = sw_uri; 225 state = sw_uri;
226 break; 226 break;
227 #if (NGX_WIN32)
228 case '\\':
229 r->complex_uri = 1;
230 break;
231 #endif
227 case '/': 232 case '/':
228 r->complex_uri = 1; 233 r->complex_uri = 1;
229 break; 234 break;
230 case '?': 235 case '?':
231 r->args_start = p; 236 r->args_start = p;
235 state = sw_check_uri; 240 state = sw_check_uri;
236 break; 241 break;
237 } 242 }
238 break; 243 break;
239 244
240 /* check "/" and "%" in URI */ 245 /* check "/", "%" and "\" (Win32) in URI */
241 case sw_check_uri: 246 case sw_check_uri:
242 switch (ch) { 247 switch (ch) {
243 case CR: 248 case CR:
244 r->uri_end = p - 1; 249 r->uri_end = p - 1;
245 r->http_minor = 9; 250 r->http_minor = 9;
255 state = sw_http_09; 260 state = sw_http_09;
256 break; 261 break;
257 case '.': 262 case '.':
258 r->uri_ext = p; 263 r->uri_ext = p;
259 break; 264 break;
265 #if (NGX_WIN32)
266 case '\\':
267 r->complex_uri = 1;
268 state = sw_after_slash_in_uri;
269 break;
270 #endif
260 case '/': 271 case '/':
261 r->uri_ext = NULL; 272 r->uri_ext = NULL;
262 state = sw_after_slash_in_uri; 273 state = sw_after_slash_in_uri;
263 break; 274 break;
264 case '%': 275 case '%':
655 enum { 666 enum {
656 sw_usual = 0, 667 sw_usual = 0,
657 sw_slash, 668 sw_slash,
658 sw_dot, 669 sw_dot,
659 sw_dot_dot, 670 sw_dot_dot,
660 #if (WIN32) 671 #if (NGX_WIN32)
661 sw_dot_dot_dot, 672 sw_dot_dot_dot,
662 #endif 673 #endif
663 sw_quoted, 674 sw_quoted,
664 sw_quoted_second 675 sw_quoted_second
665 } state, quoted_state; 676 } state, quoted_state;
669 680
670 state = sw_usual; 681 state = sw_usual;
671 p = r->uri_start; 682 p = r->uri_start;
672 u = r->uri.data; 683 u = r->uri.data;
673 r->uri_ext = NULL; 684 r->uri_ext = NULL;
685 r->args_start = NULL;
674 686
675 ch = *p++; 687 ch = *p++;
676 688
677 while (p < r->uri_start + r->uri.len + 1) { 689 while (p < r->uri_start + r->uri.len + 1 && r->args_start == NULL) {
690
691 /*
692 * we use "ch = *p++" inside the cycle but this operation is safe
693 * because after the URI there is always at least one charcter:
694 * the line feed
695 */
678 696
679 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 697 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
680 "s:%d in:'%x:%c', out:'%c'", state, ch, ch, *u); 698 "s:%d in:'%Xd:%c', out:'%c'", state, ch, ch, *u);
681 699
682 switch (state) { 700 switch (state) {
683 case sw_usual: 701 case sw_usual:
684 switch(ch) { 702 switch(ch) {
703 #if (NGX_WIN32)
704 case '\\':
705 r->uri_ext = NULL;
706
707 if (p == r->uri_start + r->uri.len) {
708
709 /*
710 * we omit the last "\" to cause redirect because
711 * the browsers do not treat "\" as "/" in relative URL path
712 */
713
714 break;
715 }
716
717 state = sw_slash;
718 *u++ = '/';
719 break;
720 #endif
685 case '/': 721 case '/':
686 r->uri_ext = NULL; 722 r->uri_ext = NULL;
687 state = sw_slash; 723 state = sw_slash;
688 *u++ = ch; 724 *u++ = ch;
689 break; 725 break;
690 case '%': 726 case '%':
691 quoted_state = state; 727 quoted_state = state;
692 state = sw_quoted; 728 state = sw_quoted;
693 break; 729 break;
730 case '?':
731 r->args_start = p;
732 break;
694 case '.': 733 case '.':
695 r->uri_ext = u + 1; 734 r->uri_ext = u + 1;
696 default: 735 default:
697 *u++ = ch; 736 *u++ = ch;
698 break; 737 break;
700 ch = *p++; 739 ch = *p++;
701 break; 740 break;
702 741
703 case sw_slash: 742 case sw_slash:
704 switch(ch) { 743 switch(ch) {
744 #if (NGX_WIN32)
745 case '\\':
746 break;
747 #endif
705 case '/': 748 case '/':
706 break; 749 break;
707 case '.': 750 case '.':
708 state = sw_dot; 751 state = sw_dot;
709 *u++ = ch; 752 *u++ = ch;
720 ch = *p++; 763 ch = *p++;
721 break; 764 break;
722 765
723 case sw_dot: 766 case sw_dot:
724 switch(ch) { 767 switch(ch) {
768 #if (NGX_WIN32)
769 case '\\':
770 /* fall through */
771 #endif
725 case '/': 772 case '/':
726 state = sw_slash; 773 state = sw_slash;
727 u--; 774 u--;
728 break; 775 break;
729 case '.': 776 case '.':
742 ch = *p++; 789 ch = *p++;
743 break; 790 break;
744 791
745 case sw_dot_dot: 792 case sw_dot_dot:
746 switch(ch) { 793 switch(ch) {
794 #if (NGX_WIN32)
795 case '\\':
796 /* fall through */
797 #endif
747 case '/': 798 case '/':
748 state = sw_slash; 799 state = sw_slash;
749 u -= 4; 800 u -= 4;
750 if (u < r->uri.data) { 801 if (u < r->uri.data) {
751 return NGX_HTTP_PARSE_INVALID_REQUEST; 802 return NGX_HTTP_PARSE_INVALID_REQUEST;
756 break; 807 break;
757 case '%': 808 case '%':
758 quoted_state = state; 809 quoted_state = state;
759 state = sw_quoted; 810 state = sw_quoted;
760 break; 811 break;
761 #if (WIN32) 812 #if (NGX_WIN32)
762 case '.': 813 case '.':
763 state = sw_dot_dot_dot; 814 state = sw_dot_dot_dot;
764 *u++ = ch; 815 *u++ = ch;
765 break; 816 break;
766 #endif 817 #endif
770 break; 821 break;
771 } 822 }
772 ch = *p++; 823 ch = *p++;
773 break; 824 break;
774 825
775 #if (WIN32) 826 #if (NGX_WIN32)
776 case sw_dot_dot_dot: 827 case sw_dot_dot_dot:
777 switch(ch) { 828 switch(ch) {
829 case '\\':
778 case '/': 830 case '/':
779 state = sw_slash; 831 state = sw_slash;
780 u -= 5; 832 u -= 5;
781 if (u < r->uri.data) { 833 if (u < r->uri.data) {
782 return NGX_HTTP_PARSE_INVALID_REQUEST; 834 return NGX_HTTP_PARSE_INVALID_REQUEST;
855 r->uri.len = u - r->uri.data; 907 r->uri.len = u - r->uri.data;
856 r->uri.data[r->uri.len] = '\0'; 908 r->uri.data[r->uri.len] = '\0';
857 909
858 if (r->uri_ext) { 910 if (r->uri_ext) {
859 r->exten.len = u - r->uri_ext; 911 r->exten.len = u - r->uri_ext;
860 912 r->exten.data = r->uri_ext;
861 if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) {
862 return NGX_HTTP_INTERNAL_SERVER_ERROR;
863 }
864
865 ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1);
866 } 913 }
867 914
868 r->uri_ext = NULL; 915 r->uri_ext = NULL;
869 916
870 return NGX_OK; 917 return NGX_OK;