Nginx-ru mailing list archive (nginx-ru@sysoev.ru)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: implicit *LWS ?
On Wed, Oct 06, 2010 at 05:42:29PM +0400, Maxim Dounin wrote:
> >
> > то есть nginx при проксировании обрезал весь контент поля начиная с CRLF.
> >
> > То же самое происходит если пытаться передавать запрос на fastcgi backend,
> > в параметре HTTP_ACCEPT я вижу только text/plain, text/html, но не */*.
> > С другими хидерами происходит то же самое - как только встречается LWS -
> > поле "обрезается", что для proxy_pass, что для fastcgi_pass.
> >
> > Вопрос: это бага или фича ? Если фича - обойти как-нибудь можно ?
>
> Это фича, LWS не поддерживаются, да и в HTTPbis они deprecated.
thanks.
Хотя, jimho, не поддерживать deprecated и not recommended headers - это
все-таки нарушение robustness principle (be liberal in what you accept).
> Если очень нужно чтобы заработало вот прям здесь и сейчас -
> где-то в районе nginx@ пробегал патч, но он ужасненький:
"Он хуже, он просто кю!".
> http://nginx.org/pipermail/nginx/2010-September/022608.html
См. аттач. Это пока "концепт-кар", толком не оттестированный, но, jimho,
более правильный.
Куда пришлось залезть:
а) изменить state-машину парсера заголовков для проверки LWS,
с добавлением (новой) точки выхода - incomplete (в случаях когда
буфера не хватает для read-ahead)
б) изменить логику чтения запроса, разрешив чтение в случае когда
буферизовано менее двух байт.
> А что за чудо генерит такие запросы?
Одно доморощенное чудо когда-то решило, что User-Agent стоит
разбить на две строки, "ведь это ж rfc!!" :) А когда встал вопрос
о том, а можем ли мы делать content-switching по версии агента -
эта грабель и вылезла.
--
In theory, there is no difference between theory and practice.
But, in practice, there is.
--- src/http/ngx_http_parse.c.orig 2010-10-06 21:37:13.000000000 +0400
+++ src/http/ngx_http_parse.c 2010-10-07 15:48:33.000000000 +0400
@@ -909,11 +909,38 @@
break;
case CR:
r->header_end = p;
- state = sw_almost_done;
+ if ( p + 2 >= b->last )
+ goto incomplete;
+ if (p[1] == LF) {
+ if (p[2] == ' ' || p[2] == '\t') {
+ /* Linear whitespace, changing CRLF into SP SP */
+ p[0] = p[1] = ' ';
+ p+=2;
+ state = sw_space_after_value;
+ continue;
+ } else {
+ /* Normal single-line header */
+ p++;
+ goto done;
+ }
+ } else {
+ return NGX_HTTP_PARSE_INVALID_HEADER;
+ };
break;
case LF:
r->header_end = p;
- goto done;
+ if ( p + 1 >= b->last )
+ goto incomplete;
+ if ( p[1] == ' ' || p[1] == '\t' ) {
+ /* Linear whitespace, changing LF to SP */
+ p[0] = ' ';
+ state = sw_space_after_value;
+ p++;
+ continue;
+ } else {
+ /* Normal, non-linear */
+ goto done;
+ };
}
break;
@@ -923,9 +950,36 @@
case ' ':
break;
case CR:
- state = sw_almost_done;
+ if (p + 2 >= b->last)
+ goto incomplete;
+
+ if (p[1] == LF) {
+ if (p[2] == ' ' || p[2] == '\t') {
+ /* Linear whitespace, changing CRLF into SP SP */
+ p[0] = p[1] = ' ';
+ p+=2;
+ continue;
+ } else {
+ /* Normal single-line header */
+ p++;
+ goto done;
+ }
+ } else {
+ return NGX_HTTP_PARSE_INVALID_HEADER;
+ };
break;
case LF:
+ if ( p + 1 >= b->last )
+ goto incomplete;
+ if ( p[1] == ' ' || p[1] == '\t' ) {
+ /* Linear whitespace, changing LF to SP */
+ p[0] = ' ';
+ p++;
+ continue;
+ } else {
+ /* Normal, non-linear */
+ goto done;
+ };
goto done;
default:
state = sw_value;
@@ -967,6 +1021,8 @@
}
}
+incomplete:
+
b->pos = p;
r->state = state;
r->header_hash = hash;
--- src/http/ngx_http_request.c.orig 2010-10-06 21:39:33.000000000 +0400
+++ src/http/ngx_http_request.c 2010-10-07 16:02:22.000000000 +0400
@@ -1118,7 +1118,9 @@
n = r->header_in->last - r->header_in->pos;
- if (n > 0) {
+ /* Return immediately only in case there are more than two bytes
+ * buffered, else LWS readahead will not be able to complete */
+ if (n > 2) {
return n;
}
@@ -1126,6 +1128,10 @@
n = c->recv(c, r->header_in->last,
r->header_in->end - r->header_in->last);
} else {
+ n = r->header_in->last - r->header_in->pos;
+ if (n > 0) {
+ return n;
+ }
n = NGX_AGAIN;
}
_______________________________________________
nginx-ru mailing list
nginx-ru@xxxxxxxxx
http://nginx.org/mailman/listinfo/nginx-ru
|