/**********************************************************
Вроде разобрался, пока без файлов, по отладке работает, но остались некоторые вопросы...
1. Таймер(ctx->sleep.timer_set) всегда скидывается после первого вызова ?
2. Нужно ли чистить текущий r->request_body->bufs при переходе на следующий буфер ? ... ngx_pfree/ngx_free_chain ?
3. Имеет ли смысл двигать pos в ngx_buf_s если модуль монопольно потребляет request_body ?
4. чем отличается r->request_body_in_file_only от r->request_body_in_persistent_file ?
4.1. r->request_body_in_clean_file ?
5. Нужны ли какие-либо еще флаги, например нашел в ngx_http_request_s waited и где-то в структурах видел delay ?
Пример кода:
**********************************************************/
/*...Инициализация контекстного хэндлера...*/
ngx_http_core_loc_conf_t *clcf;
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_rbsample_handler;
/*...*/
/*Порядок вывова ngx_http_rbsample_handler-> ngx_http_rbsample_post_handler->ngx_http_rbsample_delay_handler*/
static ngx_int_t
ngx_http_rbsample_handler(ngx_http_request_t *r)
{
/*...*/
/*
typedef struct {
ngx_event_t sleep;
ngx_int_t cur_buf_wasnt_read;
ngx_buf_t *buf;
} ngx_http_rbsample_ctx_t;
*/
ngx_http_rbsample_ctx_t *ctx;
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_rbsample_ctx_t));
ctx->sleep.handler = ngx_http_rbsample_delay_handler;
ctx->sleep.data = r;
ctx->sleep.log = r->connection->log;
ctx->cur_buf_wasnt_read=1;
ctx->buf=0;
ngx_http_set_ctx(r, ctx, ngx_http_rbsample_module);
if(r->method == NGX_HTTP_PUT || r->method == NGX_HTTP_POST) {
rc = ngx_http_read_client_request_body(r, ngx_http_rbsample_post_handler);
/*...*/
}
/*...*/
}
static void
ngx_http_rbsample_post_handler(ngx_http_request_t *r)
{
/*...*/
ctx = ngx_http_get_module_ctx(r, ngx_http_rbsample_module);
cl = r->request_body->bufs;
if( ctx->cur_buf_wasnt_read ) {
if( !ctx->buf ) ctx->buf=cl->buf;
len = ctx->buf->last - ctx->buf->pos;
ngx_http_rbsample_debug(r, ctx->buf->pos, len); //Заглушка для чтения
ctx->cur_buf_wasnt_read=0;
}
if(!ctx->cur_buf_wasnt_read && !ctx->buf->last_buf && cl->next ) {
ctx->buf= cl->next->buf;
ctx->cur_buf_wasnt_read=1;
}
if( r->request_body->rest || ctx->cur_buf_wasnt_read ) {
ngx_add_timer(&ctx->sleep, (ngx_msec_t)3000);
}
else if(!ctx->cur_buf_wasnt_read && ctx->buf->last_buf)
ctx->buf=0;
if(ctx->sleep.timer_set) ngx_del_timer(&ctx->sleep);
ngx_http_finalize_request(r, NGX_OK);
}
return;
}
static void
ngx_http_rbsample_delay_handler(ngx_event_t *ev)
{ ngx_http_rbsample_post_handler(ev->data); }