Mercurial > hg > nginx
annotate src/http/ngx_http_postpone_filter_module.c @ 9300:5be23505292b
SSI: fixed incorrect or duplicate stub output.
Following 3518:eb3aaf8bd2a9 (0.8.37), r->request_output is only set
if there are data in the first buffer sent in the subrequest. As a
result, following the change mentioned this flag cannot be used to
prevent duplicate ngx_http_ssi_stub_output() calls, since it is not
set if there was already some output, but the first buffer was empty.
Still, when there are multiple subrequests, even an empty subrequest
response might be delayed by the postpone filter, leading to a second
call of ngx_http_ssi_stub_output() during finalization from
ngx_http_writer() the subreqest buffers are released by the postpone
filter. Since r->request_output is not set after the first call, this
resulted in duplicate stub output.
Additionally, checking only the first buffer might be wrong in some
unusual cases. For example, the first buffer might be empty if
$r->flush() is called before printing any data in the embedded Perl
module.
Depending on the postpone_output value and corresponding sizes, this
issue can result in either duplicate or unexpected stub output, or
"zero size buf in writer" alerts.
Following 8124:f5515e727656 (1.23.4), it became slightly easier to
reproduce the issue, as empty static files and empty cache items now
result in a response with an empty buffer. Before the change, an empty
proxied response can be used to reproduce the issue.
Fix is check all buffers and set r->request_output if any non-empty
buffers are sent. This ensures that all unusual cases of non-empty
responses are covered, and also that r->request_output will be set
after the first stub output, preventing duplicate output.
Reported by Jan Gassen.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 04 Jul 2024 17:41:28 +0300 |
parents | 43585e0e12a3 |
children |
rev | line source |
---|---|
509 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
509 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
13 static ngx_int_t ngx_http_postpone_filter_add(ngx_http_request_t *r, |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
14 ngx_chain_t *in); |
7220
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
15 static ngx_int_t ngx_http_postpone_filter_in_memory(ngx_http_request_t *r, |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
16 ngx_chain_t *in); |
681 | 17 static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf); |
509 | 18 |
19 | |
20 static ngx_http_module_t ngx_http_postpone_filter_module_ctx = { | |
21 NULL, /* preconfiguration */ | |
681 | 22 ngx_http_postpone_filter_init, /* postconfiguration */ |
509 | 23 |
24 NULL, /* create main configuration */ | |
25 NULL, /* init main configuration */ | |
26 | |
27 NULL, /* create server configuration */ | |
28 NULL, /* merge server configuration */ | |
29 | |
30 NULL, /* create location configuration */ | |
31 NULL /* merge location configuration */ | |
32 }; | |
33 | |
34 | |
35 ngx_module_t ngx_http_postpone_filter_module = { | |
36 NGX_MODULE_V1, | |
37 &ngx_http_postpone_filter_module_ctx, /* module context */ | |
38 NULL, /* module directives */ | |
39 NGX_HTTP_MODULE, /* module type */ | |
541 | 40 NULL, /* init master */ |
681 | 41 NULL, /* init module */ |
541 | 42 NULL, /* init process */ |
43 NULL, /* init thread */ | |
44 NULL, /* exit thread */ | |
45 NULL, /* exit process */ | |
46 NULL, /* exit master */ | |
47 NGX_MODULE_V1_PADDING | |
509 | 48 }; |
49 | |
50 | |
4542
586969d972b9
Local variable "ngx_http_next_filter" renamed to "ngx_http_next_body_filter"
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
51 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; |
509 | 52 |
53 | |
54 static ngx_int_t | |
55 ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
56 { | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
57 ngx_connection_t *c; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
58 ngx_http_postponed_request_t *pr; |
509 | 59 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
60 c = r->connection; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
61 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
62 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, |
583 | 63 "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in); |
527 | 64 |
7220
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
65 if (r->subrequest_in_memory) { |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
66 return ngx_http_postpone_filter_in_memory(r, in); |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
67 } |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
68 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
69 if (r != c->data) { |
509 | 70 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
71 if (in) { |
7134
d87f29d764ce
Postpone filter: handled ngx_http_postpone_filter_add() failures.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5218
diff
changeset
|
72 if (ngx_http_postpone_filter_add(r, in) != NGX_OK) { |
d87f29d764ce
Postpone filter: handled ngx_http_postpone_filter_add() failures.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5218
diff
changeset
|
73 return NGX_ERROR; |
d87f29d764ce
Postpone filter: handled ngx_http_postpone_filter_add() failures.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5218
diff
changeset
|
74 } |
d87f29d764ce
Postpone filter: handled ngx_http_postpone_filter_add() failures.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5218
diff
changeset
|
75 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
76 return NGX_OK; |
509 | 77 } |
78 | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
79 #if 0 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
80 /* TODO: SSI may pass NULL */ |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
81 ngx_log_error(NGX_LOG_ALERT, c->log, 0, |
5218 | 82 "http postpone filter NULL inactive request"); |
641 | 83 #endif |
84 | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
85 return NGX_OK; |
583 | 86 } |
87 | |
88 if (r->postponed == NULL) { | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
89 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
90 if (in || c->buffered) { |
4542
586969d972b9
Local variable "ngx_http_next_filter" renamed to "ngx_http_next_body_filter"
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
91 return ngx_http_next_body_filter(r->main, in); |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
92 } |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
93 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
94 return NGX_OK; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
95 } |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
96 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
97 if (in) { |
7134
d87f29d764ce
Postpone filter: handled ngx_http_postpone_filter_add() failures.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5218
diff
changeset
|
98 if (ngx_http_postpone_filter_add(r, in) != NGX_OK) { |
d87f29d764ce
Postpone filter: handled ngx_http_postpone_filter_add() failures.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5218
diff
changeset
|
99 return NGX_ERROR; |
d87f29d764ce
Postpone filter: handled ngx_http_postpone_filter_add() failures.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5218
diff
changeset
|
100 } |
583 | 101 } |
102 | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
103 do { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
104 pr = r->postponed; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
105 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
106 if (pr->request) { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
107 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
108 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
109 "http postpone filter wake \"%V?%V\"", |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
110 &pr->request->uri, &pr->request->args); |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
111 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
112 r->postponed = pr->next; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
113 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
114 c->data = pr->request; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
115 |
3064 | 116 return ngx_http_post_request(pr->request, NULL); |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
117 } |
583 | 118 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
119 if (pr->out == NULL) { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
120 ngx_log_error(NGX_LOG_ALERT, c->log, 0, |
5218 | 121 "http postpone filter NULL output"); |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
122 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
123 } else { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
124 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
125 "http postpone filter output \"%V?%V\"", |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
126 &r->uri, &r->args); |
509 | 127 |
4542
586969d972b9
Local variable "ngx_http_next_filter" renamed to "ngx_http_next_body_filter"
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
128 if (ngx_http_next_body_filter(r->main, pr->out) == NGX_ERROR) { |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
129 return NGX_ERROR; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
130 } |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
131 } |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
132 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
133 r->postponed = pr->next; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
134 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
135 } while (r->postponed); |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
136 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
137 return NGX_OK; |
509 | 138 } |
139 | |
140 | |
141 static ngx_int_t | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
142 ngx_http_postpone_filter_add(ngx_http_request_t *r, ngx_chain_t *in) |
583 | 143 { |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
144 ngx_http_postponed_request_t *pr, **ppr; |
583 | 145 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
146 if (r->postponed) { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
147 for (pr = r->postponed; pr->next; pr = pr->next) { /* void */ } |
583 | 148 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
149 if (pr->request == NULL) { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
150 goto found; |
583 | 151 } |
152 | |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
153 ppr = &pr->next; |
583 | 154 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
155 } else { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
156 ppr = &r->postponed; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
157 } |
595 | 158 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
159 pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t)); |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
160 if (pr == NULL) { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
161 return NGX_ERROR; |
583 | 162 } |
2066
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
163 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
164 *ppr = pr; |
2066
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
165 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
166 pr->request = NULL; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
167 pr->out = NULL; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
168 pr->next = NULL; |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
169 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
170 found: |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
171 |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
172 if (ngx_chain_add_copy(r->pool, &pr->out, in) == NGX_OK) { |
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
173 return NGX_OK; |
2066
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
174 } |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
175 |
2377
87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
Igor Sysoev <igor@sysoev.ru>
parents:
2295
diff
changeset
|
176 return NGX_ERROR; |
583 | 177 } |
178 | |
179 | |
180 static ngx_int_t | |
7220
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
181 ngx_http_postpone_filter_in_memory(ngx_http_request_t *r, ngx_chain_t *in) |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
182 { |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
183 size_t len; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
184 ngx_buf_t *b; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
185 ngx_connection_t *c; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
186 ngx_http_core_loc_conf_t *clcf; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
187 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
188 c = r->connection; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
189 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
190 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
191 "http postpone filter in memory"); |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
192 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
193 if (r->out == NULL) { |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
194 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
195 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
196 if (r->headers_out.content_length_n != -1) { |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
197 len = r->headers_out.content_length_n; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
198 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
199 if (len > clcf->subrequest_output_buffer_size) { |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
200 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
201 "too big subrequest response: %uz", len); |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
202 return NGX_ERROR; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
203 } |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
204 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
205 } else { |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
206 len = clcf->subrequest_output_buffer_size; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
207 } |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
208 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
209 b = ngx_create_temp_buf(r->pool, len); |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
210 if (b == NULL) { |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
211 return NGX_ERROR; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
212 } |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
213 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
214 b->last_buf = 1; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
215 |
7221
43585e0e12a3
Postpone filter: prevented uninitialized r->out.
Roman Arutyunyan <arut@nginx.com>
parents:
7220
diff
changeset
|
216 r->out = ngx_alloc_chain_link(r->pool); |
43585e0e12a3
Postpone filter: prevented uninitialized r->out.
Roman Arutyunyan <arut@nginx.com>
parents:
7220
diff
changeset
|
217 if (r->out == NULL) { |
43585e0e12a3
Postpone filter: prevented uninitialized r->out.
Roman Arutyunyan <arut@nginx.com>
parents:
7220
diff
changeset
|
218 return NGX_ERROR; |
43585e0e12a3
Postpone filter: prevented uninitialized r->out.
Roman Arutyunyan <arut@nginx.com>
parents:
7220
diff
changeset
|
219 } |
43585e0e12a3
Postpone filter: prevented uninitialized r->out.
Roman Arutyunyan <arut@nginx.com>
parents:
7220
diff
changeset
|
220 |
7220
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
221 r->out->buf = b; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
222 r->out->next = NULL; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
223 } |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
224 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
225 b = r->out->buf; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
226 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
227 for ( /* void */ ; in; in = in->next) { |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
228 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
229 if (ngx_buf_special(in->buf)) { |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
230 continue; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
231 } |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
232 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
233 len = in->buf->last - in->buf->pos; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
234 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
235 if (len > (size_t) (b->end - b->last)) { |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
236 ngx_log_error(NGX_LOG_ERR, c->log, 0, |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
237 "too big subrequest response"); |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
238 return NGX_ERROR; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
239 } |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
240 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
241 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
242 "http postpone filter in memory %uz bytes", len); |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
243 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
244 b->last = ngx_cpymem(b->last, in->buf->pos, len); |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
245 in->buf->pos = in->buf->last; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
246 } |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
247 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
248 return NGX_OK; |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
249 } |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
250 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
251 |
20f139e9ffa8
Generic subrequests in memory.
Roman Arutyunyan <arut@nginx.com>
parents:
7134
diff
changeset
|
252 static ngx_int_t |
681 | 253 ngx_http_postpone_filter_init(ngx_conf_t *cf) |
509 | 254 { |
4542
586969d972b9
Local variable "ngx_http_next_filter" renamed to "ngx_http_next_body_filter"
Ruslan Ermilov <ru@nginx.com>
parents:
4412
diff
changeset
|
255 ngx_http_next_body_filter = ngx_http_top_body_filter; |
509 | 256 ngx_http_top_body_filter = ngx_http_postpone_filter; |
257 | |
258 return NGX_OK; | |
259 } |