comparison src/http/ngx_http_output_filter.c @ 60:50186b49f2ad

nginx-0.0.1-2003-02-11-10:14:40 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 11 Feb 2003 07:14:40 +0000
parents e8cdc2989cee
children 4f3e2abcc2c4
comparison
equal deleted inserted replaced
59:e8cdc2989cee 60:50186b49f2ad
53 &ngx_http_output_filter_module_ctx, /* module context */ 53 &ngx_http_output_filter_module_ctx, /* module context */
54 ngx_http_output_filter_commands, /* module directives */ 54 ngx_http_output_filter_commands, /* module directives */
55 NGX_HTTP_MODULE_TYPE, /* module type */ 55 NGX_HTTP_MODULE_TYPE, /* module type */
56 NULL /* init module */ 56 NULL /* init module */
57 }; 57 };
58
59
60 #if 1
61
62 #define next_filter ngx_http_output_filter_module_ctx.next_output_body_filter
63
64 #define need_to_copy(r, hunk) \
65 (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) \
66 && (hunk->type & NGX_HUNK_FILE)) \
67 || ((r->filter & NGX_HTTP_FILTER_NEED_TEMP) \
68 && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))))
69
70 int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
71 {
72 int rc;
73 size_t size;
74 ngx_chain_t *ce, *pe;
75 ngx_http_output_filter_ctx_t *ctx;
76 ngx_http_output_filter_conf_t *conf;
77
78 ctx = (ngx_http_output_filter_ctx_t *)
79 ngx_http_get_module_ctx(r->main ? r->main : r,
80 ngx_http_output_filter_module);
81
82 if (ctx == NULL) {
83 ngx_http_create_ctx(r, ctx, ngx_http_output_filter_module,
84 sizeof(ngx_http_output_filter_ctx_t));
85 }
86
87 /* the incoming chain ctx->in is empty */
88 if (ctx->in == NULL) {
89
90 if (hunk == NULL) {
91 return next_filter(r, NULL);
92 }
93
94 /* we do not need to copy the incoming hunk to our hunk */
95 if (!need_to_copy(r, hunk)) {
96 ctx->out.hunk = hunk;
97 ctx->out.next = NULL;
98
99 return next_filter(r, &ctx->out);
100 }
101
102 /* we need to copy the incoming hunk to our hunk */
103
104 /* allocate ctx->hunk if it's needed */
105 if (ctx->hunk == NULL) {
106
107 conf = (ngx_http_output_filter_conf_t *)
108 ngx_http_get_module_loc_conf(r->main ? r->main : r,
109 ngx_http_output_filter_module);
110
111 if (hunk->type & NGX_HUNK_LAST) {
112 size = hunk->last.mem - hunk->pos.mem;
113 if (size > conf->hunk_size) {
114 size = conf->hunk_size;
115 }
116
117 } else {
118 size = conf->hunk_size;
119 }
120
121 ngx_test_null(ctx->hunk,
122 ngx_create_temp_hunk(r->pool, size, 50, 50),
123 NGX_ERROR);
124
125 ctx->hunk->type |= NGX_HUNK_RECYCLED;
126 }
127
128 /* copy the incoming hunk or its part to our hunk
129 and pass it to the next filter */
130
131 do {
132 rc = ngx_http_output_filter_copy_hunk(ctx->hunk, hunk);
133
134 if (rc == NGX_ERROR) {
135 return rc;
136 }
137
138 #if (NGX_FILE_AIO_READ)
139
140 if (rc == NGX_AGAIN) {
141 /* add the incoming hunk to the incoming chain */
142 ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, NGX_ERROR);
143 return rc;
144 }
145
146 #endif
147 ctx->out.hunk = ctx->hunk;
148 ctx->out.next = NULL;
149
150 rc = next_filter(r, &ctx->out);
151
152 if (rc == NGX_ERROR) {
153 return rc;
154 }
155
156 if (rc == NGX_AGAIN) {
157 /* add the incoming hunk to the incoming chain */
158 ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, NGX_ERROR);
159 return rc;
160 }
161
162 /* NGX_OK */
163
164 /* set our hunk free */
165 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
166
167 /* repeat until we will have copied the whole incoming hunk */
168 } while (hunk->pos.mem < hunk->last.mem);
169
170 return NGX_OK;
171 }
172
173 /* the incoming chain ctx->in is not empty */
174
175 /* add the incoming hunk to the incoming chain */
176 if (hunk) {
177 for (ce = ctx->in; ce->next; ce = ce->next) {
178 /* void */ ;
179 }
180
181 ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR);
182 }
183
184 /* our hunk is still busy */
185 if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
186 rc = next_filter(r, NULL);
187
188 if (rc == NGX_ERROR || rc == NGX_AGAIN) {
189 return rc;
190 }
191
192 /* NGX_OK */
193 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
194 }
195
196 #if (NGX_SUPPRESS_WARN)
197 pe = NULL;
198 #endif
199
200 /* process the incoming chain ctx->in */
201 do {
202 /* find the hunks that do not need to be copied ... */
203 for (ce = ctx->in; ce; ce = ce->next) {
204 if (need_to_copy(r, ce->hunk)) {
205 break;
206 }
207 pe = ce;
208 }
209
210 /* ... and pass them to the next filter */
211 if (ctx->in != ce) {
212
213 ctx->out.hunk = ctx->in->hunk;
214 ctx->out.next = ctx->in->next;
215 ctx->in = ce;
216 pe->next = NULL;
217
218 rc = next_filter(r, &ctx->out);
219
220 if (rc == NGX_ERROR || rc == NGX_AGAIN) {
221 return rc;
222 }
223
224 /* NGX_OK */
225 if (ctx->in == NULL) {
226 return rc;
227 }
228 }
229
230
231 /* copy the first hunk or its part from the incoming chain ctx->in
232 to our hunk and pass it to the next filter */
233 do {
234 rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
235
236 if (rc == NGX_ERROR) {
237 return rc;
238 }
239
240 #if (NGX_FILE_AIO_READ)
241
242 if (rc == NGX_AGAIN) {
243 return rc;
244 }
245
246 #endif
247 ctx->out.hunk = ctx->hunk;
248 ctx->out.next = NULL;
249
250 rc = next_filter(r, &ctx->out);
251
252 if (rc == NGX_ERROR || rc == NGX_AGAIN) {
253 return rc;
254 }
255
256 /* NGX_OK */
257
258 /* set our hunk free */
259 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
260
261 /* repeat until we will have copied the whole first hunk from
262 the incoming chain ctx->in */
263 } while (ctx->in->hunk->pos.mem < ctx->in->hunk->last.mem);
264
265 /* delete the completed hunk from the incoming chain */
266 ctx->in = ctx->in->next;
267
268 /* repeat until we will have processed the whole incoming chain ctx->in */
269 } while (ctx->in);
270
271 return NGX_OK;
272 }
273
274
275 #else
58 276
59 277
60 int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) 278 int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
61 { 279 {
62 int rc, once; 280 int rc, once;
104 322
105 /* our hunk is free */ 323 /* our hunk is free */
106 } else { 324 } else {
107 ctx->out.hunk = ctx->hunk; 325 ctx->out.hunk = ctx->hunk;
108 326
327 /* XXX: should we check hunk type before copy it ? */
109 rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk); 328 rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
110 #if (NGX_FILE_AIO_READ) 329 #if (NGX_FILE_AIO_READ)
111 if (rc == NGX_AGAIN) { 330 if (rc == NGX_AGAIN) {
112 return rc; 331 return rc;
113 } 332 }
114 #endif 333 #endif
115 if (rc == NGX_ERROR) { 334 if (rc == NGX_ERROR) {
116 return rc; 335 return rc;
117 } 336 }
337
338 /* NGX_OK */
118 339
119 /* whole hunk is copied so we send to next filter chain part 340 /* whole hunk is copied so we send to next filter chain part
120 up to next hunk that need to be copied */ 341 up to next hunk that need to be copied */
121 if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) { 342 if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) {
122 ctx->out.next = ctx->in->next; 343 ctx->out.next = ctx->in->next;
240 next_output_body_filter(r, &ctx->out); 461 next_output_body_filter(r, &ctx->out);
241 } 462 }
242 } 463 }
243 } 464 }
244 465
245 if (rc == NGX_OK && ctx->hunk) 466 /* set free our hunk if operation has completed */
467 if (rc == NGX_OK && ctx->hunk) {
246 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; 468 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
469 }
247 } 470 }
248 471
249 #if (NGX_SUPPRESS_WARN) 472 #if (NGX_SUPPRESS_WARN)
250 if (rc == NGX_ALERT) { 473 if (rc == NGX_ALERT) {
251 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, 474 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
257 if (rc == NGX_OK && ctx->last) { 480 if (rc == NGX_OK && ctx->last) {
258 return NGX_OK; 481 return NGX_OK;
259 } 482 }
260 483
261 if (rc == NGX_OK) { 484 if (rc == NGX_OK) {
262 if (ctx->hunk) { 485 if (ctx->hunk) { /* XXX: double upper code ? */
263 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; 486 ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
264 } 487 }
265 #if (NGX_LEVEL_EVENT) 488 #if (NGX_LEVEL_EVENT)
266 ngx_del_event(r->connection->write, NGX_WRITE_EVENT); 489 ngx_del_event(r->connection->write, NGX_WRITE_EVENT);
267 #endif 490 #endif
268 } 491 }
269 492
270 return rc; 493 return rc;
271 } 494 }
495
496 #endif
272 497
273 498
274 static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src) 499 static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src)
275 { 500 {
276 ssize_t n, size; 501 ssize_t n, size;