Welcome! Log In Create A New Profile

Advanced

Re: [PATCH] add xslt_stylesheet_param directive

Maxim Dounin
March 04, 2012 08:00AM
Hello!

On Sun, Feb 26, 2012 at 04:15:33PM +0100, SamB wrote:

> Hi,
>
> sorry for late response, had no spare time for this. Here is new patch,
> please review it.
> I've modified the string_param-enabled - it seems to better fit my
> usage...

Please check the attached patch. It cleans up some style issues
and slightly changes parameter processing to be more uniform with
parameters from xslt_stylesheet directives.

There is also a tiny patch included which fixes long-standing
off-by-one bug in parsing parameters from xslt_stylesheet
directives.

Tests are here:
http://mdounin.ru/hg/nginx-tests/rev/6bac00bba8d4

Maxim Dounin
# HG changeset patch
# User Maxim Dounin <mdounin@mdounin.ru>
# Date 1330697803 -14400
# Node ID 4df0e70d82dd2555b2aa076197947f744c4aea44
# Parent 88e257b4bd3d61e30d1421ab6f2e417a8baedb96
Fixed off-by-one in xslt parameter parsing.

The problem was introduced in 0.7.44 (r2589) during conversion to complex
values. Previously string.len included space for terminating NUL, but
with complex values it doesn't.

diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c
--- a/src/http/modules/ngx_http_xslt_filter_module.c
+++ b/src/http/modules/ngx_http_xslt_filter_module.c
@@ -585,7 +585,7 @@ ngx_http_xslt_params(ngx_http_request_t
"xslt filter param: \"%s\"", string.data);

p = string.data;
- last = string.data + string.len - 1;
+ last = string.data + string.len;

while (p && *p) {

# HG changeset patch
# User Maxim Dounin <mdounin@mdounin.ru>
# Date 1330707634 -14400
# Node ID ceb911a15613cf81f6a3669c8d39aef596ad36e7
# Parent 4df0e70d82dd2555b2aa076197947f744c4aea44
Added xslt_param and xslt_string_param directives.

Based on patch by Samuel Behan.

diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c
--- a/src/http/modules/ngx_http_xslt_filter_module.c
+++ b/src/http/modules/ngx_http_xslt_filter_module.c
@@ -14,6 +14,7 @@
#include <libxslt/xslt.h>
#include <libxslt/xsltInternals.h>
#include <libxslt/transform.h>
+#include <libxslt/variables.h>
#include <libxslt/xsltutils.h>

#if (NGX_HAVE_EXSLT)
@@ -27,38 +28,47 @@


typedef struct {
- u_char *name;
- void *data;
+ u_char *name;
+ void *data;
} ngx_http_xslt_file_t;


typedef struct {
- ngx_array_t dtd_files; /* ngx_http_xslt_file_t */
- ngx_array_t sheet_files; /* ngx_http_xslt_file_t */
+ ngx_array_t dtd_files; /* ngx_http_xslt_file_t */
+ ngx_array_t sheet_files; /* ngx_http_xslt_file_t */
} ngx_http_xslt_filter_main_conf_t;


typedef struct {
- xsltStylesheetPtr stylesheet;
- ngx_array_t params; /* ngx_http_complex_value_t */
+ u_char *name;
+ ngx_http_complex_value_t value;
+ ngx_uint_t quote; /* unsigned quote:1; */
+} ngx_http_xslt_param_t;
+
+
+typedef struct {
+ xsltStylesheetPtr stylesheet;
+ ngx_array_t params; /* ngx_http_xslt_param_t */
} ngx_http_xslt_sheet_t;


typedef struct {
- xmlDtdPtr dtd;
- ngx_array_t sheets; /* ngx_http_xslt_sheet_t */
- ngx_hash_t types;
- ngx_array_t *types_keys;
+ xmlDtdPtr dtd;
+ ngx_array_t sheets; /* ngx_http_xslt_sheet_t */
+ ngx_hash_t types;
+ ngx_array_t *types_keys;
+ ngx_array_t *params; /* ngx_http_xslt_param_t */
} ngx_http_xslt_filter_loc_conf_t;


typedef struct {
- xmlDocPtr doc;
- xmlParserCtxtPtr ctxt;
- ngx_http_request_t *request;
- ngx_array_t params;
+ xmlDocPtr doc;
+ xmlParserCtxtPtr ctxt;
+ xsltTransformContextPtr transform;
+ ngx_http_request_t *request;
+ ngx_array_t params;

- ngx_uint_t done; /* unsigned done:1; */
+ ngx_uint_t done; /* unsigned done:1; */
} ngx_http_xslt_filter_ctx_t;


@@ -76,7 +86,7 @@ static void ngx_cdecl ngx_http_xslt_sax_
static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
ngx_http_xslt_filter_ctx_t *ctx);
static ngx_int_t ngx_http_xslt_params(ngx_http_request_t *r,
- ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params);
+ ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params, ngx_uint_t final);
static u_char *ngx_http_xslt_content_type(xsltStylesheetPtr s);
static u_char *ngx_http_xslt_encoding(xsltStylesheetPtr s);
static void ngx_http_xslt_cleanup(void *data);
@@ -85,6 +95,8 @@ static char *ngx_http_xslt_entities(ngx_
void *conf);
static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+static char *ngx_http_xslt_param(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static void ngx_http_xslt_cleanup_dtd(void *data);
static void ngx_http_xslt_cleanup_stylesheet(void *data);
static void *ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf);
@@ -117,6 +129,20 @@ static ngx_command_t ngx_http_xslt_filt
0,
NULL },

