ngx_http_charset_module supports the variables
Igor Sysoev
15 years ago
9 | 9 | |
10 | 10 | |
11 | 11 | #define NGX_HTTP_NO_CHARSET -2 |
12 | #define NGX_HTTP_CHARSET_VAR 0x10000 | |
12 | 13 | |
13 | 14 | /* 1 byte length and up to 3 bytes for the UTF-8 encoding of the UCS-2 */ |
14 | 15 | #define NGX_UTF_LEN 4 |
78 | 79 | |
79 | 80 | |
80 | 81 | static ngx_int_t ngx_http_charset_get_charset(ngx_http_charset_t *charsets, |
81 | ngx_uint_t n, u_char *charset); | |
82 | ngx_uint_t n, ngx_str_t *charset); | |
82 | 83 | static ngx_int_t ngx_http_charset_set_charset(ngx_http_request_t *r, |
83 | 84 | ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset); |
84 | 85 | static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, u_char *table); |
189 | 190 | ngx_uint_t n; |
190 | 191 | ngx_http_charset_t *charsets; |
191 | 192 | ngx_http_charset_ctx_t *ctx; |
193 | ngx_http_variable_value_t *vv; | |
192 | 194 | ngx_http_charset_loc_conf_t *lcf, *mlcf; |
193 | 195 | ngx_http_charset_main_conf_t *mcf; |
194 | 196 | |
209 | 211 | && r->headers_out.override_charset->len) |
210 | 212 | { |
211 | 213 | charset = ngx_http_charset_get_charset(charsets, n, |
212 | r->headers_out.override_charset->data); | |
214 | r->headers_out.override_charset); | |
213 | 215 | |
214 | 216 | if (charset == NGX_HTTP_NO_CHARSET) { |
215 | 217 | ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
242 | 244 | return ngx_http_next_header_filter(r); |
243 | 245 | } |
244 | 246 | } |
247 | ||
248 | if (charset >= NGX_HTTP_CHARSET_VAR) { | |
249 | vv = ngx_http_get_indexed_variable(r, | |
250 | charset - NGX_HTTP_CHARSET_VAR); | |
251 | ||
252 | charset = ngx_http_charset_get_charset(charsets, n, | |
253 | (ngx_str_t *) vv); | |
254 | } | |
245 | 255 | } |
246 | 256 | |
247 | 257 | } else { |
262 | 272 | |
263 | 273 | ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module); |
264 | 274 | |
265 | charset = ngx_http_charset_get_charset(charsets, n, mc->data); | |
275 | charset = ngx_http_charset_get_charset(charsets, n, mc); | |
266 | 276 | |
267 | 277 | ctx->charset = charset; |
268 | 278 | |
276 | 286 | if (r->headers_out.charset.len == 0) { |
277 | 287 | lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module); |
278 | 288 | |
289 | source_charset = lcf->source_charset; | |
290 | ||
291 | if (source_charset >= NGX_HTTP_CHARSET_VAR) { | |
292 | vv = ngx_http_get_indexed_variable(r, | |
293 | source_charset - NGX_HTTP_CHARSET_VAR); | |
294 | ||
295 | source_charset = ngx_http_charset_get_charset(charsets, n, | |
296 | (ngx_str_t *) vv); | |
297 | } | |
298 | ||
279 | 299 | if (charset != NGX_HTTP_NO_CHARSET) { |
280 | 300 | return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset, |
281 | lcf->source_charset); | |
282 | } | |
283 | ||
284 | if (lcf->source_charset == NGX_CONF_UNSET) { | |
301 | source_charset); | |
302 | } | |
303 | ||
304 | if (source_charset == NGX_CONF_UNSET) { | |
285 | 305 | return ngx_http_next_header_filter(r); |
286 | 306 | } |
287 | 307 | |
288 | from = &charsets[lcf->source_charset].name; | |
308 | from = &charsets[source_charset].name; | |
289 | 309 | to = &r->main->headers_out.charset; |
290 | 310 | |
291 | 311 | goto no_charset_map; |
292 | 312 | } |
293 | 313 | |
294 | 314 | source_charset = ngx_http_charset_get_charset(charsets, n, |
295 | r->headers_out.charset.data); | |
315 | &r->headers_out.charset); | |
296 | 316 | |
297 | 317 | if (charset == NGX_HTTP_NO_CHARSET |
298 | 318 | || source_charset == NGX_HTTP_NO_CHARSET) |
340 | 360 | |
341 | 361 | static ngx_int_t |
342 | 362 | ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n, |
343 | u_char *charset) | |
344 | { | |
363 | ngx_str_t *charset) | |
364 | { | |
365 | size_t len; | |
345 | 366 | ngx_uint_t i; |
346 | 367 | |
368 | len = charset->len & 0xffff; | |
369 | ||
347 | 370 | for (i = 0; i < n; i++) { |
348 | if (ngx_strcasecmp(charsets[i].name.data, charset) == 0) { | |
371 | if (charsets[i].name.len != len) { | |
372 | continue; | |
373 | } | |
374 | ||
375 | if (ngx_strncasecmp(charsets[i].name.data, charset->data, len) == 0) { | |
349 | 376 | return i; |
350 | 377 | } |
351 | 378 | } |
1260 | 1287 | char *p = conf; |
1261 | 1288 | |
1262 | 1289 | ngx_int_t *cp; |
1263 | ngx_str_t *value; | |
1290 | ngx_str_t *value, var; | |
1264 | 1291 | ngx_http_charset_main_conf_t *mcf; |
1265 | 1292 | |
1266 | 1293 | cp = (ngx_int_t *) (p + cmd->offset); |
1275 | 1302 | && ngx_strcmp(value[1].data, "off") == 0) |
1276 | 1303 | { |
1277 | 1304 | *cp = NGX_HTTP_NO_CHARSET; |
1305 | return NGX_CONF_OK; | |
1306 | } | |
1307 | ||
1308 | ||
1309 | if (value[1].data[0] == '$') { | |
1310 | var.len = value[1].len - 1; | |
1311 | var.data = value[1].data + 1; | |
1312 | ||
1313 | *cp = ngx_http_get_variable_index(cf, &var); | |
1314 | ||
1315 | if (*cp == NGX_ERROR) { | |
1316 | return NGX_CONF_ERROR; | |
1317 | } | |
1318 | ||
1319 | *cp += NGX_HTTP_CHARSET_VAR; | |
1320 | ||
1278 | 1321 | return NGX_CONF_OK; |
1279 | 1322 | } |
1280 | 1323 |