[nginx] svn commit: r4439 - in branches/stable-1.0: . src/http/modules

mdounin at mdounin.ru mdounin at mdounin.ru
Sun Feb 5 14:09:47 UTC 2012


Author: mdounin
Date: 2012-02-05 14:09:46 +0000 (Sun, 05 Feb 2012)
New Revision: 4439

Log:
Merge of r4375, r4382:

SSI changes:

*) The "if" command did not work inside the "block" command and
   produced parsing errors.

*) Added regex captures support in the expression of the "if" command.


Modified:
   branches/stable-1.0/
   branches/stable-1.0/src/http/modules/ngx_http_ssi_filter_module.c
   branches/stable-1.0/src/http/modules/ngx_http_ssi_filter_module.h


Property changes on: branches/stable-1.0
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk:3960-3974,3977-3987,3991-3996,3998,4000-4018,4020,4023,4025-4027,4034-4065,4073,4077,4086-4090,4094-4102,4106-4108,4113-4114,4129-4137,4143-4144,4147-4158,4177,4179,4182-4184,4186-4187,4189-4205,4207,4209-4210,4212,4217-4223,4227-4232,4235-4237,4265-4268,4270,4274-4276,4278-4280,4282-4284,4294-4295,4298,4300-4309,4313,4315,4320-4321,4326-4327,4335-4336,4338-4343,4372-4374,4377
   + /trunk:3960-3974,3977-3987,3991-3996,3998,4000-4018,4020,4023,4025-4027,4034-4065,4073,4077,4086-4090,4094-4102,4106-4108,4113-4114,4129-4137,4143-4144,4147-4158,4177,4179,4182-4184,4186-4187,4189-4205,4207,4209-4210,4212,4217-4223,4227-4232,4235-4237,4265-4268,4270,4274-4276,4278-4280,4282-4284,4294-4295,4298,4300-4309,4313,4315,4320-4321,4326-4327,4335-4336,4338-4343,4372-4375,4377,4382

Modified: branches/stable-1.0/src/http/modules/ngx_http_ssi_filter_module.c
===================================================================
--- branches/stable-1.0/src/http/modules/ngx_http_ssi_filter_module.c	2012-02-05 13:53:50 UTC (rev 4438)
+++ branches/stable-1.0/src/http/modules/ngx_http_ssi_filter_module.c	2012-02-05 14:09:46 UTC (rev 4439)
@@ -78,6 +78,8 @@
     ngx_str_t *name, ngx_uint_t key);
 static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r,
     ngx_http_ssi_ctx_t *ctx, ngx_str_t *text, ngx_uint_t flags);
+static ngx_int_t ngx_http_ssi_regex_match(ngx_http_request_t *r,
+    ngx_str_t *pattern, ngx_str_t *str);
 
 static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r,
     ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
@@ -624,16 +626,6 @@
                     continue;
                 }
 
-                if (cmd->conditional
-                    && (ctx->conditional == 0
-                        || ctx->conditional > cmd->conditional))
-                {
-                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                                  "invalid context of SSI command: \"%V\"",
-                                  &ctx->command);
-                    goto ssi_error;
-                }
-
                 if (!ctx->output && !cmd->block) {
 
                     if (ctx->block) {
@@ -709,6 +701,16 @@
                     }
                 }
 
