comparison src/core/ngx_output_chain.c @ 469:2ff194b74f1e release-0.1.9

nginx-0.1.9-RELEASE import *) Bugfix: the proxied request was sent without arguments if the request contains "//", "/./", "/../" or "%XX". *) Bugfix: the large compressed responses may be transferred not completely. *) Bugfix: the files bigger than 2G was not transferred on Linux that does not support sendfile64(). *) Bugfix: while the build configuration on Linux the --with-poll_module parameter was required; the bug had appeared in 0.1.8.
author Igor Sysoev <igor@sysoev.ru>
date Thu, 25 Nov 2004 16:17:31 +0000
parents bbd6b0b4a2b1
children 8e8f3af115b5
comparison
equal deleted inserted replaced
468:1a67596d0349 469:2ff194b74f1e
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10 10
11 11
12 #define NGX_NONE 1 12 #if 0
13 #define NGX_SENDFILE_LIMIT 4096
14 #endif
15
16
17 #define NGX_NONE 1
13 18
14 19
15 static ngx_inline ngx_int_t 20 static ngx_inline ngx_int_t
16 ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf); 21 ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf);
22 static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool,
23 ngx_chain_t **chain, ngx_chain_t *in);
17 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src, 24 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src,
18 ngx_uint_t sendfile); 25 ngx_uint_t sendfile);
19 26
20 27
21 ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in) 28 ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
24 size_t size, bsize; 31 size_t size, bsize;
25 ngx_chain_t *cl, *out, **last_out; 32 ngx_chain_t *cl, *out, **last_out;
26 33
27 if (ctx->in == NULL && ctx->busy == NULL) { 34 if (ctx->in == NULL && ctx->busy == NULL) {
28 35
29 /* 36 /*
30 * the short path for the case when the ctx->in and ctx->busy chains 37 * the short path for the case when the ctx->in and ctx->busy chains
31 * are empty, the incoming chain is empty too or has the single buf 38 * are empty, the incoming chain is empty too or has the single buf
32 * that does not require the copy 39 * that does not require the copy
33 */ 40 */
34 41
35 if (in == NULL) { 42 if (in == NULL) {
36 return ctx->output_filter(ctx->filter_ctx, in); 43 return ctx->output_filter(ctx->filter_ctx, in);
37 } 44 }
38 45
39 if (in->next == NULL 46 if (in->next == NULL
47 #if (NGX_SENDFILE_LIMIT)
48 && !(in->buf->in_file && in->buf->file_last > NGX_SENDFILE_LIMIT)
49 #endif
40 && (!ngx_output_chain_need_to_copy(ctx, in->buf))) 50 && (!ngx_output_chain_need_to_copy(ctx, in->buf)))
41 { 51 {
42 return ctx->output_filter(ctx->filter_ctx, in); 52 return ctx->output_filter(ctx->filter_ctx, in);
43 } 53 }
44 } 54 }
45 55
46 /* add the incoming buf to the chain ctx->in */ 56 /* add the incoming buf to the chain ctx->in */
47 57
48 if (in) { 58 if (in) {
49 if (ngx_chain_add_copy(ctx->pool, &ctx->in, in) == NGX_ERROR) { 59 if (ngx_output_chain_add_copy(ctx->pool, &ctx->in, in) == NGX_ERROR) {
50 return NGX_ERROR; 60 return NGX_ERROR;
51 } 61 }
52 } 62 }
53 63
54 last = NGX_NONE; 64 last = NGX_NONE;
189 199
190 200
191 static ngx_inline ngx_int_t 201 static ngx_inline ngx_int_t
192 ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf) 202 ngx_output_chain_need_to_copy(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf)
193 { 203 {
204 ngx_uint_t sendfile;
205
194 if (ngx_buf_special(buf)) { 206 if (ngx_buf_special(buf)) {
195 return 0; 207 return 0;
196 } 208 }
197 209
198 if (!ctx->sendfile) { 210 sendfile = ctx->sendfile;
211
212 #if (NGX_SENDFILE_LIMIT)
213
214 if (buf->in_file && buf->file_pos >= NGX_SENDFILE_LIMIT) {
215 sendfile = 0;
216 }
217
218 #endif
219
220 if (!sendfile) {
199 221
200 if (!ngx_buf_in_memory(buf)) { 222 if (!ngx_buf_in_memory(buf)) {
201 return 1; 223 return 1;
202 } 224 }
203 225
211 if (ctx->need_in_temp && (buf->memory || buf->mmap)) { 233 if (ctx->need_in_temp && (buf->memory || buf->mmap)) {
212 return 1; 234 return 1;
213 } 235 }
214 236
215 return 0; 237 return 0;
238 }
239
240
241 static ngx_int_t ngx_output_chain_add_copy(ngx_pool_t *pool,
242 ngx_chain_t **chain, ngx_chain_t *in)
243 {
244 ngx_chain_t *cl, **ll;
245 #if (NGX_SENDFILE_LIMIT)
246 ngx_buf_t *b, *buf;
247 #endif
248
249 ll = chain;
250
251 for (cl = *chain; cl; cl = cl->next) {
252 ll = &cl->next;
253 }
254
255 while (in) {
256
257 if (!(cl = ngx_alloc_chain_link(pool))) {
258 return NGX_ERROR;
259 }
260
261 #if (NGX_SENDFILE_LIMIT)
262
263 buf = in->buf;
264
265 if (buf->in_file
266 && buf->file_pos < NGX_SENDFILE_LIMIT
267 && buf->file_last > NGX_SENDFILE_LIMIT)
268 {
269 if (!(b = ngx_calloc_buf(pool))) {
270 return NGX_ERROR;
271 }
272
273 ngx_memcpy(b, buf, sizeof(ngx_buf_t));
274
275 if (ngx_buf_in_memory(buf)) {
276 buf->pos += (ssize_t) (NGX_SENDFILE_LIMIT - buf->file_pos);
277 b->last = buf->pos;
278 }
279
280 buf->file_pos = NGX_SENDFILE_LIMIT;
281 b->file_last = NGX_SENDFILE_LIMIT;
282
283 cl->buf = b;
284
285 } else {
286 cl->buf = buf;
287 in = in->next;
288 }
289
290 #else
291 cl->buf = in->buf;
292 in = in->next;
293
294 #endif
295
296 *ll = cl;
297 ll = &cl->next;
298 }
299
300 *ll = NULL;
301
302 return NGX_OK;
216 } 303 }
217 304
218 305
219 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src, 306 static ngx_int_t ngx_output_chain_copy_buf(ngx_buf_t *dst, ngx_buf_t *src,
220 ngx_uint_t sendfile) 307 ngx_uint_t sendfile)
225 size = ngx_buf_size(src); 312 size = ngx_buf_size(src);
226 313
227 if (size > (size_t) (dst->end - dst->pos)) { 314 if (size > (size_t) (dst->end - dst->pos)) {
228 size = dst->end - dst->pos; 315 size = dst->end - dst->pos;
229 } 316 }
317
318 #if (NGX_SENDFILE_LIMIT)
319
320 if (src->in_file && src->file_pos >= NGX_SENDFILE_LIMIT) {
321 sendfile = 0;
322 }
323
324 #endif
230 325
231 if (ngx_buf_in_memory(src)) { 326 if (ngx_buf_in_memory(src)) {
232 ngx_memcpy(dst->pos, src->pos, size); 327 ngx_memcpy(dst->pos, src->pos, size);
233 src->pos += size; 328 src->pos += size;
234 dst->last += size; 329 dst->last += size;