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

2014-12-01 Thread tigran.bayburtsyan
Привет.
Я пишу модуль для 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).
Покапал в интернете ничего нет по этой теме. Просмотрел коды у других
модулей вроде у меня тоже так же. 

Вот мой код. 

#include 
#include 
#include 
#include 

... // Еше несколько 

typedef struct {
char *key;
void(*callback)(const char *str, unsigned int str_length);
} toxic_request_callback;

typedef struct
{
  unsigned done:1;
  unsigned waiting_more_body:1;
  unsigned body_end:1;
} toxic_ctx;


static char *ngx_http_toxic(ngx_conf_t *cf, void *post, void *data);


static ngx_conf_post_handler_pt ngx_http_toxic_p = ngx_http_toxic;

typedef struct {
ngx_str_t   name;
} ngx_http_toxic_loc_conf_t;

static void * ngx_http_toxic_create_loc_conf(ngx_conf_t *cf)
{
ngx_http_toxic_loc_conf_t  *conf;

conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_toxic_loc_conf_t));
if (conf == NULL) {
return NULL;
}

return conf;
}

static ngx_command_t ngx_http_toxic_commands[] = {
{ ngx_string("toxic"),
  NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  ngx_conf_set_str_slot,
  NGX_HTTP_LOC_CONF_OFFSET,
  offsetof(ngx_http_toxic_loc_conf_t, name),
  &ngx_http_toxic_p },

ngx_null_command
};


static ngx_str_t toxic_string;
static ngx_http_module_t ngx_http_toxic_module_ctx = {
NULL,  /* preconfiguration */
NULL,  /* postconfiguration */

NULL,  /* create main configuration */
NULL,  /* init main configuration */

NULL,  /* create server configuration */
NULL,  /* merge server configuration */

ngx_http_toxic_create_loc_conf, /* create location configuration */
NULL   /* merge location configuration */
};


ngx_module_t ngx_http_toxic_module = {
NGX_MODULE_V1,
&ngx_http_toxic_module_ctx,/* module context */
ngx_http_toxic_commands,   /* module directives */
NGX_HTTP_MODULE,   /* module type */
NULL,  /* init master */
NULL,  /* init module */
NULL,  /* init process */
NULL,  /* init thread */
NULL,  /* exit thread */
NULL,  /* exit process */
NULL,  /* exit master */
NGX_MODULE_V1_PADDING
};

static ngx_int_t
ngx_http_toxic_handler(ngx_http_request_t *r);

static ngx_int_t toxic_excecute(ngx_http_request_t *r, char *content_type)
{
char * base_str;
int base_len = 0;

... // функционал с
base_str и base_len 

r->headers_out.content_type_len = strlen(content_type);
r->headers_out.content_type.data = (u_char *) content_type;
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = base_len;
ngx_http_send_header(r);


ngx_buf_t   *b;
ngx_chain_t  *out;
out = ngx_pcalloc(r->pool, sizeof(out));
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
if (b == NULL) {
return 0;
}
out->buf = b;
out->next = NULL;

/* adjust the pointers of the buffer */
b->pos = (u_char*)base_str;
b->last = (u_char*)base_str + base_len;
b->memory = 1;/* this buffer is in memory */
b->last_buf = 1;  /* this is the last buffer in the buffer chain */

/* send the buffer chain of response */
ngx_int_t rc;
rc = ngx_http_output_filter ( r , out );
while( rc == NGX_AGAIN ) {
if( out->next == NULL )
break;
rc = ngx_http_output_filter ( r , out->next );
out = out->next;
}

return NGX_DONE;
}


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); // Думаю проблема здесь но не
представляю что делать
}


// предполагаю что здесь уже весь POST пришел
ngx_buf_t * buf;
ngx_chain_t * chain;
char *post_body= "";
int post_len=0;

Re: Забивается папка проксированных тел

2014-12-01 Thread Maxim Dounin
Hello!

On Sun, Nov 30, 2014 at 05:47:39PM +0400, Anton Kiryushkin wrote:

