Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_charset_filter.c @ 339:8c5b69141dfd
nginx-0.0.3-2004-05-21-20:12:13 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 21 May 2004 16:12:13 +0000 |
parents | 0376cffa29e6 |
children | 0bf903191ceb |
comparison
equal
deleted
inserted
replaced
338:0376cffa29e6 | 339:8c5b69141dfd |
---|---|
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_http.h> | 4 #include <ngx_http.h> |
5 | 5 |
6 | 6 |
7 typedef struct { | 7 typedef struct { |
8 ngx_str_t from; | 8 char **tables; |
9 ngx_str_t to; | 9 ngx_str_t name; |
10 char *table; | 10 unsigned server; |
11 } ngx_http_charset_table_t; | 11 } ngx_http_charset_t; |
12 | 12 |
13 | 13 |
14 typedef struct { | 14 typedef struct { |
15 ngx_array_t tables; /* ngx_http_charset_table_t */ | 15 ngx_int_t src; |
16 ngx_int_t dst; | |
17 char *src2dst; | |
18 char *dst2src; | |
19 } ngx_http_charset_tables_t; | |
20 | |
21 | |
22 typedef struct { | |
23 ngx_array_t charsets; /* ngx_http_charset_t */ | |
24 ngx_array_t tables; /* ngx_http_charset_tables_t */ | |
16 } ngx_http_charset_main_conf_t; | 25 } ngx_http_charset_main_conf_t; |
17 | 26 |
18 | 27 |
19 typedef struct { | 28 typedef struct { |
20 ngx_str_t default_charset; | 29 ngx_flag_t enable; |
30 ngx_flag_t autodetect; | |
31 | |
32 ngx_int_t default_charset; | |
33 ngx_int_t source_charset; | |
21 } ngx_http_charset_loc_conf_t; | 34 } ngx_http_charset_loc_conf_t; |
22 | 35 |
36 | |
37 typedef struct { | |
38 ngx_int_t server; | |
39 ngx_int_t client; | |
40 } ngx_http_charset_ctx_t; | |
41 | |
42 | |
43 static void ngx_charset_recode(ngx_hunk_t *h, char *table); | |
23 | 44 |
24 static char *ngx_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd, | 45 static char *ngx_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd, |
25 void *conf); | 46 void *conf); |
26 static char *ngx_charset_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); | 47 static char *ngx_charset_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); |
27 | 48 |
49 static char *ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, | |
50 void *conf); | |
51 static ngx_int_t ngx_http_add_charset(ngx_array_t *charsets, ngx_str_t *name); | |
52 | |
28 static int ngx_http_charset_filter_init(ngx_cycle_t *cycle); | 53 static int ngx_http_charset_filter_init(ngx_cycle_t *cycle); |
29 | 54 |
30 static void *ngx_http_charset_create_main_conf(ngx_conf_t *cf); | 55 static void *ngx_http_charset_create_main_conf(ngx_conf_t *cf); |
56 static char *ngx_http_charset_init_main_conf(ngx_conf_t *cf, void *conf); | |
31 static void *ngx_http_charset_create_loc_conf(ngx_conf_t *cf); | 57 static void *ngx_http_charset_create_loc_conf(ngx_conf_t *cf); |
32 static char *ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, | 58 static char *ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, |
33 void *parent, void *child); | 59 void *parent, void *child); |
34 | 60 |
35 | 61 |
42 0, | 68 0, |
43 NULL }, | 69 NULL }, |
44 | 70 |
45 { ngx_string("default_charset"), | 71 { ngx_string("default_charset"), |
46 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | 72 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
47 ngx_conf_set_str_slot, | 73 ngx_http_set_charset_slot, |
48 NGX_HTTP_LOC_CONF_OFFSET, | 74 NGX_HTTP_LOC_CONF_OFFSET, |
49 offsetof(ngx_http_charset_loc_conf_t, default_charset), | 75 offsetof(ngx_http_charset_loc_conf_t, default_charset), |
50 NULL }, | 76 NULL }, |
51 | 77 |
78 { ngx_string("source_charset"), | |
79 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
80 ngx_http_set_charset_slot, | |
81 NGX_HTTP_LOC_CONF_OFFSET, | |
82 offsetof(ngx_http_charset_loc_conf_t, source_charset), | |
83 NULL }, | |
84 | |
85 { ngx_string("charset"), | |
86 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
87 ngx_conf_set_flag_slot, | |
88 NGX_HTTP_LOC_CONF_OFFSET, | |
89 offsetof(ngx_http_charset_loc_conf_t, enable), | |
90 NULL }, | |
91 | |
92 { ngx_string("autodetect_charset"), | |
93 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
94 ngx_conf_set_flag_slot, | |
95 NGX_HTTP_LOC_CONF_OFFSET, | |
96 offsetof(ngx_http_charset_loc_conf_t, autodetect), | |
97 NULL }, | |
98 | |
52 ngx_null_command | 99 ngx_null_command |
53 }; | 100 }; |
54 | 101 |
55 | 102 |
56 static ngx_http_module_t ngx_http_charset_filter_module_ctx = { | 103 static ngx_http_module_t ngx_http_charset_filter_module_ctx = { |
57 NULL, /* pre conf */ | 104 NULL, /* pre conf */ |
58 | 105 |
59 ngx_http_charset_create_main_conf, /* create main configuration */ | 106 ngx_http_charset_create_main_conf, /* create main configuration */ |
60 NULL, /* init main configuration */ | 107 ngx_http_charset_init_main_conf, /* init main configuration */ |
61 | 108 |
62 NULL, /* create server configuration */ | 109 NULL, /* create server configuration */ |
63 NULL, /* merge server configuration */ | 110 NULL, /* merge server configuration */ |
64 | 111 |
65 ngx_http_charset_create_loc_conf, /* create location configuration */ | 112 ngx_http_charset_create_loc_conf, /* create location configuration */ |
76 NULL /* init child */ | 123 NULL /* init child */ |
77 }; | 124 }; |
78 | 125 |
79 | 126 |
80 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | 127 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; |
128 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
129 | |
130 | |
131 static int ngx_http_charset_header_filter(ngx_http_request_t *r) | |
132 { | |
133 ngx_http_charset_t *charsets; | |
134 ngx_http_charset_ctx_t *ctx; | |
135 ngx_http_charset_loc_conf_t *lcf; | |
136 ngx_http_charset_main_conf_t *mcf; | |
137 | |
138 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); | |
139 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); | |
140 | |
141 if (lcf->enable == 0) { | |
142 return ngx_http_next_header_filter(r); | |
143 } | |
144 | |
81 #if 0 | 145 #if 0 |
82 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
83 #endif | |
84 | |
85 | |
86 static int ngx_http_charset_header_filter(ngx_http_request_t *r) | |
87 { | |
88 ngx_http_charset_loc_conf_t *lcf; | |
89 | |
90 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); | |
91 | |
92 if (lcf->default_charset.len == 0) { | 146 if (lcf->default_charset.len == 0) { |
93 return ngx_http_next_header_filter(r); | 147 return ngx_http_next_header_filter(r); |
94 } | 148 } |
149 #endif | |
95 | 150 |
96 if (r->headers_out.content_type == NULL | 151 if (r->headers_out.content_type == NULL |
97 || ngx_strncasecmp(r->headers_out.content_type->value.data, | 152 || ngx_strncasecmp(r->headers_out.content_type->value.data, |
98 "text/", 5) != 0 | 153 "text/", 5) != 0 |
99 || ngx_strstr(r->headers_out.content_type->value.data, "charset") | 154 || ngx_strstr(r->headers_out.content_type->value.data, "charset") |
104 } | 159 } |
105 | 160 |
106 if (r->headers_out.status == NGX_HTTP_MOVED_PERMANENTLY | 161 if (r->headers_out.status == NGX_HTTP_MOVED_PERMANENTLY |
107 && r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY) | 162 && r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY) |
108 { | 163 { |
109 | |
110 /* | 164 /* |
111 * do not set charset for the redirect because NN 4.x uses this | 165 * do not set charset for the redirect because NN 4.x uses this |
112 * charset instead of the next page charset | 166 * charset instead of the next page charset |
113 */ | 167 */ |
114 | 168 |
115 r->headers_out.charset.len = 0; | 169 r->headers_out.charset.len = 0; |
116 | 170 return ngx_http_next_header_filter(r); |
117 } else if (r->headers_out.charset.len == 0) { | 171 } |
118 r->headers_out.charset = lcf->default_charset; | 172 |
119 } | 173 if (r->headers_out.charset.len) { |
174 return ngx_http_next_header_filter(r); | |
175 } | |
176 | |
177 charsets = mcf->charsets.elts; | |
178 r->headers_out.charset = charsets[lcf->default_charset].name; | |
179 | |
180 if (lcf->default_charset == lcf->source_charset) { | |
181 return ngx_http_next_header_filter(r); | |
182 } | |
183 | |
184 ngx_http_create_ctx(r, ctx, ngx_http_charset_filter_module, | |
185 sizeof(ngx_http_charset_ctx_t), NGX_ERROR); | |
186 | |
187 r->filter |= NGX_HTTP_FILTER_NEED_IN_MEMORY; | |
120 | 188 |
121 return ngx_http_next_header_filter(r); | 189 return ngx_http_next_header_filter(r); |
122 } | 190 } |
123 | 191 |
124 | 192 |
125 #if 0 | |
126 static int ngx_http_charset_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | 193 static int ngx_http_charset_body_filter(ngx_http_request_t *r, ngx_chain_t *in) |
127 { | 194 { |
128 ngx_log_debug(r->connection->log, "CHARSET BODY"); | 195 char *table; |
196 ngx_chain_t *cl; | |
197 ngx_http_charset_t *charsets; | |
198 ngx_http_charset_ctx_t *ctx; | |
199 ngx_http_charset_loc_conf_t *lcf; | |
200 ngx_http_charset_main_conf_t *mcf; | |
201 | |
202 ctx = ngx_http_get_module_ctx(r, ngx_http_charset_filter_module); | |
203 | |
204 if (ctx == NULL) { | |
205 return ngx_http_next_body_filter(r, in); | |
206 } | |
207 | |
208 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); | |
209 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); | |
210 | |
211 charsets = mcf->charsets.elts; | |
212 table = charsets[lcf->source_charset].tables[lcf->default_charset]; | |
213 | |
214 for (cl = in; cl; cl = cl->next) { | |
215 ngx_charset_recode(cl->hunk, table); | |
216 } | |
217 | |
129 return ngx_http_next_body_filter(r, in); | 218 return ngx_http_next_body_filter(r, in); |
130 } | 219 } |
131 #endif | 220 |
221 | |
222 static void ngx_charset_recode(ngx_hunk_t *h, char *table) | |
223 { | |
224 u_char *p, c; | |
225 | |
226 for (p = h->pos; p < h->last; p++) { | |
227 c = *p; | |
228 *p = table[c]; | |
229 } | |
230 } | |
132 | 231 |
133 | 232 |
134 static char *ngx_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd, | 233 static char *ngx_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd, |
135 void *conf) | 234 void *conf) |
136 { | 235 { |
137 char *rv; | 236 ngx_http_charset_main_conf_t *mcf = conf; |
138 ngx_conf_t pcf; | 237 |
139 | 238 char *rv; |
140 pcf = *cf; | 239 ngx_int_t src, dst; |
240 ngx_uint_t i; | |
241 ngx_str_t *value; | |
242 ngx_conf_t pvcf; | |
243 ngx_http_charset_tables_t *table; | |
244 | |
245 value = cf->args->elts; | |
246 | |
247 src = ngx_http_add_charset(&mcf->charsets, &value[1]); | |
248 if (src == NGX_ERROR) { | |
249 return NGX_CONF_ERROR; | |
250 } | |
251 | |
252 dst = ngx_http_add_charset(&mcf->charsets, &value[2]); | |
253 if (dst == NGX_ERROR) { | |
254 return NGX_CONF_ERROR; | |
255 } | |
256 | |
257 if (src == dst) { | |
258 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
259 "\"charset_map\" between the same charsets " | |
260 "\"%s\" and \"%s\"", | |
261 value[1].data, value[2].data); | |
262 return NGX_CONF_ERROR; | |
263 } | |
264 | |
265 table = mcf->tables.elts; | |
266 for (i = 0; i < mcf->tables.nelts; i++) { | |
267 if ((src == table->src && dst == table->dst) | |
268 || (src == table->dst && dst == table->src)) | |
269 { | |
270 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
271 "duplicate \"charset_map\" between " | |
272 "\"%s\" and \"%s\"", | |
273 value[1].data, value[2].data); | |
274 return NGX_CONF_ERROR; | |
275 } | |
276 } | |
277 | |
278 if (!(table = ngx_push_array(&mcf->tables))) { | |
279 return NGX_CONF_ERROR; | |
280 } | |
281 | |
282 table->src = src; | |
283 table->dst = dst; | |
284 | |
285 if (!(table->src2dst = ngx_palloc(cf->pool, 256))) { | |
286 return NGX_CONF_ERROR; | |
287 } | |
288 | |
289 if (!(table->dst2src = ngx_palloc(cf->pool, 256))) { | |
290 return NGX_CONF_ERROR; | |
291 } | |
292 | |
293 for (i = 0; i < 128; i++) { | |
294 table->src2dst[i] = i; | |
295 table->dst2src[i] = i; | |
296 } | |
297 | |
298 for (/* void */; i < 256; i++) { | |
299 table->src2dst[i] = '?'; | |
300 table->dst2src[i] = '?'; | |
301 } | |
302 | |
303 pvcf = *cf; | |
304 cf->ctx = table; | |
141 cf->handler = ngx_charset_map; | 305 cf->handler = ngx_charset_map; |
142 cf->handler_conf = conf; | 306 cf->handler_conf = conf; |
143 rv = ngx_conf_parse(cf, NULL); | 307 rv = ngx_conf_parse(cf, NULL); |
144 *cf = pcf; | 308 *cf = pvcf; |
145 | 309 |
146 return rv; | 310 return rv; |
147 } | 311 } |
148 | 312 |
149 | 313 |
150 static char *ngx_charset_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) | 314 static char *ngx_charset_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf) |
151 { | 315 { |
152 ngx_http_charset_main_conf_t *mcf = conf; | 316 ngx_http_charset_main_conf_t *mcf = conf; |
153 | 317 |
154 ngx_int_t src, dst; | 318 ngx_int_t src, dst; |
155 ngx_str_t *args; | 319 ngx_str_t *value; |
320 ngx_http_charset_tables_t *table; | |
156 | 321 |
157 if (cf->args->nelts != 2) { | 322 if (cf->args->nelts != 2) { |
158 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameters number"); | 323 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameters number"); |
159 return NGX_CONF_ERROR; | 324 return NGX_CONF_ERROR; |
160 } | 325 } |
161 | 326 |
162 args = cf->args->elts; | 327 value = cf->args->elts; |
163 | 328 |
164 src = ngx_hextoi(args[0].data, args[0].len); | 329 src = ngx_hextoi(value[0].data, value[0].len); |
165 if (src == NGX_ERROR || src > 255) { | 330 if (src == NGX_ERROR || src > 255) { |
166 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 331 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
167 "invalid value \"%s\"", args[0].data); | 332 "invalid value \"%s\"", value[0].data); |
168 return NGX_CONF_ERROR; | 333 return NGX_CONF_ERROR; |
169 } | 334 } |
170 | 335 |
171 dst = ngx_hextoi(args[1].data, args[1].len); | 336 dst = ngx_hextoi(value[1].data, value[1].len); |
172 if (dst == NGX_ERROR || dst > 255) { | 337 if (dst == NGX_ERROR || dst > 255) { |
173 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 338 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
174 "invalid value \"%s\"", args[1].data); | 339 "invalid value \"%s\"", value[1].data); |
175 return NGX_CONF_ERROR; | 340 return NGX_CONF_ERROR; |
176 } | 341 } |
177 | 342 |
178 #if 0 | 343 table = cf->ctx; |
179 mcf->tables[src] = dst; | 344 |
180 #endif | 345 table->src2dst[src] = dst; |
346 table->dst2src[dst] = src; | |
181 | 347 |
182 return NGX_CONF_OK; | 348 return NGX_CONF_OK; |
349 } | |
350 | |
351 | |
352 static char *ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, | |
353 void *conf) | |
354 { | |
355 char *p = conf; | |
356 | |
357 ngx_int_t *cp; | |
358 ngx_str_t *value; | |
359 ngx_http_charset_t *charset; | |
360 ngx_http_conf_ctx_t *ctx; | |
361 ngx_http_charset_main_conf_t *mcf; | |
362 | |
363 cp = (ngx_int_t *) (p + cmd->offset); | |
364 | |
365 if (*cp != NGX_CONF_UNSET) { | |
366 return "is duplicate"; | |
367 } | |
368 | |
369 ctx = cf->ctx; | |
370 mcf = ctx->main_conf[ngx_http_charset_filter_module.ctx_index]; | |
371 value = cf->args->elts; | |
372 | |
373 *cp = ngx_http_add_charset(&mcf->charsets, &value[1]); | |
374 if (*cp == NGX_ERROR) { | |
375 return NGX_CONF_ERROR; | |
376 } | |
377 | |
378 if (cmd->offset == offsetof(ngx_http_charset_loc_conf_t, source_charset)) { | |
379 charset = mcf->charsets.elts; | |
380 charset[*cp].server = 1; | |
381 } | |
382 | |
383 return NGX_CONF_OK; | |
384 } | |
385 | |
386 | |
387 static ngx_int_t ngx_http_add_charset(ngx_array_t *charsets, ngx_str_t *name) | |
388 { | |
389 ngx_uint_t i; | |
390 ngx_http_charset_t *c; | |
391 | |
392 c = charsets->elts; | |
393 for (i = 0; i < charsets->nelts; i++) { | |
394 if (name->len != c[i].name.len) { | |
395 continue; | |
396 } | |
397 | |
398 if (ngx_strcasecmp(name->data, c[i].name.data) == 0) { | |
399 break; | |
400 } | |
401 } | |
402 | |
403 if (i < charsets->nelts) { | |
404 return i; | |
405 } | |
406 | |
407 if (!(c = ngx_push_array(charsets))) { | |
408 return NGX_ERROR; | |
409 } | |
410 | |
411 c->name = *name; | |
412 | |
413 return i; | |
183 } | 414 } |
184 | 415 |
185 | 416 |
186 static int ngx_http_charset_filter_init(ngx_cycle_t *cycle) | 417 static int ngx_http_charset_filter_init(ngx_cycle_t *cycle) |
187 { | 418 { |
188 ngx_http_next_header_filter = ngx_http_top_header_filter; | 419 ngx_http_next_header_filter = ngx_http_top_header_filter; |
189 ngx_http_top_header_filter = ngx_http_charset_header_filter; | 420 ngx_http_top_header_filter = ngx_http_charset_header_filter; |
190 | 421 |
191 #if 0 | |
192 ngx_http_next_body_filter = ngx_http_top_body_filter; | 422 ngx_http_next_body_filter = ngx_http_top_body_filter; |
193 ngx_http_top_body_filter = ngx_http_charset_body_filter; | 423 ngx_http_top_body_filter = ngx_http_charset_body_filter; |
194 #endif | |
195 | 424 |
196 return NGX_OK; | 425 return NGX_OK; |
197 } | 426 } |
198 | 427 |
199 | 428 |
200 static void *ngx_http_charset_create_main_conf(ngx_conf_t *cf) | 429 static void *ngx_http_charset_create_main_conf(ngx_conf_t *cf) |
201 { | 430 { |
202 ngx_http_charset_main_conf_t *mcf; | 431 ngx_http_charset_main_conf_t *mcf; |
203 | 432 |
204 ngx_test_null(mcf, | 433 if (!(mcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_main_conf_t)))) { |
205 ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_main_conf_t)), | 434 return NGX_CONF_ERROR; |
206 NGX_CONF_ERROR); | 435 } |
207 | 436 |
208 ngx_init_array(mcf->tables, cf->pool, 10, sizeof(ngx_http_charset_table_t), | 437 ngx_init_array(mcf->charsets, cf->pool, 5, sizeof(ngx_http_charset_t), |
209 NGX_CONF_ERROR); | 438 NGX_CONF_ERROR); |
210 | 439 |
440 ngx_init_array(mcf->tables, cf->pool, 10, sizeof(ngx_http_charset_tables_t), | |
441 NGX_CONF_ERROR); | |
442 | |
211 return mcf; | 443 return mcf; |
212 } | 444 } |
213 | 445 |
214 | 446 |
447 static char *ngx_http_charset_init_main_conf(ngx_conf_t *cf, void *conf) | |
448 { | |
449 ngx_http_charset_main_conf_t *mcf = conf; | |
450 | |
451 ngx_uint_t i, n; | |
452 ngx_http_charset_t *charset, *c; | |
453 ngx_http_charset_tables_t *tables; | |
454 | |
455 tables = mcf->tables.elts; | |
456 charset = mcf->charsets.elts; | |
457 | |
458 for (i = 0; i < mcf->charsets.nelts; i++) { | |
459 if (!charset[i].server) { | |
460 continue; | |
461 } | |
462 | |
463 charset[i].tables = ngx_pcalloc(cf->pool, | |
464 sizeof(char *) * mcf->charsets.nelts); | |
465 | |
466 if (charset[i].tables == NULL) { | |
467 return NGX_CONF_ERROR; | |
468 } | |
469 | |
470 for (n = 0; n < mcf->tables.nelts; n++) { | |
471 if ((ngx_int_t) i == tables[n].src) { | |
472 charset[i].tables[tables[n].dst] = tables[n].src2dst; | |
473 continue; | |
474 } | |
475 | |
476 if ((ngx_int_t) i == tables[n].dst) { | |
477 charset[i].tables[tables[n].src] = tables[n].dst2src; | |
478 } | |
479 } | |
480 } | |
481 | |
482 for (i = 0; i < mcf->charsets.nelts; i++) { | |
483 if (!charset[i].server) { | |
484 continue; | |
485 } | |
486 | |
487 for (n = 0; n < mcf->charsets.nelts; n++) { | |
488 if (i == n) { | |
489 continue; | |
490 } | |
491 | |
492 if (charset[i].tables[n]) { | |
493 continue; | |
494 } | |
495 | |
496 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
497 " no \"charset_map\" between the charsets " | |
498 "\"%s\" and \"%s\"", | |
499 charset[i].name.data, charset[n].name.data); | |
500 return NGX_CONF_ERROR; | |
501 } | |
502 } | |
503 | |
504 return NGX_CONF_OK; | |
505 } | |
506 | |
507 | |
215 static void *ngx_http_charset_create_loc_conf(ngx_conf_t *cf) | 508 static void *ngx_http_charset_create_loc_conf(ngx_conf_t *cf) |
216 { | 509 { |
217 ngx_http_charset_loc_conf_t *lcf; | 510 ngx_http_charset_loc_conf_t *lcf; |
218 | 511 |
219 ngx_test_null(lcf, | 512 if (!(lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_loc_conf_t)))) { |
220 ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_loc_conf_t)), | 513 return NGX_CONF_ERROR; |
221 NGX_CONF_ERROR); | 514 } |
515 | |
516 lcf->enable = NGX_CONF_UNSET; | |
517 lcf->autodetect = NGX_CONF_UNSET; | |
518 lcf->default_charset = NGX_CONF_UNSET; | |
519 lcf->source_charset = NGX_CONF_UNSET; | |
222 | 520 |
223 return lcf; | 521 return lcf; |
224 } | 522 } |
225 | 523 |
226 | 524 |
228 void *parent, void *child) | 526 void *parent, void *child) |
229 { | 527 { |
230 ngx_http_charset_loc_conf_t *prev = parent; | 528 ngx_http_charset_loc_conf_t *prev = parent; |
231 ngx_http_charset_loc_conf_t *conf = child; | 529 ngx_http_charset_loc_conf_t *conf = child; |
232 | 530 |
233 ngx_conf_merge_str_value(conf->default_charset, | 531 ngx_conf_merge_value(conf->enable, prev->enable, 0); |
234 prev->default_charset, ""); | 532 ngx_conf_merge_value(conf->autodetect, prev->autodetect, 0); |
533 | |
534 if (conf->default_charset == NGX_CONF_UNSET) { | |
535 conf->default_charset = prev->default_charset; | |
536 } | |
537 | |
538 if (conf->source_charset == NGX_CONF_UNSET) { | |
539 conf->source_charset = prev->source_charset; | |
540 } | |
235 | 541 |
236 return NGX_CONF_OK; | 542 return NGX_CONF_OK; |
237 } | 543 } |