changeset 60:df7d3fff122b NGINX_0_1_30

nginx 0.1.30 *) Bugfix: the worker process may got caught in an endless loop if the SSI was used. *) Bugfix: the response encrypted by SSL may not transferred complete. *) Bugfix: if the length of the response part received at once from proxied or FastCGI server was equal to 500, then nginx returns the 500 response code; in proxy mode the bug appeared in 0.1.29 only. *) Bugfix: nginx did not consider the directives with 8 or 9 parameters as invalid. *) Feature: the "return" directive can return the 204 response code. *) Feature: the "ignore_invalid_headers" directive.
author Igor Sysoev <http://sysoev.ru>
date Sat, 14 May 2005 00:00:00 +0400
parents 4cb463ba8cce
children 345d4a254bfb
files CHANGES CHANGES.ru src/core/nginx.h src/core/ngx_conf_file.c src/core/ngx_conf_file.h src/event/ngx_event_openssl.c src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_header_filter_module.c src/http/ngx_http_parse.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/ngx_http_special_response.c src/http/ngx_http_upstream.c src/http/ngx_http_write_filter_module.c
diffstat 15 files changed, 112 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,22 @@
+
+Changes with nginx 0.1.30                                        14 May 2005
+
+    *) Bugfix: the worker process may got caught in an endless loop if the 
+       SSI was used.
+
+    *) Bugfix: the response encrypted by SSL may not transferred complete.
+
+    *) Bugfix: if the length of the response part received at once from 
+       proxied or FastCGI server was equal to 500, then nginx returns the 
+       500 response code; in proxy mode the bug appeared in 0.1.29 only.
+
+    *) Bugfix: nginx did not consider the directives with 8 or 9 parameters 
+       as invalid.
+
+    *) Feature: the "return" directive can return the 204 response code.
+
+    *) Feature: the "ignore_invalid_headers" directive.
+
 
 Changes with nginx 0.1.29                                        12 May 2005
 
@@ -42,8 +61,9 @@ Changes with nginx 0.1.29               
 
     *) Feature: the "fastcgi_param" directive.
 
-    *) Change: the "fastcgi_set_var" and "fastcgi_params" directive are 
-       canceled and must be replaced with the fastcgi_param directives.
+    *) 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.
 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,3 +1,23 @@
+
+Изменения в nginx 0.1.30                                          14.05.2005
+
+    *) Исправление: при использовании SSI рабочий процесс мог зациклиться.
+
+    *) Исправление: при использовании SSL ответ мог передаваться не до 
+       конца.
+
+    *) Исправление: если длина части ответа, полученного за один раз от 
+       проксируемого или FastCGI сервера была равна 500 байт, то nginx 
+       возвращал код ответа 500; в режиме прокси ошибка появилась только в 
+       0.1.29.
+
+    *) Исправление: nginx не считал неверными директивы с 8-ю или 9-ю 
+       параметрами.
+
+    *) Добавление: директива return может возвращать код ответа 204.
+
+    *) Добавление: директива ignore_invalid_headers.
+
 
 Изменения в nginx 0.1.29                                          12.05.2005
 
@@ -42,8 +62,8 @@
 
     *) Добавление: директива fastcgi_param.
 
-    *) Изменение: директивы fastcgi_set_var и fastcgi_params упразднены и 
-       должны быть замены директивами fastcgi_param.
+    *) Изменение: директивы fastcgi_root, fastcgi_set_var и fastcgi_params 
+       упразднены и должны быть замены директивами fastcgi_param.
 
     *) Добавление: директива index может использовать переменные.
 
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VER          "nginx/0.1.29"
+#define NGINX_VER          "nginx/0.1.30"
 
 #define NGINX_VAR          "NGINX"
 #define NGX_NEWPID_EXT     ".newbin"
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -263,7 +263,7 @@ ngx_conf_handler(ngx_conf_t *cf, ngx_int
                         valid = 0;
                     }
 
