[nginx] svn commit: r4382 - trunk/src/http/modules
vbart at nginx.com
vbart at nginx.com
Sun Dec 25 20:08:37 UTC 2011
Author: vbart
Date: 2011-12-25 20:08:37 +0000 (Sun, 25 Dec 2011)
New Revision: 4382
Log:
SSI: added regex captures support in the expression of the "if" command.
Modified:
trunk/src/http/modules/ngx_http_ssi_filter_module.c
trunk/src/http/modules/ngx_http_ssi_filter_module.h
Modified: trunk/src/http/modules/ngx_http_ssi_filter_module.c
===================================================================
--- trunk/src/http/modules/ngx_http_ssi_filter_module.c 2011-12-25 19:32:31 UTC (rev 4381)
+++ trunk/src/http/modules/ngx_http_ssi_filter_module.c 2011-12-25 20:08:37 UTC (rev 4382)
@@ -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);
@@ -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: trunk/src/http/modules/ngx_http_ssi_filter_module.h
===================================================================
--- trunk/src/http/modules/ngx_http_ssi_filter_module.h 2011-12-25 19:32:31 UTC (rev 4381)
+++ trunk/src/http/modules/ngx_http_ssi_filter_module.h 2011-12-25 20:08:37 UTC (rev 4382)
@@ -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