changeset 4895:508e61393b6c

Event pipe: fixed handling of buf_to_file data. Input filter might free a buffer if there is no data in it, and in case of first buffer (used for cache header and request header, aka p->buf_to_file) this resulted in cache corruption. Buffer memory was reused to read upstream response before headers were written to disk. Fix is to avoid moving pointers in ngx_event_pipe_add_free_buf() to a buffer start if we were asked to free a buffer used by p->buf_to_file. This fixes occasional cache file corruption, usually resulted in "cache file ... has md5 collision" alerts. Reported by Anatoli Marinov.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 30 Oct 2012 11:14:24 +0000
parents 0156fd6f48fa
children ab7ce0eb4cf7
files src/event/ngx_event_pipe.c src/http/ngx_http_upstream.c
diffstat 2 files changed, 10 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -946,8 +946,15 @@ ngx_event_pipe_add_free_buf(ngx_event_pi
         return NGX_ERROR;
     }
 
-    b->pos = b->start;
-    b->last = b->start;
+    if (p->buf_to_file && b->start == p->buf_to_file->start) {
+        b->pos = p->buf_to_file->last;
+        b->last = p->buf_to_file->last;
+
+    } else {
+        b->pos = b->start;
+        b->last = b->start;
+    }
+
     b->shadow = NULL;
 
     cl->buf = b;
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -2287,6 +2287,7 @@ ngx_http_upstream_send_response(ngx_http
             return;
         }
 
+        p->buf_to_file->start = u->buffer.start;
         p->buf_to_file->pos = u->buffer.start;
         p->buf_to_file->last = u->buffer.pos;
         p->buf_to_file->temporary = 1;