Mercurial > hg > nginx
annotate src/http/modules/ngx_http_xslt_filter_module.c @ 4367:9c4acdf9b276 stable-1.0
Merge of r4315:
Allowed add_header for proxied 206 replies.
It was working for nginx's own 206 replies as they are seen as 200 in the
headers filter module (range filter goes later in the headers filter chain),
but not for proxied replies.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 14 Dec 2011 18:06:21 +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 } |