changeset 30:e1ada20fc595 NGINX_0_1_15

nginx 0.1.15 *) Bugfix: the error while the connecting to the FastCGI server caused segmentation fault. *) Bugfix: the correct handling of the regular expression, that has different number of the captures and substitutions. *) Feature: the location, that is passed to the FastCGI server, can be regular expression. *) Bugfix: the FastCGI's parameter REQUEST_URI is now passed with the arguments and in the original state. *) Bugfix: the ngx_http_rewrite_module module was required to be built to use the regular expressions in locations. *) Bugfix: the directive "proxy_preserve_host on" adds port 80 to the "Host" headers, if upstream listen on port 80; bug appeared in 0.1.14. *) Bugfix: the same paths in autoconfiguration parameters --http-client-body-temp-path=PATH and --http-proxy-temp-path=PATH, or --http-client-body-temp-path=PATH and --http-fastcgi-temp-path=PATH caused segmentation fault.
author Igor Sysoev <http://sysoev.ru>
date Wed, 19 Jan 2005 00:00:00 +0300
parents 3efadd1f18f7
children 1b17dd824438
files CHANGES CHANGES.ru auto/lib/conf conf/nginx.conf src/core/nginx.h src/core/ngx_file.c src/core/ngx_regex.c src/core/ngx_regex.h src/event/modules/ngx_epoll_module.c src/event/ngx_event.c src/http/modules/ngx_http_fastcgi_handler.c src/http/modules/ngx_http_rewrite_handler.c src/http/modules/proxy/ngx_http_proxy_handler.c src/http/ngx_http_core_module.c src/http/ngx_http_upstream.c src/os/unix/ngx_channel.c
diffstat 16 files changed, 146 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,29 @@
+
+Changes with nginx 0.1.15                                        19 Jan 2005
+
+    *) Bugfix: the error while the connecting to the FastCGI server caused 
+       segmentation fault.
+
+    *) Bugfix: the correct handling of the regular exporession, that has 
+       different number of the captures and substitutions.
+
+    *) Feature: the location, that is passed to the FastCGI server, can be 
+       regualar expression.
+
+    *) Bugfix: the FastCGI's parameter REQUEST_URI is now passed with the 
+       arguments and in the original state.
+
+    *) Bugfix: the ngx_http_rewrite_module module was required to be built to 
+       use the regular expressions in locations.
+
+    *) Bugfix: the directive "proxy_preserve_host  on" adds port 80 to the 
+       "Host" headers, if upstream listen on port 80; bug appeared in 0.1.14.
+
+    *) Bugfix: the same pathes in autoconfiguration paramters 
+       --http-client-body-temp-path=PATH and --http-proxy-temp-path=PATH, or 
+       --http-client-body-temp-path=PATH nad --http-fastcgi-temp-path=PATH 
+       caused segmentation fault.
+
 
 Changes with nginx 0.1.14                                        18 Jan 2005
 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,3 +1,30 @@
+
+Изменения в nginx 0.1.15                                          19.01.2005
+
+    *) Исправление: ошибка соединения с FastCGI-сервером вызывала 
+       segmentation fault.
+
+    *) Исправление: корректная обработка регулярного выражения, в котором 
+       число выделенных частей не совпадает с числом подстановок.
+
+    *) Добавление: location, который передаётся FastCGI-серверу, может быть 
+       задан с помощью регулярного выражения.
+
+    *) Исправление: параметр FastCGI REQUEST_URI теперь передаётся вместе с 
+       аргументами и в том виде, в котором был получен от клиента.
+
+    *) Исправление: для использования регулярных выражений в location нужно 
+       было собирать nginx вместе с ngx_http_rewrite_module.
+
+    *) Исправление: если бэкенд слушал на 80-ом порту, то при использовании 
+       директивы "proxy_preserve_host  on" в заголовке "Host" указывался 
+       также порт 80; ошибка появилась в 0.1.14.
+
+    *) Исправление: если задать одинаковые пути в параметрах автоконфигурации 
+       --http-client-body-temp-path=PATH и --http-proxy-temp-path=PATH или 
+       --http-client-body-temp-path=PATH и --http-fastcgi-temp-path=PATH, то 
+       происходил segmentation fault.
+
 
 Изменения в nginx 0.1.14                                          18.01.2005
 
