Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_xslt_filter_module.c @ 4553:3dd8a403faa1
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.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 22 Mar 2012 10:43:33 +0000 |
parents | d620f497c50f |
children | 212a0251951b |
rev | line source |
---|---|
2139 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
2139 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 #include <libxml/parser.h> | |
13 #include <libxml/tree.h> | |
14 #include <libxslt/xslt.h> | |
15 #include <libxslt/xsltInternals.h> | |
16 #include <libxslt/transform.h> | |
17 #include <libxslt/xsltutils.h> | |
18 | |
2299 | 19 #if (NGX_HAVE_EXSLT) |
20 #include <libexslt/exslt.h> | |
21 #endif | |
22 | |
2139 | 23 |
24 #ifndef NGX_HTTP_XSLT_REUSE_DTD | |
25 #define NGX_HTTP_XSLT_REUSE_DTD 1 | |
26 #endif | |
27 | |
28 | |
29 typedef struct { | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
30 u_char *name; |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
31 void *data; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
32 } ngx_http_xslt_file_t; |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
33 |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
34 |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
35 typedef struct { |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
36 ngx_array_t dtd_files; /* ngx_http_xslt_file_t */ |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
37 ngx_array_t sheet_files; /* ngx_http_xslt_file_t */ |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
38 } ngx_http_xslt_filter_main_conf_t; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
39 |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
40 |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
41 typedef struct { |
2139 | 42 xsltStylesheetPtr stylesheet; |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
43 ngx_array_t params; /* ngx_http_complex_value_t */ |
2139 | 44 } ngx_http_xslt_sheet_t; |
45 | |
46 | |
47 typedef struct { | |
48 xmlDtdPtr dtd; | |
2153
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
49 ngx_array_t sheets; /* ngx_http_xslt_sheet_t */ |
2148 | 50 ngx_hash_t types; |
51 ngx_array_t *types_keys; | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
52 } ngx_http_xslt_filter_loc_conf_t; |
2139 | 53 |
54 | |
55 typedef struct { | |
56 xmlDocPtr doc; | |
57 xmlParserCtxtPtr ctxt; | |
58 ngx_http_request_t *request; | |
59 ngx_array_t params; | |
2153
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
60 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
61 ngx_uint_t done; /* unsigned done:1; */ |
2139 | 62 } ngx_http_xslt_filter_ctx_t; |
63 | |
64 | |
65 static ngx_int_t ngx_http_xslt_send(ngx_http_request_t *r, | |
66 ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b); | |
67 static ngx_int_t ngx_http_xslt_add_chunk(ngx_http_request_t *r, | |
68 ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b); | |
69 | |
70 | |
71 static void ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name, | |
72 const xmlChar *externalId, const xmlChar *systemId); | |
73 static void ngx_cdecl ngx_http_xslt_sax_error(void *data, const char *msg, ...); | |
74 | |
75 | |
76 static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, | |
77 ngx_http_xslt_filter_ctx_t *ctx); | |
78 static ngx_int_t ngx_http_xslt_params(ngx_http_request_t *r, | |
79 ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params); | |
2153
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
80 static u_char *ngx_http_xslt_content_type(xsltStylesheetPtr s); |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
81 static u_char *ngx_http_xslt_encoding(xsltStylesheetPtr s); |
2139 | 82 static void ngx_http_xslt_cleanup(void *data); |
83 | |
84 static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, | |
85 void *conf); | |
86 static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, | |
87 void *conf); | |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
88 static void ngx_http_xslt_cleanup_dtd(void *data); |
2139 | 89 static void ngx_http_xslt_cleanup_stylesheet(void *data); |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
90 static void *ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf); |
2139 | 91 static void *ngx_http_xslt_filter_create_conf(ngx_conf_t *cf); |
92 static char *ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, | |
93 void *child); | |
94 static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf); | |
2196
fab3fa7339ff
call ngx_http_xslt_filter_exit()
Igor Sysoev <igor@sysoev.ru>
parents:
2159
diff
changeset
|
95 static void ngx_http_xslt_filter_exit(ngx_cycle_t *cycle); |
2139 | 96 |
97 | |
98 ngx_str_t ngx_http_xslt_default_types[] = { | |
99 ngx_string("text/xml"), | |
100 ngx_null_string | |
101 }; | |
102 | |
103 | |
104 static ngx_command_t ngx_http_xslt_filter_commands[] = { | |
105 | |
106 { ngx_string("xml_entities"), | |
2150
50cede290146
fix xslt module context levels
Igor Sysoev <igor@sysoev.ru>
parents:
2148
diff
changeset
|
107 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
2139 | 108 ngx_http_xslt_entities, |
109 NGX_HTTP_LOC_CONF_OFFSET, | |
110 0, | |
111 NULL }, | |
112 | |
113 { ngx_string("xslt_stylesheet"), | |
2151
c8331f70d799
xslt_stylesheet should be valid for location only
Igor Sysoev <igor@sysoev.ru>
parents:
2150
diff
changeset
|
114 NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
2139 | 115 ngx_http_xslt_stylesheet, |
116 NGX_HTTP_LOC_CONF_OFFSET, | |
117 0, | |
118 NULL }, | |
119 | |
120 { ngx_string("xslt_types"), | |
2150
50cede290146
fix xslt module context levels
Igor Sysoev <igor@sysoev.ru>
parents:
2148
diff
changeset
|
121 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
2139 | 122 ngx_http_types_slot, |
123 NGX_HTTP_LOC_CONF_OFFSET, | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
124 offsetof(ngx_http_xslt_filter_loc_conf_t, types_keys), |
2139 | 125 &ngx_http_xslt_default_types[0] }, |
126 | |
127 ngx_null_command | |
128 }; | |
129 | |
130 | |
131 static ngx_http_module_t ngx_http_xslt_filter_module_ctx = { | |
132 NULL, /* preconfiguration */ | |
133 ngx_http_xslt_filter_init, /* postconfiguration */ | |
134 | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
135 ngx_http_xslt_filter_create_main_conf, /* create main configuration */ |
2139 | 136 NULL, /* init main configuration */ |
137 | |
138 NULL, /* create server configuration */ | |
139 NULL, /* merge server configuration */ | |
140 | |
141 ngx_http_xslt_filter_create_conf, /* create location configuration */ | |
142 ngx_http_xslt_filter_merge_conf /* merge location configuration */ | |
143 }; | |
144 | |
145 | |
146 ngx_module_t ngx_http_xslt_filter_module = { | |
147 NGX_MODULE_V1, | |
148 &ngx_http_xslt_filter_module_ctx, /* module context */ | |
149 ngx_http_xslt_filter_commands, /* module directives */ | |
150 NGX_HTTP_MODULE, /* module type */ | |
151 NULL, /* init master */ | |
152 NULL, /* init module */ | |
153 NULL, /* init process */ | |
154 NULL, /* init thread */ | |
155 NULL, /* exit thread */ | |
2983 | 156 ngx_http_xslt_filter_exit, /* exit process */ |
2196
fab3fa7339ff
call ngx_http_xslt_filter_exit()
Igor Sysoev <igor@sysoev.ru>
parents:
2159
diff
changeset
|
157 ngx_http_xslt_filter_exit, /* exit master */ |
2139 | 158 NGX_MODULE_V1_PADDING |
159 }; | |
160 | |
161 | |
162 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | |
163 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
164 | |
165 | |
166 static ngx_int_t | |
167 ngx_http_xslt_header_filter(ngx_http_request_t *r) | |
168 { | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
169 ngx_http_xslt_filter_ctx_t *ctx; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
170 ngx_http_xslt_filter_loc_conf_t *conf; |
2139 | 171 |
172 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
173 "xslt filter header"); | |
174 | |
175 if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) { | |
176 return ngx_http_next_header_filter(r); | |
177 } | |
178 | |
179 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); | |
180 | |
181 if (conf->sheets.nelts == 0 | |
2148 | 182 || ngx_http_test_content_type(r, &conf->types) == NULL) |
2139 | 183 { |
184 return ngx_http_next_header_filter(r); | |
185 } | |
186 | |
187 ctx = ngx_http_get_module_ctx(r, ngx_http_xslt_filter_module); | |
188 | |
189 if (ctx) { | |
190 return ngx_http_next_header_filter(r); | |
191 } | |
192 | |
193 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_xslt_filter_ctx_t)); | |
194 if (ctx == NULL) { | |
195 return NGX_ERROR; | |
196 } | |
197 | |
198 ngx_http_set_ctx(r, ctx, ngx_http_xslt_filter_module); | |
199 | |
200 r->main_filter_need_in_memory = 1; | |
201 | |
202 return NGX_OK; | |
203 } | |
204 | |
205 | |
206 static ngx_int_t | |
207 ngx_http_xslt_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
208 { | |
2984
097c1242995b
preserve XML wellFormed field before freeing memory
Igor Sysoev <igor@sysoev.ru>
parents:
2983
diff
changeset
|
209 int wellFormed; |
2139 | 210 ngx_chain_t *cl; |
211 ngx_http_xslt_filter_ctx_t *ctx; | |
212 | |
213 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
214 "xslt filter body"); | |
215 | |
216 if (in == NULL) { | |
217 return ngx_http_next_body_filter(r, in); | |
218 } | |
219 | |
220 ctx = ngx_http_get_module_ctx(r, ngx_http_xslt_filter_module); | |
221 | |
222 if (ctx == NULL || ctx->done) { | |
223 return ngx_http_next_body_filter(r, in); | |
224 } | |
225 | |
226 for (cl = in; cl; cl = cl->next) { | |
227 | |
228 if (ngx_http_xslt_add_chunk(r, ctx, cl->buf) != NGX_OK) { | |
229 | |
3642 | 230 if (ctx->ctxt->myDoc) { |
2139 | 231 |
232 #if (NGX_HTTP_XSLT_REUSE_DTD) | |
233 ctx->ctxt->myDoc->extSubset = NULL; | |
234 #endif | |
235 xmlFreeDoc(ctx->ctxt->myDoc); | |
236 } | |
237 | |
238 xmlFreeParserCtxt(ctx->ctxt); | |
239 | |
240 return ngx_http_xslt_send(r, ctx, NULL); | |
241 } | |
242 | |
2899
61d5b945730a
fix XSLT filter in SSI subrequests
Igor Sysoev <igor@sysoev.ru>
parents:
2882
diff
changeset
|
243 if (cl->buf->last_buf || cl->buf->last_in_chain) { |
2139 | 244 |
245 ctx->doc = ctx->ctxt->myDoc; | |
246 | |
247 #if (NGX_HTTP_XSLT_REUSE_DTD) | |
248 ctx->doc->extSubset = NULL; | |
249 #endif | |
250 | |
2984
097c1242995b
preserve XML wellFormed field before freeing memory
Igor Sysoev <igor@sysoev.ru>
parents:
2983
diff
changeset
|
251 wellFormed = ctx->ctxt->wellFormed; |
097c1242995b
preserve XML wellFormed field before freeing memory
Igor Sysoev <igor@sysoev.ru>
parents:
2983
diff
changeset
|
252 |
2139 | 253 xmlFreeParserCtxt(ctx->ctxt); |
254 | |
2984
097c1242995b
preserve XML wellFormed field before freeing memory
Igor Sysoev <igor@sysoev.ru>
parents:
2983
diff
changeset
|
255 if (wellFormed) { |
2139 | 256 return ngx_http_xslt_send(r, ctx, |
257 ngx_http_xslt_apply_stylesheet(r, ctx)); | |
258 } | |
259 | |
260 xmlFreeDoc(ctx->doc); | |
261 | |
262 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
263 "not well formed XML document"); | |
264 | |
265 return ngx_http_xslt_send(r, ctx, NULL); | |
266 } | |
267 } | |
268 | |
269 return NGX_OK; | |
270 } | |
271 | |
272 | |
273 static ngx_int_t | |
274 ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx, | |
275 ngx_buf_t *b) | |
276 { | |
277 ngx_int_t rc; | |
278 ngx_chain_t out; | |
279 ngx_pool_cleanup_t *cln; | |
280 | |
281 ctx->done = 1; | |
282 | |
283 if (b == NULL) { | |
2821
26e06e009ced
allow to pass image filter errors via the same location where the filter is set
Igor Sysoev <igor@sysoev.ru>
parents:
2787
diff
changeset
|
284 return ngx_http_filter_finalize_request(r, NULL, |
2787
3daf68f2efe3
ngx_http_filter_finalize_request() and ngx_http_clean_header()
Igor Sysoev <igor@sysoev.ru>
parents:
2588
diff
changeset
|
285 NGX_HTTP_INTERNAL_SERVER_ERROR); |
2139 | 286 } |
287 | |
288 cln = ngx_pool_cleanup_add(r->pool, 0); | |
289 | |
290 if (cln == NULL) { | |
291 ngx_free(b->pos); | |
2821
26e06e009ced
allow to pass image filter errors via the same location where the filter is set
Igor Sysoev <igor@sysoev.ru>
parents:
2787
diff
changeset
|
292 return ngx_http_filter_finalize_request(r, NULL, |
2139 | 293 NGX_HTTP_INTERNAL_SERVER_ERROR); |
294 } | |
295 | |
2159
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
296 if (r == r->main) { |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
297 r->headers_out.content_length_n = b->last - b->pos; |
2139 | 298 |
2159
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
299 if (r->headers_out.content_length) { |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
300 r->headers_out.content_length->hash = 0; |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
301 r->headers_out.content_length = NULL; |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
302 } |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
303 |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
304 ngx_http_clear_last_modified(r); |
2139 | 305 } |
306 | |
307 rc = ngx_http_next_header_filter(r); | |
308 | |
309 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { | |
310 ngx_free(b->pos); | |
311 return rc; | |
312 } | |
313 | |
314 cln->handler = ngx_http_xslt_cleanup; | |
315 cln->data = b->pos; | |
316 | |
317 out.buf = b; | |
318 out.next = NULL; | |
319 | |
320 return ngx_http_next_body_filter(r, &out); | |
321 } | |
322 | |
323 | |
324 static ngx_int_t | |
325 ngx_http_xslt_add_chunk(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx, | |
326 ngx_buf_t *b) | |
327 { | |
3686
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
328 int err; |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
329 xmlParserCtxtPtr ctxt; |
2139 | 330 |
331 if (ctx->ctxt == NULL) { | |
332 | |
333 ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); | |
334 if (ctxt == NULL) { | |
335 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
336 "xmlCreatePushParserCtxt() failed"); | |
337 return NGX_ERROR; | |
338 } | |
339 | |
3686
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
340 ctxt->sax->externalSubset = ngx_http_xslt_sax_external_subset; |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
341 ctxt->sax->setDocumentLocator = NULL; |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
342 ctxt->sax->warning = NULL; |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
343 ctxt->sax->error = ngx_http_xslt_sax_error; |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
344 ctxt->sax->fatalError = ngx_http_xslt_sax_error; |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
345 ctxt->sax->_private = ctx; |
2139 | 346 ctxt->replaceEntities = 1; |
347 ctxt->loadsubset = 1; | |
348 | |
349 ctx->ctxt = ctxt; | |
350 ctx->request = r; | |
351 } | |
352 | |
2899
61d5b945730a
fix XSLT filter in SSI subrequests
Igor Sysoev <igor@sysoev.ru>
parents:
2882
diff
changeset
|
353 err = xmlParseChunk(ctx->ctxt, (char *) b->pos, (int) (b->last - b->pos), |
61d5b945730a
fix XSLT filter in SSI subrequests
Igor Sysoev <igor@sysoev.ru>
parents:
2882
diff
changeset
|
354 (b->last_buf) || (b->last_in_chain)); |
2139 | 355 |
356 if (err == 0) { | |
357 b->pos = b->last; | |
358 return NGX_OK; | |
359 } | |
360 | |
361 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
362 "xmlParseChunk() failed, error:%d", err); | |
363 | |
364 return NGX_ERROR; | |
365 } | |
366 | |
367 | |
368 static void | |
369 ngx_http_xslt_sax_external_subset(void *data, const xmlChar *name, | |
370 const xmlChar *externalId, const xmlChar *systemId) | |
371 { | |
3686
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
372 xmlParserCtxtPtr ctxt = data; |
2139 | 373 |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
374 xmlDocPtr doc; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
375 xmlDtdPtr dtd; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
376 ngx_http_request_t *r; |
3686
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
377 ngx_http_xslt_filter_ctx_t *ctx; |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
378 ngx_http_xslt_filter_loc_conf_t *conf; |
2139 | 379 |
3686
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
380 ctx = ctxt->sax->_private; |
2139 | 381 r = ctx->request; |
382 | |
383 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); | |
384 | |
385 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
386 "xslt filter extSubset: \"%s\" \"%s\" \"%s\"", | |
387 name ? name : (xmlChar *) "", | |
388 externalId ? externalId : (xmlChar *) "", | |
389 systemId ? systemId : (xmlChar *) ""); | |
390 | |
3686
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
391 doc = ctxt->myDoc; |
2139 | 392 |
393 #if (NGX_HTTP_XSLT_REUSE_DTD) | |
394 | |
395 dtd = conf->dtd; | |
396 | |
397 #else | |
398 | |
399 dtd = xmlCopyDtd(conf->dtd); | |
400 if (dtd == NULL) { | |
401 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
402 "xmlCopyDtd() failed"); | |
403 return; | |
404 } | |
405 | |
406 if (doc->children == NULL) { | |
407 xmlAddChild((xmlNodePtr) doc, (xmlNodePtr) dtd); | |
408 | |
409 } else { | |
410 xmlAddPrevSibling(doc->children, (xmlNodePtr) dtd); | |
411 } | |
412 | |
413 #endif | |
414 | |
415 doc->extSubset = dtd; | |
416 } | |
417 | |
418 | |
419 static void ngx_cdecl | |
420 ngx_http_xslt_sax_error(void *data, const char *msg, ...) | |
421 { | |
3686
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
422 xmlParserCtxtPtr ctxt = data; |
2139 | 423 |
3686
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
424 size_t n; |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
425 va_list args; |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
426 ngx_http_xslt_filter_ctx_t *ctx; |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
427 u_char buf[NGX_MAX_ERROR_STR]; |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
428 |
47c1a9bff989
use xmlSAXHandler._private field to store xslt filter context
Igor Sysoev <igor@sysoev.ru>
parents:
3642
diff
changeset
|
429 ctx = ctxt->sax->_private; |
2139 | 430 |
431 buf[0] = '\0'; | |
432 | |
433 va_start(args, msg); | |
434 n = (size_t) vsnprintf((char *) buf, NGX_MAX_ERROR_STR, msg, args); | |
435 va_end(args); | |
436 | |
437 while (--n && (buf[n] == CR || buf[n] == LF)) { /* void */ } | |
438 | |
439 ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0, | |
2999 | 440 "libxml2 error: \"%*s\"", n + 1, buf); |
2139 | 441 } |
442 | |
443 | |
444 static ngx_buf_t * | |
445 ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r, | |
446 ngx_http_xslt_filter_ctx_t *ctx) | |
447 { | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
448 int len, rc, doc_type; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
449 u_char *type, *encoding; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
450 ngx_buf_t *b; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
451 ngx_uint_t i; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
452 xmlChar *buf; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
453 xmlDocPtr doc, res; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
454 ngx_http_xslt_sheet_t *sheet; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
455 ngx_http_xslt_filter_loc_conf_t *conf; |
2139 | 456 |
457 conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); | |
458 sheet = conf->sheets.elts; | |
459 doc = ctx->doc; | |
460 | |
461 /* preallocate array for 4 params */ | |
462 | |
463 if (ngx_array_init(&ctx->params, r->pool, 4 * 2 + 1, sizeof(char *)) | |
464 != NGX_OK) | |
465 { | |
466 xmlFreeDoc(doc); | |
467 return NULL; | |
468 } | |
469 | |
470 for (i = 0; i < conf->sheets.nelts; i++) { | |
471 | |
472 if (ngx_http_xslt_params(r, ctx, &sheet[i].params) != NGX_OK) { | |
473 xmlFreeDoc(doc); | |
474 return NULL; | |
475 } | |
476 | |
477 res = xsltApplyStylesheet(sheet[i].stylesheet, doc, ctx->params.elts); | |
478 | |
479 xmlFreeDoc(doc); | |
480 | |
481 if (res == NULL) { | |
482 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
483 "xsltApplyStylesheet() failed"); | |
484 return NULL; | |
485 } | |
486 | |
487 doc = res; | |
488 | |
489 /* reset array elements */ | |
490 ctx->params.nelts = 0; | |
491 } | |
492 | |
2153
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
493 /* there must be at least one stylesheet */ |
2139 | 494 |
2159
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
495 if (r == r->main) { |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
496 type = ngx_http_xslt_content_type(sheet[i - 1].stylesheet); |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
497 |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
498 } else { |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
499 type = NULL; |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
500 } |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
501 |
2153
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
502 encoding = ngx_http_xslt_encoding(sheet[i - 1].stylesheet); |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
503 doc_type = doc->type; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
504 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
505 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
506 "xslt filter type: %d t:%s e:%s", |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
507 doc_type, type ? type : (u_char *) "(null)", |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
508 encoding ? encoding : (u_char *) "(null)"); |
2139 | 509 |
510 rc = xsltSaveResultToString(&buf, &len, doc, sheet[i - 1].stylesheet); | |
511 | |
512 xmlFreeDoc(doc); | |
513 | |
514 if (rc != 0) { | |
515 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
516 "xsltSaveResultToString() failed"); | |
517 return NULL; | |
518 } | |
519 | |
520 if (len == 0) { | |
521 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
522 "xsltSaveResultToString() returned zero-length result"); | |
523 return NULL; | |
524 } | |
525 | |
526 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); | |
527 if (b == NULL) { | |
528 ngx_free(buf); | |
529 return NULL; | |
530 } | |
531 | |
532 b->pos = buf; | |
533 b->last = buf + len; | |
534 b->memory = 1; | |
535 | |
2159
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
536 if (encoding) { |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
537 r->headers_out.charset.len = ngx_strlen(encoding); |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
538 r->headers_out.charset.data = encoding; |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
539 } |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
540 |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
541 if (r != r->main) { |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
542 return b; |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
543 } |
0ec936b0010a
clear Last-Modified; set content-type and length for main request only
Igor Sysoev <igor@sysoev.ru>
parents:
2158
diff
changeset
|
544 |
2899
61d5b945730a
fix XSLT filter in SSI subrequests
Igor Sysoev <igor@sysoev.ru>
parents:
2882
diff
changeset
|
545 b->last_buf = 1; |
61d5b945730a
fix XSLT filter in SSI subrequests
Igor Sysoev <igor@sysoev.ru>
parents:
2882
diff
changeset
|
546 |
2153
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
547 if (type) { |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
548 len = ngx_strlen(type); |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
549 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
550 r->headers_out.content_type_len = len; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
551 r->headers_out.content_type.len = len; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
552 r->headers_out.content_type.data = type; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
553 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
554 } else if (doc_type == XML_HTML_DOCUMENT_NODE) { |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
555 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
556 r->headers_out.content_type_len = sizeof("text/html") - 1; |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3508
diff
changeset
|
557 ngx_str_set(&r->headers_out.content_type, "text/html"); |
2153
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
558 } |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
559 |
2882
896db5a09bd2
reset content_type hash value, this fixes a bug when XSLT responses
Igor Sysoev <igor@sysoev.ru>
parents:
2821
diff
changeset
|
560 r->headers_out.content_type_lowcase = NULL; |
896db5a09bd2
reset content_type hash value, this fixes a bug when XSLT responses
Igor Sysoev <igor@sysoev.ru>
parents:
2821
diff
changeset
|
561 |
2139 | 562 return b; |
563 } | |
564 | |
565 | |
566 static ngx_int_t | |
567 ngx_http_xslt_params(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx, | |
568 ngx_array_t *params) | |
569 { | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
570 u_char *p, *last, *value, *dst, *src, **s; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
571 size_t len; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
572 ngx_uint_t i; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
573 ngx_str_t string; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
574 ngx_http_complex_value_t *param; |
2139 | 575 |
576 param = params->elts; | |
577 | |
578 for (i = 0; i < params->nelts; i++) { | |
579 | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
580 if (ngx_http_complex_value(r, ¶m[i], &string) != NGX_OK) { |
2139 | 581 return NGX_ERROR; |
582 } | |
583 | |
584 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
585 "xslt filter param: \"%s\"", string.data); | |
586 | |
587 p = string.data; | |
4553
3dd8a403faa1
Fixed off-by-one in xslt parameter parsing.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
588 last = string.data + string.len; |
2139 | 589 |
590 while (p && *p) { | |
591 | |
592 value = p; | |
593 p = (u_char *) ngx_strchr(p, '='); | |
594 if (p == NULL) { | |
595 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
596 "invalid libxslt parameter \"%s\"", value); | |
597 return NGX_ERROR; | |
598 } | |
599 *p++ = '\0'; | |
600 | |
601 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
602 "xslt filter param name: \"%s\"", value); | |
603 | |
604 s = ngx_array_push(&ctx->params); | |
605 if (s == NULL) { | |
606 return NGX_ERROR; | |
607 } | |
608 | |
609 *s = value; | |
610 | |
611 value = p; | |
612 p = (u_char *) ngx_strchr(p, ':'); | |
613 | |
614 if (p) { | |
615 len = p - value; | |
616 *p++ = '\0'; | |
617 | |
618 } else { | |
619 len = last - value; | |
620 } | |
621 | |
622 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
623 "xslt filter param value: \"%s\"", value); | |
624 | |
625 dst = value; | |
626 src = value; | |
627 | |
628 ngx_unescape_uri(&dst, &src, len, 0); | |
629 | |
630 *dst = '\0'; | |
631 | |
632 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
633 "xslt filter param unescaped: \"%s\"", value); | |
634 | |
635 s = ngx_array_push(&ctx->params); | |
636 if (s == NULL) { | |
637 return NGX_ERROR; | |
638 } | |
639 | |
640 *s = value; | |
641 } | |
642 } | |
643 | |
644 s = ngx_array_push(&ctx->params); | |
645 if (s == NULL) { | |
646 return NGX_ERROR; | |
647 } | |
648 | |
649 *s = NULL; | |
650 | |
651 return NGX_OK; | |
652 } | |
653 | |
654 | |
2153
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
655 static u_char * |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
656 ngx_http_xslt_content_type(xsltStylesheetPtr s) |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
657 { |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
658 u_char *type; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
659 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
660 if (s->mediaType) { |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
661 return s->mediaType; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
662 } |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
663 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
664 for (s = s->imports; s; s = s->next) { |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
665 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
666 type = ngx_http_xslt_content_type(s); |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
667 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
668 if (type) { |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
669 return type; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
670 } |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
671 } |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
672 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
673 return NULL; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
674 } |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
675 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
676 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
677 static u_char * |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
678 ngx_http_xslt_encoding(xsltStylesheetPtr s) |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
679 { |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
680 u_char *encoding; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
681 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
682 if (s->encoding) { |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
683 return s->encoding; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
684 } |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
685 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
686 for (s = s->imports; s; s = s->next) { |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
687 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
688 encoding = ngx_http_xslt_encoding(s); |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
689 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
690 if (encoding) { |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
691 return encoding; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
692 } |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
693 } |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
694 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
695 return NULL; |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
696 } |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
697 |
6476e445d6ce
xsl:output's media-type and encoding support
Igor Sysoev <igor@sysoev.ru>
parents:
2152
diff
changeset
|
698 |
2139 | 699 static void |
700 ngx_http_xslt_cleanup(void *data) | |
701 { | |
702 ngx_free(data); | |
703 } | |
704 | |
705 | |
706 static char * | |
707 ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
708 { | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
709 ngx_http_xslt_filter_loc_conf_t *xlcf = conf; |
2139 | 710 |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
711 ngx_str_t *value; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
712 ngx_uint_t i; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
713 ngx_pool_cleanup_t *cln; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
714 ngx_http_xslt_file_t *file; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
715 ngx_http_xslt_filter_main_conf_t *xmcf; |
2139 | 716 |
717 if (xlcf->dtd) { | |
718 return "is duplicate"; | |
719 } | |
720 | |
721 value = cf->args->elts; | |
722 | |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
723 xmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_xslt_filter_module); |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
724 |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
725 file = xmcf->dtd_files.elts; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
726 for (i = 0; i < xmcf->dtd_files.nelts; i++) { |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
727 if (ngx_strcmp(file[i].name, &value[1].data) == 0) { |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
728 xlcf->dtd = file[i].data; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
729 return NGX_CONF_OK; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
730 } |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
731 } |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
732 |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
733 cln = ngx_pool_cleanup_add(cf->pool, 0); |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
734 if (cln == NULL) { |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
735 return NGX_CONF_ERROR; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
736 } |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
737 |
2139 | 738 xlcf->dtd = xmlParseDTD(NULL, (xmlChar *) value[1].data); |
739 | |
740 if (xlcf->dtd == NULL) { | |
741 ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "xmlParseDTD() failed"); | |
742 return NGX_CONF_ERROR; | |
743 } | |
744 | |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
745 cln->handler = ngx_http_xslt_cleanup_dtd; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
746 cln->data = xlcf->dtd; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
747 |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
748 file = ngx_array_push(&xmcf->dtd_files); |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
749 if (file == NULL) { |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
750 return NGX_CONF_ERROR; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
751 } |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
752 |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
753 file->name = value[1].data; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
754 file->data = xlcf->dtd; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
755 |
2139 | 756 return NGX_CONF_OK; |
757 } | |
758 | |
759 | |
760 | |
761 static char * | |
762 ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
763 { | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
764 ngx_http_xslt_filter_loc_conf_t *xlcf = conf; |
2139 | 765 |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
766 ngx_str_t *value; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
767 ngx_uint_t i, n; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
768 ngx_pool_cleanup_t *cln; |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
769 ngx_http_xslt_file_t *file; |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
770 ngx_http_xslt_sheet_t *sheet; |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
771 ngx_http_complex_value_t *param; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
772 ngx_http_compile_complex_value_t ccv; |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
773 ngx_http_xslt_filter_main_conf_t *xmcf; |
2139 | 774 |
775 value = cf->args->elts; | |
776 | |
777 if (xlcf->sheets.elts == NULL) { | |
778 if (ngx_array_init(&xlcf->sheets, cf->pool, 1, | |
779 sizeof(ngx_http_xslt_sheet_t)) | |
780 != NGX_OK) | |
781 { | |
782 return NGX_CONF_ERROR; | |
783 } | |
784 } | |
785 | |
786 sheet = ngx_array_push(&xlcf->sheets); | |
787 if (sheet == NULL) { | |
788 return NGX_CONF_ERROR; | |
789 } | |
790 | |
791 ngx_memzero(sheet, sizeof(ngx_http_xslt_sheet_t)); | |
792 | |
793 if (ngx_conf_full_name(cf->cycle, &value[1], 0) != NGX_OK) { | |
794 return NGX_CONF_ERROR; | |
795 } | |
796 | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
797 xmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_xslt_filter_module); |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
798 |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
799 file = xmcf->sheet_files.elts; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
800 for (i = 0; i < xmcf->sheet_files.nelts; i++) { |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
801 if (ngx_strcmp(file[i].name, &value[1].data) == 0) { |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
802 sheet->stylesheet = file[i].data; |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
803 goto found; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
804 } |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
805 } |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
806 |
2139 | 807 cln = ngx_pool_cleanup_add(cf->pool, 0); |
808 if (cln == NULL) { | |
809 return NGX_CONF_ERROR; | |
810 } | |
811 | |
812 sheet->stylesheet = xsltParseStylesheetFile(value[1].data); | |
813 if (sheet->stylesheet == NULL) { | |
814 ngx_conf_log_error(NGX_LOG_ERR, cf, 0, | |
815 "xsltParseStylesheetFile(\"%s\") failed", | |
816 value[1].data); | |
817 return NGX_CONF_ERROR; | |
818 } | |
819 | |
820 cln->handler = ngx_http_xslt_cleanup_stylesheet; | |
821 cln->data = sheet->stylesheet; | |
822 | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
823 file = ngx_array_push(&xmcf->sheet_files); |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
824 if (file == NULL) { |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
825 return NGX_CONF_ERROR; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
826 } |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
827 |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
828 file->name = value[1].data; |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
829 file->data = sheet->stylesheet; |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
830 |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
831 found: |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
832 |
2139 | 833 n = cf->args->nelts; |
834 | |
835 if (n == 2) { | |
836 return NGX_CONF_OK; | |
837 } | |
838 | |
839 if (ngx_array_init(&sheet->params, cf->pool, n - 2, | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
840 sizeof(ngx_http_complex_value_t)) |
2139 | 841 != NGX_OK) |
842 { | |
843 return NGX_CONF_ERROR; | |
844 } | |
845 | |
846 for (i = 2; i < n; i++) { | |
847 | |
848 param = ngx_array_push(&sheet->params); | |
849 if (param == NULL) { | |
850 return NGX_CONF_ERROR; | |
851 } | |
852 | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
853 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
2139 | 854 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
855 ccv.cf = cf; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
856 ccv.value = &value[i]; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
857 ccv.complex_value = param; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
858 ccv.zero = 1; |
2139 | 859 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2299
diff
changeset
|
860 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
2139 | 861 return NGX_CONF_ERROR; |
862 } | |
863 } | |
864 | |
865 return NGX_CONF_OK; | |
866 } | |
867 | |
868 | |
869 static void | |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
870 ngx_http_xslt_cleanup_dtd(void *data) |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
871 { |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
872 xmlFreeDtd(data); |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
873 } |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
874 |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
875 |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
876 static void |
2139 | 877 ngx_http_xslt_cleanup_stylesheet(void *data) |
878 { | |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
879 xsltFreeStylesheet(data); |
2139 | 880 } |
881 | |
882 | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
883 static void * |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
884 ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf) |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
885 { |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
886 ngx_http_xslt_filter_main_conf_t *conf; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
887 |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
888 conf = ngx_palloc(cf->pool, sizeof(ngx_http_xslt_filter_main_conf_t)); |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
889 if (conf == NULL) { |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2899
diff
changeset
|
890 return NULL; |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
891 } |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
892 |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
893 if (ngx_array_init(&conf->dtd_files, cf->pool, 1, |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
894 sizeof(ngx_http_xslt_file_t)) |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
895 != NGX_OK) |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
896 { |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
897 return NULL; |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
898 } |
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
899 |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
900 if (ngx_array_init(&conf->sheet_files, cf->pool, 1, |
2156
0c6d0bd60579
reuse compiled DTD hash in different locations, add DTD cleanup
Igor Sysoev <igor@sysoev.ru>
parents:
2154
diff
changeset
|
901 sizeof(ngx_http_xslt_file_t)) |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
902 != NGX_OK) |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
903 { |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
904 return NULL; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
905 } |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
906 |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
907 return conf; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
908 } |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
909 |
2139 | 910 |
911 static void * | |
912 ngx_http_xslt_filter_create_conf(ngx_conf_t *cf) | |
913 { | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
914 ngx_http_xslt_filter_loc_conf_t *conf; |
2139 | 915 |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
916 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_xslt_filter_loc_conf_t)); |
2139 | 917 if (conf == NULL) { |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2899
diff
changeset
|
918 return NULL; |
2139 | 919 } |
920 | |
921 /* | |
922 * set by ngx_pcalloc(): | |
923 * | |
2148 | 924 * conf->dtd = NULL; |
925 * conf->sheets = { NULL }; | |
926 * conf->types = { NULL }; | |
927 * conf->types_keys = NULL; | |
2139 | 928 */ |
929 | |
930 return conf; | |
931 } | |
932 | |
933 | |
934 static char * | |
935 ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
936 { | |
2154
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
937 ngx_http_xslt_filter_loc_conf_t *prev = parent; |
4f48a2765da0
reuse compiled XSLT tree in different locations
Igor Sysoev <igor@sysoev.ru>
parents:
2153
diff
changeset
|
938 ngx_http_xslt_filter_loc_conf_t *conf = child; |
2139 | 939 |
940 if (conf->dtd == NULL) { | |
941 conf->dtd = prev->dtd; | |
942 } | |
943 | |
944 if (conf->sheets.nelts == 0) { | |
945 conf->sheets = prev->sheets; | |
946 } | |
947 | |
3372
6b8e5c882e47
support "*" in gzip_types, ssi_types, etc
Igor Sysoev <igor@sysoev.ru>
parents:
3115
diff
changeset
|
948 if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types, |
6b8e5c882e47
support "*" in gzip_types, ssi_types, etc
Igor Sysoev <igor@sysoev.ru>
parents:
3115
diff
changeset
|
949 &prev->types_keys, &prev->types, |
2148 | 950 ngx_http_xslt_default_types) |
2139 | 951 != NGX_OK) |
952 { | |
953 return NGX_CONF_ERROR; | |
954 } | |
955 | |
956 return NGX_CONF_OK; | |
957 } | |
958 | |
959 | |
960 static ngx_int_t | |
961 ngx_http_xslt_filter_init(ngx_conf_t *cf) | |
962 { | |
963 xmlInitParser(); | |
964 | |
2299 | 965 #if (NGX_HAVE_EXSLT) |
966 exsltRegisterAll(); | |
967 #endif | |
968 | |
2139 | 969 ngx_http_next_header_filter = ngx_http_top_header_filter; |
970 ngx_http_top_header_filter = ngx_http_xslt_header_filter; | |
971 | |
972 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
973 ngx_http_top_body_filter = ngx_http_xslt_body_filter; | |
974 | |
975 return NGX_OK; | |
976 } | |
977 | |
978 | |
979 static void | |
980 ngx_http_xslt_filter_exit(ngx_cycle_t *cycle) | |
981 { | |
982 xsltCleanupGlobals(); | |
983 xmlCleanupParser(); | |
984 } |