Mercurial > hg > nginx
comparison src/http/ngx_http_parse.c @ 509:9b8c906f6e63 release-0.1.29
nginx-0.1.29-RELEASE import
*) Feature: the ngx_http_ssi_module supports "include virtual" command.
*) Feature: the ngx_http_ssi_module supports the condition command like
'if expr="$NAME"' and "else" and "endif" commands. Only one nested
level is supported.
*) Feature: the ngx_http_ssi_module supports the DATE_LOCAL and
DATE_GMT variables and "config timefmt" command.
*) Feature: the "ssi_ignore_recycled_buffers" directive.
*) Bugfix: the "echo" command did not show the default value for the
empty QUERY_STRING variable.
*) Change: the ngx_http_proxy_module was rewritten.
*) Feature: the "proxy_redirect", "proxy_pass_request_headers",
"proxy_pass_request_body", and "proxy_method" directives.
*) Feature: the "proxy_set_header" directive. The "proxy_x_var" was
canceled and must be replaced with the proxy_set_header directive.
*) Change: the "proxy_preserve_host" is canceled and must be replaced
with the "proxy_set_header Host $host" and the "proxy_redirect off"
directives, the "proxy_set_header Host $host:$proxy_port" directive
and the appropriate proxy_redirect directives.
*) Change: the "proxy_set_x_real_ip" is canceled and must be replaced
with the "proxy_set_header X-Real-IP $remote_addr" directive.
*) Change: the "proxy_add_x_forwarded_for" is canceled and must be
replaced with
the "proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for"
directive.
*) Change: the "proxy_set_x_url" is canceled and must be replaced with
the "proxy_set_header X-URL http://$host:$server_port$request_uri"
directive.
*) Feature: the "fastcgi_param" directive.
*) Change: the "fastcgi_root", "fastcgi_set_var" and "fastcgi_params"
directive are canceled and must be replaced with the fastcgi_param
directives.
*) Feature: the "index" directive can use the variables.
*) Feature: the "index" directive can be used at http and server levels.
*) Change: the last index only in the "index" directive can be absolute.
*) Feature: the "rewrite" directive can use the variables.
*) Feature: the "internal" directive.
*) Feature: the CONTENT_LENGTH, CONTENT_TYPE, REMOTE_PORT, SERVER_ADDR,
SERVER_PORT, SERVER_PROTOCOL, DOCUMENT_ROOT, SERVER_NAME,
REQUEST_METHOD, REQUEST_URI, and REMOTE_USER variables.
*) Change: nginx now passes the invalid lines in a client request
headers or a backend response header.
*) Bugfix: if the backend did not transfer response for a long time and
the "send_timeout" was less than "proxy_read_timeout", then nginx
returned the 408 response.
*) Bugfix: the segmentation fault was occurred if the backend sent an
invalid line in response header; the bug had appeared in 0.1.26.
*) Bugfix: the segmentation fault may occurred in FastCGI fault
tolerance configuration.
*) Bugfix: the "expires" directive did not remove the previous
"Expires" and "Cache-Control" headers.
*) Bugfix: nginx did not take into account trailing dot in "Host"
header line.
*) Bugfix: the ngx_http_auth_module did not work under Linux.
*) Bugfix: the rewrite directive worked incorrectly, if the arguments
were in a request.
*) Bugfix: nginx could not be built on MacOS X.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 12 May 2005 14:58:06 +0000 |
parents | cd3117ad9aab |
children | c12967aadd87 |
comparison
equal
deleted
inserted
replaced
508:ca1020ce99ba | 509:9b8c906f6e63 |
---|---|
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 | 10 |
11 | 11 |
12 ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b) | 12 ngx_int_t |
13 ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b) | |
13 { | 14 { |
14 u_char c, ch, *p, *m; | 15 u_char c, ch, *p, *m; |
15 enum { | 16 enum { |
16 sw_start = 0, | 17 sw_start = 0, |
17 sw_method, | 18 sw_method, |
61 state = sw_method; | 62 state = sw_method; |
62 break; | 63 break; |
63 | 64 |
64 case sw_method: | 65 case sw_method: |
65 if (ch == ' ') { | 66 if (ch == ' ') { |
66 r->method_end = p; | 67 r->method_end = p - 1; |
67 m = r->request_start; | 68 m = r->request_start; |
68 | 69 |
69 if (p - m == 3) { | 70 if (p - m == 3) { |
70 | 71 |
71 if (m[0] == 'G' && m[1] == 'E' && m[2] == 'T') { | 72 if (m[0] == 'G' && m[1] == 'E' && m[2] == 'T') { |
500 | 501 |
501 return NGX_OK; | 502 return NGX_OK; |
502 } | 503 } |
503 | 504 |
504 | 505 |
505 ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b) | 506 ngx_int_t |
507 ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b) | |
506 { | 508 { |
507 u_char c, ch, *p; | 509 u_char c, ch, *p; |
508 ngx_uint_t hash; | 510 ngx_uint_t hash; |
509 enum { | 511 enum { |
510 sw_start = 0, | 512 sw_start = 0, |
511 sw_name, | 513 sw_name, |
512 sw_space_before_value, | 514 sw_space_before_value, |
513 sw_value, | 515 sw_value, |
514 sw_space_after_value, | 516 sw_space_after_value, |
515 sw_ignore_line, | 517 sw_ignore_line, |
516 sw_skip_line, | |
517 sw_almost_done, | 518 sw_almost_done, |
518 sw_header_almost_done | 519 sw_header_almost_done |
519 } state; | 520 } state; |
520 | 521 |
521 state = r->state; | 522 state = r->state; |
526 | 527 |
527 switch (state) { | 528 switch (state) { |
528 | 529 |
529 /* first char */ | 530 /* first char */ |
530 case sw_start: | 531 case sw_start: |
531 r->invalid_header = 0; | |
532 | |
533 switch (ch) { | 532 switch (ch) { |
534 case CR: | 533 case CR: |
535 r->header_end = p; | 534 r->header_end = p; |
536 state = sw_header_almost_done; | 535 state = sw_header_almost_done; |
537 break; | 536 break; |
546 if (c >= 'a' && c <= 'z') { | 545 if (c >= 'a' && c <= 'z') { |
547 hash = c; | 546 hash = c; |
548 break; | 547 break; |
549 } | 548 } |
550 | 549 |
551 if (ch == '-') { | |
552 hash = ch; | |
553 break; | |
554 } | |
555 | |
556 if (ch >= '0' && ch <= '9') { | 550 if (ch >= '0' && ch <= '9') { |
557 hash = ch; | 551 hash = ch; |
558 break; | 552 break; |
559 } | 553 } |
560 | 554 |
561 r->invalid_header = 1; | |
562 state = sw_skip_line; | |
563 break; | 555 break; |
564 | 556 |
565 } | 557 } |
566 break; | 558 break; |
567 | 559 |
587 if (ch >= '0' && ch <= '9') { | 579 if (ch >= '0' && ch <= '9') { |
588 hash += ch; | 580 hash += ch; |
589 break; | 581 break; |
590 } | 582 } |
591 | 583 |
584 if (ch == CR) { | |
585 r->header_name_end = p; | |
586 r->header_start = p; | |
587 r->header_end = p; | |
588 state = sw_almost_done; | |
589 break; | |
590 } | |
591 | |
592 if (ch == LF) { | |
593 r->header_name_end = p; | |
594 r->header_start = p; | |
595 r->header_end = p; | |
596 goto done; | |
597 } | |
598 | |
592 /* IIS may send the duplicate "HTTP/1.1 ..." lines */ | 599 /* IIS may send the duplicate "HTTP/1.1 ..." lines */ |
593 if (ch == '/' | 600 if (ch == '/' |
594 && r->proxy | 601 && r->upstream |
595 && p - r->header_start == 4 | 602 && p - r->header_name_start == 4 |
596 && ngx_strncmp(r->header_start, "HTTP", 4) == 0) | 603 && ngx_strncmp(r->header_name_start, "HTTP", 4) == 0) |
597 { | 604 { |
598 state = sw_ignore_line; | 605 state = sw_ignore_line; |
599 break; | 606 break; |
600 } | 607 } |
601 | 608 |
602 r->invalid_header = 1; | |
603 state = sw_skip_line; | |
604 break; | 609 break; |
605 | 610 |
606 /* space* before header value */ | 611 /* space* before header value */ |
607 case sw_space_before_value: | 612 case sw_space_before_value: |
608 switch (ch) { | 613 switch (ch) { |
609 case ' ': | 614 case ' ': |
610 break; | 615 break; |
611 case CR: | 616 case CR: |
612 r->header_start = r->header_end = p; | 617 r->header_start = p; |
618 r->header_end = p; | |
613 state = sw_almost_done; | 619 state = sw_almost_done; |
614 break; | 620 break; |
615 case LF: | 621 case LF: |
616 r->header_start = r->header_end = p; | 622 r->header_start = p; |
623 r->header_end = p; | |
617 goto done; | 624 goto done; |
618 default: | 625 default: |
619 r->header_start = p; | 626 r->header_start = p; |
620 state = sw_value; | 627 state = sw_value; |
621 break; | 628 break; |
664 default: | 671 default: |
665 break; | 672 break; |
666 } | 673 } |
667 break; | 674 break; |
668 | 675 |
669 /* skip header line */ | |
670 case sw_skip_line: | |
671 switch (ch) { | |
672 case CR: | |
673 r->header_end = p; | |
674 state = sw_almost_done; | |
675 break; | |
676 case LF: | |
677 r->header_end = p; | |
678 goto done; | |
679 default: | |
680 break; | |
681 } | |
682 break; | |
683 | |
684 /* end of header line */ | 676 /* end of header line */ |
685 case sw_almost_done: | 677 case sw_almost_done: |
686 switch (ch) { | 678 switch (ch) { |
687 case LF: | 679 case LF: |
688 goto done; | 680 goto done; |
722 | 714 |
723 return NGX_HTTP_PARSE_HEADER_DONE; | 715 return NGX_HTTP_PARSE_HEADER_DONE; |
724 } | 716 } |
725 | 717 |
726 | 718 |
727 ngx_int_t ngx_http_parse_complex_uri(ngx_http_request_t *r) | 719 ngx_int_t |
720 ngx_http_parse_complex_uri(ngx_http_request_t *r) | |
728 { | 721 { |
729 u_char c, ch, decoded, *p, *u; | 722 u_char c, ch, decoded, *p, *u; |
730 enum { | 723 enum { |
731 sw_usual = 0, | 724 sw_usual = 0, |
732 sw_slash, | 725 sw_slash, |
999 | 992 |
1000 r->uri_ext = NULL; | 993 r->uri_ext = NULL; |
1001 | 994 |
1002 return NGX_OK; | 995 return NGX_OK; |
1003 } | 996 } |
997 | |
998 | |
999 ngx_int_t | |
1000 ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name, | |
1001 ngx_str_t *value) | |
1002 { | |
1003 ngx_uint_t i; | |
1004 u_char *start, *last, *end, ch; | |
1005 ngx_table_elt_t **h; | |
1006 | |
1007 h = headers->elts; | |
1008 | |
1009 for (i = 0; i < headers->nelts; i++) { | |
1010 | |
1011 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0, | |
1012 "parse header: \"%V: %V\"", &h[i]->key, &h[i]->value); | |
1013 | |
1014 if (name->len > h[i]->value.len) { | |
1015 continue; | |
1016 } | |
1017 | |
1018 start = h[i]->value.data; | |
1019 end = h[i]->value.data + h[i]->value.len; | |
1020 | |
1021 while (start < end) { | |
1022 | |
1023 if (ngx_strncasecmp(start, name->data, name->len) != 0) { | |
1024 goto skip; | |
1025 } | |
1026 | |
1027 for (start += name->len; start < end && *start == ' '; start++) { | |
1028 /* void */ | |
1029 } | |
1030 | |
1031 if (value == NULL) { | |
1032 if (start == end || *start == ',') { | |
1033 return i; | |
1034 } | |
1035 | |
1036 goto skip; | |
1037 } | |
1038 | |
1039 if (start == end || *start++ != '=') { | |
1040 /* the invalid header value */ | |
1041 goto skip; | |
1042 } | |
1043 | |
1044 while (start < end && *start == ' ') { start++; } | |
1045 | |
1046 for (last = start; last < end && *last != ';'; last++) { | |
1047 /* void */ | |
1048 } | |
1049 | |
1050 value->len = last - start; | |
1051 value->data = start; | |
1052 | |
1053 return i; | |
1054 | |
1055 skip: | |
1056 while (start < end) { | |
1057 ch = *start++; | |
1058 if (ch == ';' || ch == ',') { | |
1059 break; | |
1060 } | |
1061 } | |
1062 | |
1063 while (start < end && *start == ' ') { start++; } | |
1064 } | |
1065 } | |
1066 | |
1067 return NGX_DECLINED; | |
1068 } |