--- a/auto/lib/conf
+++ b/auto/lib/conf
@@ -2,7 +2,7 @@
 # Copyright (C) Igor Sysoev
 
 
-if [ $USE_PCRE = YES ]; then
+if [ $USE_PCRE = YES -o $PCRE != NONE ]; then
     . auto/lib/pcre/conf
 fi
 
--- a/conf/nginx.conf
+++ b/conf/nginx.conf
@@ -32,6 +32,10 @@ http {
             index  index.html index.htm;
         }
 
+        # deny access to .htaccess files
+        #
+        #location ~ \.ht {
+        #    deny  all;
+        #}
     }
-
 }
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VER          "nginx/0.1.14"
+#define NGINX_VER          "nginx/0.1.15"
 
 #define NGINX_VAR          "NGINX"
 #define NGX_NEWPID_EXT     ".newbin"
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -252,9 +252,19 @@ ngx_int_t ngx_add_path(ngx_conf_t *cf, n
             for (n = 0; n < 3; n++) {
                 if (p[i]->level[n] != path->level[n]) {
                     if (path->conf_file == NULL) {
+                        if (p[i]->conf_file == NULL) {
+                            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                                      "the default path name \"%V\" has "
+                                      "the same name as another default path, "
+                                      "but the different levels, you need to "
+                                      "redefine one of them in http section",
+                                      &p[i]->name);
+                            return NGX_ERROR;
+                        }
+
                         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                                       "the path name \"%V\" in %s:%ui has "
-                                      "the same name as default path but "
+                                      "the same name as default path, but "
                                       "the different levels, you need to "
                                       "define default path in http section",
                                       &p[i]->name, p[i]->conf_file, p[i]->line);
--- a/src/core/ngx_regex.c
+++ b/src/core/ngx_regex.c
@@ -79,16 +79,28 @@ ngx_regex_t *ngx_regex_compile(ngx_str_t
 }
 
 
+ngx_uint_t ngx_regex_capture_count(ngx_regex_t *re)
+{
+    int  rc, n;
+
+    n = 0;
+
+    rc = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &n);
+
+    return (ngx_uint_t) n;
+}
+
+
 ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s,
-                         int *matches, ngx_int_t size)
+                         int *captures, ngx_int_t size)
 {
     int  rc;
 
     rc = pcre_exec(re, NULL, (const char *) s->data, s->len, 0, 0,
-                   matches, size);
+                   captures, size);
 
     if (rc == -1) {
-        return NGX_DECLINED;
+        return NGX_REGEX_NO_MATCHED;
     }
 
     return rc;
--- a/src/core/ngx_regex.h
+++ b/src/core/ngx_regex.h
@@ -14,15 +14,18 @@
 #include <pcre.h>
 
 
-#define NGX_REGEX_CASELESS  PCRE_CASELESS
+#define NGX_REGEX_NO_MATCHED  -1000
+
+#define NGX_REGEX_CASELESS    PCRE_CASELESS
 
 typedef pcre  ngx_regex_t;
 
 void ngx_regex_init();
 ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options,
                                ngx_pool_t *pool, ngx_str_t *err);
+ngx_uint_t ngx_regex_capture_count(ngx_regex_t *re);
 ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s,
-                         int *matches, ngx_int_t size);
+                         int *captures, ngx_int_t size);
 
 #define ngx_regex_exec_n  "pcre_exec()"
 
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -229,7 +229,7 @@ static int ngx_epoll_add_event(ngx_event
     }
 
     ee.events = event | flags;
