платная доработка nginx
Igor Sysoev
is at rambler-co.ru
Wed Jan 28 09:59:11 MSK 2009
On Tue, Jan 27, 2009 at 12:30:43PM +0000, Sergey Bochenkov wrote:
>
> Я, конечно, не знаток, но как тут уже сказали, эта фича порождает много
> философских вопросов, а с технической точки зрения никаких сложностей
> вроде бы нет.
>
> Например, прилагаемый патч должен (если я ничего не забыл) решать вашу проблему.
> Патч для 0.7.32 версии.
Скорее всего, придётся делать именно так, хотя мне этот патч не нравился.
Я хотел отложить ngx_http_discard_request_body() до момента, когда будет ясно,
что тело не нужно, но такого момента нет: в теле ответа может быть ssi,
а откладывать до конца передачи ответа нельзя, так как может быть dead lock:
браузер хочет влитьь нам тело реквеста и не принимает наш ответ.
Единственный момент, POST'ы в статику нельзя делать по умолчанию - это
означает, что в статический сервер можно будет влить кучу одномегабайтных
временных файлов (client_max_body_size 1m при client_body_buffer_size 8k/16k).
Стало быть опять встаёт вопрос об имени директивы:
post_to_static on|off
Варианты ?
> * Dmitry Alekhin <dmitry at ivoho.com> [2009-01-23 04:19:27 +0300]:
>
> > Всем привет,
> >
> > Какое то время назад я поднимал тему о возможности обработки virtual include-ов не GET а POST методом, в случае вызова
> > 'родительского' html-я c SSI POST-ом.
> >
> > Тема как то затухла, и стало непонятно, толи это невозможно из за архитектуры nginx , то ли просто никому кроме меня не нужно.
> > Прошу прощения что пишу в список рассылки, но я готов оплатить разумную стоимость разработки патча для nginx если это возможно.
> > Думаю, квалифицированных разработчиков под nginx - в данном списке рассылке тусуется больше всего.
> > Сам Игорь молчит :)
> >
> > Спасибо,
> >
> > Дмитрий
> >
> > PS - Почта для связи dmitry at ivoho.com
> >
>
> --- src/http/modules/ngx_http_static_module.c 2009-01-16 16:53:08.000000000 +0300
> +++ src/http/modules/ngx_http_static_module.c 2009-01-27 15:11:15.274859288 +0300
> @@ -10,6 +10,7 @@
>
>
> static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r);
> +static void ngx_http_static_body_handler(ngx_http_request_t *r);
> static ngx_int_t ngx_http_static_init(ngx_conf_t *cf);
>
>
> @@ -44,8 +45,8 @@
> };
>
>
> -static ngx_int_t
> -ngx_http_static_handler(ngx_http_request_t *r)
> +static void
> +ngx_http_static_body_handler(ngx_http_request_t *r)
> {
> u_char *last, *location;
> size_t root, len;
> @@ -54,23 +55,10 @@
> ngx_uint_t level;
> ngx_log_t *log;
> ngx_buf_t *b;
> - ngx_chain_t out;
> + ngx_chain_t out, *cl, **ll;
> ngx_open_file_info_t of;
> ngx_http_core_loc_conf_t *clcf;
>
> - if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
> - return NGX_HTTP_NOT_ALLOWED;
> - }
> -
> - if (r->uri.data[r->uri.len - 1] == '/') {
> - return NGX_DECLINED;
> - }
> -
> - /* TODO: Win32 */
> - if (r->zero_in_uri) {
> - return NGX_DECLINED;
> - }
> -
> log = r->connection->log;
>
> /*
> @@ -80,7 +68,8 @@
>
> last = ngx_http_map_uri_to_path(r, &path, &root, 0);
> if (last == NULL) {
> - return NGX_HTTP_INTERNAL_SERVER_ERROR;
> + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
> + return;
> }
>
> path.len = last - path.data;
> @@ -104,7 +93,8 @@
> switch (of.err) {
>
> case 0:
> - return NGX_HTTP_INTERNAL_SERVER_ERROR;
> + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
> + return;
>
> case NGX_ENOENT:
> case NGX_ENOTDIR:
> @@ -132,7 +122,8 @@
> ngx_open_file_n " \"%s\" failed", path.data);
> }
>
> - return rc;
> + ngx_http_finalize_request(r, rc);
> + return;
> }
>
> r->root_tested = !r->error_page;
> @@ -145,7 +136,8 @@
>
> r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
> if (r->headers_out.location == NULL) {
> - return NGX_HTTP_INTERNAL_SERVER_ERROR;
> + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
> + return;
> }
>
> len = r->uri.len + 1;
> @@ -162,7 +154,8 @@
>
> location = ngx_pnalloc(r->pool, len);
> if (location == NULL) {
> - return NGX_HTTP_INTERNAL_SERVER_ERROR;
> + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
> + return;
> }
>
> last = ngx_copy(location, r->uri.data, r->uri.len);
> @@ -183,7 +176,8 @@
> r->headers_out.location->value.len = len;
> r->headers_out.location->value.data = location;
>
> - return NGX_HTTP_MOVED_PERMANENTLY;
> + ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY);
> + return;
> }
>
> #if !(NGX_WIN32) /* the not regular files are probably Unix specific */
> @@ -192,21 +186,36 @@
> ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
> "\"%s\" is not a regular file", path.data);
>
> - return NGX_HTTP_NOT_FOUND;
> + ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
> + return;
> }
>
> #endif
>
> - if (r->method & NGX_HTTP_POST) {
> - return NGX_HTTP_NOT_ALLOWED;
> - }
> + ll = &r->request_body->bufs;
> + cl = *ll;
>
> - rc = ngx_http_discard_request_body(r);
> + for (; cl; cl = cl->next) {
> + b = ngx_alloc_buf(r->pool);
> + if (b == NULL) {
> + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
> + return;
> + }
>
> - if (rc != NGX_OK) {
> - return rc;
> + ngx_memcpy(b, cl->buf, sizeof(ngx_buf_t));
> +
> + *ll = ngx_alloc_chain_link(r->pool);
> + if (*ll == NULL) {
> + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
> + return;
> + }
> +
> + (*ll)->buf = b;
> + ll = &(*ll)->next;
> }
>
> + *ll = NULL;
> +
> log->action = "sending response to client";
>
> r->headers_out.status = NGX_HTTP_OK;
> @@ -214,11 +223,13 @@
> r->headers_out.last_modified_time = of.mtime;
>
> if (ngx_http_set_content_type(r) != NGX_OK) {
> - return NGX_HTTP_INTERNAL_SERVER_ERROR;
> + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
> + return;
> }
>
> if (r != r->main && of.size == 0) {
> - return ngx_http_send_header(r);
> + ngx_http_finalize_request(r, ngx_http_send_header(r));
> + return;
> }
>
> r->allow_ranges = 1;
> @@ -227,18 +238,21 @@
>
> b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
> if (b == NULL) {
> - return NGX_HTTP_INTERNAL_SERVER_ERROR;
> + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
> + return;
> }
>
> b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
> if (b->file == NULL) {
> - return NGX_HTTP_INTERNAL_SERVER_ERROR;
> + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
> + return;
> }
>
> rc = ngx_http_send_header(r);
>
> if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
> - return rc;
> + ngx_http_finalize_request(r, rc);
> + return;
> }
>
> b->file_pos = 0;
> @@ -256,7 +270,44 @@
> out.buf = b;
> out.next = NULL;
>
> - return ngx_http_output_filter(r, &out);
> + ngx_http_finalize_request(r, ngx_http_output_filter(r, &out));
> + return;
> +}
> +
> +
> +static ngx_int_t
> +ngx_http_static_handler(ngx_http_request_t *r)
> +{
> + ngx_int_t rc;
> +
> + if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
> + return NGX_HTTP_NOT_ALLOWED;
> + }
> +
> + if (r->uri.data[r->uri.len - 1] == '/') {
> + return NGX_DECLINED;
> + }
> +
> + /* TODO: Win32 */
> + if (r->zero_in_uri) {
> + return NGX_DECLINED;
> + }
> +
> + if (!(r->method & NGX_HTTP_POST)) {
> + rc = ngx_http_discard_request_body(r);
> +
> + if (rc != NGX_OK) {
> + return rc;
> + }
> + }
> +
> + rc = ngx_http_read_client_request_body(r, ngx_http_static_body_handler);
> +
> + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
> + return rc;
> + }
> +
> + return NGX_DONE;
> }
>
>
> --- src/http/ngx_http_core_module.c 2009-01-21 15:11:22.000000000 +0300
> +++ src/http/ngx_http_core_module.c 2009-01-27 11:56:38.538741816 +0300
> @@ -685,7 +685,7 @@
> };
>
>
> -static ngx_str_t ngx_http_core_get_method = { 3, (u_char *) "GET " };
> +/* static ngx_str_t ngx_http_core_get_method = { 3, (u_char *) "GET " }; */
>
>
> void
> @@ -2020,7 +2020,7 @@
>
> sr->request_body = r->request_body;
>
> - sr->method = NGX_HTTP_GET;
> + sr->method = r->method; /* NGX_HTTP_GET; */
> sr->http_version = r->http_version;
>
> sr->request_line = r->request_line;
> @@ -2038,7 +2038,7 @@
> sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
>
> sr->unparsed_uri = r->unparsed_uri;
> - sr->method_name = ngx_http_core_get_method;
> + sr->method_name = r->method_name; /* ngx_http_core_get_method; */
> sr->http_protocol = r->http_protocol;
>
> if (ngx_http_set_exten(sr) != NGX_OK) {
--
Игорь Сысоев
http://sysoev.ru
More information about the nginx-ru
mailing list