comparison src/http/modules/ngx_http_charset_filter_module.c @ 496:f39b9e29530d NGINX_0_8_0

nginx 0.8.0 *) Feature: the "keepalive_requests" directive. *) Feature: the "limit_rate_after" directive. Thanks to Ivan Debnar. *) Bugfix: XLST filter did not work in subrequests. *) Bugfix: in relative paths handling in nginx/Windows. *) Bugfix: in proxy_store, fastcgi_store, proxy_cache, and fastcgi_cache in nginx/Windows. *) Bugfix: in memory allocation error handling. Thanks to Maxim Dounin and Kirill A. Korinskiy.
author Igor Sysoev <http://sysoev.ru>
date Tue, 02 Jun 2009 00:00:00 +0400
parents 499474178a11
children 5c576ea5dbd9
comparison
equal deleted inserted replaced
495:6d9fb4461113 496:f39b9e29530d
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 12 #define NGX_HTTP_CHARSET_OFF -2
13 #define NGX_HTTP_CHARSET_VAR 0x10000 13 #define NGX_HTTP_NO_CHARSET -3
14 #define NGX_HTTP_CHARSET_VAR 0x10000
14 15
15 /* 1 byte length and up to 3 bytes for the UTF-8 encoding of the UCS-2 */ 16 /* 1 byte length and up to 3 bytes for the UTF-8 encoding of the UCS-2 */
16 #define NGX_UTF_LEN 4 17 #define NGX_UTF_LEN 4
17 18
18 #define NGX_HTML_ENTITY_LEN (sizeof("&#1114111;") - 1) 19 #define NGX_HTML_ENTITY_LEN (sizeof("&#1114111;") - 1)
59 60
60 61
61 typedef struct { 62 typedef struct {
62 u_char *table; 63 u_char *table;
63 ngx_int_t charset; 64 ngx_int_t charset;
65 ngx_str_t charset_name;
64 66
65 ngx_chain_t *busy; 67 ngx_chain_t *busy;
66 ngx_chain_t *free_bufs; 68 ngx_chain_t *free_bufs;
67 ngx_chain_t *free_buffers; 69 ngx_chain_t *free_buffers;
68 70
80 ngx_http_charset_t *charset; 82 ngx_http_charset_t *charset;
81 ngx_uint_t characters; 83 ngx_uint_t characters;
82 } ngx_http_charset_conf_ctx_t; 84 } ngx_http_charset_conf_ctx_t;
83 85
84 86
85 static ngx_int_t ngx_http_charset_get_charset(ngx_http_charset_t *charsets, 87 static ngx_int_t ngx_http_destination_charset(ngx_http_request_t *r,
86 ngx_uint_t n, ngx_str_t *charset); 88 ngx_str_t *name);
87 static ngx_int_t ngx_http_charset_set_charset(ngx_http_request_t *r, 89 static ngx_int_t ngx_http_main_request_charset(ngx_http_request_t *r,
90 ngx_str_t *name);
91 static ngx_int_t ngx_http_source_charset(ngx_http_request_t *r,
92 ngx_str_t *name);
93 static ngx_int_t ngx_http_get_charset(ngx_http_request_t *r, ngx_str_t *name);
94 static ngx_inline void ngx_http_set_charset(ngx_http_request_t *r,
95 ngx_str_t *charset);
96 static ngx_int_t ngx_http_charset_ctx(ngx_http_request_t *r,
88 ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset); 97 ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset);
89 static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, u_char *table); 98 static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, u_char *table);
90 static ngx_chain_t *ngx_http_charset_recode_from_utf8(ngx_pool_t *pool, 99 static ngx_chain_t *ngx_http_charset_recode_from_utf8(ngx_pool_t *pool,
91 ngx_buf_t *buf, ngx_http_charset_ctx_t *ctx); 100 ngx_buf_t *buf, ngx_http_charset_ctx_t *ctx);
92 static ngx_chain_t *ngx_http_charset_recode_to_utf8(ngx_pool_t *pool, 101 static ngx_chain_t *ngx_http_charset_recode_to_utf8(ngx_pool_t *pool,
205 214
206 static ngx_int_t 215 static ngx_int_t
207 ngx_http_charset_header_filter(ngx_http_request_t *r) 216 ngx_http_charset_header_filter(ngx_http_request_t *r)
208 { 217 {
209 ngx_int_t charset, source_charset; 218 ngx_int_t charset, source_charset;
210 ngx_str_t *mc, *from, *to, s; 219 ngx_str_t dst, src;
211 ngx_uint_t n;
212 ngx_http_charset_t *charsets; 220 ngx_http_charset_t *charsets;
213 ngx_http_charset_ctx_t *ctx;
214 ngx_http_variable_value_t *vv;
215 ngx_http_charset_loc_conf_t *lcf, *mlcf;
216 ngx_http_charset_main_conf_t *mcf; 221 ngx_http_charset_main_conf_t *mcf;
217 222
218 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
219
220 charsets = mcf->charsets.elts;
221 n = mcf->charsets.nelts;
222
223 /* destination charset */
224
225 if (r == r->main) { 223 if (r == r->main) {
226 224 charset = ngx_http_destination_charset(r, &dst);
227 if (!r->ignore_content_encoding
228 && r->headers_out.content_encoding
229 && r->headers_out.content_encoding->value.len)
230 {
231 return ngx_http_next_header_filter(r);
232 }
233
234 if (r->headers_out.content_type.len == 0) {
235 return ngx_http_next_header_filter(r);
236 }
237
238 if (r->headers_out.override_charset
239 && r->headers_out.override_charset->len)
240 {
241 charset = ngx_http_charset_get_charset(charsets, n,
242 r->headers_out.override_charset);
243
244 if (charset == NGX_HTTP_NO_CHARSET) {
245 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
246 "unknown charset \"%V\" to override",
247 r->headers_out.override_charset);
248
249 return ngx_http_next_header_filter(r);
250 }
251
252 } else {
253 mlcf = ngx_http_get_module_loc_conf(r,
254 ngx_http_charset_filter_module);
255 charset = mlcf->charset;
256
257 if (charset == NGX_HTTP_NO_CHARSET) {
258 return ngx_http_next_header_filter(r);
259 }
260
261 if (r->headers_out.charset.len) {
262 if (mlcf->override_charset == 0) {
263 return ngx_http_next_header_filter(r);
264 }
265
266 } else {
267 if (ngx_http_test_content_type(r, &mlcf->types) == NULL) {
268 return ngx_http_next_header_filter(r);
269 }
270 }
271
272 if (charset >= NGX_HTTP_CHARSET_VAR) {
273 vv = ngx_http_get_indexed_variable(r,
274 charset - NGX_HTTP_CHARSET_VAR);
275
276 if (vv == NULL || vv->not_found) {
277 return NGX_ERROR;
278 }
279
280 s.len = vv->len;
281 s.data = vv->data;
282
283 charset = ngx_http_charset_get_charset(charsets, n, &s);
284 }
285 }
286 225
287 } else { 226 } else {
288 ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module); 227 charset = ngx_http_main_request_charset(r, &dst);
289 228 }
290 if (ctx == NULL) { 229
291 230 if (charset == NGX_ERROR) {
292 mc = &r->main->headers_out.charset; 231 return NGX_ERROR;
293 232 }
294 if (mc->len == 0) { 233
295 return ngx_http_next_header_filter(r); 234 if (charset == NGX_DECLINED) {
296 } 235 return ngx_http_next_header_filter(r);
297 236 }
298 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t)); 237
299 if (ctx == NULL) { 238 /* charset: charset index or NGX_HTTP_NO_CHARSET */
300 return NGX_ERROR; 239
301 } 240 source_charset = ngx_http_source_charset(r, &src);
302 241
303 ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module); 242 if (source_charset == NGX_ERROR) {
304 243 return NGX_ERROR;
305 charset = ngx_http_charset_get_charset(charsets, n, mc); 244 }
306 245
307 ctx->charset = charset; 246 /*
308 247 * source_charset: charset index, NGX_HTTP_NO_CHARSET,
309 } else { 248 * or NGX_HTTP_CHARSET_OFF
310 charset = ctx->charset; 249 */
311 } 250
312 } 251 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
313 252 "charset: \"%V\" > \"%V\"", &src, &dst);
314 /* source charset */ 253
315 254 if (source_charset == NGX_HTTP_CHARSET_OFF) {
316 if (r->headers_out.charset.len == 0) { 255 ngx_http_set_charset(r, &dst);
317 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); 256
318 257 return ngx_http_next_header_filter(r);
319 source_charset = lcf->source_charset; 258 }
320
321 if (source_charset >= NGX_HTTP_CHARSET_VAR) {
322 vv = ngx_http_get_indexed_variable(r,
323 source_charset - NGX_HTTP_CHARSET_VAR);
324
325 if (vv == NULL || vv->not_found) {
326 return NGX_ERROR;
327 }
328
329 s.len = vv->len;
330 s.data = vv->data;
331
332 source_charset = ngx_http_charset_get_charset(charsets, n, &s);
333 }
334
335 if (charset != NGX_HTTP_NO_CHARSET) {
336 return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset,
337 source_charset);
338 }
339
340 if (source_charset == NGX_CONF_UNSET) {
341 return ngx_http_next_header_filter(r);
342 }
343
344 from = &charsets[source_charset].name;
345 to = &r->main->headers_out.charset;
346
347 goto no_charset_map;
348 }
349
350 source_charset = ngx_http_charset_get_charset(charsets, n,
351 &r->headers_out.charset);
352 259
353 if (charset == NGX_HTTP_NO_CHARSET 260 if (charset == NGX_HTTP_NO_CHARSET
354 || source_charset == NGX_HTTP_NO_CHARSET) 261 || source_charset == NGX_HTTP_NO_CHARSET)
355 { 262 {
356 if (charset != source_charset 263 if (source_charset != charset
357 || ngx_strcasecmp(r->main->headers_out.charset.data, 264 || ngx_strncasecmp(dst.data, src.data, dst.len) != 0)
358 r->headers_out.charset.data)
359 != 0)
360 { 265 {
361 from = &r->headers_out.charset;
362 to = (charset == NGX_HTTP_NO_CHARSET) ?
363 &r->main->headers_out.charset:
364 &charsets[charset].name;
365
366 goto no_charset_map; 266 goto no_charset_map;
367 } 267 }
368 268
269 ngx_http_set_charset(r, &dst);
270
369 return ngx_http_next_header_filter(r); 271 return ngx_http_next_header_filter(r);
370 } 272 }
273
274 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
275 charsets = mcf->charsets.elts;
371 276
372 if (source_charset != charset 277 if (source_charset != charset
373 && (charsets[source_charset].tables == NULL 278 && (charsets[source_charset].tables == NULL
374 || charsets[source_charset].tables[charset] == NULL)) 279 || charsets[source_charset].tables[charset] == NULL))
375 { 280 {
376 from = &charsets[source_charset].name;
377 to = &charsets[charset].name;
378
379 goto no_charset_map; 281 goto no_charset_map;
380 } 282 }
381 283
382 r->headers_out.content_type.len = r->headers_out.content_type_len; 284 r->headers_out.content_type.len = r->headers_out.content_type_len;
383 285
384 return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset, 286 ngx_http_set_charset(r, &dst);
385 source_charset); 287
288 if (source_charset != charset) {
289 return ngx_http_charset_ctx(r, charsets, charset, source_charset);
290 }
291
292 return ngx_http_next_header_filter(r);
386 293
387 no_charset_map: 294 no_charset_map:
388 295
389 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 296 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
390 "no \"charset_map\" between the charsets \"%V\" and \"%V\"", 297 "no \"charset_map\" between the charsets \"%V\" and \"%V\"",
391 from, to); 298 &src, &dst);
392 299
393 return ngx_http_next_header_filter(r); 300 return ngx_http_next_header_filter(r);
394 } 301 }
395 302
396 303
397 static ngx_int_t 304 static ngx_int_t
398 ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n, 305 ngx_http_destination_charset(ngx_http_request_t *r, ngx_str_t *name)
399 ngx_str_t *charset) 306 {
400 { 307 ngx_int_t charset;
401 ngx_uint_t i; 308 ngx_http_charset_t *charsets;
309 ngx_http_variable_value_t *vv;
310 ngx_http_charset_loc_conf_t *mlcf;
311 ngx_http_charset_main_conf_t *mcf;
312
313 if (!r->ignore_content_encoding
314 && r->headers_out.content_encoding
315 && r->headers_out.content_encoding->value.len)
316 {
317 return NGX_DECLINED;
318 }
319
320 if (r->headers_out.content_type.len == 0) {
321 return NGX_DECLINED;
322 }
323
324 if (r->headers_out.override_charset
325 && r->headers_out.override_charset->len)
326 {
327 *name = *r->headers_out.override_charset;
328
329 charset = ngx_http_get_charset(r, name);
330
331 if (charset != NGX_HTTP_NO_CHARSET) {
332 return charset;
333 }
334
335 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
336 "unknown charset \"%V\" to override", name);
337
338 return NGX_DECLINED;
339 }
340
341 mlcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
342 charset = mlcf->charset;
343
344 if (charset == NGX_HTTP_CHARSET_OFF) {
345 return NGX_DECLINED;
346 }
347
348 if (r->headers_out.charset.len) {
349 if (mlcf->override_charset == 0) {
350 return NGX_DECLINED;
351 }
352
353 } else {
354 if (ngx_http_test_content_type(r, &mlcf->types) == NULL) {
355 return NGX_DECLINED;
356 }
357 }
358
359 if (charset < NGX_HTTP_CHARSET_VAR) {
360 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
361 charsets = mcf->charsets.elts;
362 *name = charsets[charset].name;
363 return charset;
364 }
365
366 vv = ngx_http_get_indexed_variable(r, charset - NGX_HTTP_CHARSET_VAR);
367
368 if (vv == NULL || vv->not_found) {
369 return NGX_ERROR;
370 }
371
372 name->len = vv->len;
373 name->data = vv->data;
374
375 return ngx_http_get_charset(r, name);
376 }
377
378
379 static ngx_int_t
380 ngx_http_main_request_charset(ngx_http_request_t *r, ngx_str_t *src)
381 {
382 ngx_int_t charset;
383 ngx_str_t *main_charset;
384 ngx_http_charset_ctx_t *ctx;
385
386 ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module);
387
388 if (ctx) {
389 *src = ctx->charset_name;
390 return ctx->charset;
391 }
392
393 main_charset = &r->main->headers_out.charset;
394
395 if (main_charset->len == 0) {
396 return NGX_DECLINED;
397 }
398
399 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
400 if (ctx == NULL) {
401 return NGX_ERROR;
402 }
403
404 ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module);
405
406 charset = ngx_http_get_charset(r, main_charset);
407
408 ctx->charset = charset;
409 ctx->charset_name = *main_charset;
410 *src = *main_charset;
411
412 return charset;
413 }
414
415
416 static ngx_int_t
417 ngx_http_source_charset(ngx_http_request_t *r, ngx_str_t *name)
418 {
419 ngx_int_t charset;
420 ngx_http_charset_t *charsets;
421 ngx_http_variable_value_t *vv;
422 ngx_http_charset_loc_conf_t *lcf;
423 ngx_http_charset_main_conf_t *mcf;
424
425 if (r->headers_out.charset.len) {
426 *name = r->headers_out.charset;
427 return ngx_http_get_charset(r, name);
428 }
429
430 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
431
432 charset = lcf->source_charset;
433
434 if (charset == NGX_HTTP_CHARSET_OFF) {
435 name->len = 0;
436 return charset;
437 }
438
439 if (charset < NGX_HTTP_CHARSET_VAR) {
440 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
441 charsets = mcf->charsets.elts;
442 *name = charsets[charset].name;
443 return charset;
444 }
445
446 vv = ngx_http_get_indexed_variable(r, charset - NGX_HTTP_CHARSET_VAR);
447
448 if (vv == NULL || vv->not_found) {
449 return NGX_ERROR;
450 }
451
452 name->len = vv->len;
453 name->data = vv->data;
454
455 return ngx_http_get_charset(r, name);
456 }
457
458
459 static ngx_int_t
460 ngx_http_get_charset(ngx_http_request_t *r, ngx_str_t *name)
461 {
462 ngx_uint_t i, n;
463 ngx_http_charset_t *charset;
464 ngx_http_charset_main_conf_t *mcf;
465
466 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
467
468 charset = mcf->charsets.elts;
469 n = mcf->charsets.nelts;
402 470
403 for (i = 0; i < n; i++) { 471 for (i = 0; i < n; i++) {
404 if (charsets[i].name.len != charset->len) { 472 if (charset[i].name.len != name->len) {
405 continue; 473 continue;
406 } 474 }
407 475
408 if (ngx_strncasecmp(charsets[i].name.data, charset->data, charset->len) 476 if (ngx_strncasecmp(charset[i].name.data, name->data, name->len) == 0) {
409 == 0)
410 {
411 return i; 477 return i;
412 } 478 }
413 } 479 }
414 480
415 return NGX_HTTP_NO_CHARSET; 481 return NGX_HTTP_NO_CHARSET;
416 } 482 }
417 483
418 484
419 static ngx_int_t 485 static ngx_inline void
420 ngx_http_charset_set_charset(ngx_http_request_t *r, 486 ngx_http_set_charset(ngx_http_request_t *r, ngx_str_t *charset)
421 ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset) 487 {
422 { 488 if (r != r->main) {
423 ngx_http_charset_ctx_t *ctx; 489 return;
490 }
424 491
425 if (r->headers_out.status == NGX_HTTP_MOVED_PERMANENTLY 492 if (r->headers_out.status == NGX_HTTP_MOVED_PERMANENTLY
426 || r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY) 493 || r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY)
427 { 494 {
428 /* 495 /*
429 * do not set charset for the redirect because NN 4.x 496 * do not set charset for the redirect because NN 4.x
430 * use this charset instead of the next page charset 497 * use this charset instead of the next page charset
431 */ 498 */
432 499
433 r->headers_out.charset.len = 0; 500 r->headers_out.charset.len = 0;
434 501 return;
435 return ngx_http_next_header_filter(r); 502 }
436 } 503
437 504 r->headers_out.charset = *charset;
438 r->headers_out.charset = charsets[charset].name; 505 }
439 r->utf8 = charsets[charset].utf8; 506
440 507
441 if (source_charset == NGX_CONF_UNSET || source_charset == charset) { 508 static ngx_int_t
442 return ngx_http_next_header_filter(r); 509 ngx_http_charset_ctx(ngx_http_request_t *r, ngx_http_charset_t *charsets,
443 } 510 ngx_int_t charset, ngx_int_t source_charset)
511 {
512 ngx_http_charset_ctx_t *ctx;
444 513
445 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t)); 514 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
446 if (ctx == NULL) { 515 if (ctx == NULL) {
447 return NGX_ERROR; 516 return NGX_ERROR;
448 } 517 }
449 518
450 ngx_http_set_ctx(r, ctx, ngx_http_charset_filter_module); 519 ngx_http_set_ctx(r, ctx, ngx_http_charset_filter_module);
451 520
452 ctx->table = charsets[source_charset].tables[charset]; 521 ctx->table = charsets[source_charset].tables[charset];
453 ctx->charset = charset; 522 ctx->charset = charset;
523 ctx->charset_name = charsets[charset].name;
454 ctx->length = charsets[charset].length; 524 ctx->length = charsets[charset].length;
455 ctx->from_utf8 = charsets[source_charset].utf8; 525 ctx->from_utf8 = charsets[source_charset].utf8;
456 ctx->to_utf8 = charsets[charset].utf8; 526 ctx->to_utf8 = charsets[charset].utf8;
457 527
458 r->filter_need_in_memory = 1; 528 r->filter_need_in_memory = 1;
1336 value = cf->args->elts; 1406 value = cf->args->elts;
1337 1407
1338 if (cmd->offset == offsetof(ngx_http_charset_loc_conf_t, charset) 1408 if (cmd->offset == offsetof(ngx_http_charset_loc_conf_t, charset)
1339 && ngx_strcmp(value[1].data, "off") == 0) 1409 && ngx_strcmp(value[1].data, "off") == 0)
1340 { 1410 {
1341 *cp = NGX_HTTP_NO_CHARSET; 1411 *cp = NGX_HTTP_CHARSET_OFF;
1342 return NGX_CONF_OK; 1412 return NGX_CONF_OK;
1343 } 1413 }
1344 1414
1345 1415
1346 if (value[1].data[0] == '$') { 1416 if (value[1].data[0] == '$') {
1416 { 1486 {
1417 ngx_http_charset_main_conf_t *mcf; 1487 ngx_http_charset_main_conf_t *mcf;
1418 1488
1419 mcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_main_conf_t)); 1489 mcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_main_conf_t));
1420 if (mcf == NULL) { 1490 if (mcf == NULL) {
1421 return NGX_CONF_ERROR; 1491 return NULL;
1422 } 1492 }
1423 1493
1424 if (ngx_array_init(&mcf->charsets, cf->pool, 2, sizeof(ngx_http_charset_t)) 1494 if (ngx_array_init(&mcf->charsets, cf->pool, 2, sizeof(ngx_http_charset_t))
1425 != NGX_OK) 1495 != NGX_OK)
1426 { 1496 {
1427 return NGX_CONF_ERROR; 1497 return NULL;
1428 } 1498 }
1429 1499
1430 if (ngx_array_init(&mcf->tables, cf->pool, 1, 1500 if (ngx_array_init(&mcf->tables, cf->pool, 1,
1431 sizeof(ngx_http_charset_tables_t)) 1501 sizeof(ngx_http_charset_tables_t))
1432 != NGX_OK) 1502 != NGX_OK)
1433 { 1503 {
1434 return NGX_CONF_ERROR; 1504 return NULL;
1435 } 1505 }
1436 1506
1437 if (ngx_array_init(&mcf->recodes, cf->pool, 2, 1507 if (ngx_array_init(&mcf->recodes, cf->pool, 2,
1438 sizeof(ngx_http_charset_recode_t)) 1508 sizeof(ngx_http_charset_recode_t))
1439 != NGX_OK) 1509 != NGX_OK)
1440 { 1510 {
1441 return NGX_CONF_ERROR; 1511 return NULL;
1442 } 1512 }
1443 1513
1444 return mcf; 1514 return mcf;
1445 } 1515 }
1446 1516
1450 { 1520 {
1451 ngx_http_charset_loc_conf_t *lcf; 1521 ngx_http_charset_loc_conf_t *lcf;
1452 1522
1453 lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_loc_conf_t)); 1523 lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_loc_conf_t));
1454 if (lcf == NULL) { 1524 if (lcf == NULL) {
1455 return NGX_CONF_ERROR; 1525 return NULL;
1456 } 1526 }
1457 1527
1458 /* 1528 /*
1459 * set by ngx_pcalloc(): 1529 * set by ngx_pcalloc():
1460 * 1530 *
1487 { 1557 {
1488 return NGX_CONF_ERROR; 1558 return NGX_CONF_ERROR;
1489 } 1559 }
1490 1560
1491 ngx_conf_merge_value(conf->override_charset, prev->override_charset, 0); 1561 ngx_conf_merge_value(conf->override_charset, prev->override_charset, 0);
1492 ngx_conf_merge_value(conf->charset, prev->charset, NGX_HTTP_NO_CHARSET); 1562 ngx_conf_merge_value(conf->charset, prev->charset, NGX_HTTP_CHARSET_OFF);
1493 1563 ngx_conf_merge_value(conf->source_charset, prev->source_charset,
1494 if (conf->source_charset == NGX_CONF_UNSET) { 1564 NGX_HTTP_CHARSET_OFF);
1495 conf->source_charset = prev->source_charset; 1565
1496 } 1566 if (conf->charset == NGX_HTTP_CHARSET_OFF
1497 1567 || conf->source_charset == NGX_HTTP_CHARSET_OFF
1498 if (conf->charset == NGX_HTTP_NO_CHARSET
1499 || conf->source_charset == NGX_CONF_UNSET
1500 || conf->charset == conf->source_charset) 1568 || conf->charset == conf->source_charset)
1501 { 1569 {
1502 return NGX_CONF_OK; 1570 return NGX_CONF_OK;
1503 } 1571 }
1504 1572