Кстати, об основополагающем вопросе... Это число, наверно, следующее по количеству упоминаний после фразы "Hello world" и foo-bar-baz в различных тюториалах по программированию. Когда-то я перевел отрывок из книги, в котором рассказывается о его истории, на русский. Вот от.
В целом, Дугласа Адамса, наверно, стоит почитать каждому -- в нем столько злободневного и в то же время вечного...
2009-04-11
2009-04-05
correcting Transfer-encoding:chunked problem in nginx
While Igor Sysoev is thinking on how to properly (i.e. robustly and efficiently) implement handling of Content-encoding:chunked with unset Content-Length in nginx, I needed to hack a quick workaround (for those, who need it "here and now"). I decided to post it here for those who may need it:
In the mean time I've sorted out for myself the server's internals. What can I say? First of all the event-driven architecture is complicated. Especially, when there's no high-level description, who is calling what. And especially under virtually complete absence of comments in the code.
And about C and Lisp (based on examining the source of the two HTTP-servers: nginx and Hunchentoot). Lisp is clay, shape whatever you want with all the connected advantages and shortcomings. C... There's a children's construction set from metal bars and corners. It's fun to play with them. And, generally, everything is quite clear, it's possible to assemble good, solid constructions. But making a vase with rounded corners — it's for the geeks...
--- old/ngx_http_request.c 2009-04-05 20:41:18.000000000 +0300
+++ new/ngx_http_request.c 2009-04-05 20:38:33.000000000 +0300
@@ -1403,16 +1403,6 @@
return NGX_ERROR;
}
- if (r->headers_in.transfer_encoding
- && ngx_strcasestrn(r->headers_in.transfer_encoding->value.data,
- "chunked", 7 - 1))
- {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent \"Transfer-Encoding: chunked\" header");
- ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
- return NGX_ERROR;
- }
-
if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
if (r->headers_in.keep_alive) {
r->headers_in.keep_alive_n =
--- old/ngx_http_request_body.c 2009-04-05 20:41:39.000000000 +0300
+++ new/ngx_http_request_body.c 2009-04-05 20:34:45.000000000 +0300
@@ -54,11 +54,6 @@
r->request_body = rb;
- if (r->headers_in.content_length_n < 0) {
- post_handler(r);
- return NGX_OK;
- }
-
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (r->headers_in.content_length_n == 0) {
@@ -180,7 +175,8 @@
} else {
b = NULL;
- rb->rest = r->headers_in.content_length_n;
+ rb->rest = r->headers_in.content_length_n >= 0 ? r->headers_in.content_length_n
+ : NGX_MAX_SIZE_T_VALUE;
next = &rb->bufs;
}
In the mean time I've sorted out for myself the server's internals. What can I say? First of all the event-driven architecture is complicated. Especially, when there's no high-level description, who is calling what. And especially under virtually complete absence of comments in the code.
And about C and Lisp (based on examining the source of the two HTTP-servers: nginx and Hunchentoot). Lisp is clay, shape whatever you want with all the connected advantages and shortcomings. C... There's a children's construction set from metal bars and corners. It's fun to play with them. And, generally, everything is quite clear, it's possible to assemble good, solid constructions. But making a vase with rounded corners — it's for the geeks...
исправляем проблему с Transfer-encoding:chunked в nginx
Пока Игорь Сысоев думает над тем, как правильно (т.е. надежно и быстродейственно) реализовать обработку Content-encoding:chunked при не заданной Content-Length в nginx, мне пришлось сделать workaround (для тех, кому это нужно "здесь и сейчас"). Решил его выложить, может, кому-то кроме меня это тоже будет нужно:
Мимоходом, разобрался немного во внутренностях этого сервера. Что можно сказать? Во-первых, event-driven архитектура — это сложно. Особенно, когда нет общего описания, кто кого вызывает. И особенно при почти полном отсутствии комментариев в коде.
Ну и про С и Lisp (по итогам копания в коде двух HTTP-серверов: nginx и Hunchentoot). Lisp — это глина, лепи себе, что заблагорассудится, со всеми вытекающими плюсами и минусами. C... Есть такие конструторы из металлических планок и уголков. Интересно с ними играться. И, в общем-то, довольно понятно все, можно собрать хорошие, надежные конструкции. Но вот сделать из этого какую-нибудь вазу с закругленными углами — это для фанатов...
--- old/ngx_http_request.c 2009-04-05 20:41:18.000000000 +0300
+++ new/ngx_http_request.c 2009-04-05 20:38:33.000000000 +0300
@@ -1403,16 +1403,6 @@
return NGX_ERROR;
}
- if (r->headers_in.transfer_encoding
- && ngx_strcasestrn(r->headers_in.transfer_encoding->value.data,
- "chunked", 7 - 1))
- {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent \"Transfer-Encoding: chunked\" header");
- ngx_http_finalize_request(r, NGX_HTTP_LENGTH_REQUIRED);
- return NGX_ERROR;
- }
-
if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
if (r->headers_in.keep_alive) {
r->headers_in.keep_alive_n =
--- old/ngx_http_request_body.c 2009-04-05 20:41:39.000000000 +0300
+++ new/ngx_http_request_body.c 2009-04-05 20:34:45.000000000 +0300
@@ -54,11 +54,6 @@
r->request_body = rb;
- if (r->headers_in.content_length_n < 0) {
- post_handler(r);
- return NGX_OK;
- }
-
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
if (r->headers_in.content_length_n == 0) {
@@ -180,7 +175,8 @@
} else {
b = NULL;
- rb->rest = r->headers_in.content_length_n;
+ rb->rest = r->headers_in.content_length_n >= 0 ? r->headers_in.content_length_n
+ : NGX_MAX_SIZE_T_VALUE;
next = &rb->bufs;
}
Мимоходом, разобрался немного во внутренностях этого сервера. Что можно сказать? Во-первых, event-driven архитектура — это сложно. Особенно, когда нет общего описания, кто кого вызывает. И особенно при почти полном отсутствии комментариев в коде.
Ну и про С и Lisp (по итогам копания в коде двух HTTP-серверов: nginx и Hunchentoot). Lisp — это глина, лепи себе, что заблагорассудится, со всеми вытекающими плюсами и минусами. C... Есть такие конструторы из металлических планок и уголков. Интересно с ними играться. И, в общем-то, довольно понятно все, можно собрать хорошие, надежные конструкции. Но вот сделать из этого какую-нибудь вазу с закругленными углами — это для фанатов...