> Ну не прямо так и называются, но проявляется примерно так:
> 
> 25583852000 lrwx--   1 www-data www-data   64 Nov 30 16:46
> /proc/11733/fd/597 -> /tmp/nginx.client_body_temp/025513\ (deleted)
> 25583855270 lrwx--   1 www-data www-data   64 Nov 30 16:46
> /proc/11733/fd/924 -> /tmp/nginx.client_body_temp/023652\ (deleted)
> 25583866600 lrwx--   1 www-data www-data   64 Nov 30 16:46
> /proc/11733/fd/2057 -> /tmp/nginx.client_body_temp/025516\ (deleted)
> 25583872670 lrwx--   1 www-data www-data   64 Nov 30 16:46
> /proc/11733/fd/2664 -> /tmp/nginx.client_body_temp/020235\ (deleted)

Это временные файлы, которые nginx использует для чтения тела 
запроса, если размер тела превышает client_body_buffer_size. Сами 
файлы удалены, но nginx ещё держит их открытыми - видимо, 
соответствующие запросы пока ещё выполняются.

Само по себе использование временных файлов является штатным 
поведением (в логах при этом будет warning про "a client request 
body is buffered to a temporary file").  Если есть причины думать, 
что что-то происходит нештатно - e.g., файлы не закрываются по 
завершению запроса - имеет смысл начать со сбора информации, 
демонстрирующей проблему.

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

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

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

2014-12-01 Thread Maxim Dounin
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 mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: Забивается папка проксированных тел

2014-12-01 Thread Anton Kiryushkin
Здравствуйте.

Максим, будьте любезны подсказать, как это лучше сделать. Сервер достаточно
нагружен, чтобы включать какой-то отладочный лог.

1 декабря 2014 г., 17:49 пользователь Maxim Dounin 
написал:

> Hello!
>
> On Sun, Nov 30, 2014 at 05:47:39PM +0400, Anton Kiryushkin wrote:
>
> > Ну не прямо так и называются, но проявляется примерно так:
> >
> > 25583852000 lrwx--   1 www-data www-data   64 Nov 30 16:46
> > /proc/11733/fd/597 -> /tmp/nginx.client_body_temp/025513\ (deleted)
> > 25583855270 lrwx--   1 www-data www-data   64 Nov 30 16:46
> > /proc/11733/fd/924 -> /tmp/nginx.client_body_temp/023652\ (deleted)
> > 25583866600 lrwx--   1 www-data www-data   64 Nov 30 16:46
> > /proc/11733/fd/2057 -> /tmp/nginx.client_body_temp/025516\ (deleted)
> > 25583872670 lrwx--   1 www-data www-data   64 Nov 30 16:46
> > /proc/11733/fd/2664 -> /tmp/nginx.client_body_temp/020235\ (deleted)
>
> Это временные файлы, которые nginx использует для чтения тела
> запроса, если размер тела превышает client_body_buffer_size. Сами
> файлы удалены, но nginx ещё держит их открытыми - видимо,
> соответствующие запросы пока ещё выполняются.
>
> Само по себе использование временных файлов является штатным
> поведением (в логах при этом будет warning про "a client request
> body is buffered to a temporary file").  Если есть причины думать,
> что что-то происходит нештатно - e.g., файлы не закрываются по
> завершению запроса - имеет смысл начать со сбора информации,
> демонстрирующей проблему.
>
> --
> Maxim Dounin
> http://nginx.org/
>
> ___
> nginx-ru mailing list
> nginx-ru@nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-ru
>



-- 
Best regards,
Anton Kiryushkin
___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru

Re: Забивается папка проксированных тел

2014-12-01 Thread Maxim Dounin
Hello!

On Mon, Dec 01, 2014 at 07:52:41PM +0400, Anton Kiryushkin wrote:

> Максим, будьте любезны подсказать, как это лучше сделать. Сервер достаточно
> нагружен, чтобы включать какой-то отладочный лог.

Для начала имеет смысл посмотреть на какой-нибудь конкретный файл, 
и убедится, что он действительно в течении долгого времени 
удерживается открытым.  Или, наоборот, убедится, что он 
замечательно удаляется, и проблемы точно нет.

То же самое для многих файлов сразу можно сделать, собрав списоки 
открытых файлов одного процесса через достаточно большой интервал 
времени (больше, чем "долгие" запросы на вашем сайте), и сравнив 
их.

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

___
nginx-ru mailing list
nginx-ru@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-ru