Mercurial > hg > nginx
annotate src/http/ngx_http_postpone_filter_module.c @ 2199:ffb512f0eabd
fix building on FreeBSD prior to 4.8, it has no GLOB_NOMATCH
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 22 Aug 2008 12:54:32 +0000 |
parents | 2bb4441a8c28 |
children | 173900227c06 |
rev | line source |
---|---|
509 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_http.h> | |
10 | |
11 | |
583 | 12 static ngx_int_t |
13 ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r); | |
681 | 14 static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf); |
509 | 15 |
16 | |
17 static ngx_http_module_t ngx_http_postpone_filter_module_ctx = { | |
18 NULL, /* preconfiguration */ | |
681 | 19 ngx_http_postpone_filter_init, /* postconfiguration */ |
509 | 20 |
21 NULL, /* create main configuration */ | |
22 NULL, /* init main configuration */ | |
23 | |
24 NULL, /* create server configuration */ | |
25 NULL, /* merge server configuration */ | |
26 | |
27 NULL, /* create location configuration */ | |
28 NULL /* merge location configuration */ | |
29 }; | |
30 | |
31 | |
32 ngx_module_t ngx_http_postpone_filter_module = { | |
33 NGX_MODULE_V1, | |
34 &ngx_http_postpone_filter_module_ctx, /* module context */ | |
35 NULL, /* module directives */ | |
36 NGX_HTTP_MODULE, /* module type */ | |
541 | 37 NULL, /* init master */ |
681 | 38 NULL, /* init module */ |
541 | 39 NULL, /* init process */ |
40 NULL, /* init thread */ | |
41 NULL, /* exit thread */ | |
42 NULL, /* exit process */ | |
43 NULL, /* exit master */ | |
44 NGX_MODULE_V1_PADDING | |
509 | 45 }; |
46 | |
47 | |
48 static ngx_http_output_body_filter_pt ngx_http_next_filter; | |
49 | |
50 | |
51 static ngx_int_t | |
52 ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
53 { | |
54 ngx_int_t rc; | |
55 ngx_chain_t *out; | |
56 ngx_http_postponed_request_t *pr, **ppr; | |
57 | |
583 | 58 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
59 "http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in); | |
527 | 60 |
509 | 61 if (r != r->connection->data || (r->postponed && in)) { |
62 | |
63 if (r->postponed) { | |
64 for (pr = r->postponed; pr->next; pr = pr->next) { /* void */ } | |
65 | |
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 } | |
74 | |
75 if (ppr) { | |
76 pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t)); | |
77 if (pr == NULL) { | |
78 return NGX_ERROR; | |
79 } | |
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 | |
641 | 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, | |
643 | 99 "the same buf was used in postponed %p %p", |
100 b, b->pos); | |
641 | 101 ngx_debug_point(); |
102 return NGX_ERROR; | |
103 } | |
104 b = cl->buf; | |
105 } | |
106 } | |
107 #endif | |
108 | |
509 | 109 if (r != r->connection->data || r->postponed->request) { |
110 return NGX_AGAIN; | |
111 } | |
112 } | |
113 | |
114 if (r->postponed) { | |
115 out = r->postponed->out; | |
597 | 116 if (out) { |
117 r->postponed = r->postponed->next; | |
118 } | |
509 | 119 |
120 } else { | |
121 out = in; | |
122 } | |
123 | |
595 | 124 rc = NGX_OK; |
125 | |
597 | 126 if (out |
127 || (r->connection->buffered | |
128 & (NGX_HTTP_LOWLEVEL_BUFFERED|NGX_LOWLEVEL_BUFFERED))) | |
129 { | |
595 | 130 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
131 "http postpone filter out \"%V?%V\"", &r->uri, &r->args); | |
509 | 132 |
595 | 133 if (!(out && out->next == NULL && ngx_buf_sync_only(out->buf))) { |
134 | |
135 rc = ngx_http_next_filter(r->main, out); | |
509 | 136 |
595 | 137 if (rc == NGX_ERROR) { |
138 /* NGX_ERROR may be returned by any filter */ | |
139 r->connection->error = 1; | |
140 } | |
141 } | |
583 | 142 } |
143 | |
144 if (r->postponed == NULL) { | |
145 return rc; | |
146 } | |
147 | |
148 rc = ngx_http_postpone_filter_output_postponed_request(r); | |
149 | |
150 if (rc == NGX_ERROR) { | |
151 /* NGX_ERROR may be returned by any filter */ | |
152 r->connection->error = 1; | |
509 | 153 } |
154 | |
155 return rc; | |
156 } | |
157 | |
158 | |
159 static ngx_int_t | |
583 | 160 ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r) |
161 { | |
162 ngx_int_t rc; | |
595 | 163 ngx_chain_t *out; |
665 | 164 ngx_http_log_ctx_t *ctx; |
583 | 165 ngx_http_postponed_request_t *pr; |
166 | |
167 for ( ;; ) { | |
168 pr = r->postponed; | |
169 | |
170 if (pr == NULL) { | |
2066
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
171 break; |
583 | 172 } |
173 | |
174 if (pr->request) { | |
175 | |
176 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
177 "http postpone filter handle \"%V?%V\"", | |
178 &pr->request->uri, &pr->request->args); | |
179 | |
665 | 180 ctx = r->connection->log->data; |
181 ctx->current_request = pr->request; | |
182 | |
583 | 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 | |
597 | 198 if (pr == NULL) { |
2066
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
199 break; |
597 | 200 } |
201 | |
595 | 202 out = pr->out; |
203 | |
204 if (out) { | |
583 | 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 | |
595 | 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 } | |
583 | 213 } |
214 } | |
215 | |
216 r->postponed = r->postponed->next; | |
217 } | |
2066
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
218 |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
219 if (r->out) { |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
220 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
221 "http postpone filter out again \"%V?%V\"", |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
222 &r->uri, &r->args); |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
223 |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
224 r->connection->data = r; |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
225 return NGX_AGAIN; |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
226 } |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
227 |
2bb4441a8c28
fix bug when inactive subrequest is truncated,
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
228 return NGX_OK; |
583 | 229 } |
230 | |
231 | |
232 static ngx_int_t | |
681 | 233 ngx_http_postpone_filter_init(ngx_conf_t *cf) |
509 | 234 { |
235 ngx_http_next_filter = ngx_http_top_body_filter; | |
236 ngx_http_top_body_filter = ngx_http_postpone_filter; | |
237 | |
238 return NGX_OK; | |
239 } |