comparison 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
comparison
equal deleted inserted replaced
7219:d0d32b33167d 7220:20f139e9ffa8
9 #include <ngx_core.h> 9 #include <ngx_core.h>
10 #include <ngx_http.h> 10 #include <ngx_http.h>
11 11
12 12
13 static ngx_int_t ngx_http_postpone_filter_add(ngx_http_request_t *r, 13 static ngx_int_t ngx_http_postpone_filter_add(ngx_http_request_t *r,
14 ngx_chain_t *in);
15 static ngx_int_t ngx_http_postpone_filter_in_memory(ngx_http_request_t *r,
14 ngx_chain_t *in); 16 ngx_chain_t *in);
15 static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf); 17 static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf);
16 18
17 19
18 static ngx_http_module_t ngx_http_postpone_filter_module_ctx = { 20 static ngx_http_module_t ngx_http_postpone_filter_module_ctx = {
58 c = r->connection; 60 c = r->connection;
59 61
60 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, 62 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
61 "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in); 63 "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);
62 64
65 if (r->subrequest_in_memory) {
66 return ngx_http_postpone_filter_in_memory(r, in);
67 }
68
63 if (r != c->data) { 69 if (r != c->data) {
64 70
65 if (in) { 71 if (in) {
66 if (ngx_http_postpone_filter_add(r, in) != NGX_OK) { 72 if (ngx_http_postpone_filter_add(r, in) != NGX_OK) {
67 return NGX_ERROR; 73 return NGX_ERROR;
170 return NGX_ERROR; 176 return NGX_ERROR;
171 } 177 }
172 178
173 179
174 static ngx_int_t 180 static ngx_int_t
181 ngx_http_postpone_filter_in_memory(ngx_http_request_t *r, ngx_chain_t *in)
182 {
183 size_t len;
184 ngx_buf_t *b;
185 ngx_connection_t *c;
186 ngx_http_core_loc_conf_t *clcf;
187
188 c = r->connection;
189
190 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
191 "http postpone filter in memory");
192
193 if (r->out == NULL) {
194 r->out = ngx_alloc_chain_link(r->pool);
195 if (r->out == NULL) {
196 return NGX_ERROR;
197 }
198
199 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
200
201 if (r->headers_out.content_length_n != -1) {
202 len = r->headers_out.content_length_n;
203
204 if (len > clcf->subrequest_output_buffer_size) {
205 ngx_log_error(NGX_LOG_ERR, c->log, 0,
206 "too big subrequest response: %uz", len);
207 return NGX_ERROR;
208 }
209
210 } else {
211 len = clcf->subrequest_output_buffer_size;
212 }
213
214 b = ngx_create_temp_buf(r->pool, len);
215 if (b == NULL) {
216 return NGX_ERROR;
217 }
218
219 b->last_buf = 1;
220
221 r->out->buf = b;
222 r->out->next = NULL;
223 }
224
225 b = r->out->buf;
226
227 for ( /* void */ ; in; in = in->next) {
228
229 if (ngx_buf_special(in->buf)) {
230 continue;
231 }
232
233 len = in->buf->last - in->buf->pos;
234
235 if (len > (size_t) (b->end - b->last)) {
236 ngx_log_error(NGX_LOG_ERR, c->log, 0,
237 "too big subrequest response");
238 return NGX_ERROR;
239 }
240
241 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
242 "http postpone filter in memory %uz bytes", len);
243
244 b->last = ngx_cpymem(b->last, in->buf->pos, len);
245 in->buf->pos = in->buf->last;
246 }
247
248 return NGX_OK;
249 }
250
251
252 static ngx_int_t
175 ngx_http_postpone_filter_init(ngx_conf_t *cf) 253 ngx_http_postpone_filter_init(ngx_conf_t *cf)
176 { 254 {
177 ngx_http_next_body_filter = ngx_http_top_body_filter; 255 ngx_http_next_body_filter = ngx_http_top_body_filter;
178 ngx_http_top_body_filter = ngx_http_postpone_filter; 256 ngx_http_top_body_filter = ngx_http_postpone_filter;
179 257