Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: IE7 bug / force response to HTTP/1.0
On Mon, Apr 21, 2008 at 03:44:41PM +0400, Andrew V. Statsenko wrote:
> Коллеги, очень похоже, что наступил за замечательные грабли с MS IE7, а
> именно:
>
> есть схема:
>
> [Browser]-->[Nginx frontend]-->[Apache backend]
>
> Иногда, для отчетов apache должен отдавать "Content-Type:
> application/vnd.ms-excel" и далее динамически формируемые CSV данные для
> клиента. Если apache отдает Transfer-Encoding: chunked , то IE7
> предлагает диалог этот файл открыть или сохранить, но при любом выборе
> "загрузить" этот отчет не может, ругаясь на что-то в духе "узел сети не
> может быть найден".
>
> Firefix & Opera успешно работают, ответы (проверено через tcpdump &
> ngrep) все браузеры получают одинаковые.
>
> Проблема на backend решается через форсирование ответа в HTTP/1.0
> примерно такой конструкцией в apache:
>
> SetEnvIf Request_URI exporter nokeepalive downgrade-1.0
> force-response-1.0
>
> и этом случае при обращении IE7 напрямую на backend все работает
> (т.е. ???убираем ???Transfer-Encoding: chunked), но при обращении на
> frontend IE7 опять ломается (на сей раз по всей видимости из-за
> отсутствия Content-Length).
>
> Вопросы:
>
> 1. Возможно ли сконфигурировать nginx, так, чтобы по некоторым localtion
> он форсировал HTTP/1.0 ? То есть _теоретически_ примерно так:
>
> location /
> {
> force_response_to_1_0;
>
> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
> proxy_set_header Host $http_host;
> proxy_pass http://some.backend.host;
>
> }
>
>
> 2. Если (1) невозможно/сложно , то есть ли возможность добавить
> хидер ???Content-Length непосредственно на frontend'е - вычислить эту
> длину самим nginx'ом и вставить хидер ?
>
> 3. Любые другие варианты решения ?
>
>
> P.S.
> Разломать схему frontend-backend не могу. Слишком будет хлопотно.
> Чтобы вычислять ??? ???Content-Length на backend, потребуется _сильно_
> перепиливать генератор отчетов, что _очень_ не хочется делать.
>
> P.S.S.
> По поводу продукции компании MS испытываю массу разнообразнейших эмоций,
> но если кто-нибудь знает, о том, что эту багу можно вылечить на стороне
> браузера (патч, update ?), то был бы безмерно признателен за наводку.
Прилагаемый патч добавляет директиву
chunked_encoding off;
--
Игорь Сысоев
http://sysoev.ru
Index: src/http/ngx_http_core_module.c
===================================================================
--- src/http/ngx_http_core_module.c (revision 1293)
+++ src/http/ngx_http_core_module.c (working copy)
@@ -486,6 +486,13 @@
offsetof(ngx_http_core_loc_conf_t, msie_refresh),
NULL },
+ { ngx_string("chunked_encoding"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, chunked_encoding),
+ NULL },
+
{ ngx_string("log_not_found"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
@@ -2717,6 +2724,7 @@
lcf->port_in_redirect = NGX_CONF_UNSET;
lcf->msie_padding = NGX_CONF_UNSET;
lcf->msie_refresh = NGX_CONF_UNSET;
+ lcf->chunked_encoding = NGX_CONF_UNSET;
lcf->log_not_found = NGX_CONF_UNSET;
lcf->recursive_error_pages = NGX_CONF_UNSET;
lcf->server_tokens = NGX_CONF_UNSET;
@@ -2938,6 +2946,7 @@
ngx_conf_merge_value(conf->port_in_redirect, prev->port_in_redirect, 1);
ngx_conf_merge_value(conf->msie_padding, prev->msie_padding, 1);
ngx_conf_merge_value(conf->msie_refresh, prev->msie_refresh, 0);
+ ngx_conf_merge_value(conf->chunked_encoding, prev->chunked_encoding, 1);
ngx_conf_merge_value(conf->log_not_found, prev->log_not_found, 1);
ngx_conf_merge_value(conf->recursive_error_pages,
prev->recursive_error_pages, 0);
Index: src/http/ngx_http_core_module.h
===================================================================
--- src/http/ngx_http_core_module.h (revision 1293)
+++ src/http/ngx_http_core_module.h (working copy)
@@ -302,6 +302,7 @@
ngx_flag_t port_in_redirect; /* port_in_redirect */
ngx_flag_t msie_padding; /* msie_padding */
ngx_flag_t msie_refresh; /* msie_refresh */
+ ngx_flag_t chunked_encoding; /* chunked_encoding */
ngx_flag_t log_not_found; /* log_not_found */
ngx_flag_t recursive_error_pages; /* recursive_error_pages */
ngx_flag_t server_tokens; /* server_tokens */
Index: src/http/modules/ngx_http_chunked_filter_module.c
===================================================================
--- src/http/modules/ngx_http_chunked_filter_module.c (revision 1293)
+++ src/http/modules/ngx_http_chunked_filter_module.c (working copy)
@@ -50,6 +50,8 @@
static ngx_int_t
ngx_http_chunked_header_filter(ngx_http_request_t *r)
{
+ ngx_http_core_loc_conf_t *clcf;
+
if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED
|| r->headers_out.status == NGX_HTTP_NO_CONTENT
|| r->headers_out.status == NGX_HTTP_CREATED
@@ -58,6 +60,12 @@
return ngx_http_next_header_filter(r);
}
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (clcf->chunked_encoding == 0) {
+ return ngx_http_next_header_filter(r);
+ }
+
if (r->headers_out.content_length_n == -1) {
if (r->http_version < NGX_HTTP_VERSION_11) {
r->keepalive = 0;
|