changeset 100:d6800bbe720e NGINX_0_2_4

nginx 0.2.4 *) Feature: the ngx_http_ssi_module supports "$var=text", "$var!=text", "$var=/text/", and "$var!=/text/" expressions in the "if" command. *) Bugfix: in proxying location without trailing slash; bug appeared in 0.1.44. *) Bugfix: the segmentation fault may occurred if the "rtsig" method was used; bug appeared in 0.2.0.
author Igor Sysoev <http://sysoev.ru>
date Mon, 03 Oct 2005 00:00:00 +0400
parents 942ae8bb3ece
children 5bb09dde34e7
files CHANGES CHANGES.ru src/core/nginx.h src/event/modules/ngx_rtsig_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_ssi_filter_module.c src/os/unix/ngx_atomic.h
diffstat 7 files changed, 170 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,15 @@
+
+Changes with nginx 0.2.4                                         03 Oct 2005
+
+    *) Feature: the ngx_http_ssi_module supports "$var=text", "$var!=text", 
+       "$var=/text/", and "$var!=/text/" expressions in the "if" command.
+
+    *) Bugfix: in proxying location without trailing slash; bug appeared in 
+       0.1.44.
+
+    *) Bugfix: the segmentation fault may occurred if the "rtsig" method 
+       was used; bug appeared in 0.2.0.
+
 
 Changes with nginx 0.2.3                                         30 Sep 2005
 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,3 +1,16 @@
+
+Изменения в nginx 0.2.4                                           03.10.2005
+
+    *) Добавление: модуль ngx_http_ssi_module поддерживает выражения 
+       "$var=text", "$var!=text", "$var=/text/" и "$var!=/text/" в команде 
+       if.
+
+    *) Исправление: ошибки при проксировании location без слэша в конце; 
+       ошибка появилась в 0.1.44.
+
+    *) Исправление: при использовании метода rtsig мог произойти 
+       segmentation fault; ошибка появилась в 0.2.0.
+
 
 Изменения в nginx 0.2.3                                           30.09.2005
 
@@ -7,7 +20,7 @@
 
 Изменения в nginx 0.2.2                                           30.09.2005
 
-    *) Добавление: команда config errmsg в модуле ngx_http_ssi_module.
+    *) Добавление: команда config errmsg в модуле ngx_http_sssi_module.
 
     *) Изменение: переменные модуля ngx_http_geo_module можно 
        переопределять директивой set.
@@ -22,7 +35,7 @@
        файлы, начинающиеся на точку.
 
     *) Исправление: если SSL handshake завершался с ошибкой, то это могло 
-       привести также в закрытию другого соединения. Спасибо Rob Mueller.
+       привести также к закрытию другого соединения. Спасибо Rob Mueller.
 
     *) Исправление: экспортные версии MSIE 5.x не могли соединиться по 
        HTTPS.
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VER          "nginx/0.2.3"
+#define NGINX_VER          "nginx/0.2.4"
 
 #define NGINX_VAR          "NGINX"
 #define NGX_OLDPID_EXT     ".oldbin"
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -428,9 +428,15 @@ ngx_rtsig_process_events(ngx_cycle_t *cy
             return NGX_OK;
         }
 
