Mercurial > hg > ngx_http_bytes_filter_module
comparison ngx_http_bytes_filter_module.c @ 11:47a21c299f11
Fix work with multiple buffers.
1. Always free or pass out buffers got from callers.
2. Don't pass out zero size bufs, pass null chain instead.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sat, 02 Aug 2008 05:01:22 +0400 |
parents | 42975d951e9f |
children | 48cdd1bfa48e |
comparison
equal
deleted
inserted
replaced
10:42975d951e9f | 11:47a21c299f11 |
---|---|
355 } | 355 } |
356 | 356 |
357 return ngx_http_next_body_filter(r, in); | 357 return ngx_http_next_body_filter(r, in); |
358 } | 358 } |
359 | 359 |
360 for (ll = &in, cl = in; cl; ll = &cl->next, cl = cl->next, | 360 for (ll = &in, cl = in; cl; cl = cl->next, ctx->offset += size) { |
361 ctx->offset += size) | |
362 { | |
363 | 361 |
364 buf = cl->buf; | 362 buf = cl->buf; |
365 size = ngx_buf_size(buf); | 363 size = ngx_buf_size(buf); |
366 | 364 |
367 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 365 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
369 | 367 |
370 if (ngx_buf_special(buf)) { | 368 if (ngx_buf_special(buf)) { |
371 /* pass out anyway */ | 369 /* pass out anyway */ |
372 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 370 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
373 "bytes body filter: special buffer"); | 371 "bytes body filter: special buffer"); |
372 ll = &cl->next; | |
374 continue; | 373 continue; |
375 } | 374 } |
376 | 375 |
377 next: | 376 next: |
378 if (range->start > ctx->offset + size) { | 377 if (range->start > ctx->offset + size || range->end < ctx->offset) { |
379 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 378 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
380 "bytes body filter: fully ignored buffer"); | 379 "bytes body filter: fully ignored buffer"); |
380 buf->pos = buf->last; | |
381 *ll = cl->next; | 381 *ll = cl->next; |
382 buf->pos = buf->last; | |
383 continue; | 382 continue; |
384 } | 383 } |
385 | 384 |
386 /* todo: do not create buffers/links if not needed */ | 385 /* we should either free or reuse original buffer */ |
386 | |
387 if (range == last - 1 || range[1].start > ctx->offset + size) { | |
388 b = buf; | |
389 goto fixup; | |
390 } | |
387 | 391 |
388 b = ngx_calloc_buf(r->pool); | 392 b = ngx_calloc_buf(r->pool); |
389 if (b == NULL) { | 393 if (b == NULL) { |
390 return NGX_ERROR; | 394 return NGX_ERROR; |
391 } | 395 } |
418 | 422 |
419 if (buf->last_buf && range == last - 1) { | 423 if (buf->last_buf && range == last - 1) { |
420 b->last_buf = 1; | 424 b->last_buf = 1; |
421 } | 425 } |
422 | 426 |
427 fixup: | |
423 if (b->in_file) { | 428 if (b->in_file) { |
424 | 429 |
425 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 430 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
426 "bytes body filter: in file, %O-%O", | 431 "bytes body filter: in file, %O-%O", |
427 b->file_pos, b->file_last); | 432 b->file_pos, b->file_last); |
460 range++; | 465 range++; |
461 if (range < last) { | 466 if (range < last) { |
462 goto next; | 467 goto next; |
463 } | 468 } |
464 } | 469 } |
470 | |
471 ll = &cl->next; | |
465 } | 472 } |
466 | 473 |
467 return ngx_http_next_body_filter(r, in); | 474 return ngx_http_next_body_filter(r, in); |
468 } | 475 } |
469 | 476 |