Re: Проблемы с получением request body

Maxim Dounin mdounin at mdounin.ru
Mon Dec 1 15:15:11 UTC 2014


Hello!

On Mon, Dec 01, 2014 at 08:35:35AM -0500, tigran.bayburtsyan wrote:

> Привет.
> Я пишу модуль для Nginx в котором будут обрабатываются POST запросы.
> Нашел несколько opensource проектов в которых тоже обрабатываются запросы
> такого типа.
> Например https://github.com/calio/form-input-nginx-module .
> Сделал этот функционал , но оно работает только на локальной среде. Если
> пробую с какого то online сервера то ответ от Nginx пустой.
> 
> Как я представляю в remote сервере request_body приходит гораздо медленнее
> чем на локале и где то возврашет ответ до исполнения хандлера
> ngx_http_read_client_request_body(r,toxic_post_body_handler).
> Покапал в интернете ничего нет по этой теме. Просмотрел коды у других
> модулей вроде у меня тоже так же. 
> 
> Вот мой код. 

[...]

> static void toxic_post_body_handler(ngx_http_request_t *r)
> {
>     toxic_ctx *ctx;
> 
>     ctx = ngx_http_get_module_ctx(r, ngx_http_toxic_module);
>     ctx->done = 1;
> #if defined(nginx_version) && nginx_version >= 8011
>     r->main->count--;
> #endif
>     /* waiting_more_body my rewrite phase handler */
>     if (ctx->waiting_more_body) {
>         ctx->waiting_more_body = 0;
>         ngx_http_core_run_phases(r->main); // Думаю проблема здесь но не
> представляю что делать
>     }

А зачем вы вообще всё это делаете?

Вызов toxic_post_body_handler() происходит тогда и только тогда, 
когда тело получено.  Ничего уменьшать или звать тут не надо - 
следует обработать тело, отправить ответ, после чего 
финализировать запрос с помощью ngx_http_finalize_request().

[...]

>             rc =
> ngx_http_read_client_request_body(r,toxic_post_body_handler);
>             if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
>                     return rc;
>             }
> 
>             if (rc == NGX_AGAIN) {
>                ctx->waiting_more_body = 1;
>                ngx_http_set_ctx(r, ctx, ngx_http_toxic_module);
>                return NGX_DONE;
>             }

Это неправильно.  Если вы читаете тело, то в случае любого 
положительного ответа от ngx_http_read_client_request_body() 
следует возвращать из обраотчика NGX_DONE.  А всю работу - делать 
в обработчике тела, так:

    rc = ngx_http_read_client_request_body(r, handler);

    if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
        return rc;
    }

    return NGX_DONE;

-- 
Maxim Dounin
http://nginx.org/



Подробная информация о списке рассылки nginx-ru