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