-    ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);
+    ee.data.u64 = (uintptr_t) c | ev->instance;
 
     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                    "epoll add event: fd:%d op:%d ev:%08XD",
@@ -282,7 +282,7 @@ static int ngx_epoll_del_event(ngx_event
     if (e->active) {
         op = EPOLL_CTL_MOD;
         ee.events = prev | flags;
-        ee.data.ptr = (void *) ((uintptr_t) c | ev->instance);
+        ee.data.u64 = (uintptr_t) c | ev->instance;
 
     } else {
         op = EPOLL_CTL_DEL;
@@ -311,7 +311,7 @@ static int ngx_epoll_add_connection(ngx_
     struct epoll_event  ee;
 
     ee.events = EPOLLIN|EPOLLOUT|EPOLLET;
-    ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance);
+    ee.data.u64 = (uintptr_t) c | c->read->instance;
 
     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
                    "epoll add connection: fd:%d ev:%08XD", c->fd, ee.events);
@@ -351,7 +351,7 @@ static int ngx_epoll_del_connection(ngx_
 
     op = EPOLL_CTL_DEL;
     ee.events = 0;
-    ee.data.ptr = NULL;
+    ee.data.u64 = 0;
 
     if (epoll_ctl(ep, op, c->fd, &ee) == -1) {
         ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -318,6 +318,7 @@ static ngx_int_t ngx_event_process_init(
     rev = cycle->read_events;
     for (i = 0; i < cycle->connection_n; i++) {
         rev[i].closed = 1;
+        rev[i].instance = 1;
 #if (NGX_THREADS)
         rev[i].lock = &c[i].lock;
         rev[i].own_lock = &c[i].lock;
@@ -325,7 +326,7 @@ static ngx_int_t ngx_event_process_init(
     }
 
     cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * ecf->connections,
-                                   cycle->log);
+                                    cycle->log);
     if (cycle->write_events == NULL) {
         return NGX_ERROR;
     }
@@ -361,6 +362,7 @@ static ngx_int_t ngx_event_process_init(
 
         ngx_memzero(c, sizeof(ngx_connection_t));
         ngx_memzero(rev, sizeof(ngx_event_t));
+        ngx_memzero(wev, sizeof(ngx_event_t));
 
         c->fd = s[i].fd;
         c->listening = &s[i];
--- a/src/http/modules/ngx_http_fastcgi_handler.c
+++ b/src/http/modules/ngx_http_fastcgi_handler.c
@@ -144,6 +144,9 @@ static ngx_str_t ngx_http_fastcgi_method
 };
 
 
+static ngx_str_t ngx_http_fastcgi_uri = ngx_string("/");
+
+
 static ngx_http_header_t ngx_http_fastcgi_headers_in[] = {
     { ngx_string("Status"), offsetof(ngx_http_fastcgi_headers_in_t, status) },
 
@@ -474,8 +477,8 @@ static ngx_int_t ngx_http_fastcgi_create
     }
 
     if (flcf->params & NGX_HTTP_FASTCGI_REQUEST_URI) {
-        len += 1 + ((r->uri.len > 127) ? 4 : 1)
-                 + sizeof("REQUEST_URI") - 1 + r->uri.len;
+        len += 1 + ((r->unparsed_uri.len > 127) ? 4 : 1)
+                 + sizeof("REQUEST_URI") - 1 + r->unparsed_uri.len;
     }
 
     if (flcf->params & NGX_HTTP_FASTCGI_SCRIPT_NAME) {
@@ -734,7 +737,7 @@ static ngx_int_t ngx_http_fastcgi_create
     if (flcf->params & NGX_HTTP_FASTCGI_REQUEST_URI) {
         *b->last++ = sizeof("REQUEST_URI") - 1;
 
-        len = r->uri.len;
+        len = r->unparsed_uri.len;
         if (len > 127) {
             *b->last++ = (u_char) (((len >> 24) & 0x7f) | 0x80);
             *b->last++ = (u_char) ((len >> 16) & 0xff);
@@ -746,7 +749,7 @@ static ngx_int_t ngx_http_fastcgi_create
         }
 
         b->last = ngx_cpymem(b->last, "REQUEST_URI", sizeof("REQUEST_URI") - 1);
-        b->last = ngx_cpymem(b->last, r->uri.data, len);
+        b->last = ngx_cpymem(b->last, r->unparsed_uri.data, len);
     }
 
 
@@ -1718,7 +1721,6 @@ static char *ngx_http_fastcgi_pass(ngx_c
         unix_upstream.name = value[1];
         unix_upstream.url = value[1];
 
-
         if (!(lcf->peers = ngx_unix_upstream_parse(cf, &unix_upstream))) {
             return NGX_CONF_ERROR;
         }
@@ -1744,9 +1746,10 @@ static char *ngx_http_fastcgi_pass(ngx_c
 
     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
 
-    lcf->location = &clcf->name;
     clcf->handler = ngx_http_fastcgi_handler;
 
+    lcf->location = clcf->regex ? &ngx_http_fastcgi_uri: &clcf->name;
+
     if (clcf->name.data[clcf->name.len - 1] == '/') {
         clcf->auto_redirect = 1;
     }
--- a/src/http/modules/ngx_http_rewrite_handler.c
+++ b/src/http/modules/ngx_http_rewrite_handler.c
@@ -23,7 +23,7 @@ typedef struct {
 
 typedef struct {
     ngx_regex_t  *regex;
-    ngx_uint_t    msize;
+    ngx_uint_t    ncaptures;
 
     ngx_array_t   ops;
     ngx_uint_t    size;
@@ -113,7 +113,7 @@ ngx_module_t  ngx_http_rewrite_module = 
 
 static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r)
 {
-    int                          *matches;
+    int                          *captures;
     u_char                       *p;
     size_t                        len;
     uintptr_t                     data;
@@ -132,18 +132,20 @@ static ngx_int_t ngx_http_rewrite_handle
     rule = scf->rules.elts;
     for (i = 0; i < scf->rules.nelts; i++) {
 
-        if (rule[i].msize) {
-            if (!(matches = ngx_palloc(r->pool, rule[i].msize * sizeof(int)))) {
+        if (rule[i].ncaptures) {
+            captures = ngx_palloc(r->pool, rule[i].ncaptures * sizeof(int));
+            if (captures == NULL) {
                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
         } else {
-            matches = NULL;
+            captures = NULL;
         }
 
-        rc = ngx_regex_exec(rule[i].regex, &r->uri, matches, rule[i].msize);
+        rc = ngx_regex_exec(rule[i].regex, &r->uri,
+                            captures, rule[i].ncaptures);
 
-        if (rc == NGX_DECLINED) {
+        if (rc == NGX_REGEX_NO_MATCHED) {
             if (scf->log) {
                 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
                               "\"%V\" does not match \"%V\"",
@@ -174,7 +176,7 @@ static ngx_int_t ngx_http_rewrite_handle
         uri.len = rule[i].size;
 
         for (n = 1; n < (ngx_uint_t) rc; n++) {
-           uri.len += matches[2 * n + 1] - matches[2 * n];
+           uri.len += captures[2 * n + 1] - captures[2 * n];
         }
 
         if (!(uri.data = ngx_palloc(r->pool, uri.len))) {
@@ -198,11 +200,13 @@ static ngx_int_t ngx_http_rewrite_handle
 
             } else { /* NGX_HTTP_REWRITE_COPY_MATCH */
                 m = 2 * op[n].data;
-                p = ngx_cpymem(p, &r->uri.data[matches[m]],
-                               matches[m + 1] - matches[m]);
+                p = ngx_cpymem(p, &r->uri.data[captures[m]],
+                               captures[m + 1] - captures[m]);
             }
         }
 
+        uri.len = p - uri.data;
+
         if (scf->log) {
             ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
                           "rewritten uri: \"%V\"", &uri);
@@ -309,7 +313,7 @@ static char *ngx_http_rewrite_rule(ngx_c
     u_char                   *data, *p;
     size_t                    len;
     ngx_str_t                *value, err;
-    ngx_uint_t                i;
+    ngx_uint_t                i, n;
     ngx_http_rewrite_op_t    *op;
     ngx_http_rewrite_rule_t  *rule;
     u_char                    errstr[NGX_MAX_CONF_ERRSTR];
@@ -321,7 +325,7 @@ static char *ngx_http_rewrite_rule(ngx_c
     ngx_init_array(rule->ops, cf->pool, 5, sizeof(ngx_http_rewrite_op_t),
                    NGX_CONF_ERROR);
 
-    rule->msize = 0;
+    rule->ncaptures = 0;
     rule->size = 0;
     rule->status = 0;
     rule->last = 0;
@@ -371,8 +375,8 @@ static char *ngx_http_rewrite_rule(ngx_c
                 op->op = NGX_HTTP_REWRITE_COPY_MATCH; 
                 op->data = value[2].data[++i] - '0';
 
-                if (rule->msize < op->data) {
-                    rule->msize = op->data;
+                if (rule->ncaptures < op->data) {
+                    rule->ncaptures = op->data;
                 }
 
                 i++;
@@ -414,9 +418,22 @@ static char *ngx_http_rewrite_rule(ngx_c
             }
         }
 
-        if (rule->msize) {
-            rule->msize++;
-            rule->msize *= 3;
+        n = ngx_regex_capture_count(rule->regex);
+
+        if (rule->ncaptures > n) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "pattern \"%V\" has less captures "
+                               "than referrenced in substitution \"%V\"",
+                               &value[1], &value[2]);
+            return NGX_CONF_ERROR;
+        }
+
+        if (rule->ncaptures < n) {
+            rule->ncaptures = n;
+        }
+
+        if (rule->ncaptures) {
+            rule->ncaptures = (rule->ncaptures + 1) * 3;
         }
 
         if (cf->args->nelts > 3) {
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -1351,6 +1351,7 @@ static char *ngx_http_proxy_set_pass(ngx
         lcf->upstream->port_text = inet_upstream.port_text;
         lcf->upstream->uri = inet_upstream.uri;
         lcf->upstream->uri_separator = "";
+        lcf->upstream->default_port = inet_upstream.default_port;
     }
 
     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -678,7 +678,7 @@ static ngx_int_t ngx_http_find_location(
 
         n = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0);
 
-        if (n == NGX_DECLINED) {
+        if (n == NGX_REGEX_NO_MATCHED) {
             continue;
         }
 
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1034,7 +1034,7 @@ static void ngx_http_upstream_finalize_r
         r->connection->log->handler = u->saved_handler;
     }
 
-    if (u->pipe.temp_file->file.fd) {
+    if (u->pipe.temp_file) {
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "http upstream temp fd: %d",
                        u->pipe.temp_file->file.fd);
@@ -1048,7 +1048,7 @@ static void ngx_http_upstream_finalize_r
     }
 #endif
 
-    if (u->pipe.temp_file->file.fd) {
+    if (u->pipe.temp_file) {
         r->file.fd = u->pipe.temp_file->file.fd;
 
 #if 0
--- a/src/os/unix/ngx_channel.c
+++ b/src/os/unix/ngx_channel.c
@@ -58,6 +58,7 @@ ngx_int_t ngx_write_channel(ngx_socket_t
     msg.msg_namelen = 0;
     msg.msg_iov = iov;
     msg.msg_iovlen = 1;
+    msg.msg_flags = 0;
 
     n = sendmsg(s, &msg, 0);