Проблемы с получением request body
Привет. Я пишу модуль для 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: Забивается папка проксированных тел
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
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: Забивается папка проксированных тел
Здравствуйте. Максим, будьте любезны подсказать, как это лучше сделать. Сервер достаточно нагружен, чтобы включать какой-то отладочный лог. 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: Забивается папка проксированных тел
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