changeset 551:483cca230603 release-0.2.4

nginx-0.2.4-RELEASE import *) 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; the bug had appeared in 0.1.44. *) Bugfix: the segmentation fault may occurred if the "rtsig" method was used; the bug had appeared in 0.2.0.
author Igor Sysoev <igor@sysoev.ru>
date Mon, 03 Oct 2005 12:53:14 +0000
parents da3c2b580c08
children b6f3197058d3
files docs/xml/nginx/changes.xml 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 6 files changed, 185 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -9,6 +9,46 @@
 <title lang="en">nginx changelog</title>
 
 
+<changes ver="0.2.4" date="03.10.2005">
+
+<change type="feature">
+<para lang="ru">
+модуль ngx_http_ssi_module поддерживает выражения
+"$var=text", "$var!=text", "$var=/text/" и "$var!=/text/"
+в команде if.
+</para>
+<para lang="en">
+the ngx_http_ssi_module supports
+"$var=text", "$var!=text", "$var=/text/", and "$var!=/text/" expressions
+in the "if" command.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+ошибки при проксировании location без слэша в конце;
+ошибка появилась в 0.1.44.
+</para>
+<para lang="en">
+in proxying location without trailing slash;
+bug appeared in 0.1.44.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+при использовании метода rtsig мог произойти segmentation fault;
+ошибка появилась в 0.2.0.
+</para>
+<para lang="en">
+the segmentation fault may occurred if the "rtsig" method was used;
+bug appeared in 0.2.0.
+</para>
+</change>
+
+</changes>
+
+
 <changes ver="0.2.3" date="30.09.2005">
 
 <change type="bugfix">
@@ -29,7 +69,7 @@ bug appeared in 0.2.2.
 
 <change type="feature">
 <para lang="ru">
-команда config errmsg в модуле ngx_http_ssi_module.
+команда config errmsg в модуле ngx_http_sssi_module.
 </para>
 <para lang="en">
 the "config errmsg" command of the ngx_http_ssi_module.
@@ -78,7 +118,7 @@ the ngx_http_autoindex_module now do not
 <change type="bugfix">
 <para lang="ru">
 если SSL handshake завершался с ошибкой, то это могло привести также
-в закрытию другого соединения.
+к закрытию другого соединения.
 Спасибо Rob Mueller.
 </para>
 <para lang="en">
--- 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".
  */