[nginx] svn commit: r4555 - trunk/src/http/modules
mdounin at mdounin.ru
mdounin at mdounin.ru
Thu Mar 22 10:44:01 UTC 2012
Author: mdounin
Date: 2012-03-22 10:44:00 +0000 (Thu, 22 Mar 2012)
New Revision: 4555
URL: http://trac.nginx.org/nginx/changeset/4555/nginx
Log:
Added xslt_param and xslt_string_param directives.
Based on patch by Samuel Behan.
Modified:
trunk/src/http/modules/ngx_http_xslt_filter_module.c
Modified: trunk/src/http/modules/ngx_http_xslt_filter_module.c
===================================================================
--- trunk/src/http/modules/ngx_http_xslt_filter_module.c 2012-03-22 10:43:33 UTC (rev 4554)
+++ trunk/src/http/modules/ngx_http_xslt_filter_module.c 2012-03-22 10:44:00 UTC (rev 4555)
@@ -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 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 @@
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 @@
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 @@
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 @@
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, ¶m[i], &string) != NGX_OK) {
+ if (ngx_http_complex_value(r, ¶m[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 @@
}
}
- 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_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 @@
}
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 @@
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 = ¶m->value;
ccv.zero = 1;
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
@@ -866,6 +954,48 @@
}
+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 = ¶m->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 @@
* conf->sheets = { NULL };
* conf->types = { NULL };
* conf->types_keys = NULL;
+ * conf->params = NULL;
*/
return conf;
@@ -945,6 +1076,10 @@
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)
More information about the nginx-devel
mailing list