+ { ngx_string("xslt_param"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
+ ngx_http_xslt_param,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("xslt_string_param"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
+ ngx_http_xslt_param,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ (void *) 1 },
+
{ ngx_string("xslt_types"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_types_slot,
@@ -469,13 +495,31 @@ ngx_http_xslt_apply_stylesheet(ngx_http_

for (i = 0; i < conf->sheets.nelts; i++) {

- if (ngx_http_xslt_params(r, ctx, &sheet[i].params) != NGX_OK) {
+ ctx->transform = xsltNewTransformContext(sheet[i].stylesheet, doc);
+ if (ctx->transform == NULL) {
xmlFreeDoc(doc);
return NULL;
}

- res = xsltApplyStylesheet(sheet[i].stylesheet, doc, ctx->params.elts);
+ if (conf->params
+ && ngx_http_xslt_params(r, ctx, conf->params, 0) != NGX_OK)
+ {
+ xsltFreeTransformContext(ctx->transform);
+ xmlFreeDoc(doc);
+ return NULL;
+ }

+ if (ngx_http_xslt_params(r, ctx, &sheet[i].params, 1) != NGX_OK) {
+ xsltFreeTransformContext(ctx->transform);
+ xmlFreeDoc(doc);
+ return NULL;
+ }
+
+ res = xsltApplyStylesheetUser(sheet[i].stylesheet, doc,
+ ctx->params.elts, NULL, NULL,
+ ctx->transform);
+
+ xsltFreeTransformContext(ctx->transform);
xmlFreeDoc(doc);

if (res == NULL) {
@@ -565,25 +609,66 @@ ngx_http_xslt_apply_stylesheet(ngx_http_

static ngx_int_t
ngx_http_xslt_params(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
- ngx_array_t *params)
+ ngx_array_t *params, ngx_uint_t final)
{
- u_char *p, *last, *value, *dst, *src, **s;
- size_t len;
- ngx_uint_t i;
- ngx_str_t string;
- ngx_http_complex_value_t *param;
+ u_char *p, *last, *value, *dst, *src, **s;
+ size_t len;
+ ngx_uint_t i;
+ ngx_str_t string;
+ ngx_http_xslt_param_t *param;

param = params->elts;

for (i = 0; i < params->nelts; i++) {

- if (ngx_http_complex_value(r, &param[i], &string) != NGX_OK) {
+ if (ngx_http_complex_value(r, &param[i].value, &string) != NGX_OK) {
return NGX_ERROR;
}

ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"xslt filter param: \"%s\"", string.data);

+ if (param[i].name) {
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "xslt filter param name: \"%s\"", param[i].name);
+
+ if (param[i].quote) {
+ if (xsltQuoteOneUserParam(ctx->transform, param[i].name,
+ string.data)
+ != 0)
+ {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "xsltQuoteOneUserParam(\"%s\", \"%s\") failed",
+ param[i].name, string.data);
+ return NGX_ERROR;
+ }
+
+ continue;
+ }
+
+ s = ngx_array_push(&ctx->params);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
+
+ *s = param[i].name;
+
+ s = ngx_array_push(&ctx->params);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
+
+ *s = string.data;
+
+ continue;
+ }
+
+ /*
+ * parse param1=value1:param2=value2 syntax as used by parameters
+ * specified in xslt_stylesheet directives
+ */
+
p = string.data;
last = string.data + string.len;

@@ -641,13 +726,15 @@ ngx_http_xslt_params(ngx_http_request_t
}
}

- s = ngx_array_push(&ctx->params);
- if (s == NULL) {
- return NGX_ERROR;
+ if (final) {
+ s = ngx_array_push(&ctx->params);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
+
+ *s = NULL;
}

- *s = NULL;
-
return NGX_OK;
}

@@ -768,7 +855,7 @@ ngx_http_xslt_stylesheet(ngx_conf_t *cf,
ngx_pool_cleanup_t *cln;
ngx_http_xslt_file_t *file;
ngx_http_xslt_sheet_t *sheet;
- ngx_http_complex_value_t *param;
+ ngx_http_xslt_param_t *param;
ngx_http_compile_complex_value_t ccv;
ngx_http_xslt_filter_main_conf_t *xmcf;

@@ -837,7 +924,7 @@ found:
}

if (ngx_array_init(&sheet->params, cf->pool, n - 2,
- sizeof(ngx_http_complex_value_t))
+ sizeof(ngx_http_xslt_param_t))
!= NGX_OK)
{
return NGX_CONF_ERROR;
@@ -850,11 +937,12 @@ found:
return NGX_CONF_ERROR;
}

+ ngx_memzero(param, sizeof(ngx_http_xslt_param_t));
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));

ccv.cf = cf;
ccv.value = &value[i];
- ccv.complex_value = param;
+ ccv.complex_value = &param->value;
ccv.zero = 1;

if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
@@ -866,6 +954,48 @@ found:
}


+static char *
+ngx_http_xslt_param(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_xslt_filter_loc_conf_t *xlcf = conf;
+
+ ngx_http_xslt_param_t *param;
+ ngx_http_compile_complex_value_t ccv;
+ ngx_str_t *value;
+
+ value = cf->args->elts;
+
+ if (xlcf->params == NULL) {
+ xlcf->params = ngx_array_create(cf->pool, 2,
+ sizeof(ngx_http_xslt_param_t));
+ if (xlcf->params == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ param = ngx_array_push(xlcf->params);
+ if (param == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ param->name = value[1].data;
+ param->quote = (cmd->post == NULL) ? 0 : 1;
+
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[2];
+ ccv.complex_value = &param->value;
+ ccv.zero = 1;
+
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
static void
ngx_http_xslt_cleanup_dtd(void *data)
{
@@ -925,6 +1055,7 @@ ngx_http_xslt_filter_create_conf(ngx_con
* conf->sheets = { NULL };
* conf->types = { NULL };
* conf->types_keys = NULL;
+ * conf->params = NULL;
*/

return conf;
@@ -945,6 +1076,10 @@ ngx_http_xslt_filter_merge_conf(ngx_conf
conf->sheets = prev->sheets;
}

+ if (conf->params == NULL) {
+ conf->params = prev->params;
+ }
+
if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
&prev->types_keys, &prev->types,
ngx_http_xslt_default_types)
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[PATCH] add xslt_stylesheet_param directive Attachments

SamB 1756 January 24, 2012 05:04PM

Re: [PATCH] add xslt_stylesheet_param directive

Maxim Dounin 673 January 30, 2012 08:54PM

Re: [PATCH] add xslt_stylesheet_param directive Attachments

SamB 560 February 04, 2012 11:50AM

Re: [PATCH] add xslt_stylesheet_param directive

Laurence Rowe 608 February 07, 2012 08:04PM

Re: [PATCH] add xslt_stylesheet_param directive Attachments

SamB 553 February 08, 2012 07:58AM

Re: [PATCH] add xslt_stylesheet_param directive

Maxim Dounin 570 February 09, 2012 06:14PM

Re: [PATCH] add xslt_stylesheet_param directive

SamB 760 February 10, 2012 12:50PM

Re: [PATCH] add xslt_stylesheet_param directive

Maxim Dounin 675 February 09, 2012 06:14PM

Re: [PATCH] add xslt_stylesheet_param directive

SamB 713 February 10, 2012 12:02PM

Re: [PATCH] add xslt_stylesheet_param directive Attachments

SamB 640 February 26, 2012 10:18AM

Re: [PATCH] add xslt_stylesheet_param directive

Maxim Dounin 467 March 04, 2012 08:00AM

Re: [PATCH] add xslt_stylesheet_param directive

SamB 624 March 05, 2012 05:34PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 287
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready