static ngx_int_t ngx_http_subs_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { ngx_int_t rc; ngx_log_t *log; ngx_chain_t *cl, *temp; ngx_http_subs_ctx_t *ctx; ngx_http_subs_loc_conf_t *slcf; log = r->connection->log; slcf = ngx_http_get_module_loc_conf(r, ngx_http_subs_filter_module); if (slcf == NULL) { return ngx_http_next_body_filter(r, in); } ctx = ngx_http_get_module_ctx(r, ngx_http_subs_filter_module); if (ctx == NULL) { return ngx_http_next_body_filter(r, in); } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http subs filter \"%V\"", &r->uri); if (in == NULL && ctx->busy == NULL) { return ngx_http_next_body_filter(r, in); } if (ngx_http_subs_body_filter_init_context(r, in) != NGX_OK){ goto failed; } for (cl = ctx->in; cl; cl = cl->next) { if (cl->buf->last_buf || cl->buf->last_in_chain){ ctx->last = 1; } /* TODO: check the flush flag */ rc = ngx_http_subs_body_filter_process_buffer(r, cl->buf); if (rc == NGX_DECLINED) { continue; } else if (rc == NGX_ERROR) { goto failed; } if (cl->next != NULL) { continue; } if (ctx->last) { /* copy line_in to ctx->out. */ if (ngx_buf_size(ctx->line_in) > 0) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "[subs_filter] Lost last linefeed, output anyway."); if (ngx_http_subs_out_chain_append(r, ctx, ctx->line_in) != NGX_OK) { goto failed; } } if (ctx->out_buf == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "[subs_filter] The last buffer is zero size."); /* * This is a zero buffer, it should not be set the temporary * or memory flag * */ ctx->out_buf = ngx_calloc_buf(r->pool); if (ctx->out_buf == NULL) { goto failed; } ctx->out_buf->sync = 1; temp = ngx_alloc_chain_link(r->pool); if (temp == NULL) { goto failed; } temp->buf = ctx->out_buf; temp->next = NULL; *ctx->last_out = temp; ctx->last_out = &temp->next; } ctx->out_buf->last_buf = (r == r->main) ? 1 : 0; ctx->out_buf->last_in_chain = cl->buf->last_in_chain; break; } } /* It doesn't output anything, return */ if ((ctx->out == NULL) && (ctx->busy == NULL)) { return NGX_OK; } return ngx_http_subs_output(r, ctx, in); failed: ngx_log_error(NGX_LOG_ERR, log, 0, "[subs_filter] ngx_http_subs_body_filter error."); return NGX_ERROR; }
static ngx_int_t ngx_http_subs_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { ngx_int_t rc; ngx_log_t *log; ngx_chain_t *cl, *ll; ngx_http_subs_ctx_t *ctx; ngx_http_subs_loc_conf_t *slcf; ll = NULL; log = r->connection->log; slcf = ngx_http_get_module_loc_conf(r, ngx_http_subs_filter_module); if (slcf == NULL) { return ngx_http_next_body_filter(r, in); } ctx = ngx_http_get_module_ctx(r, ngx_http_subs_filter_module); if (ctx == NULL) { return ngx_http_next_body_filter(r, in); } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http subs filter \"%V\"", &r->uri); if (in == NULL && ctx->busy == NULL) { return ngx_http_next_body_filter(r, in); } if (ngx_http_subs_body_filter_init_context(r, in) != NGX_OK){ goto failed; } for (cl = ctx->in; cl; cl = cl->next) { if (cl->buf->last_buf || cl->buf->last_in_chain){ ctx->last = 1; } /* TODO: check the flush tag */ rc = ngx_http_subs_body_filter_process_buffer(r, cl->buf); if (rc == NGX_DECLINED) { continue; } else if (rc == NGX_ERROR) { goto failed; } if (cl->next != NULL) { continue; } if (ctx->last) { /* copy line_in to ctx->out. */ if (ngx_buf_size(ctx->line_in) > 0) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "[subs_filter] Lost last linefeed, output anyway."); if (ngx_http_subs_out_chain_append(r, ctx, ctx->line_in) != NGX_OK) { goto failed; } } if (ctx->out_buf == NULL) { if (ngx_http_subs_get_chain_buf(r, ctx) != NGX_OK) { goto failed; } } ctx->out_buf->sync = 1; ctx->out_buf->last_buf = (r == r->main) ? 1 : 0; ctx->out_buf->last_in_chain = cl->buf->last_in_chain; break; } } /* It doesn't output anything, return */ if ((ctx->last_out == &ctx->out) && (ctx->busy == NULL)) { return NGX_OK; } ngx_http_subs_body_filter_clean_context(r, ctx); return ngx_http_subs_output(r, ctx, in); failed: ngx_http_subs_body_filter_clean_context(r, ctx); ngx_log_error(NGX_LOG_ERR, log, 0, "[subs_filter] ngx_http_subs_body_filter error."); return NGX_ERROR; }