@Hung Nguyen, Sorry did not see your response. Looks like my email settings were incorrect and I was not receiving the emails.
I am looking for a way to send custom response without having to change the config. Dk. On Fri, Jul 6, 2018 at 2:33 PM Dk Jack <dnj0...@gmail.com> wrote: > Hi, > I thought I solved my issue but it looks like I haven't. It just took some > time for the log messages to show up. > I've attached my code below. In my code, the > call HttpModuleProcessRequest returns a non-zero value if > the requests needs to be blocked. Would appreciate if some one can help. > Thanks > > > ----------------------------------------------------------------------------------------------------------------------------------------------- > PS: The issue seems to happen for request that my module blocked, so it > seems to be related to the send header call. > > SendResponseBuffer(ngx_http_request_t *r, ngx_uint_t http_status, char > *reason, ngx_int_t rlen) > { > ngx_int_t rc; > ngx_log_t *log = r->connection->log; > ngx_buf_t *buf = ngx_create_temp_buf(r->pool, (rlen+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; > } > > 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; > > r->headers_out.status = http_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"; > r->header_only = 1; > r->headers_out.content_length_n = 0; > > 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; > } > > return ngx_http_output_filter(r, out_chain); > } > > typedef struct { > unsigned done:1; > } ngx_http_mod_ctx_t; > > 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_log_error(NGX_LOG_DEBUG, r->connection->log, 0, > "%s: uri:\"%V\" uuri: \"%V\" call-count:%ud", > __FUNCTION__, &r->uri, &r->unparsed_uri, r->main->count); > > ngx_int_t rc = 0; > if (!ctx->done) { > char buf[512]; > ngx_uint_t len; > ngx_uint_t http_status; > > rc = HttpModuleProcessRequest(r, &http_status, buf, &len); > if (!rc) { > rc = SendResponseBuffer(r, http_status, buf, len); > } > } > > ctx->done = 1; > //ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, > // "%s: rc = %d, uri:\"%V\"", __FUNCTION__, rc, &r->uri); > > if ((rc != 0) && (rc != NGX_DECLINED)) { > return rc; > } > > // per http://www.nginxguts.com/2011/01/phases/, ACCESS_PHASE handler > should return NGX_OK here. > // however, returning NGX_OK causes nginx to hang. > return NGX_DECLINED; > } > > static ngx_int_t > ngx_http_module_init (ngx_conf_t *cf) > { > ngx_http_handler_pt *hptr; > ngx_http_core_main_conf_t *cmcf; > > cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); > hptr = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers); > > if (hptr == NULL) { > ngx_log_error(NGX_LOG_ERR, cf->log, 0, "Cannot retrieve Nginx access > phase handler pointer"); > return NGX_ERROR; > } > > *hptr = ngx_http_request_handler; > ngx_log_error(NGX_LOG_INFO, cf->log, 0, "[init] Installed request > handler"); > > return NGX_OK; > } > > > On Thu, Jul 5, 2018 at 5:44 PM Dk Jack <dnj0...@gmail.com> wrote: > >> Hi, >> I have an nginx module. The purpose of my module is to inspect every >> request and make a binary decision (i.e drop or allow). When dropping, I am >> sending a custom status code and response message. I've setup my module >> handler to be called in the NGX_HTTP_REWRITE_PHASE. Things seem to be >> working fine for the most part except for a small issue. >> >> I am seeing 'header already sent' messages in the nginx error.log. In my >> handler, I create a context for my module and attach it request using >> the ngx_http_set_ctx call. I am using the context to store some info and >> also to prevent my module from processing the same request multiple times. >> My module processes the request only once. >> >> I get the 'header already sent' message only for a fraction of the >> requests. The messages seem to be generated only for requests that I >> allowed in my module. In my module handler, I return an NGX_DECLINED return >> code when I allow a request. The message is not generated for every allowed >> request but only for some of the allowed requests. When the error is >> generated it is always for POST request and not all POST requests cause >> this error message to be logged. >> >> Could someone explain what could be going on here or where I should look >> at next to debug this further? Any pointers are appreciated. Thanks. >> >> Dk. >> >>
_______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel