Mercurial > hg > nginx
comparison src/http/ngx_http_postpone_filter_module.c @ 2377:87b8c44906b5
*) refactor subrequest handling, now they run as separate posted requests
*) now $upstream_addr, $upstream_status, $upstream_response_time can be used
with log_subrequest
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 08 Dec 2008 14:23:20 +0000 |
parents | 173900227c06 |
children | 23e6f26fb4bd |
comparison
equal
deleted
inserted
replaced
2376:29d89920a749 | 2377:87b8c44906b5 |
---|---|
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_http.h> | 9 #include <ngx_http.h> |
10 | 10 |
11 | 11 |
12 static ngx_int_t | 12 static ngx_int_t ngx_http_postpone_filter_add(ngx_http_request_t *r, |
13 ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r); | 13 ngx_chain_t *in); |
14 static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf); | 14 static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf); |
15 | 15 |
16 | 16 |
17 static ngx_http_module_t ngx_http_postpone_filter_module_ctx = { | 17 static ngx_http_module_t ngx_http_postpone_filter_module_ctx = { |
18 NULL, /* preconfiguration */ | 18 NULL, /* preconfiguration */ |
49 | 49 |
50 | 50 |
51 static ngx_int_t | 51 static ngx_int_t |
52 ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in) | 52 ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in) |
53 { | 53 { |
54 ngx_int_t rc; | 54 ngx_connection_t *c; |
55 ngx_chain_t *out; | 55 ngx_http_postponed_request_t *pr; |
56 ngx_http_postponed_request_t *pr, **ppr; | |
57 | 56 |
58 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 57 c = r->connection; |
58 | |
59 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
59 "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in); | 60 "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in); |
60 | 61 |
61 if (r != r->connection->data || (r->postponed && in)) { | 62 if (r != c->data) { |
62 | 63 |
63 if (r->postponed) { | 64 if (in) { |
64 for (pr = r->postponed; pr->next; pr = pr->next) { /* void */ } | 65 ngx_http_postpone_filter_add(r, in); |
65 | 66 return NGX_OK; |
66 ppr = pr->request ? &pr->next : NULL; | |
67 | |
68 } else { | |
69 ppr = &r->postponed; | |
70 #if (NGX_SUPPRESS_WARN) | |
71 pr = NULL; | |
72 #endif | |
73 } | 67 } |
74 | 68 |
75 if (ppr) { | 69 #if 0 |
76 pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t)); | 70 /* TODO: SSI may pass NULL */ |
77 if (pr == NULL) { | 71 ngx_log_error(NGX_LOG_ALERT, c->log, 0, |
78 return NGX_ERROR; | 72 "http postpone filter NULL inactive request", |
79 } | 73 &r->uri, &r->args); |
80 | |
81 *ppr = pr; | |
82 | |
83 pr->request = NULL; | |
84 pr->out = NULL; | |
85 pr->next = NULL; | |
86 } | |
87 | |
88 if (ngx_chain_add_copy(r->pool, &pr->out, in) == NGX_ERROR) { | |
89 return NGX_ERROR; | |
90 } | |
91 | |
92 #if 1 | |
93 { | |
94 ngx_chain_t *cl; | |
95 ngx_buf_t *b = NULL; | |
96 for (cl = pr->out; cl; cl = cl->next) { | |
97 if (cl->buf == b) { | |
98 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | |
99 "the same buf was used in postponed %p %p", | |
100 b, b->pos); | |
101 ngx_debug_point(); | |
102 return NGX_ERROR; | |
103 } | |
104 b = cl->buf; | |
105 } | |
106 } | |
107 #endif | 74 #endif |
108 | 75 |
109 if (r != r->connection->data || r->postponed->request) { | 76 return NGX_OK; |
110 return NGX_AGAIN; | |
111 } | |
112 } | |
113 | |
114 if (r->postponed) { | |
115 out = r->postponed->out; | |
116 if (out) { | |
117 r->postponed = r->postponed->next; | |
118 } | |
119 | |
120 } else { | |
121 out = in; | |
122 } | |
123 | |
124 rc = NGX_OK; | |
125 | |
126 if (out | |
127 || (r->connection->buffered | |
128 & (NGX_HTTP_LOWLEVEL_BUFFERED|NGX_LOWLEVEL_BUFFERED))) | |
129 { | |
130 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
131 "http postpone filter out \"%V?%V\"", &r->uri, &r->args); | |
132 | |
133 if (!(out && out->next == NULL && ngx_buf_sync_only(out->buf))) { | |
134 | |
135 rc = ngx_http_next_filter(r->main, out); | |
136 | |
137 if (rc == NGX_ERROR) { | |
138 /* NGX_ERROR may be returned by any filter */ | |
139 r->connection->error = 1; | |
140 } | |
141 } | |
142 } | 77 } |
143 | 78 |
144 if (r->postponed == NULL) { | 79 if (r->postponed == NULL) { |
145 return rc; | 80 |
81 if (in || c->buffered) { | |
82 return ngx_http_next_filter(r->main, in); | |
83 } | |
84 | |
85 return NGX_OK; | |
146 } | 86 } |
147 | 87 |
148 rc = ngx_http_postpone_filter_output_postponed_request(r); | 88 if (in) { |
149 | 89 ngx_http_postpone_filter_add(r, in); |
150 if (rc == NGX_ERROR) { | |
151 /* NGX_ERROR may be returned by any filter */ | |
152 r->connection->error = 1; | |
153 } | 90 } |
154 | 91 |
155 return rc; | 92 do { |
93 pr = r->postponed; | |
94 | |
95 if (pr->request) { | |
96 | |
97 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
98 "http postpone filter wake \"%V?%V\"", | |
99 &pr->request->uri, &pr->request->args); | |
100 | |
101 r->postponed = pr->next; | |
102 | |
103 c->data = pr->request; | |
104 | |
105 return ngx_http_post_request(pr->request); | |
106 } | |
107 | |
108 if (pr->out == NULL) { | |
109 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
110 "http postpone filter NULL output", | |
111 &r->uri, &r->args); | |
112 | |
113 } else { | |
114 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | |
115 "http postpone filter output \"%V?%V\"", | |
116 &r->uri, &r->args); | |
117 | |
118 if (ngx_http_next_filter(r->main, pr->out) == NGX_ERROR) { | |
119 return NGX_ERROR; | |
120 } | |
121 } | |
122 | |
123 r->postponed = pr->next; | |
124 | |
125 } while (r->postponed); | |
126 | |
127 return NGX_OK; | |
156 } | 128 } |
157 | 129 |
158 | 130 |
159 static ngx_int_t | 131 static ngx_int_t |
160 ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r) | 132 ngx_http_postpone_filter_add(ngx_http_request_t *r, ngx_chain_t *in) |
161 { | 133 { |
162 ngx_int_t rc; | 134 ngx_http_postponed_request_t *pr, **ppr; |
163 ngx_chain_t *out; | |
164 ngx_http_log_ctx_t *ctx; | |
165 ngx_http_postponed_request_t *pr; | |
166 | 135 |
167 for ( ;; ) { | 136 if (r->postponed) { |
168 pr = r->postponed; | 137 for (pr = r->postponed; pr->next; pr = pr->next) { /* void */ } |
169 | 138 |
170 if (pr == NULL) { | 139 if (pr->request == NULL) { |
171 break; | 140 goto found; |
172 } | 141 } |
173 | 142 |
174 if (pr->request) { | 143 ppr = &pr->next; |
175 | 144 |
176 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 145 } else { |
177 "http postpone filter handle \"%V?%V\"", | 146 ppr = &r->postponed; |
178 &pr->request->uri, &pr->request->args); | |
179 | |
180 ctx = r->connection->log->data; | |
181 ctx->current_request = pr->request; | |
182 | |
183 if (!pr->request->done) { | |
184 r->connection->data = pr->request; | |
185 return NGX_AGAIN; | |
186 } | |
187 | |
188 rc = ngx_http_postpone_filter_output_postponed_request(pr->request); | |
189 | |
190 if (rc == NGX_AGAIN || rc == NGX_ERROR) { | |
191 return rc; | |
192 } | |
193 | |
194 r->postponed = r->postponed->next; | |
195 pr = r->postponed; | |
196 } | |
197 | |
198 if (pr == NULL) { | |
199 break; | |
200 } | |
201 | |
202 out = pr->out; | |
203 | |
204 if (out) { | |
205 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
206 "http postpone filter out postponed \"%V?%V\"", | |
207 &r->uri, &r->args); | |
208 | |
209 if (!(out && out->next == NULL && ngx_buf_sync_only(out->buf))) { | |
210 if (ngx_http_next_filter(r->main, out) == NGX_ERROR) { | |
211 return NGX_ERROR; | |
212 } | |
213 } | |
214 } | |
215 | |
216 r->postponed = r->postponed->next; | |
217 } | 147 } |
218 | 148 |
219 if (r != r->main && r->out) { | 149 pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t)); |
220 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 150 if (pr == NULL) { |
221 "http postpone filter out again \"%V?%V\"", | 151 return NGX_ERROR; |
222 &r->uri, &r->args); | |
223 | |
224 r->connection->data = r; | |
225 return NGX_AGAIN; | |
226 } | 152 } |
227 | 153 |
228 return NGX_OK; | 154 *ppr = pr; |
155 | |
156 pr->request = NULL; | |
157 pr->out = NULL; | |
158 pr->next = NULL; | |
159 | |
160 found: | |
161 | |
162 if (ngx_chain_add_copy(r->pool, &pr->out, in) == NGX_OK) { | |
163 return NGX_OK; | |
164 } | |
165 | |
166 return NGX_ERROR; | |
229 } | 167 } |
230 | 168 |
231 | 169 |
232 static ngx_int_t | 170 static ngx_int_t |
233 ngx_http_postpone_filter_init(ngx_conf_t *cf) | 171 ngx_http_postpone_filter_init(ngx_conf_t *cf) |