Mercurial > hg > nginx-vendor-0-5
comparison src/http/modules/ngx_http_charset_filter_module.c @ 78:9db7e0b5b27f NGINX_0_1_39
nginx 0.1.39
*) The changes in the ngx_http_charset_module: the "default_charset"
directive was canceled; the "charset" directive sets the response
charset; the "source_charset" directive sets the source charset only.
*) Bugfix: the backend "WWW-Authenticate" header line did not
transferred while the 401 response code redirecting.
*) Bugfix: the ngx_http_proxy_module and ngx_http_fastcgi_module may
close a connection before anything was transferred to a client; bug
appeared in 0.1.38.
*) Workaround: the Linux glibc crypt_r() initialization bug.
*) Bugfix: the ngx_http_ssi_module did not support the relative URI in
the "include virtual" command.
*) Bugfix: if the backend response had the "Location" header line and
nginx should not rewrite this line, then the 500 code response body
was transferred; bug appeared in 0.1.29.
*) Bugfix: some directives of the ngx_http_proxy_module and
ngx_http_fastcgi_module were not inherited from the server to the
location level; bug appeared in 0.1.29.
*) Bugfix: the ngx_http_ssl_module did not support the certificate
chain.
*) Bugfix: the ngx_http_autoindex_module did not show correctly the
long file names; bug appeared in 0.1.38.
*) Bugfixes in IMAP/POP3 proxy in interaction with a backend at the
login state.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Thu, 14 Jul 2005 00:00:00 +0400 |
parents | 77969b24f355 |
children | 71c46860eb55 |
comparison
equal
deleted
inserted
replaced
77:e6b3de2dc637 | 78:9db7e0b5b27f |
---|---|
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_http.h> | 9 #include <ngx_http.h> |
10 | 10 |
11 | 11 |
12 #define NGX_HTTP_NO_CHARSET -2 | |
13 | |
14 | |
12 typedef struct { | 15 typedef struct { |
13 char **tables; | 16 char **tables; |
14 ngx_str_t name; | 17 ngx_str_t name; |
15 | 18 |
16 unsigned server:1; | 19 ngx_uint_t utf8; /* unsigned utf8:1; */ |
17 unsigned utf8:1; | |
18 } ngx_http_charset_t; | 20 } ngx_http_charset_t; |
21 | |
22 | |
23 typedef struct { | |
24 ngx_int_t src; | |
25 ngx_int_t dst; | |
26 } ngx_http_charset_recode_t; | |
19 | 27 |
20 | 28 |
21 typedef struct { | 29 typedef struct { |
22 ngx_int_t src; | 30 ngx_int_t src; |
23 ngx_int_t dst; | 31 ngx_int_t dst; |
27 | 35 |
28 | 36 |
29 typedef struct { | 37 typedef struct { |
30 ngx_array_t charsets; /* ngx_http_charset_t */ | 38 ngx_array_t charsets; /* ngx_http_charset_t */ |
31 ngx_array_t tables; /* ngx_http_charset_tables_t */ | 39 ngx_array_t tables; /* ngx_http_charset_tables_t */ |
40 ngx_array_t recodes; /* ngx_http_charset_recode_t */ | |
32 } ngx_http_charset_main_conf_t; | 41 } ngx_http_charset_main_conf_t; |
33 | 42 |
34 | 43 |
35 typedef struct { | 44 typedef struct { |
36 ngx_flag_t enable; | 45 ngx_int_t charset; |
37 | |
38 ngx_int_t default_charset; | |
39 ngx_int_t source_charset; | 46 ngx_int_t source_charset; |
40 } ngx_http_charset_loc_conf_t; | 47 } ngx_http_charset_loc_conf_t; |
41 | 48 |
42 | 49 |
43 typedef struct { | 50 typedef struct { |
44 ngx_int_t server; | 51 ngx_int_t server; |
45 ngx_int_t client; | 52 ngx_int_t client; |
46 } ngx_http_charset_ctx_t; | 53 } ngx_http_charset_ctx_t; |
47 | 54 |
48 | 55 |
49 static ngx_uint_t ngx_charset_recode(ngx_buf_t *b, char *table); | 56 static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, char *table); |
50 | 57 |
51 static char *ngx_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd, | 58 static char *ngx_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd, |
52 void *conf); | 59 void *conf); |
53 static char *ngx_charset_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); | 60 static char *ngx_charset_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf); |
54 | 61 |
57 static ngx_int_t ngx_http_add_charset(ngx_array_t *charsets, ngx_str_t *name); | 64 static ngx_int_t ngx_http_add_charset(ngx_array_t *charsets, ngx_str_t *name); |
58 | 65 |
59 static ngx_int_t ngx_http_charset_filter_init(ngx_cycle_t *cycle); | 66 static ngx_int_t ngx_http_charset_filter_init(ngx_cycle_t *cycle); |
60 | 67 |
61 static void *ngx_http_charset_create_main_conf(ngx_conf_t *cf); | 68 static void *ngx_http_charset_create_main_conf(ngx_conf_t *cf); |
62 static char *ngx_http_charset_init_main_conf(ngx_conf_t *cf, void *conf); | |
63 static void *ngx_http_charset_create_loc_conf(ngx_conf_t *cf); | 69 static void *ngx_http_charset_create_loc_conf(ngx_conf_t *cf); |
64 static char *ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, | 70 static char *ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, |
65 void *parent, void *child); | 71 void *parent, void *child); |
72 static ngx_int_t ngx_http_charset_postconfiguration(ngx_conf_t *cf); | |
66 | 73 |
67 | 74 |
68 static ngx_command_t ngx_http_charset_filter_commands[] = { | 75 static ngx_command_t ngx_http_charset_filter_commands[] = { |
76 | |
77 { ngx_string("charset"), | |
78 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF | |
79 |NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1, | |
80 ngx_http_set_charset_slot, | |
81 NGX_HTTP_LOC_CONF_OFFSET, | |
82 offsetof(ngx_http_charset_loc_conf_t, charset), | |
83 NULL }, | |
84 | |
85 { ngx_string("source_charset"), | |
86 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF | |
87 |NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1, | |
88 ngx_http_set_charset_slot, | |
89 NGX_HTTP_LOC_CONF_OFFSET, | |
90 offsetof(ngx_http_charset_loc_conf_t, source_charset), | |
91 NULL }, | |
69 | 92 |
70 { ngx_string("charset_map"), | 93 { ngx_string("charset_map"), |
71 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2, | 94 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2, |
72 ngx_charset_map_block, | 95 ngx_charset_map_block, |
73 NGX_HTTP_MAIN_CONF_OFFSET, | 96 NGX_HTTP_MAIN_CONF_OFFSET, |
74 0, | 97 0, |
75 NULL }, | 98 NULL }, |
76 | 99 |
77 { ngx_string("default_charset"), | |
78 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
79 ngx_http_set_charset_slot, | |
80 NGX_HTTP_LOC_CONF_OFFSET, | |
81 offsetof(ngx_http_charset_loc_conf_t, default_charset), | |
82 NULL }, | |
83 | |
84 { ngx_string("source_charset"), | |
85 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
86 ngx_http_set_charset_slot, | |
87 NGX_HTTP_LOC_CONF_OFFSET, | |
88 offsetof(ngx_http_charset_loc_conf_t, source_charset), | |
89 NULL }, | |
90 | |
91 { ngx_string("charset"), | |
92 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
93 ngx_conf_set_flag_slot, | |
94 NGX_HTTP_LOC_CONF_OFFSET, | |
95 offsetof(ngx_http_charset_loc_conf_t, enable), | |
96 NULL }, | |
97 | |
98 ngx_null_command | 100 ngx_null_command |
99 }; | 101 }; |
100 | 102 |
101 | 103 |
102 static ngx_http_module_t ngx_http_charset_filter_module_ctx = { | 104 static ngx_http_module_t ngx_http_charset_filter_module_ctx = { |
103 NULL, /* preconfiguration */ | 105 NULL, /* preconfiguration */ |
104 NULL, /* postconfiguration */ | 106 ngx_http_charset_postconfiguration, /* postconfiguration */ |
105 | 107 |
106 ngx_http_charset_create_main_conf, /* create main configuration */ | 108 ngx_http_charset_create_main_conf, /* create main configuration */ |
107 ngx_http_charset_init_main_conf, /* init main configuration */ | 109 NULL, /* init main configuration */ |
108 | 110 |
109 NULL, /* create server configuration */ | 111 NULL, /* create server configuration */ |
110 NULL, /* merge server configuration */ | 112 NULL, /* merge server configuration */ |
111 | 113 |
112 ngx_http_charset_create_loc_conf, /* create location configuration */ | 114 ngx_http_charset_create_loc_conf, /* create location configuration */ |
137 ngx_http_charset_main_conf_t *mcf; | 139 ngx_http_charset_main_conf_t *mcf; |
138 | 140 |
139 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); | 141 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); |
140 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); | 142 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); |
141 | 143 |
142 if (lcf->enable == 0) { | 144 if (lcf->charset == NGX_HTTP_NO_CHARSET) { |
143 return ngx_http_next_header_filter(r); | 145 return ngx_http_next_header_filter(r); |
144 } | 146 } |
145 | 147 |
146 if (r->headers_out.content_type.len == 0) { | 148 if (r->headers_out.content_type.len == 0) { |
147 return ngx_http_next_header_filter(r); | 149 return ngx_http_next_header_filter(r); |
174 if (r->headers_out.charset.len) { | 176 if (r->headers_out.charset.len) { |
175 return ngx_http_next_header_filter(r); | 177 return ngx_http_next_header_filter(r); |
176 } | 178 } |
177 | 179 |
178 charsets = mcf->charsets.elts; | 180 charsets = mcf->charsets.elts; |
179 r->headers_out.charset = charsets[lcf->default_charset].name; | 181 r->headers_out.charset = charsets[lcf->charset].name; |
180 r->utf8 = charsets[lcf->default_charset].utf8; | 182 r->utf8 = charsets[lcf->charset].utf8; |
181 | 183 |
182 if (lcf->default_charset == lcf->source_charset) { | 184 if (lcf->source_charset == NGX_CONF_UNSET |
185 || lcf->source_charset == lcf->charset) | |
186 { | |
183 return ngx_http_next_header_filter(r); | 187 return ngx_http_next_header_filter(r); |
184 } | 188 } |
185 | 189 |
186 | 190 |
187 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t)); | 191 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t)); |
216 | 220 |
217 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); | 221 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); |
218 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); | 222 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); |
219 | 223 |
220 charsets = mcf->charsets.elts; | 224 charsets = mcf->charsets.elts; |
221 table = charsets[lcf->source_charset].tables[lcf->default_charset]; | 225 table = charsets[lcf->source_charset].tables[lcf->charset]; |
222 | 226 |
223 for (cl = in; cl; cl = cl->next) { | 227 for (cl = in; cl; cl = cl->next) { |
224 ngx_charset_recode(cl->buf, table); | 228 ngx_http_charset_recode(cl->buf, table); |
225 } | 229 } |
226 | 230 |
227 return ngx_http_next_body_filter(r, in); | 231 return ngx_http_next_body_filter(r, in); |
228 } | 232 } |
229 | 233 |
230 | 234 |
231 static ngx_uint_t | 235 static ngx_uint_t |
232 ngx_charset_recode(ngx_buf_t *b, char *table) | 236 ngx_http_charset_recode(ngx_buf_t *b, char *table) |
233 { | 237 { |
234 u_char *p; | 238 u_char *p; |
235 ngx_uint_t change; | 239 ngx_uint_t change; |
236 | 240 |
237 change = 0; | 241 change = 0; |
383 { | 387 { |
384 char *p = conf; | 388 char *p = conf; |
385 | 389 |
386 ngx_int_t *cp; | 390 ngx_int_t *cp; |
387 ngx_str_t *value; | 391 ngx_str_t *value; |
388 ngx_http_charset_t *charset; | |
389 ngx_http_charset_main_conf_t *mcf; | 392 ngx_http_charset_main_conf_t *mcf; |
390 | 393 |
391 cp = (ngx_int_t *) (p + cmd->offset); | 394 cp = (ngx_int_t *) (p + cmd->offset); |
392 | 395 |
393 if (*cp != NGX_CONF_UNSET) { | 396 if (*cp != NGX_CONF_UNSET) { |
394 return "is duplicate"; | 397 return "is duplicate"; |
395 } | 398 } |
396 | 399 |
400 value = cf->args->elts; | |
401 | |
402 if (cmd->offset == offsetof(ngx_http_charset_loc_conf_t, charset) | |
403 && ngx_strcmp(value[1].data, "off") == 0) | |
404 { | |
405 *cp = NGX_HTTP_NO_CHARSET; | |
406 return NGX_CONF_OK; | |
407 } | |
408 | |
397 mcf = ngx_http_conf_get_module_main_conf(cf, | 409 mcf = ngx_http_conf_get_module_main_conf(cf, |
398 ngx_http_charset_filter_module); | 410 ngx_http_charset_filter_module); |
399 | 411 |
400 value = cf->args->elts; | |
401 | |
402 *cp = ngx_http_add_charset(&mcf->charsets, &value[1]); | 412 *cp = ngx_http_add_charset(&mcf->charsets, &value[1]); |
403 if (*cp == NGX_ERROR) { | 413 if (*cp == NGX_ERROR) { |
404 return NGX_CONF_ERROR; | 414 return NGX_CONF_ERROR; |
405 } | |
406 | |
407 if (cmd->offset == offsetof(ngx_http_charset_loc_conf_t, source_charset)) { | |
408 charset = mcf->charsets.elts; | |
409 charset[*cp].server = 1; | |
410 } | 415 } |
411 | 416 |
412 return NGX_CONF_OK; | 417 return NGX_CONF_OK; |
413 } | 418 } |
414 | 419 |
439 return NGX_ERROR; | 444 return NGX_ERROR; |
440 } | 445 } |
441 | 446 |
442 c->tables = NULL; | 447 c->tables = NULL; |
443 c->name = *name; | 448 c->name = *name; |
444 c->server = 0; | |
445 | 449 |
446 if (ngx_strcasecmp(name->data, "utf-8") == 0) { | 450 if (ngx_strcasecmp(name->data, "utf-8") == 0) { |
447 c->utf8 = 1; | 451 c->utf8 = 1; |
448 } | 452 } |
449 | 453 |
473 if (mcf == NULL) { | 477 if (mcf == NULL) { |
474 return NGX_CONF_ERROR; | 478 return NGX_CONF_ERROR; |
475 } | 479 } |
476 | 480 |
477 if (ngx_array_init(&mcf->charsets, cf->pool, 2, sizeof(ngx_http_charset_t)) | 481 if (ngx_array_init(&mcf->charsets, cf->pool, 2, sizeof(ngx_http_charset_t)) |
478 == NGX_ERROR) | 482 == NGX_ERROR) |
479 { | 483 { |
480 return NGX_CONF_ERROR; | 484 return NGX_CONF_ERROR; |
481 } | 485 } |
482 | 486 |
483 if (ngx_array_init(&mcf->tables, cf->pool, 4, | 487 if (ngx_array_init(&mcf->tables, cf->pool, 1, |
484 sizeof(ngx_http_charset_tables_t)) == NGX_ERROR) | 488 sizeof(ngx_http_charset_tables_t)) == NGX_ERROR) |
485 { | 489 { |
486 return NGX_CONF_ERROR; | 490 return NGX_CONF_ERROR; |
487 } | 491 } |
488 | 492 |
493 if (ngx_array_init(&mcf->recodes, cf->pool, 2, | |
494 sizeof(ngx_http_charset_recode_t)) == NGX_ERROR) | |
495 { | |
496 return NGX_CONF_ERROR; | |
497 } | |
498 | |
489 return mcf; | 499 return mcf; |
490 } | 500 } |
491 | 501 |
492 | 502 |
503 static void * | |
504 ngx_http_charset_create_loc_conf(ngx_conf_t *cf) | |
505 { | |
506 ngx_http_charset_loc_conf_t *lcf; | |
507 | |
508 lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_loc_conf_t)); | |
509 if (lcf == NULL) { | |
510 return NGX_CONF_ERROR; | |
511 } | |
512 | |
513 lcf->charset = NGX_CONF_UNSET; | |
514 lcf->source_charset = NGX_CONF_UNSET; | |
515 | |
516 return lcf; | |
517 } | |
518 | |
519 | |
493 static char * | 520 static char * |
494 ngx_http_charset_init_main_conf(ngx_conf_t *cf, void *conf) | 521 ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) |
495 { | 522 { |
496 ngx_http_charset_main_conf_t *mcf = conf; | 523 ngx_http_charset_loc_conf_t *prev = parent; |
497 | 524 ngx_http_charset_loc_conf_t *conf = child; |
498 ngx_uint_t i, n; | 525 |
499 ngx_http_charset_t *charset; | 526 ngx_uint_t i; |
500 ngx_http_charset_tables_t *tables; | 527 ngx_http_charset_recode_t *recode; |
501 | 528 ngx_http_charset_main_conf_t *mcf; |
529 | |
530 ngx_conf_merge_value(conf->charset, prev->charset, NGX_HTTP_NO_CHARSET); | |
531 | |
532 if (conf->source_charset == NGX_CONF_UNSET) { | |
533 conf->source_charset = prev->source_charset; | |
534 } | |
535 | |
536 if (conf->charset == NGX_HTTP_NO_CHARSET | |
537 || conf->source_charset == NGX_CONF_UNSET | |
538 || conf->charset == conf->source_charset) | |
539 { | |
540 return NGX_CONF_OK; | |
541 } | |
542 | |
543 mcf = ngx_http_conf_get_module_main_conf(cf, | |
544 ngx_http_charset_filter_module); | |
545 recode = mcf->recodes.elts; | |
546 for (i = 0; i < mcf->recodes.nelts; i++) { | |
547 if (conf->source_charset == recode[i].src | |
548 && conf->charset == recode[i].dst) | |
549 { | |
550 return NGX_CONF_OK; | |
551 } | |
552 } | |
553 | |
554 recode = ngx_array_push(&mcf->recodes); | |
555 if (recode == NULL) { | |
556 return NGX_CONF_ERROR; | |
557 } | |
558 | |
559 recode->src = conf->source_charset; | |
560 recode->dst = conf->charset; | |
561 | |
562 return NGX_CONF_OK; | |
563 } | |
564 | |
565 | |
566 static ngx_int_t | |
567 ngx_http_charset_postconfiguration(ngx_conf_t *cf) | |
568 { | |
569 ngx_int_t c; | |
570 ngx_uint_t i, t; | |
571 ngx_http_charset_t *charset; | |
572 ngx_http_charset_recode_t *recode; | |
573 ngx_http_charset_tables_t *tables; | |
574 ngx_http_charset_main_conf_t *mcf; | |
575 | |
576 mcf = ngx_http_conf_get_module_main_conf(cf, | |
577 ngx_http_charset_filter_module); | |
578 | |
579 recode = mcf->recodes.elts; | |
502 tables = mcf->tables.elts; | 580 tables = mcf->tables.elts; |
503 charset = mcf->charsets.elts; | 581 charset = mcf->charsets.elts; |
504 | 582 |
505 for (i = 0; i < mcf->charsets.nelts; i++) { | 583 for (i = 0; i < mcf->recodes.nelts; i++) { |
506 if (!charset[i].server) { | 584 |
507 continue; | 585 c = recode[i].src; |
508 } | 586 |
509 | 587 charset[c].tables = ngx_pcalloc(cf->pool, |
510 charset[i].tables = ngx_pcalloc(cf->pool, | |
511 sizeof(char *) * mcf->charsets.nelts); | 588 sizeof(char *) * mcf->charsets.nelts); |
512 if (charset[i].tables == NULL) { | 589 if (charset[c].tables == NULL) { |
513 return NGX_CONF_ERROR; | 590 return NGX_ERROR; |
514 } | 591 } |
515 | 592 |
516 for (n = 0; n < mcf->tables.nelts; n++) { | 593 for (t = 0; t < mcf->tables.nelts; t++) { |
517 if ((ngx_int_t) i == tables[n].src) { | 594 |
518 charset[i].tables[tables[n].dst] = tables[n].src2dst; | 595 if (c == tables[t].src && recode[i].dst == tables[t].dst) { |
519 continue; | 596 charset[c].tables[tables[t].dst] = tables[t].src2dst; |
597 goto next; | |
520 } | 598 } |
521 | 599 |
522 if ((ngx_int_t) i == tables[n].dst) { | 600 if (c == tables[t].dst && recode[i].dst == tables[t].src) { |
523 charset[i].tables[tables[n].src] = tables[n].dst2src; | 601 charset[c].tables[tables[t].src] = tables[t].dst2src; |
602 goto next; | |
524 } | 603 } |
525 } | 604 } |
526 } | 605 |
527 | 606 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, |
528 for (i = 0; i < mcf->charsets.nelts; i++) { | 607 " no \"charset_map\" between the charsets " |
529 if (!charset[i].server) { | 608 "\"%V\" and \"%V\"", |
530 continue; | 609 &charset[c].name, &charset[recode[i].dst].name); |
531 } | 610 return NGX_ERROR; |
532 | 611 |
533 for (n = 0; n < mcf->charsets.nelts; n++) { | 612 next: |
534 if (i == n) { | 613 continue; |
535 continue; | 614 } |
536 } | 615 |
537 | 616 return NGX_OK; |
538 if (charset[i].tables[n]) { | 617 } |
539 continue; | |
540 } | |
541 | |
542 ngx_log_error(NGX_LOG_EMERG, cf->log, 0, | |
543 " no \"charset_map\" between the charsets " | |
544 "\"%V\" and \"%V\"", | |
545 &charset[i].name, &charset[n].name); | |
546 return NGX_CONF_ERROR; | |
547 } | |
548 } | |
549 | |
550 return NGX_CONF_OK; | |
551 } | |
552 | |
553 | |
554 static void * | |
555 ngx_http_charset_create_loc_conf(ngx_conf_t *cf) | |
556 { | |
557 ngx_http_charset_loc_conf_t *lcf; | |
558 | |
559 lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_loc_conf_t)); | |
560 if (lcf == NULL) { | |
561 return NGX_CONF_ERROR; | |
562 } | |
563 | |
564 lcf->enable = NGX_CONF_UNSET; | |
565 lcf->default_charset = NGX_CONF_UNSET; | |
566 lcf->source_charset = NGX_CONF_UNSET; | |
567 | |
568 return lcf; | |
569 } | |
570 | |
571 | |
572 static char * | |
573 ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
574 { | |
575 ngx_http_charset_loc_conf_t *prev = parent; | |
576 ngx_http_charset_loc_conf_t *conf = child; | |
577 | |
578 ngx_conf_merge_value(conf->enable, prev->enable, 0); | |
579 | |
580 if (conf->default_charset == NGX_CONF_UNSET) { | |
581 conf->default_charset = prev->default_charset; | |
582 } | |
583 | |
584 if (conf->source_charset == NGX_CONF_UNSET) { | |
585 conf->source_charset = prev->source_charset; | |
586 } | |
587 | |
588 if (conf->default_charset == NGX_CONF_UNSET | |
589 && conf->source_charset != NGX_CONF_UNSET) | |
590 { | |
591 conf->default_charset = conf->source_charset; | |
592 } | |
593 | |
594 if (conf->source_charset == NGX_CONF_UNSET | |
595 && conf->default_charset != NGX_CONF_UNSET) | |
596 { | |
597 conf->source_charset = conf->default_charset; | |
598 } | |
599 | |
600 if (conf->enable | |
601 && (conf->default_charset == NGX_CONF_UNSET | |
602 || conf->source_charset == NGX_CONF_UNSET)) | |
603 { | |
604 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
605 "the \"source_charset\" or \"default_charset\" " | |
606 "must be specified when \"charset\" is on"); | |
607 return NGX_CONF_ERROR; | |
608 } | |
609 | |
610 return NGX_CONF_OK; | |
611 } |