Mercurial > hg > nginx
comparison src/http/ngx_http_output_filter.c @ 40:d5d4f3bba6f0
nginx-0.0.1-2002-12-26-10:24:21 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 26 Dec 2002 07:24:21 +0000 |
parents | b2e039840718 |
children | 59e7c7f30d49 |
comparison
equal
deleted
inserted
replaced
39:83fa61cd3d2f | 40:d5d4f3bba6f0 |
---|---|
8 #include <ngx_http.h> | 8 #include <ngx_http.h> |
9 #include <ngx_http_config.h> | 9 #include <ngx_http_config.h> |
10 #include <ngx_http_output_filter.h> | 10 #include <ngx_http_output_filter.h> |
11 | 11 |
12 | 12 |
13 int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk); | 13 static int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk); |
14 static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src); | 14 static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src); |
15 #if 0 | |
16 static int ngx_http_output_filter_init( | |
17 int (**next_filter)(ngx_http_request_t *r, ngx_chain_t *ch)); | |
18 #endif | |
19 static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool); | 15 static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool); |
20 | 16 |
21 | 17 |
22 static ngx_command_t ngx_http_output_filter_commands[] = { | 18 static ngx_command_t ngx_http_output_filter_commands[] = { |
23 | 19 |
24 {"output_buffer", ngx_conf_set_size_slot, | 20 {ngx_string("output_buffer"), |
21 ngx_conf_set_size_slot, | |
25 offsetof(ngx_http_output_filter_conf_t, hunk_size), | 22 offsetof(ngx_http_output_filter_conf_t, hunk_size), |
26 NGX_HTTP_LOC_CONF, NGX_CONF_TAKE1, | 23 NGX_HTTP_LOC_CONF, |
27 "set output filter buffer size"}, | 24 NGX_CONF_TAKE1}, |
28 | 25 |
29 {NULL} | 26 {ngx_string(""), NULL, 0, 0, 0} |
30 | |
31 }; | 27 }; |
32 | 28 |
33 | 29 |
34 ngx_http_module_t ngx_http_output_filter_module = { | 30 static ngx_http_module_t ngx_http_output_filter_module_ctx = { |
35 NGX_HTTP_MODULE, | 31 NGX_HTTP_MODULE, |
36 | 32 |
37 NULL, /* create server config */ | 33 NULL, /* create server config */ |
38 ngx_http_output_filter_create_conf, /* create location config */ | 34 ngx_http_output_filter_create_conf, /* create location config */ |
39 ngx_http_output_filter_commands, /* module directives */ | 35 |
40 | |
41 NULL, /* init module */ | |
42 NULL, /* translate handler */ | 36 NULL, /* translate handler */ |
43 | 37 |
44 NULL, /* output header filter */ | 38 NULL, /* output header filter */ |
45 NULL, /* next output header filter */ | 39 NULL, /* next output header filter */ |
46 ngx_http_output_filter, /* output body filter */ | 40 (ngx_http_output_body_filter_p) ngx_http_output_filter, |
41 /* output body filter */ | |
47 NULL /* next output body filter */ | 42 NULL /* next output body filter */ |
48 }; | 43 }; |
49 | 44 |
50 | 45 |
51 #if 0 | 46 ngx_module_t ngx_http_output_filter_module = { |
52 static int (*ngx_http_output_next_filter)(ngx_http_request_t *r, | 47 &ngx_http_output_filter_module_ctx, /* module context */ |
53 ngx_chain_t *ch); | 48 ngx_http_output_filter_commands, /* module directives */ |
54 #endif | 49 NGX_HTTP_MODULE_TYPE, /* module type */ |
55 | 50 NULL /* init module */ |
56 | 51 }; |
57 int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) | 52 |
53 | |
54 static int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) | |
58 { | 55 { |
59 int rc, once; | 56 int rc, once; |
60 size_t size; | 57 size_t size; |
61 ssize_t n; | 58 ssize_t n; |
62 ngx_chain_t *ce; | 59 ngx_chain_t *ce; |
63 ngx_http_output_filter_ctx_t *ctx; | 60 ngx_http_output_filter_ctx_t *ctx; |
64 ngx_http_output_filter_conf_t *conf; | 61 ngx_http_output_filter_conf_t *conf; |
65 | 62 |
66 ctx = (ngx_http_output_filter_ctx_t *) | 63 ctx = (ngx_http_output_filter_ctx_t *) |
67 ngx_get_module_ctx(r->main ? r->main : r, | 64 ngx_http_get_module_ctx(r->main ? r->main : r, |
68 ngx_http_output_filter_module); | 65 ngx_http_output_filter_module_ctx); |
69 | 66 |
70 if (ctx == NULL) { | 67 if (ctx == NULL) { |
71 ngx_http_create_ctx(r, ctx, | 68 ngx_http_create_ctx(r, ctx, |
72 ngx_http_output_filter_module, | 69 ngx_http_output_filter_module_ctx, |
73 sizeof(ngx_http_output_filter_ctx_t)); | 70 sizeof(ngx_http_output_filter_ctx_t)); |
74 | 71 } |
75 #if 0 | 72 |
76 ctx->next_filter = ngx_http_output_next_filter; | 73 if (hunk && (hunk->type & NGX_HUNK_LAST)) { |
77 #endif | |
78 } | |
79 | |
80 if (hunk && (hunk->type & NGX_HUNK_LAST)) | |
81 ctx->last = 1; | 74 ctx->last = 1; |
75 } | |
82 | 76 |
83 for (once = 1; once || ctx->in; once = 0) { | 77 for (once = 1; once || ctx->in; once = 0) { |
84 | 78 |
85 /* input chain is not empty */ | 79 /* input chain is not empty */ |
86 if (ctx->in) { | 80 if (ctx->in) { |
87 | 81 |
88 /* add hunk to input chain */ | 82 /* add hunk to input chain */ |
89 if (once && hunk) { | 83 if (once && hunk) { |
90 for (ce = ctx->in; ce->next; ce = ce->next) | 84 for (ce = ctx->in; ce->next; ce = ce->next) { |
91 /* void */ ; | 85 /* void */ ; |
86 } | |
92 | 87 |
93 ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR); | 88 ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR); |
94 } | 89 } |
95 | 90 |
96 /* our hunk is still busy */ | 91 /* our hunk is still busy */ |
97 if (ctx->hunk->pos.mem < ctx->hunk->last.mem) { | 92 if (ctx->hunk->pos.mem < ctx->hunk->last.mem) { |
98 rc = ngx_http_output_filter_module. | 93 rc = ngx_http_output_filter_module_ctx. |
99 next_output_body_filter(r, NULL); | 94 next_output_body_filter(r, NULL); |
100 #if 0 | |
101 rc = ctx->next_filter(r, NULL); | |
102 #endif | |
103 | 95 |
104 /* our hunk is free */ | 96 /* our hunk is free */ |
105 } else { | 97 } else { |
106 ctx->out.hunk = ctx->hunk; | 98 ctx->out.hunk = ctx->hunk; |
107 | 99 |
108 rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk); | 100 rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk); |
109 #if (NGX_FILE_AIO_READ) | 101 #if (NGX_FILE_AIO_READ) |
110 if (rc == NGX_AGAIN) | 102 if (rc == NGX_AGAIN) { |
111 return rc; | 103 return rc; |
104 } | |
112 #endif | 105 #endif |
113 if (rc == NGX_ERROR) | 106 if (rc == NGX_ERROR) { |
114 return rc; | 107 return rc; |
108 } | |
115 | 109 |
116 /* whole hunk is copied so we send to next filter chain part | 110 /* whole hunk is copied so we send to next filter chain part |
117 up to next hunk that need to be copied */ | 111 up to next hunk that need to be copied */ |
118 if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) { | 112 if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) { |
119 ctx->out.next = ctx->in->next; | 113 ctx->out.next = ctx->in->next; |
120 | 114 |
121 for (ce = ctx->in->next; ce; ce = ce->next) { | 115 for (ce = ctx->in->next; ce; ce = ce->next) { |
122 if (ce->hunk->type & NGX_HUNK_FILE) | 116 if (ce->hunk->type & NGX_HUNK_FILE) { |
123 break; | 117 break; |
118 } | |
124 | 119 |
125 if ((ce->hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP)) | 120 if ((ce->hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP)) |
126 && (r->filter & NGX_HTTP_FILTER_NEED_TEMP)) | 121 && (r->filter & NGX_HTTP_FILTER_NEED_TEMP)) |
122 { | |
127 break; | 123 break; |
124 } | |
128 } | 125 } |
129 | 126 |
130 ctx->out.next = ce; | 127 ctx->out.next = ce; |
131 | 128 |
132 } else { | 129 } else { |
133 ctx->out.next = NULL; | 130 ctx->out.next = NULL; |
134 } | 131 } |
135 | 132 |
136 rc = ngx_http_output_filter_module. | 133 rc = ngx_http_output_filter_module_ctx. |
137 next_output_body_filter(r, &ctx->out); | 134 next_output_body_filter(r, &ctx->out); |
138 #if 0 | |
139 rc = ctx->next_filter(r, &ctx->out); | |
140 #endif; | |
141 } | 135 } |
142 | 136 |
143 /* delete completed hunks from input chain */ | 137 /* delete completed hunks from input chain */ |
144 for (ce = ctx->in; ce; ce = ce->next) { | 138 for (ce = ctx->in; ce; ce = ce->next) { |
145 if (ce->hunk->pos.file == ce->hunk->last.file) | 139 if (ce->hunk->pos.file == ce->hunk->last.file) { |
146 ctx->in = ce->next; | 140 ctx->in = ce->next; |
147 } | 141 } |
148 | 142 } |
149 if (rc == NGX_OK && ctx->hunk) | 143 |
144 if (rc == NGX_OK && ctx->hunk) { | |
150 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; | 145 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; |
151 else | 146 } else { |
152 return rc; | 147 return rc; |
148 } | |
153 | 149 |
154 /* input chain is empty */ | 150 /* input chain is empty */ |
155 } else { | 151 } else { |
156 | 152 |
157 if (hunk == NULL) { | 153 if (hunk == NULL) { |
158 rc = ngx_http_output_filter_module. | 154 rc = ngx_http_output_filter_module_ctx. |
159 next_output_body_filter(r, NULL); | 155 next_output_body_filter(r, NULL); |
160 #if 0 | |
161 rc = ctx->next_filter(r, NULL); | |
162 #endif; | |
163 | 156 |
164 } else { | 157 } else { |
165 | 158 |
166 /* we need to copy hunk to our hunk */ | 159 /* we need to copy hunk to our hunk */ |
167 if (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) | 160 if (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) |
173 /* out hunk is still busy */ | 166 /* out hunk is still busy */ |
174 if (ctx->hunk && ctx->hunk->pos.mem < ctx->hunk->last.mem) { | 167 if (ctx->hunk && ctx->hunk->pos.mem < ctx->hunk->last.mem) { |
175 ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, | 168 ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, |
176 NGX_ERROR); | 169 NGX_ERROR); |
177 | 170 |
178 rc = ngx_http_output_filter_module. | 171 rc = ngx_http_output_filter_module_ctx. |
179 next_output_body_filter(r, NULL); | 172 next_output_body_filter(r, NULL); |
180 #if 0 | |
181 rc = ctx->next_filter(r, NULL); | |
182 #endif | |
183 | 173 |
184 } else { | 174 } else { |
185 if (ctx->hunk == NULL) { | 175 if (ctx->hunk == NULL) { |
186 | 176 |
187 if (hunk->type & NGX_HUNK_LAST) { | 177 if (hunk->type & NGX_HUNK_LAST) { |
188 | 178 |
189 conf = (ngx_http_output_filter_conf_t *) | 179 conf = (ngx_http_output_filter_conf_t *) |
190 ngx_get_module_loc_conf(r->main ? r->main : r, | 180 ngx_http_get_module_loc_conf( |
191 ngx_http_output_filter_module); | 181 r->main ? r->main : r, |
182 ngx_http_output_filter_module_ctx); | |
192 | 183 |
193 size = hunk->last.mem - hunk->pos.mem; | 184 size = hunk->last.mem - hunk->pos.mem; |
194 if (size > conf->hunk_size) | 185 if (size > conf->hunk_size) { |
195 size = conf->hunk_size; | 186 size = conf->hunk_size; |
187 } | |
196 | 188 |
197 } else { | 189 } else { |
198 size = conf->hunk_size; | 190 size = conf->hunk_size; |
199 } | 191 } |
200 | 192 |
213 NGX_ERROR); | 205 NGX_ERROR); |
214 | 206 |
215 return rc; | 207 return rc; |
216 } | 208 } |
217 #endif | 209 #endif |
218 if (rc == NGX_ERROR) | 210 if (rc == NGX_ERROR) { |
219 return rc; | 211 return rc; |
220 | 212 } |
221 if (hunk->pos.mem < hunk->last.mem) | 213 |
214 if (hunk->pos.mem < hunk->last.mem) { | |
222 ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, | 215 ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, |
223 NGX_ERROR); | 216 NGX_ERROR); |
217 } | |
224 | 218 |
225 ctx->out.hunk = ctx->hunk; | 219 ctx->out.hunk = ctx->hunk; |
226 ctx->out.next = NULL; | 220 ctx->out.next = NULL; |
227 | 221 |
228 rc = ngx_http_output_filter_module. | 222 rc = ngx_http_output_filter_module_ctx. |
229 next_output_body_filter(r, &ctx->out); | 223 next_output_body_filter(r, &ctx->out); |
230 #if 0 | |
231 rc = ctx->next_filter(r, &ctx->out); | |
232 #endif | |
233 } | 224 } |
234 } | 225 } |
235 | 226 |
236 } else { | 227 } else { |
237 ctx->out.hunk = hunk; | 228 ctx->out.hunk = hunk; |
238 ctx->out.next = NULL; | 229 ctx->out.next = NULL; |
239 | 230 |
240 rc = ngx_http_output_filter_module. | 231 rc = ngx_http_output_filter_module_ctx. |
241 next_output_body_filter(r, &ctx->out); | 232 next_output_body_filter(r, &ctx->out); |
242 #if 0 | |
243 rc = ctx->next_filter(r, &ctx->out); | |
244 #endif | |
245 } | 233 } |
246 } | 234 } |
247 } | 235 } |
248 | 236 |
249 if (rc == NGX_OK && ctx->hunk) | 237 if (rc == NGX_OK && ctx->hunk) |
250 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; | 238 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; |
251 } | 239 } |
252 | 240 |
253 if (rc == NGX_OK && ctx->last) | 241 if (rc == NGX_OK && ctx->last) { |
254 return NGX_OK; | 242 return NGX_OK; |
243 } | |
255 | 244 |
256 if (rc == NGX_OK) { | 245 if (rc == NGX_OK) { |
257 if (ctx->hunk) | 246 if (ctx->hunk) { |
258 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; | 247 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; |
259 #if level_event | 248 } |
249 #if (!NGX_ONESHOT_EVENT) | |
260 ngx_del_event(r->connection->write, NGX_WRITE_EVENT); | 250 ngx_del_event(r->connection->write, NGX_WRITE_EVENT); |
261 #endif | 251 #endif |
262 } | 252 } |
263 | 253 |
264 return rc; | 254 return rc; |
269 { | 259 { |
270 size_t size; | 260 size_t size; |
271 ssize_t n; | 261 ssize_t n; |
272 | 262 |
273 size = src->last.mem - src->pos.mem; | 263 size = src->last.mem - src->pos.mem; |
274 if (size > dst->end - dst->pos.mem) | 264 if (size > dst->end - dst->pos.mem) { |
275 size = dst->end - dst->pos.mem; | 265 size = dst->end - dst->pos.mem; |
266 } | |
276 | 267 |
277 if (src->type & NGX_HUNK_FILE) { | 268 if (src->type & NGX_HUNK_FILE) { |
278 n = ngx_read_file(src->file, dst->pos.mem, size, src->pos.file); | 269 n = ngx_read_file(src->file, dst->pos.mem, size, src->pos.file); |
279 | 270 |
280 if (n == NGX_ERROR) { | 271 if (n == NGX_ERROR) { |
299 | 290 |
300 src->pos.mem += size; | 291 src->pos.mem += size; |
301 dst->last.mem += size; | 292 dst->last.mem += size; |
302 } | 293 } |
303 | 294 |
304 #if 1 | 295 if (src->type & NGX_HUNK_LAST) { |
305 if (src->type & NGX_HUNK_LAST) | |
306 dst->type |= NGX_HUNK_LAST; | 296 dst->type |= NGX_HUNK_LAST; |
307 #endif | 297 } |
308 | 298 |
309 return NGX_OK; | 299 return NGX_OK; |
310 } | 300 } |
311 | 301 |
312 | 302 |
320 | 310 |
321 conf->hunk_size = NGX_CONF_UNSET; | 311 conf->hunk_size = NGX_CONF_UNSET; |
322 | 312 |
323 return conf; | 313 return conf; |
324 } | 314 } |
325 | |
326 #if 0 | |
327 static int ngx_http_output_filter_init( | |
328 int (**next_filter)(ngx_http_request_t *r, ngx_chain_t *ch)) | |
329 { | |
330 ngx_http_output_next_filter = *next_filter; | |
331 *next_filter = NULL; | |
332 | |
333 return NGX_OK; | |
334 } | |
335 #endif |