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 }