December 01, 2014 08:35AM
Привет.
Я пишу модуль для 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 <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include <ngx_event.h>

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

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;
chain = r->request_body->bufs;
while (chain) {
buf = chain->buf;
int len = buf->end - buf->start;
if(post_len > 0)
{
post_body = (char*)realloc(post_body, sizeof(char) * (len + post_len));
strncat(post_body, (char *)buf->start, len);
}
else
{
post_body = (char*)malloc(sizeof(char) * len);
int i;
for(i=0;i<len;i++)
{
post_body[i] = buf->start[i];
}
post_body[len] = '\0';
}
post_len += len;
chain = chain->next;
}

............................ // функционал с post_body и post_len

}

/*
* Main handler function of the module.
*/
static ngx_int_t
ngx_http_toxic_handler(ngx_http_request_t *r)
{
ngx_int_t rc;
toxic_ctx *ctx;

if ((r->method & (NGX_HTTP_POST|NGX_HTTP_PUT))) {
ctx = ngx_http_get_module_ctx(r, ngx_http_toxic_module);

if (ctx != NULL) {
if (ctx->done) {
return NGX_DECLINED;
}

return NGX_DONE;
}

ctx = ngx_pcalloc(r->pool, sizeof(toxic_ctx));
if (ctx == NULL) {
return NGX_ERROR;
}

ngx_http_set_ctx(r, ctx, ngx_http_toxic_module);

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_finalize_request(r, toxic_excecute(r, "text/html"));

return NGX_OK;
}

/*
* Function for the directive toxic , it validates its value
* and copies it to a static variable to be printed later
*/
static char * ngx_http_toxic(ngx_conf_t *cf, void *post, void *data)
{
ngx_http_core_loc_conf_t *clcf;

clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = ngx_http_toxic_handler;

ngx_str_t *name = data; // i.e., first field of ngx_http_toxic_loc_conf_t

if (ngx_strcmp(name->data, "") == 0) {
return NGX_CONF_ERROR;
}

return NGX_CONF_OK;
}
Subject Author Posted

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

tigran.bayburtsyan December 01, 2014 08:35AM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 168
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready