платная доработка nginx

Igor Sysoev is at rambler-co.ru
Wed Jan 28 14:21:25 MSK 2009


On Wed, Jan 28, 2009 at 10:56:51AM +0000, Valery Kholodkov wrote:

> 
> "Igor Sysoev" <is at rambler-co.ru> wrote:
> 
> > Скорее всего, придётся делать именно так, хотя мне этот патч не
> > нравился.
> > Я хотел отложить ngx_http_discard_request_body() до момента, когда
> > будет ясно,
> > что тело не нужно, но такого момента нет: в теле ответа может быть
> > ssi,
> > а откладывать до конца передачи ответа нельзя, так как может быть dead
> > lock:
> > браузер хочет влитьь нам тело реквеста и не принимает наш ответ.
> 
> Думаю, что нужно завести фазу приема тела запроса, а вместо функции ngx_http_output_filter завести функцию, которая помещает переданные ей буферы в очередь в ngx_http_request_t и отдает NGX_OK.

ngx_http_output_filter() только в случае статики передаёт файловый буфер
однократно. В случае прокси/fastcgi ngx_http_output_filter() вызывается
по мере получения данных от бэкенда.

> Фаза приема тела запроса выполнит либо ngx_http_read_client_request_body, либо ngx_http_discard_request_body в зависимости от флага, и в случае ngx_http_read_client_request_body отдаст код 
> 
> {
>     ngx_http_finalize_request(r, ngx_http_output_filter(r, r->queue));
> }
> 
> в качестве post_handler. В таком случае все модули на content-фазе подвергнуться минимальным изменениям.

В смысле - фаза приёма тела вызывается после контентной ?
А как быть с телом для проксирования и прочая ?
Но даже, если вызывать после контента - неизвестно, что в теле -
есть SSI или нет.

> > Единственный момент, POST'ы в статику нельзя делать по умолчанию -
> > это
> > означает, что в статический сервер можно будет влить кучу
> > одномегабайтных
> > временных файлов (client_max_body_size 1m при client_body_buffer_size
> > 8k/16k).
> > Стало быть опять встаёт вопрос об имени директивы:
> > 
> > post_to_static on|off
> > 
> > Варианты ?
> 
> static_post 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
> 
> -- 
> Regards,
> Valery Kholodkov

-- 
Игорь Сысоев
http://sysoev.ru





More information about the nginx-ru mailing list