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