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 }