<div dir="ltr">Hi,<div>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.</div><div><br><div>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?</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div>Any inputs are greatly appreciated. Thanks.</div><div><br></div><div>regards,</div><div>Dk.</div><div><br></div><div><div><font face="monospace, monospace">http_mod_send_response(ngx_http_request_t *r, ngx_uint_t custom_status, char *body, ngx_int_t blen)</font></div><div><font face="monospace, monospace">{</font></div><div><font face="monospace, monospace">  ngx_int_t rc;</font></div><div><font face="monospace, monospace">  ngx_log_t *log = r->connection->log;</font></div><div><font face="monospace, monospace">  ngx_buf_t *buf = ngx_create_temp_buf(r->pool, (blen+16)); // pad.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  if (NULL == buf) {</font></div><div><font face="monospace, monospace">    ngx_log_error(NGX_LOG_ERR, log, 0, "%s: Failed to allocate buffer", __FUNCTION__);</font></div><div><font face="monospace, monospace">    return NGX_ERROR;</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  buf->last = ngx_copy(buf->start, (unsigned char*) data, dlen);</font></div><div><font face="monospace, monospace">  rc = ngx_http_discard_request_body(r);</font></div><div><font face="monospace, monospace">  if (rc != NGX_OK) {</font></div><div><font face="monospace, monospace">    ngx_log_error(NGX_LOG_ERR, log, 0, "%s: Discard req. body failed. rc=%i", __FUNCTION__, rc);</font></div><div><font face="monospace, monospace">    return rc;</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  r->headers_out.status = custom_status;</font></div><div><font face="monospace, monospace">  r->headers_out.content_length_n = buf->last - buf->pos;</font></div><div><font face="monospace, monospace">  r->headers_out.content_type.len = sizeof("text/plain") - 1;</font></div><div><font face="monospace, monospace">  r->headers_out.content_type.data = (u_char *) "text/plain";</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  rc = ngx_http_send_header(r);</font></div><div><font face="monospace, monospace">  if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {</font></div><div><font face="monospace, monospace">    ngx_log_error(NGX_LOG_ERR, log, 0, "%s: Send header failed. rc=%i", __FUNCTION__, rc);</font></div><div><font face="monospace, monospace">    return rc;</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  ngx_chain_t *out_chain = ngx_alloc_chain_link(r->pool);</font></div><div><font face="monospace, monospace">  if (NULL == out_chain) {</font></div><div><font face="monospace, monospace">    ngx_log_error(NGX_LOG_ERR, log, 0, "%s: Buffer chain alloc failed", __FUNCTION__);</font></div><div><font face="monospace, monospace">    return NGX_ERROR;</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  out_chain->buf = buf;</font></div><div><font face="monospace, monospace">  out_chain->next = NULL;</font></div><div><font face="monospace, monospace">  buf->last_buf = 1;</font></div><div><font face="monospace, monospace">  buf->last_in_chain = 1;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  return ngx_http_output_filter(r, out_chain);</font></div><div><font face="monospace, monospace">}</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">typedef struct {</font></div><div><font face="monospace, monospace">  unsigned done:1;</font></div><div><font face="monospace, monospace">} ngx_http_mod_ctx_t;</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">int</font></div><div><font face="monospace, monospace">http_module_process_request(ngx_http_request_t *r, ngx_uint_t *status, char *body, ngx_uint_t *blen)</font></div><div><font face="monospace, monospace">{</font></div><div><font face="monospace, monospace">  if (/* request matches criteria */) {</font></div><div><font face="monospace, monospace">    /* other boiler plate code */</font></div><div><font face="monospace, monospace">    *status = get_custom_status();</font></div><div><font face="monospace, monospace">    *body = get_custom_body();</font></div><div><font face="monospace, monospace">    *blen = ngx_strlen(body);</font></div><div><font face="monospace, monospace">    return *status;    // this can be different from custom status.</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  return NGX_DECLINED;</font></div><div><font face="monospace, monospace">}</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">static ngx_int_t</font></div><div><font face="monospace, monospace">ngx_http_request_handler(ngx_http_request_t *r)</font></div><div><font face="monospace, monospace">{</font></div><div><font face="monospace, monospace">  ngx_http_mod_ctx_t *ctx = ngx_http_get_module_ctx(r, nginx_http_module);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  if (ctx) {</font></div><div><font face="monospace, monospace">    ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "duplicate</font></div><div><font face="monospace, monospace">    invokation");</font></div><div><font face="monospace, monospace">    return NGX_DECLINED;</font></div><div><font face="monospace, monospace">  } else {</font></div><div><font face="monospace, monospace">    ctx = ngx_palloc(r->connection->pool, sizeof(ngx_http_mod_ctx_t));</font></div><div><font face="monospace, monospace">    if (ctx == NULL) {</font></div><div><font face="monospace, monospace">      ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,</font></div><div><font face="monospace, monospace">      "Out of memory. Cannot allocate context");</font></div><div><font face="monospace, monospace">      return NGX_ERROR;</font></div><div><font face="monospace, monospace">    }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    ctx->done = 0;</font></div><div><font face="monospace, monospace">    ngx_http_set_ctx(r, ctx, nginx_http_module);</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  ngx_int_t rc = 0;</font></div><div><font face="monospace, monospace">  char custom_body[512];</font></div><div><font face="monospace, monospace">  ngx_uint_t blen;</font></div><div><font face="monospace, monospace">  ngx_uint_t custom_status;</font></div><div><font face="monospace, monospace">  if (!ctx->done) {</font></div><div><font face="monospace, monospace">    rc = http_module_process_request(r, &custom_status, custom_body, &blen);</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  ctx->done = 1;</font></div><div><font face="monospace, monospace">  if ((rc != 0) && (rc != NGX_DECLINED)) {</font></div><div><font face="monospace, monospace">    return http_mod_send_response(r, custom_status, custom_body, blen);</font></div><div><font face="monospace, monospace">    /* alternate implementation, send response in content handler.</font></div><div><font face="monospace, monospace">      ngx_buf_t *buf = ngx_create_temp_buf(r->pool, blen);</font></div><div><font face="monospace, monospace">      buf->last = ngx_copy(buf->start, (unsigned char*) data, dlen);</font></div><div><font face="monospace, monospace">      ctx->custom_body = buf;</font></div><div><font face="monospace, monospace">      ctx->rcode = custom_status;</font></div><div><font face="monospace, monospace">     */</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  return NGX_DECLINED;</font></div><div><font face="monospace, monospace">}</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">static ngx_int_t</font></div><div><font face="monospace, monospace">http_module_content_handler(ngx_http_request_t *r)</font></div><div><font face="monospace, monospace">{</font></div><div><font face="monospace, monospace">  ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s: invoked", __FUNCTION__);</font></div><div><font face="monospace, monospace">  ngx_http_ss_ctx_t *ctx = ngx_http_get_module_ctx(r, nginx_mitigator_module);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  if (ctx && ctx->content) {</font></div><div><font face="monospace, monospace">    ctx->content = 0;</font></div><div><font face="monospace, monospace">    return http_mod_send_response(r, ctx->rcode, ctx->custom_body);</font></div><div><font face="monospace, monospace">  } else {</font></div><div><font face="monospace, monospace">    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,</font></div><div><font face="monospace, monospace">                  "%s: ctx = %p, content = %d", __FUNCTION__, ctx, ctx ? ctx->content : -1);</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  return NGX_DECLINED;</font></div><div><font face="monospace, monospace">}</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">static ngx_int_t</font></div><div><font face="monospace, monospace">ngx_http_module_init (ngx_conf_t *cf)</font></div><div><font face="monospace, monospace">{</font></div><div><font face="monospace, monospace">  ngx_http_core_main_conf_t *cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  if (!cmcf) {</font></div><div><font face="monospace, monospace">    ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Failed to retrieve module main conf");</font></div><div><font face="monospace, monospace">    return NGX_ERROR;</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  ngx_http_handler_pt *hptr = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers);</font></div><div><font face="monospace, monospace">  if (hptr == NULL) {</font></div><div><font face="monospace, monospace">    ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Could not retrieve access phase handler");</font></div><div><font face="monospace, monospace">    return NGX_ERROR;</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  *hptr = ngx_http_request_handler;</font></div><div><font face="monospace, monospace">  ngx_log_error(NGX_LOG_INFO, cf->log, 0, "[init] Installed request handler");</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  ngx_http_handler_pt *cptr = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);</font></div><div><font face="monospace, monospace">  if (cptr == NULL) {</font></div><div><font face="monospace, monospace">    ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Could not retrieve access phase handler");</font></div><div><font face="monospace, monospace">    return NGX_ERROR;</font></div><div><font face="monospace, monospace">  }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  *cptr = ngx_http_request_handler;</font></div><div><font face="monospace, monospace">  ngx_log_error(NGX_LOG_INFO, cf->log, 0, "[init] Installed request handler");</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">  return NGX_OK;</font></div><div><font face="monospace, monospace">}</font></div></div><div><br></div><div><p style="margin:0px;font-stretch:normal;font-size:12px;line-height:normal;font-family:Helvetica"><br></p></div></div></div>