March 17, 2013 05:47AM
Ok, i'll attach my calling to subrequest code, its working flawlessly except the case i reported here:
//------------------------------------------------------------------
/*
Note: the purspose of this code is to call a handler module (at rewrite phase), send special POST subrequest to another server (independant of the main request), wait with the module untill subrequest finishes, process its data , then continue to backend or next handler module
*/

// the subrequest will call this handler after it finishes
ngx_int_t ngx_aaa_post_subrequest_handler (ngx_http_request_t *r, void *data, ngx_int_t rc)
{
ngx_aaa_ctx_t *ctx = (ngx_aaa_ctx_t*)data;
ngx_chain_t *bufs;
ngx_uint_t status;

if (rc != NGX_OK)
{
NGX_aaa_LOG_ERROR("bad response (nginx code %d)",rc);
ctx->post.error = 1;
aaa_SUB_PROF_END
ngx_http_core_run_phases(r->main); // continue main request
return NGX_OK; //cannot return rc if != NGX_OK - see below
}

if (r->upstream) // when sending to another server, then subrequest is passed on upstream module
{
bufs = r->upstream->out_bufs;
status = r->upstream->state->status;
}
else // runs on the same nginx, another port
{
NGX_aaa_LOG_ERROR("response could not get by 'upstream' method. aborting");
ctx->post.error = 1;
aaa_SUB_PROF_END
ngx_http_core_run_phases(r->main);
return NGX_OK;
}

if (status != NGX_HTTP_OK) // == 200 OK
{
NGX_aaa_LOG_ERROR("bad response status (%d)",status);
ctx->post.error = 1;
aaa_SUB_PROF_END
ngx_http_core_run_phases(r->main);
return NGX_OK; // when returning error in subrequest, the nginx loops over it untill ok, or after 2 loops its stucks the main req.
}

ctx->post.done = 1;

ctx->post.response_data = ngx_aaa_utils_get_data_from_bufs(r, bufs);

ctx->post.response_handler(r, data); // passing ctx->post->response_data to ngx_aaa_response_handler() - data parsing

if (!ctx->post.response_data)
ngx_http_core_run_phases(r->main);

if (!ctx->standalone)
ngx_http_core_run_phases(r->main); // release main request from its wait and send it to the backend server

return NGX_OK;

}

// main code of calling to subrequest
ngx_int_t ngx_aaa_send_post_subrequest(ngx_http_request_t *r, ngx_aaa_ctx_t *ctx, char *_uri, ngx_str_t *data, ngx_uint_t is_ret)
{
ngx_http_request_t *sr;
ngx_uint_t flags = 0;
ngx_http_post_subrequest_t *psr;
ngx_str_t uri;
ngx_int_t res;
ngx_buf_t *buf;

flags = NGX_HTTP_SUBREQUEST_IN_MEMORY;

uri.data = (u_char*)_uri;
uri.len = strlen(_uri);

psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
if (!psr)
return NGX_HTTP_INTERNAL_SERVER_ERROR;

ctx->done = 0;
ctx->post.done = 0;
ctx->post.start = 1;

if (is_ret) // return answer to caller, async
{
psr->handler = ngx_aaa_post_subrequest_handler; // register callback function for returning ans from the other end
psr->data = ctx;
}
else
psr = NULL;

// this func only registers the subreq in queue, but not activates it yet
// note: sr->request_body is nulled during this func, alloc later
res = ngx_http_subrequest(r, &uri, NULL , &sr, psr, flags);
if (res)
return NGX_HTTP_INTERNAL_SERVER_ERROR;

ngx_memzero(&sr->headers_in, sizeof(sr->headers_in));

buf = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
if (!buf)
return NGX_ERROR;

// args is an ngx_str_t with the body
sr->method = NGX_HTTP_POST;

ngx_memcpy(&(sr->method_name), &ngx_aaa_post_method_name, sizeof(ngx_str_t));

buf->temporary = 1;

buf->pos = data->data;
buf->last = buf->pos + data->len;

// do not inherit rb from parent
sr->request_body = ngx_palloc(r->pool, sizeof(ngx_http_request_body_t));
NGX_aaa_CHECK_ALLOC_AND_RETURN(sr->request_body)

// note: always alloc bufs even if ptr is lid - since its garbage from former request ! (caused seg fault in mod_proxy !)
sr->request_body->bufs = ngx_alloc_chain_link(r->pool);
NGX_aaa_CHECK_ALLOC_AND_RETURN(sr->request_body->bufs)

// post body - re-populate , do not inherit from parent
sr->request_body->bufs->buf = buf;
sr->request_body->bufs->next = NULL;
sr->request_body->buf = buf;

sr->header_in = NULL;
buf->last_in_chain = 1;
buf->last_buf = 1;

sr->request_body_in_single_buf = 1;

sr->headers_in.content_length_n = ngx_buf_size(buf);

ngx_str_t c_len_key = ngx_string("Content-Length");
ngx_str_t c_len_l;
char len_str[20];
sprintf(len_str, "%lu", ngx_buf_size(buf));
c_len_l.data = (u_char*)len_str;
c_len_l.len = strlen(len_str);

ngx_aaa_set_input_header(sr, &sr->headers_in.content_length, &c_len_key, &c_len_l);

ngx_str_t key, l;

ngx_str_set(&key,"Content-Type");
ngx_str_set(&l, "application/x-www-form-urlencoded");
ngx_aaa_set_input_header(sr, &sr->headers_in.content_type, &key, &l);

return NGX_OK;
}

// handler module main function - calls the subrequest, waits for it to finish
ngx_int_t ngx_aaa_handler(ngx_http_request_t *r)
{

// pseudo code: alloc module ctx - only once

if (ctx->post.start)
{
// check if post subrequest has ended - then call next module handler
if (ctx->post.done)
{
return NGX_DECLINED; // declined - if hdl is reg. in rewrite phase
}
else // wait for post subrequest to finish unless error
{
if (ctx->post.error)
{
return NGX_DECLINED; // subrequest finished - call next handler module
}
else
{
return NGX_AGAIN; // wait untill finish response to our subrequest
}
}

}

// prepare subrequest
// ngx_str - post body for the subrequest
ctx->post.response_handler = ngx_aaa_response_handler; // for subrequest response data parsing

rc = ngx_aaa_send_post_subrequest(r, ctx, url, ngx_str, 1);

if (rc != NGX_OK)
{
NGX_aaa_LOG_ERROR("ngx_aaa_send_post_subrequest failed (error %d)",rc);
return NGX_DECLINED;
}

/* NGX_DECLINED == pass to next handler, do not wait.
* NGX_OK == wait for subrequest to finish first (non blocking, of course)
*/

return NGX_OK;
}
//------------------------------------------------------------------

i'de appreciate your help,
BTW, is there any "nginx subrequest coding guide" documentation available ? its very confusing and lacks much info on the web, i got it working only thru alot of trial-and-error.
Tnx
Gad
Subject Author Posted

nginx + my module crashes only when ignore client abort = on

gadh March 14, 2013 11:36AM

Re: nginx + my module crashes only when ignore client abort = on

gadh March 14, 2013 11:58AM

Re: nginx + my module crashes only when ignore client abort = on

Maxim Dounin March 14, 2013 12:34PM

Re: nginx + my module crashes only when ignore client abort = on

gadh March 14, 2013 12:46PM

Re: nginx + my module crashes only when ignore client abort = on

Maxim Dounin March 14, 2013 01:06PM

Re: nginx + my module crashes only when ignore client abort = on

gadh March 17, 2013 05:47AM

Re: nginx + my module crashes only when ignore client abort = on

gadh March 17, 2013 03:00PM

Re: nginx + my module crashes only when ignore client abort = on

Maxim Dounin March 17, 2013 07:54PM

Re: nginx + my module crashes only when ignore client abort = on

gadh March 18, 2013 01:40AM

Re: nginx + my module crashes only when ignore client abort = on

Maxim Dounin March 18, 2013 07:18AM

Re: nginx + my module crashes only when ignore client abort = on

gadh March 18, 2013 07:24AM

Re: nginx + my module crashes only when ignore client abort = on

gadh March 18, 2013 09:45AM

Re: nginx + my module crashes only when ignore client abort = on

gadh April 09, 2013 08:59AM



Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 303
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