comparison src/http/ngx_http_parse.c @ 58:b55cbf18157e NGINX_0_1_29

nginx 0.1.29 *) 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; bug 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 <http://sysoev.ru>
date Thu, 12 May 2005 00:00:00 +0400
parents 3050baa54a26
children df7d3fff122b
comparison
equal deleted inserted replaced
57:5df375c55338 58:b55cbf18157e
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 }