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