Mercurial > hg > nginx-quic
diff src/http/ngx_http_postpone_filter_module.c @ 7220:20f139e9ffa8
Generic subrequests in memory.
Previously, only the upstream response body could be accessed with the
NGX_HTTP_SUBREQUEST_IN_MEMORY feature. Now any response body from a subrequest
can be saved in a memory buffer. It is available as a single buffer in r->out
and the buffer size is configured by the subrequest_output_buffer_size
directive.
Upstream, proxy and fastcgi code used to handle the old-style feature is
removed.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Wed, 28 Feb 2018 16:56:58 +0300 |
parents | d87f29d764ce |
children | 43585e0e12a3 |
line wrap: on
line diff
--- a/src/http/ngx_http_postpone_filter_module.c +++ b/src/http/ngx_http_postpone_filter_module.c @@ -12,6 +12,8 @@ static ngx_int_t ngx_http_postpone_filter_add(ngx_http_request_t *r, ngx_chain_t *in); +static ngx_int_t ngx_http_postpone_filter_in_memory(ngx_http_request_t *r, + ngx_chain_t *in); static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf); @@ -60,6 +62,10 @@ ngx_http_postpone_filter(ngx_http_reques ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in); + if (r->subrequest_in_memory) { + return ngx_http_postpone_filter_in_memory(r, in); + } + if (r != c->data) { if (in) { @@ -172,6 +178,78 @@ found: static ngx_int_t +ngx_http_postpone_filter_in_memory(ngx_http_request_t *r, ngx_chain_t *in) +{ + size_t len; + ngx_buf_t *b; + ngx_connection_t *c; + ngx_http_core_loc_conf_t *clcf; + + c = r->connection; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http postpone filter in memory"); + + if (r->out == NULL) { + r->out = ngx_alloc_chain_link(r->pool); + if (r->out == NULL) { + return NGX_ERROR; + } + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (r->headers_out.content_length_n != -1) { + len = r->headers_out.content_length_n; + + if (len > clcf->subrequest_output_buffer_size) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "too big subrequest response: %uz", len); + return NGX_ERROR; + } + + } else { + len = clcf->subrequest_output_buffer_size; + } + + b = ngx_create_temp_buf(r->pool, len); + if (b == NULL) { + return NGX_ERROR; + } + + b->last_buf = 1; + + r->out->buf = b; + r->out->next = NULL; + } + + b = r->out->buf; + + for ( /* void */ ; in; in = in->next) { + + if (ngx_buf_special(in->buf)) { + continue; + } + + len = in->buf->last - in->buf->pos; + + if (len > (size_t) (b->end - b->last)) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "too big subrequest response"); + return NGX_ERROR; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, + "http postpone filter in memory %uz bytes", len); + + b->last = ngx_cpymem(b->last, in->buf->pos, len); + in->buf->pos = in->buf->last; + } + + return NGX_OK; +} + + +static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf) { ngx_http_next_body_filter = ngx_http_top_body_filter;