-                } else if (cf->args->nelts <= 10
+                } else if (cf->args->nelts <= NGX_CONF_MAX_ARGS
                            && (cmd->type
                                & argument_number[cf->args->nelts - 1]))
                 {
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -27,6 +27,8 @@
 #define NGX_CONF_TAKE6       0x00000040
 #define NGX_CONF_TAKE7       0x00000080
 
+#define NGX_CONF_MAX_ARGS    8
+
 #define NGX_CONF_TAKE12      (NGX_CONF_TAKE1|NGX_CONF_TAKE2)
 #define NGX_CONF_TAKE13      (NGX_CONF_TAKE1|NGX_CONF_TAKE3)
 
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -361,8 +361,9 @@ ngx_ssl_send_chain(ngx_connection_t *c, 
             return NGX_CHAIN_ERROR;
         }
 
-        if (n < 0) {
-            n = 0;
+        if (n == NGX_AGAIN) {
+            c->buffered = 1;
+            return in;
         }
 
         buf->pos += n;
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -144,6 +144,13 @@ static ngx_command_t  ngx_http_core_comm
       offsetof(ngx_http_core_srv_conf_t, restrict_host_names),
       &ngx_http_restrict_host_names },
 
+    { ngx_string("ignore_invalid_headers"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_flag_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_core_srv_conf_t, ignore_invalid_headers),
+      NULL },
+
     { ngx_string("location"),
       NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
       ngx_http_core_location,
@@ -505,7 +512,10 @@ ngx_http_core_run_phases(ngx_http_reques
                 continue;
             }
 
-            if (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_ERROR) {
+            if (rc >= NGX_HTTP_SPECIAL_RESPONSE
+                || rc == NGX_HTTP_NO_CONTENT
+                || rc == NGX_ERROR)
+            {
                 ngx_http_finalize_request(r, rc);
                 return;
             }
@@ -1578,6 +1588,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t
     cscf->client_header_timeout = NGX_CONF_UNSET_MSEC;
     cscf->client_header_buffer_size = NGX_CONF_UNSET_SIZE;
     cscf->restrict_host_names = NGX_CONF_UNSET_UINT;
+    cscf->ignore_invalid_headers = NGX_CONF_UNSET;
 
     return cscf;
 }
@@ -1663,6 +1674,9 @@ ngx_http_core_merge_srv_conf(ngx_conf_t 
     ngx_conf_merge_unsigned_value(conf->restrict_host_names,
                               prev->restrict_host_names, 0);
 
+    ngx_conf_merge_value(conf->ignore_invalid_headers,
+                              prev->ignore_invalid_headers, 1);
+
     return NGX_CONF_OK;
 }
 
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -87,6 +87,8 @@ typedef struct {
     ngx_msec_t                 client_header_timeout;
 
     ngx_uint_t                 restrict_host_names;
+
+    ngx_flag_t                 ignore_invalid_headers;
 } ngx_http_core_srv_conf_t;
 
 
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -48,7 +48,7 @@ static ngx_str_t ngx_http_status_lines[]
     ngx_null_string,  /* "201 Created" */
     ngx_null_string,  /* "202 Accepted" */
     ngx_null_string,  /* "203 Non-Authoritative Information" */
-    ngx_null_string,  /* "204 No Content" */
+    ngx_string("204 No Content"),
     ngx_null_string,  /* "205 Reset Content" */
     ngx_string("206 Partial Content"),
 
@@ -167,8 +167,8 @@ ngx_http_header_filter(ngx_http_request_
 
     if (r->headers_out.last_modified_time != -1) {
         if (r->headers_out.status != NGX_HTTP_OK
-            && r->headers_out.status != NGX_HTTP_NOT_MODIFIED
-            && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT)
+            && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT
+            && r->headers_out.status != NGX_HTTP_NOT_MODIFIED)
         {
             r->headers_out.last_modified_time = -1;
             r->headers_out.last_modified = NULL;
@@ -193,6 +193,16 @@ ngx_http_header_filter(ngx_http_request_
             /* 2XX */
             status = r->headers_out.status - NGX_HTTP_OK;
 
+            if (r->headers_out.status == NGX_HTTP_NO_CONTENT) {
+                r->header_only = 1;
+                r->headers_out.content_type.len = 0;
+                r->headers_out.content_type.data = NULL;
+                r->headers_out.last_modified_time = -1;
+                r->headers_out.last_modified = NULL;
+                r->headers_out.content_length = NULL;
+                r->headers_out.content_length_n = -1;
+            }
+
         } else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST) {
             /* 3XX */
             status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -529,6 +529,8 @@ ngx_http_parse_header_line(ngx_http_requ
 
         /* first char */
         case sw_start:
+            r->invalid_header = 0;
+
             switch (ch) {
             case CR:
                 r->header_end = p;
@@ -552,6 +554,8 @@ ngx_http_parse_header_line(ngx_http_requ
                     break;
                 }
 
+                r->invalid_header = 1;
+
                 break;
 
             }
@@ -606,6 +610,8 @@ ngx_http_parse_header_line(ngx_http_requ
                 break;
             }
 
+            r->invalid_header = 1;
+
             break;
 
         /* space* before header value */
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -725,6 +725,7 @@ ngx_http_process_request_headers(ngx_eve
     ngx_connection_t           *c;
     ngx_http_header_t          *hh;
     ngx_http_request_t         *r;
+    ngx_http_core_srv_conf_t   *cscf;
     ngx_http_core_main_conf_t  *cmcf;
 
     c = rev->data;
@@ -742,6 +743,7 @@ ngx_http_process_request_headers(ngx_eve
     }
 
     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+    cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
     hh = (ngx_http_header_t *) cmcf->headers_in_hash.buckets;
 
     rc = NGX_AGAIN;
@@ -783,8 +785,7 @@ ngx_http_process_request_headers(ngx_eve
 
         if (rc == NGX_OK) {
 
-#if 0
-            if (r->invalid_header) {
+            if (r->invalid_header && cscf->ignore_invalid_headers) {
 
                 /* there was error while a header line parsing */
 
@@ -796,7 +797,6 @@ ngx_http_process_request_headers(ngx_eve
                               &header);
                 continue;
             }
-#endif
 
             /* a header line has been parsed successfully */
 
@@ -1406,7 +1406,9 @@ ngx_http_finalize_request(ngx_http_reque
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http finalize request: %d, \"%V\"", rc, &r->uri);
 
-    if (r->parent && rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+    if (r->parent
+        && (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_HTTP_NO_CONTENT))
+    {
         ngx_http_finalize_request(r, ngx_http_special_response_handler(r, rc));
         return;
     }
@@ -1450,7 +1452,7 @@ ngx_http_finalize_request(ngx_http_reque
         return;
     }
 
-    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE || rc == NGX_HTTP_NO_CONTENT) {
 
         if (r->connection->read->timer_set) {
             ngx_del_timer(r->connection->read);
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -42,6 +42,7 @@
 
 
 #define NGX_HTTP_OK                        200
+#define NGX_HTTP_NO_CONTENT                204
 #define NGX_HTTP_PARTIAL_CONTENT           206
 
 #define NGX_HTTP_SPECIAL_RESPONSE          300
@@ -337,6 +338,8 @@ struct ngx_http_request_s {
     /* URI with "\0" or "%00" */
     unsigned                          zero_in_uri:1;
 
+    unsigned                          invalid_header:1;
+
     unsigned                          valid_location:1;
     unsigned                          valid_unparsed_uri:1;
     unsigned                          uri_changed:1;
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -191,6 +191,10 @@ static char error_504_page[] =
 
 static ngx_str_t error_pages[] = {
 
+    ngx_null_string,             /* 204 */
+
+#define NGX_HTTP_LEVEL_200  1
+
     /* ngx_null_string, */       /* 300 */
     ngx_string(error_301_page),
     ngx_string(error_302_page),
@@ -290,17 +294,23 @@ ngx_http_special_response_handler(ngx_ht
         }
     }
 
-    if (error < NGX_HTTP_BAD_REQUEST) {
+    if (error == NGX_HTTP_NO_CONTENT) {
+        /* 204 */
+        err = 0;
+
+    } else if (error < NGX_HTTP_BAD_REQUEST) {
         /* 3XX */
         err = error - NGX_HTTP_MOVED_PERMANENTLY;
 
     } else if (error < NGX_HTTP_NGX_CODES) {
         /* 4XX */
-        err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_300;
+        err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_200
+                                           + NGX_HTTP_LEVEL_300;
 
     } else {
         /* 49X, 5XX */
-        err = error - NGX_HTTP_NGX_CODES + NGX_HTTP_LEVEL_300
+        err = error - NGX_HTTP_NGX_CODES + NGX_HTTP_LEVEL_200
+                                         + NGX_HTTP_LEVEL_300
                                          + NGX_HTTP_LEVEL_400;
         switch (error) {
             case NGX_HTTP_TO_HTTPS:
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -779,12 +779,6 @@ ngx_http_upstream_process_header(ngx_eve
         return;
     }
 
-    if (n == NGX_HTTP_INTERNAL_SERVER_ERROR) {
-        ngx_http_upstream_finalize_request(r, u,
-                                           NGX_HTTP_INTERNAL_SERVER_ERROR);
-        return;
-    }
-
     u->header_in.last += n;
 
 #if 0
--- a/src/http/ngx_http_write_filter_module.c
+++ b/src/http/ngx_http_write_filter_module.c
@@ -168,6 +168,7 @@ ngx_http_write_filter(ngx_http_request_t
         return NGX_OK;
     }
 
+#if 0
     /*
      * avoid the output if there are no incoming bufs but there are
      * the postponed requests or data
@@ -176,6 +177,7 @@ ngx_http_write_filter(ngx_http_request_t
     if (in == NULL && r->postponed) {
         return NGX_OK;
     }
+#endif
 
     if (c->write->delayed) {
         return NGX_AGAIN;