Mercurial > hg > nginx
comparison src/http/modules/ngx_http_charset_filter_module.c @ 752:907361d07f25
ngx_http_charset_module supports the variables
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 09 Oct 2006 14:16:36 +0000 |
parents | 7e24168b0853 |
children | 36f7b549f481 |
comparison
equal
deleted
inserted
replaced
751:bae59a740c40 | 752:907361d07f25 |
---|---|
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_NO_CHARSET -2 |
13 #define NGX_HTTP_CHARSET_VAR 0x10000 | |
13 | 14 |
14 /* 1 byte length and up to 3 bytes for the UTF-8 encoding of the UCS-2 */ | 15 /* 1 byte length and up to 3 bytes for the UTF-8 encoding of the UCS-2 */ |
15 #define NGX_UTF_LEN 4 | 16 #define NGX_UTF_LEN 4 |
16 | 17 |
17 #define NGX_HTML_ENTITY_LEN (sizeof("") - 1) | 18 #define NGX_HTML_ENTITY_LEN (sizeof("") - 1) |
77 ngx_uint_t characters; | 78 ngx_uint_t characters; |
78 } ngx_http_charset_conf_ctx_t; | 79 } ngx_http_charset_conf_ctx_t; |
79 | 80 |
80 | 81 |
81 static ngx_int_t ngx_http_charset_get_charset(ngx_http_charset_t *charsets, | 82 static ngx_int_t ngx_http_charset_get_charset(ngx_http_charset_t *charsets, |
82 ngx_uint_t n, u_char *charset); | 83 ngx_uint_t n, ngx_str_t *charset); |
83 static ngx_int_t ngx_http_charset_set_charset(ngx_http_request_t *r, | 84 static ngx_int_t ngx_http_charset_set_charset(ngx_http_request_t *r, |
84 ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset); | 85 ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset); |
85 static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, u_char *table); | 86 static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, u_char *table); |
86 static ngx_chain_t *ngx_http_charset_recode_from_utf8(ngx_pool_t *pool, | 87 static ngx_chain_t *ngx_http_charset_recode_from_utf8(ngx_pool_t *pool, |
87 ngx_buf_t *buf, ngx_http_charset_ctx_t *ctx); | 88 ngx_buf_t *buf, ngx_http_charset_ctx_t *ctx); |
188 ngx_int_t charset, source_charset; | 189 ngx_int_t charset, source_charset; |
189 ngx_str_t *mc, *from, *to; | 190 ngx_str_t *mc, *from, *to; |
190 ngx_uint_t n; | 191 ngx_uint_t n; |
191 ngx_http_charset_t *charsets; | 192 ngx_http_charset_t *charsets; |
192 ngx_http_charset_ctx_t *ctx; | 193 ngx_http_charset_ctx_t *ctx; |
194 ngx_http_variable_value_t *vv; | |
193 ngx_http_charset_loc_conf_t *lcf, *mlcf; | 195 ngx_http_charset_loc_conf_t *lcf, *mlcf; |
194 ngx_http_charset_main_conf_t *mcf; | 196 ngx_http_charset_main_conf_t *mcf; |
195 | 197 |
196 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); | 198 mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module); |
197 | 199 |
208 | 210 |
209 if (r->headers_out.override_charset | 211 if (r->headers_out.override_charset |
210 && r->headers_out.override_charset->len) | 212 && r->headers_out.override_charset->len) |
211 { | 213 { |
212 charset = ngx_http_charset_get_charset(charsets, n, | 214 charset = ngx_http_charset_get_charset(charsets, n, |
213 r->headers_out.override_charset->data); | 215 r->headers_out.override_charset); |
214 | 216 |
215 if (charset == NGX_HTTP_NO_CHARSET) { | 217 if (charset == NGX_HTTP_NO_CHARSET) { |
216 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 218 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
217 "unknown charset \"%V\" to override", | 219 "unknown charset \"%V\" to override", |
218 r->headers_out.override_charset); | 220 r->headers_out.override_charset); |
241 && ngx_strncasecmp(ct, "application/x-javascript", 24) != 0) | 243 && ngx_strncasecmp(ct, "application/x-javascript", 24) != 0) |
242 { | 244 { |
243 return ngx_http_next_header_filter(r); | 245 return ngx_http_next_header_filter(r); |
244 } | 246 } |
245 } | 247 } |
248 | |
249 if (charset >= NGX_HTTP_CHARSET_VAR) { | |
250 vv = ngx_http_get_indexed_variable(r, | |
251 charset - NGX_HTTP_CHARSET_VAR); | |
252 | |
253 charset = ngx_http_charset_get_charset(charsets, n, | |
254 (ngx_str_t *) vv); | |
255 } | |
246 } | 256 } |
247 | 257 |
248 } else { | 258 } else { |
249 ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module); | 259 ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module); |
250 | 260 |
261 return NGX_ERROR; | 271 return NGX_ERROR; |
262 } | 272 } |
263 | 273 |
264 ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module); | 274 ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module); |
265 | 275 |
266 charset = ngx_http_charset_get_charset(charsets, n, mc->data); | 276 charset = ngx_http_charset_get_charset(charsets, n, mc); |
267 | 277 |
268 ctx->charset = charset; | 278 ctx->charset = charset; |
269 | 279 |
270 } else { | 280 } else { |
271 charset = ctx->charset; | 281 charset = ctx->charset; |
275 /* source charset */ | 285 /* source charset */ |
276 | 286 |
277 if (r->headers_out.charset.len == 0) { | 287 if (r->headers_out.charset.len == 0) { |
278 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); | 288 lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); |
279 | 289 |
290 source_charset = lcf->source_charset; | |
291 | |
292 if (source_charset >= NGX_HTTP_CHARSET_VAR) { | |
293 vv = ngx_http_get_indexed_variable(r, | |
294 source_charset - NGX_HTTP_CHARSET_VAR); | |
295 | |
296 source_charset = ngx_http_charset_get_charset(charsets, n, | |
297 (ngx_str_t *) vv); | |
298 } | |
299 | |
280 if (charset != NGX_HTTP_NO_CHARSET) { | 300 if (charset != NGX_HTTP_NO_CHARSET) { |
281 return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset, | 301 return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset, |
282 lcf->source_charset); | 302 source_charset); |
283 } | 303 } |
284 | 304 |
285 if (lcf->source_charset == NGX_CONF_UNSET) { | 305 if (source_charset == NGX_CONF_UNSET) { |
286 return ngx_http_next_header_filter(r); | 306 return ngx_http_next_header_filter(r); |
287 } | 307 } |
288 | 308 |
289 from = &charsets[lcf->source_charset].name; | 309 from = &charsets[source_charset].name; |
290 to = &r->main->headers_out.charset; | 310 to = &r->main->headers_out.charset; |
291 | 311 |
292 goto no_charset_map; | 312 goto no_charset_map; |
293 } | 313 } |
294 | 314 |
295 source_charset = ngx_http_charset_get_charset(charsets, n, | 315 source_charset = ngx_http_charset_get_charset(charsets, n, |
296 r->headers_out.charset.data); | 316 &r->headers_out.charset); |
297 | 317 |
298 if (charset == NGX_HTTP_NO_CHARSET | 318 if (charset == NGX_HTTP_NO_CHARSET |
299 || source_charset == NGX_HTTP_NO_CHARSET) | 319 || source_charset == NGX_HTTP_NO_CHARSET) |
300 { | 320 { |
301 if (charset != source_charset | 321 if (charset != source_charset |
339 } | 359 } |
340 | 360 |
341 | 361 |
342 static ngx_int_t | 362 static ngx_int_t |
343 ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n, | 363 ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n, |
344 u_char *charset) | 364 ngx_str_t *charset) |
345 { | 365 { |
366 size_t len; | |
346 ngx_uint_t i; | 367 ngx_uint_t i; |
347 | 368 |
369 len = charset->len & 0xffff; | |
370 | |
348 for (i = 0; i < n; i++) { | 371 for (i = 0; i < n; i++) { |
349 if (ngx_strcasecmp(charsets[i].name.data, charset) == 0) { | 372 if (charsets[i].name.len != len) { |
373 continue; | |
374 } | |
375 | |
376 if (ngx_strncasecmp(charsets[i].name.data, charset->data, len) == 0) { | |
350 return i; | 377 return i; |
351 } | 378 } |
352 } | 379 } |
353 | 380 |
354 return NGX_HTTP_NO_CHARSET; | 381 return NGX_HTTP_NO_CHARSET; |
1259 ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 1286 ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
1260 { | 1287 { |
1261 char *p = conf; | 1288 char *p = conf; |
1262 | 1289 |
1263 ngx_int_t *cp; | 1290 ngx_int_t *cp; |
1264 ngx_str_t *value; | 1291 ngx_str_t *value, var; |
1265 ngx_http_charset_main_conf_t *mcf; | 1292 ngx_http_charset_main_conf_t *mcf; |
1266 | 1293 |
1267 cp = (ngx_int_t *) (p + cmd->offset); | 1294 cp = (ngx_int_t *) (p + cmd->offset); |
1268 | 1295 |
1269 if (*cp != NGX_CONF_UNSET) { | 1296 if (*cp != NGX_CONF_UNSET) { |
1274 | 1301 |
1275 if (cmd->offset == offsetof(ngx_http_charset_loc_conf_t, charset) | 1302 if (cmd->offset == offsetof(ngx_http_charset_loc_conf_t, charset) |
1276 && ngx_strcmp(value[1].data, "off") == 0) | 1303 && ngx_strcmp(value[1].data, "off") == 0) |
1277 { | 1304 { |
1278 *cp = NGX_HTTP_NO_CHARSET; | 1305 *cp = NGX_HTTP_NO_CHARSET; |
1306 return NGX_CONF_OK; | |
1307 } | |
1308 | |
1309 | |
1310 if (value[1].data[0] == '$') { | |
1311 var.len = value[1].len - 1; | |
1312 var.data = value[1].data + 1; | |
1313 | |
1314 *cp = ngx_http_get_variable_index(cf, &var); | |
1315 | |
1316 if (*cp == NGX_ERROR) { | |
1317 return NGX_CONF_ERROR; | |
1318 } | |
1319 | |
1320 *cp += NGX_HTTP_CHARSET_VAR; | |
1321 | |
1279 return NGX_CONF_OK; | 1322 return NGX_CONF_OK; |
1280 } | 1323 } |
1281 | 1324 |
1282 mcf = ngx_http_conf_get_module_main_conf(cf, | 1325 mcf = ngx_http_conf_get_module_main_conf(cf, |
1283 ngx_http_charset_filter_module); | 1326 ngx_http_charset_filter_module); |