Mercurial > hg > nginx
comparison src/http/ngx_http_parse.c @ 200:abeaebe0a33c
nginx-0.0.1-2003-11-28-20:41:47 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 28 Nov 2003 17:41:47 +0000 |
parents | 2357fa41738a |
children | 267ea1d98683 |
comparison
equal
deleted
inserted
replaced
199:a65b630b3a66 | 200:abeaebe0a33c |
---|---|
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_http.h> | 4 #include <ngx_http.h> |
5 | 5 |
6 int ngx_http_parse_request_line(ngx_http_request_t *r) | 6 int ngx_http_parse_request_line(ngx_http_request_t *r) |
7 { | 7 { |
8 char ch; | 8 char ch, *p; |
9 char *p; | |
10 enum { | 9 enum { |
11 sw_start = 0, | 10 sw_start = 0, |
12 sw_G, | 11 sw_G, |
13 sw_GE, | 12 sw_GE, |
14 sw_H, | 13 sw_H, |
196 case '%': | 195 case '%': |
197 r->complex_uri = 1; | 196 r->complex_uri = 1; |
198 state = sw_uri; | 197 state = sw_uri; |
199 break; | 198 break; |
200 case '/': | 199 case '/': |
201 #if (WIN32) | |
202 r->complex_uri = 1; | 200 r->complex_uri = 1; |
203 #endif | |
204 break; | 201 break; |
205 case '?': | 202 case '?': |
206 r->args_start = p; | 203 r->args_start = p; |
207 state = sw_uri; | 204 state = sw_uri; |
208 break; | 205 break; |
419 r->state = state; | 416 r->state = state; |
420 return NGX_AGAIN; | 417 return NGX_AGAIN; |
421 } | 418 } |
422 } | 419 } |
423 | 420 |
421 | |
424 int ngx_http_parse_header_line(ngx_http_request_t *r, ngx_hunk_t *h) | 422 int ngx_http_parse_header_line(ngx_http_request_t *r, ngx_hunk_t *h) |
425 { | 423 { |
426 char c, ch; | 424 char c, ch, *p; |
427 char *p; | 425 enum { |
428 enum { | |
429 sw_start = 0, | 426 sw_start = 0, |
430 sw_name, | 427 sw_name, |
431 sw_space_before_value, | 428 sw_space_before_value, |
432 sw_value, | 429 sw_value, |
433 sw_space_after_value, | 430 sw_space_after_value, |
620 } else { | 617 } else { |
621 r->state = state; | 618 r->state = state; |
622 return NGX_AGAIN; | 619 return NGX_AGAIN; |
623 } | 620 } |
624 } | 621 } |
622 | |
623 | |
624 int ngx_http_parse_complex_uri(ngx_http_request_t *r) | |
625 { | |
626 char c, ch, decoded, *p, *u; | |
627 enum { | |
628 sw_usual = 0, | |
629 sw_slash, | |
630 sw_dot, | |
631 sw_dot_dot, | |
632 #if (WIN32) | |
633 sw_dot_dot_dot, | |
634 #endif | |
635 sw_quoted, | |
636 sw_quoted_second | |
637 } state, quoted_state; | |
638 | |
639 decoded = '\0'; | |
640 quoted_state = sw_usual; | |
641 | |
642 state = sw_usual; | |
643 p = r->uri_start; | |
644 u = r->uri.data; | |
645 | |
646 ch = *p++; | |
647 | |
648 while (p < r->uri_start + r->uri.len + 1) { | |
649 | |
650 ngx_log_debug(r->connection->log, "S: %d UN: '%x:%c', URI: '%c'" _ | |
651 state _ ch _ ch _ *u); | |
652 | |
653 switch (state) { | |
654 case sw_usual: | |
655 switch(ch) { | |
656 case '/': | |
657 state = sw_slash; | |
658 *u++ = ch; | |
659 break; | |
660 case '%': | |
661 quoted_state = state; | |
662 state = sw_quoted; | |
663 break; | |
664 default: | |
665 *u++ = ch; | |
666 break; | |
667 } | |
668 ch = *p++; | |
669 break; | |
670 | |
671 case sw_slash: | |
672 switch(ch) { | |
673 case '/': | |
674 break; | |
675 case '.': | |
676 state = sw_dot; | |
677 *u++ = ch; | |
678 break; | |
679 case '%': | |
680 quoted_state = state; | |
681 state = sw_quoted; | |
682 break; | |
683 default: | |
684 state = sw_usual; | |
685 *u++ = ch; | |
686 break; | |
687 } | |
688 ch = *p++; | |
689 break; | |
690 | |
691 case sw_dot: | |
692 switch(ch) { | |
693 case '/': | |
694 state = sw_slash; | |
695 u--; | |
696 break; | |
697 case '.': | |
698 state = sw_dot_dot; | |
699 *u++ = ch; | |
700 break; | |
701 case '%': | |
702 quoted_state = state; | |
703 state = sw_quoted; | |
704 break; | |
705 default: | |
706 state = sw_usual; | |
707 *u++ = ch; | |
708 break; | |
709 } | |
710 ch = *p++; | |
711 break; | |
712 | |
713 case sw_dot_dot: | |
714 switch(ch) { | |
715 case '/': | |
716 state = sw_slash; | |
717 u -= 4; | |
718 if (u < r->uri.data) { | |
719 return NGX_HTTP_PARSE_INVALID_REQUEST; | |
720 } | |
721 while (*(u - 1) != '/') { | |
722 u--; | |
723 } | |
724 break; | |
725 case '%': | |
726 quoted_state = state; | |
727 state = sw_quoted; | |
728 break; | |
729 #if (WIN32) | |
730 case '.': | |
731 state = sw_dot_dot_dot; | |
732 *u++ = ch; | |
733 break; | |
734 #endif | |
735 default: | |
736 state = sw_usual; | |
737 *u++ = ch; | |
738 break; | |
739 } | |
740 ch = *p++; | |
741 break; | |
742 | |
743 #if (WIN32) | |
744 case sw_dot_dot_dot: | |
745 switch(ch) { | |
746 case '/': | |
747 state = sw_slash; | |
748 u -= 5; | |
749 if (u < r->uri.data) { | |
750 return NGX_HTTP_PARSE_INVALID_REQUEST; | |
751 } | |
752 while (*u != '/') { | |
753 u--; | |
754 } | |
755 if (u < r->uri.data) { | |
756 return NGX_HTTP_PARSE_INVALID_REQUEST; | |
757 } | |
758 while (*(u - 1) != '/') { | |
759 u--; | |
760 } | |
761 break; | |
762 case '%': | |
763 quoted_state = state; | |
764 state = sw_quoted; | |
765 break; | |
766 default: | |
767 state = sw_usual; | |
768 *u++ = ch; | |
769 break; | |
770 } | |
771 ch = *p++; | |
772 break; | |
773 #endif | |
774 | |
775 case sw_quoted: | |
776 if (ch >= '0' && ch <= '9') { | |
777 decoded = ch - '0'; | |
778 state = sw_quoted_second; | |
779 ch = *p++; | |
780 break; | |
781 } | |
782 | |
783 c = ch | 0x20; | |
784 if (c >= 'a' && c <= 'f') { | |
785 decoded = c - 'a' + 10; | |
786 state = sw_quoted_second; | |
787 ch = *p++; | |
788 break; | |
789 } | |
790 | |
791 return NGX_HTTP_PARSE_INVALID_REQUEST; | |
792 | |
793 case sw_quoted_second: | |
794 if (ch >= '0' && ch <= '9') { | |
795 ch = (decoded << 4) + ch - '0'; | |
796 state = quoted_state; | |
797 break; | |
798 } | |
799 | |
800 c = ch | 0x20; | |
801 if (c >= 'a' && c <= 'f') { | |
802 ch = (decoded << 4) + c - 'a' + 10; | |
803 state = quoted_state; | |
804 break; | |
805 } | |
806 | |
807 return NGX_HTTP_PARSE_INVALID_REQUEST; | |
808 } | |
809 } | |
810 | |
811 r->uri.len = u - r->uri.data; | |
812 r->uri.data[r->uri.len] = '\0'; | |
813 | |
814 return NGX_OK; | |
815 } |