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