Hi Muhammad, On Mon, Sep 25, 2023 at 12:01:11AM +0800, Muhammad Nuzaihan wrote: > Hi, > > I would like to return an error message based on the *response* body. > > I know i can do it easily with *request* body (with "return > NGX_HTTP_BAD_REQUEST") but my case i want to do it with *response* > body. > > Also i have tried this code with response body filter but i got "*1 > header already sent, client: 127.0.0.1, server: localhost":
That's because you need to delay sending the response, both header and body, before making the decision about the response code. It's quite complicated. If you send the header right away, there's no way to change it in the future. You can look into ngx_http_xslt_filter_module and ngx_http_image_filter_module for inspiration. For the xslt module (src/http/modules/ngx_http_xslt_filter_module.c), its header filter ngx_http_xslt_header_filter() does not call ngx_http_next_header_filter() on first call (ctx == NULL). Its body filter ngx_http_xslt_body_filter() also does not call ngx_http_next_body_filter() right away. Instead, it buffers the entire response body. Upon body completion, ngx_http_xslt_send() is called, which sends both header (ngx_http_next_header_filter()) and buffered body (ngx_http_next_body_filter()). If a decision is made to trigger an error, ngx_http_filter_finalize_request() is called instead. > Thank you for your guidance. > > Code: > > ``` > return ngx_http_filter_finalize_request(request, > &ngx_m_module, > NGX_HTTP_BAD_REQUEST); > ``` > RESPONSE BODY CODE: > > ngx_int_t ResponseBodyFilter(ngx_http_request_t *request, > ngx_chain_t *chain_head) { > // Set the logging level to debug > // TODO: remove > request->connection->log->log_level = NGX_LOG_DEBUG; > > // Get our context so we can store the response body data > FilterContext *ctx = GetModuleFilterContext(request); > if (ctx == NULL) { > return NGX_ERROR; > } > > return ngx_http_filter_finalize_request(request, > &ngx_my_module, > NGX_HTTP_BAD_REQUEST); > > } > > ngx_int_t ModuleInit(ngx_conf_t *cf) { > kNextRequestBodyFilter = ngx_http_top_request_body_filter; > ngx_http_top_request_body_filter = RequestBodyFilter; > > kNextResponseBodyFilter = ngx_http_top_body_filter; > ngx_http_top_body_filter = ResponseBodyFilter; > > kNextHeaderFilter = ngx_http_top_header_filter; > ngx_http_top_header_filter = HeaderFilter; > > return NGX_OK; > } > _______________________________________________ > nginx-devel mailing list > nginx-devel@nginx.org > https://mailman.nginx.org/mailman/listinfo/nginx-devel -- Roman Arutyunyan _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel