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

gadh nginx-forum at
Sun Mar 17 09:47:24 UTC 2013

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;
		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.
		ctx->post.error = 1;
		return NGX_OK;

	if (status != NGX_HTTP_OK) // == 200 OK
		NGX_aaa_LOG_ERROR("bad  response status (%d)",status);
		ctx->post.error = 1;
		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)

    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; = (u_char*)_uri;
	uri.len = strlen(_uri);

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

    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;
    	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)

	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,

	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));

	// 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);

	// 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)); = (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,

	ngx_str_t key, l;

	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
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
				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
    	return NGX_DECLINED;

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

    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.

Posted at Nginx Forum:,237362,237454#msg-237454

More information about the nginx mailing list