-        /* TODO: old_cycles */
+        c = ngx_cycle->files[si.si_fd];
+
+        if (c == NULL) {
+            /* the stale event */
 
-        c = ngx_cycle->files[si.si_fd];
+            ngx_accept_mutex_unlock();
+
+            return NGX_OK;
+        }
 
         instance = signo - rtscf->signo;
 
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -430,7 +430,7 @@ ngx_http_proxy_create_request(ngx_http_r
 
     escape = 0;
 
-    loc_len = r->valid_location ? u->conf->location->len - 1 : 0;
+    loc_len = r->valid_location ? u->conf->location->len : 0;
 
     if (plcf->upstream.pass_unparsed_uri && r->valid_unparsed_uri) {
         len += r->unparsed_uri.len;
@@ -514,12 +514,12 @@ ngx_http_proxy_create_request(ngx_http_r
                              r->method_name.len + 1);
     }
 
-    b->last = ngx_cpymem(b->last, u->conf->uri.data, u->conf->uri.len - 1);
-
     if (plcf->upstream.pass_unparsed_uri && r->valid_unparsed_uri) {
         b->last = ngx_cpymem(b->last, r->unparsed_uri.data,
                              r->unparsed_uri.len);
     } else {
+        b->last = ngx_cpymem(b->last, u->conf->uri.data, u->conf->uri.len);
+
         if (escape) {
             ngx_escape_uri(b->last, r->uri.data + loc_len,
                            r->uri.len - loc_len, NGX_ESCAPE_URI);
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -1603,9 +1603,16 @@ static ngx_int_t
 ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
     ngx_str_t **params)
 {
-    ngx_str_t                  *expr, var;
-    ngx_uint_t                  i;
+    u_char                     *p, *last;
+    ngx_str_t                  *expr, var, left, right;
+    ngx_int_t                   rc;
+    ngx_uint_t                  negative, noregex;
     ngx_http_variable_value_t  *vv;
+#if (NGX_PCRE)
+    ngx_str_t                   err;
+    ngx_regex_t                *regex;
+    u_char                      errstr[NGX_MAX_CONF_ERRSTR];
+#endif
 
     expr = params[NGX_HTTP_SSI_IF_EXPR];
 
@@ -1615,11 +1622,26 @@ ngx_http_ssi_if(ngx_http_request_t *r, n
         return NGX_HTTP_SSI_ERROR;
     }
 
-    var.len = expr->len - 1;
     var.data = expr->data + 1;
+    last = expr->data + expr->len;
+
+    for (p = var.data; p < last; p++) {
+        if (*p >= 'A' && *p <= 'Z') {
+            *p |= 0x20;
+            continue;
+        }
 
-    for (i = 0; i < var.len; i++) {
-        var.data[i] = ngx_tolower(var.data[i]);
+        if ((*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || *p == '_') {
+            continue;
+        }
+
+        break;
+    }
+
+    var.len = p - var.data;
+
+    while (p < last && *p == ' ') {
+        p++;
     }
 
     vv = ngx_http_get_variable(r, &var);
@@ -1628,7 +1650,100 @@ ngx_http_ssi_if(ngx_http_request_t *r, n
         return NGX_HTTP_SSI_ERROR;
     }
 
-    if (vv != NGX_HTTP_VAR_NOT_FOUND && vv->text.len != 0) {
+    if (p == last) {
+        if (vv != NGX_HTTP_VAR_NOT_FOUND && vv->text.len != 0) {
+            ctx->output = 1;
+
+        } else {
+            ctx->output = 0;
+        }
+
+        return NGX_OK;
+    }
+
+    if (p < last && *p == '=') {
+        negative = 0;
+        p++;
+
+    } else if (p + 1 < last && *p == '!' && *(p + 1) == '=') {
+        negative = 1;
+        p += 2;
+
+    } else {
+        goto invalid_expression;
+    }
+
+    while (p < last && *p == ' ') {
+        p++;
+    }
+
+    if (p < last && *p == '/') {
+        if (*(last - 1) != '/') {
+            goto invalid_expression;
+        }
+
+        noregex = 0;
+        last--;
+	p++;
+
+    } else {
+        noregex = 1;
+    }
+
+    right.len = last - p;
+    right.data = p;
+
+    if (vv == NGX_HTTP_VAR_NOT_FOUND) {
+        left.len = 0;
+        left.data = (u_char *) "";
+
+    } else {
+        left = vv->text;
+    }
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "left: \"%V\" right: \"%V\"", &left, &right);
+
+    if (noregex) {
+        if (left.len != right.len) {
+            rc = -1;
+
+        } else {
+            rc = ngx_strncmp(left.data, right.data, right.len);
+        }
+
+    } else {
+#if (NGX_PCRE)
+        err.len = NGX_MAX_CONF_ERRSTR;
+        err.data = errstr;
+
+        right.data[right.len] = '\0';
+
+        regex = ngx_regex_compile(&right, 0, r->pool, &err);
+
+        if (regex == NULL) {
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s", err.data);
+            return NGX_HTTP_SSI_ERROR;
+        }
+
+        rc = ngx_regex_exec(regex, &left, NULL, 0);
+
+        if (rc != NGX_REGEX_NO_MATCHED && rc < 0) {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
+                          rc, &left, &right);
+            return NGX_HTTP_SSI_ERROR;
+        }
+#else
+        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                      "the using of the regex \"%V\" in SSI "
+                      "requires PCRE library", &right);
+
+        return NGX_HTTP_SSI_ERROR;
+#endif
+    }
+
+    if ((rc == 0 && !negative) || (rc != 0 && negative)) {
         ctx->output = 1;
 
     } else {
@@ -1636,6 +1751,13 @@ ngx_http_ssi_if(ngx_http_request_t *r, n
     }
 
     return NGX_OK;
+
+invalid_expression:
+
+    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                  "invalid expression in \"%V\"", expr);
+
+    return NGX_HTTP_SSI_ERROR;
 }
 
 
--- a/src/os/unix/ngx_atomic.h
+++ b/src/os/unix/ngx_atomic.h
@@ -308,8 +308,9 @@ typedef volatile ngx_atomic_uint_t  ngx_
  * this branch is unlikely to be taken.
  *
  * the "=&r" means that no input registers can be used.
- * the "=&b" means that the base registers can be used only, i.e. any register
- * except r0.  the r0 register can not be used in "addi  r0, r0, 1".
+ * the "=&b" means that the base registers can be used only, i.e.
+ * any register except r0.  the r0 register always has a zero value and
+ * could not be used in "addi  r0, r0, 1".
  * the "1b" means the nearest backward label "1" and the "1f" means
  * the nearest forward label "1".
  */