Welcome! Log In Create A New Profile

Advanced

2: header already sent

July 12, 2018 04:32PM
Hi,
Sorry for sending this again. I haven't been able to resolve my issue. I've
read several modules for example and gone over several docs etc. but with
no success so far.

In my module, I need to either drop the request or allow the request. When
I drop the request, I need to send custom response and status. The custom
response and status don't come from the config file. When I send the
response in the content phase handler, I am am seeing 'header already sent'
messages in the error log. How can prevent further processing of the
request after my handler is called for the terminal case?

Since my module needs to examine all requests irrespective of the uri, I
tried registering a content phase handler and send the custom response in
that handler. However, my content phase handler is never invoked. I suspect
some other content handler is overriding my content handler. Is there a
way I can prevent that i.e. for a request, can I force only my content
handler to be called.

Please let me know what I am doing wrong? I just need to send/perform
custom response/actions when a request matches my criteria. I've include a
skeleton of my code.
Any inputs are greatly appreciated. Thanks.

regards,
Dk.

http_mod_send_response(ngx_http_request_t *r, ngx_uint_t custom_status,
char *body, ngx_int_t blen)
{
ngx_int_t rc;
ngx_log_t *log = r->connection->log;
ngx_buf_t *buf = ngx_create_temp_buf(r->pool, (blen+16)); // pad.

if (NULL == buf) {
ngx_log_error(NGX_LOG_ERR, log, 0, "%s: Failed to allocate buffer",
__FUNCTION__);
return NGX_ERROR;
}

buf->last = ngx_copy(buf->start, (unsigned char*) data, dlen);
rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK) {
ngx_log_error(NGX_LOG_ERR, log, 0, "%s: Discard req. body failed.
rc=%i", __FUNCTION__, rc);
return rc;
}

r->headers_out.status = custom_status;
r->headers_out.content_length_n = buf->last - buf->pos;
r->headers_out.content_type.len = sizeof("text/plain") - 1;
r->headers_out.content_type.data = (u_char *) "text/plain";

rc = ngx_http_send_header(r);
if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
ngx_log_error(NGX_LOG_ERR, log, 0, "%s: Send header failed. rc=%i",
__FUNCTION__, rc);
return rc;
}

ngx_chain_t *out_chain = ngx_alloc_chain_link(r->pool);
if (NULL == out_chain) {
ngx_log_error(NGX_LOG_ERR, log, 0, "%s: Buffer chain alloc failed",
__FUNCTION__);
return NGX_ERROR;
}

out_chain->buf = buf;
out_chain->next = NULL;
buf->last_buf = 1;
buf->last_in_chain = 1;

return ngx_http_output_filter(r, out_chain);
}

typedef struct {
unsigned done:1;
} ngx_http_mod_ctx_t;

int
http_module_process_request(ngx_http_request_t *r, ngx_uint_t *status, char
*body, ngx_uint_t *blen)
{
if (/* request matches criteria */) {
/* other boiler plate code */
*status = get_custom_status();
*body = get_custom_body();
*blen = ngx_strlen(body);
return *status; // this can be different from custom status.
}

return NGX_DECLINED;
}

static ngx_int_t
ngx_http_request_handler(ngx_http_request_t *r)
{
ngx_http_mod_ctx_t *ctx = ngx_http_get_module_ctx(r, nginx_http_module);

if (ctx) {
ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "duplicate
invokation");
return NGX_DECLINED;
} else {
ctx = ngx_palloc(r->connection->pool, sizeof(ngx_http_mod_ctx_t));
if (ctx == NULL) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"Out of memory. Cannot allocate context");
return NGX_ERROR;
}

ctx->done = 0;
ngx_http_set_ctx(r, ctx, nginx_http_module);
}

ngx_int_t rc = 0;
char custom_body[512];
ngx_uint_t blen;
ngx_uint_t custom_status;
if (!ctx->done) {
rc = http_module_process_request(r, &custom_status, custom_body, &blen);
}

ctx->done = 1;
if ((rc != 0) && (rc != NGX_DECLINED)) {
return http_mod_send_response(r, custom_status, custom_body, blen);
/* alternate implementation, send response in content handler.
ngx_buf_t *buf = ngx_create_temp_buf(r->pool, blen);
buf->last = ngx_copy(buf->start, (unsigned char*) data, dlen);
ctx->custom_body = buf;
ctx->rcode = custom_status;
*/
}

return NGX_DECLINED;
}

static ngx_int_t
http_module_content_handler(ngx_http_request_t *r)
{
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s: invoked",
__FUNCTION__);
ngx_http_ss_ctx_t *ctx = ngx_http_get_module_ctx(r,
nginx_mitigator_module);

if (ctx && ctx->content) {
ctx->content = 0;
return http_mod_send_response(r, ctx->rcode, ctx->custom_body);
} else {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"%s: ctx = %p, content = %d", __FUNCTION__, ctx, ctx ?
ctx->content : -1);
}

return NGX_DECLINED;
}

static ngx_int_t
ngx_http_module_init (ngx_conf_t *cf)
{
ngx_http_core_main_conf_t *cmcf = ngx_http_conf_get_module_main_conf(cf,
ngx_http_core_module);

if (!cmcf) {
ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Failed to retrieve module main
conf");
return NGX_ERROR;
}

ngx_http_handler_pt *hptr =
ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);
if (hptr == NULL) {
ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Could not retrieve access phase
handler");
return NGX_ERROR;
}

*hptr = ngx_http_request_handler;
ngx_log_error(NGX_LOG_INFO, cf->log, 0, "[init] Installed request
handler");

ngx_http_handler_pt *cptr =
ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
if (cptr == NULL) {
ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Could not retrieve access phase
handler");
return NGX_ERROR;
}

*cptr = ngx_http_request_handler;
ngx_log_error(NGX_LOG_INFO, cf->log, 0, "[init] Installed request
handler");

return NGX_OK;
}
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

2: header already sent

dnj0496 93 July 12, 2018 04:32PM

Re: 2: header already sent

dnj0496 18 July 13, 2018 04:20PM

Re: 2: header already sent

Roman Arutyunyan 14 July 14, 2018 05:38PM

Re: 2: header already sent

dnj0496 9 July 14, 2018 08:22PM

Re: 2: header already sent

Roman Arutyunyan 12 July 15, 2018 01:28AM

Re: 2: header already sent

dnj0496 10 July 15, 2018 09:12PM

Re: 2: header already sent

Roman Arutyunyan 11 July 16, 2018 07:30AM

Re: 2: header already sent

dnj0496 28 July 16, 2018 08:14PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 66
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 254 on July 05, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready