comparison src/http/modules/ngx_http_charset_filter_module.c @ 244:500a3242dff6 NGINX_0_4_7

nginx 0.4.7 *) Feature: the ngx_http_flv_module. *) Feature: the $request_body_file variable. *) Feature: the "charset" and "source_charset" directives support the variables. *) Bugfix: if an "include" SSI command were before another "include" SSI command with an "wait" parameter, then the "wait" parameter might not work. *) Bugfix: if the "proxy_buffering off" directive was used or while working with memcached the connections might not be closed on timeout. *) Bugfix: nginx did not run on 64-bit platforms except amd64, sparc64, and ppc64.
author Igor Sysoev <http://sysoev.ru>
date Tue, 10 Oct 2006 00:00:00 +0400
parents 38e7b94d63ac
children fbf2b2f66c9f
comparison
equal deleted inserted replaced
243:d371c9d33781 244:500a3242dff6
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("&#1114111;") - 1) 18 #define NGX_HTML_ENTITY_LEN (sizeof("&#1114111;") - 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);