+                if (cmd->conditional
+                    && (ctx->conditional == 0
+                        || ctx->conditional > cmd->conditional))
+                {
+                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                                  "invalid context of SSI command: \"%V\"",
+                                  &ctx->command);
+                    goto ssi_error;
+                }
+
                 if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) {
                     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                                   "too many SSI command paramters: \"%V\"",
@@ -1531,6 +1533,30 @@
 
     ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
 
+#if (NGX_PCRE)
+    {
+    ngx_str_t  *value;
+
+    if (key >= '0' && key <= '9') {
+        i = key - '0';
+
+        if (i < ctx->ncaptures) {
+            value = ngx_palloc(r->pool, sizeof(ngx_str_t));
+            if (value == NULL) {
+                return NULL;
+            }
+
+            i *= 2;
+
+            value->data = ctx->captures_data + ctx->captures[i];
+            value->len = ctx->captures[i + 1] - ctx->captures[i];
+
+            return value;
+        }
+    }
+    }
+#endif
+
     if (ctx->variables == NULL) {
         return NULL;
     }
@@ -1820,6 +1846,115 @@
 
 
 static ngx_int_t
+ngx_http_ssi_regex_match(ngx_http_request_t *r, ngx_str_t *pattern,
+    ngx_str_t *str)
+{
+#if (NGX_PCRE)
+    int                   rc, *captures;
+    u_char               *p, errstr[NGX_MAX_CONF_ERRSTR];
+    size_t                size;
+    ngx_int_t             key;
+    ngx_str_t            *vv, name, value;
+    ngx_uint_t            i, n;
+    ngx_http_ssi_ctx_t   *ctx;
+    ngx_http_ssi_var_t   *var;
+    ngx_regex_compile_t   rgc;
+
+    ngx_memzero(&rgc, sizeof(ngx_regex_compile_t));
+
+    rgc.pattern = *pattern;
+    rgc.pool = r->pool;
+    rgc.err.len = NGX_MAX_CONF_ERRSTR;
+    rgc.err.data = errstr;
+
+    if (ngx_regex_compile(&rgc) != NGX_OK) {
+        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err);
+        return NGX_HTTP_SSI_ERROR;
+    }
+
+    n = (rgc.captures + 1) * 3;
+
+    captures = ngx_palloc(r->pool, n * sizeof(int));
+    if (captures == NULL) {
+        return NGX_ERROR;
+    }
+
+    rc = ngx_regex_exec(rgc.regex, str, captures, n);
+
+    if (rc < NGX_REGEX_NO_MATCHED) {
+        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                      ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
+                      rc, str, pattern);
+        return NGX_HTTP_SSI_ERROR;
+    }
+
+    if (rc == NGX_REGEX_NO_MATCHED) {
+        return NGX_DECLINED;
+    }
+
+    ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
+
+    ctx->ncaptures = rc;
+    ctx->captures = captures;
+    ctx->captures_data = str->data;
+
+    if (rgc.named_captures > 0) {
+
+        if (ctx->variables == NULL) {
+            ctx->variables = ngx_list_create(r->pool, 4,
+                                             sizeof(ngx_http_ssi_var_t));
+            if (ctx->variables == NULL) {
+                return NGX_ERROR;
+            }
+        }
+
+        size = rgc.name_size;
+        p = rgc.names;
+
+        for (i = 0; i < (ngx_uint_t) rgc.named_captures; i++, p += size) {
+
+            name.data = &p[2];
+            name.len = ngx_strlen(name.data);
+
+            n = 2 * ((p[0] << 8) + p[1]);
+
+            value.data = &str->data[captures[n]];
+            value.len = captures[n + 1] - captures[n];
+
+            key = ngx_hash_strlow(name.data, name.data, name.len);
+
+            vv = ngx_http_ssi_get_variable(r, &name, key);
+
+            if (vv) {
+                *vv = value;
+                continue;
+            }
+
+            var = ngx_list_push(ctx->variables);
+            if (var == NULL) {
+                return NGX_ERROR;
+            }
+
+            var->name = name;
+            var->key = key;
+            var->value = value;
+        }
+    }
+
+    return NGX_OK;
+
+#else
+
+    ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                  "the using of the regex \"%V\" in SSI requires PCRE library",
+                  pattern);
+    return NGX_HTTP_SSI_ERROR;
+
+#endif
+}
+
+
+static ngx_int_t
 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
     ngx_str_t **params)
 {
@@ -2451,39 +2586,17 @@
         }
 
     } else {
-#if (NGX_PCRE)
-        ngx_regex_compile_t  rgc;
-        u_char               errstr[NGX_MAX_CONF_ERRSTR];
-
         right.data[right.len] = '\0';
 
-        ngx_memzero(&rgc, sizeof(ngx_regex_compile_t));
+        rc = ngx_http_ssi_regex_match(r, &right, &left);
 
-        rgc.pattern = right;
-        rgc.pool = r->pool;
-        rgc.err.len = NGX_MAX_CONF_ERRSTR;
-        rgc.err.data = errstr;
-
-        if (ngx_regex_compile(&rgc) != NGX_OK) {
-            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err);
-            return NGX_HTTP_SSI_ERROR;
+        if (rc == NGX_OK) {
+            rc = 0;
+        } else if (rc == NGX_DECLINED) {
+            rc = -1;
+        } else {
+            return rc;
         }
-
-        rc = ngx_regex_exec(rgc.regex, &left, NULL, 0);
-
-        if (rc < NGX_REGEX_NO_MATCHED) {
-            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                          ngx_regex_exec_n " failed: %i 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)) {

Modified: branches/stable-1.0/src/http/modules/ngx_http_ssi_filter_module.h
===================================================================
--- branches/stable-1.0/src/http/modules/ngx_http_ssi_filter_module.h	2012-02-05 13:53:50 UTC (rev 4438)
+++ branches/stable-1.0/src/http/modules/ngx_http_ssi_filter_module.h	2012-02-05 14:09:46 UTC (rev 4439)
@@ -64,6 +64,12 @@
     ngx_list_t               *variables;
     ngx_array_t              *blocks;
 
+#if (NGX_PCRE)
+    ngx_uint_t                ncaptures;
+    int                      *captures;
+    u_char                   *captures_data;
+#endif
+
     unsigned                  conditional:2;
     unsigned                  encoding:2;
     unsigned                  block:1;



More information about the nginx-devel mailing list