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