On Thu, Oct 26, 2006 at 05:20:10PM +0200, Plüm, Rüdiger, VF EITO wrote: > > Index: modules/cache/mod_disk_cache.c > > =================================================================== > > --- modules/cache/mod_disk_cache.c (revision 450104) > > +++ modules/cache/mod_disk_cache.c (working copy) > > > @@ -998,12 +998,16 @@ > > dobj->file_size = 0; > > } > > > > - for (e = APR_BRIGADE_FIRST(bb); > > - e != APR_BRIGADE_SENTINEL(bb); > > - e = APR_BUCKET_NEXT(e)) > > - { > > + e = APR_BRIGADE_FIRST(bb); > > + while (e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e)) { > > const char *str; > > apr_size_t length, written; > > + > > + if (APR_BUCKET_IS_METADATA(e)) { > > + e = APR_BUCKET_NEXT(e); > > + continue; > > + } > > + > > Why ignore the metadata buckets? This means that flush buckets do not get > passed > up the chain via the temporary brigade tmpbb. This is bad IMHO. > I guess the best thing we can do here is to add them to tmpbb before doing the > continue. Of course this means that all additions need to be done to the tail > of tmpbb.
Yeah, I noticed this too. For FLUSH buckets batching them up in tmpbb is no good either, they need to be sent up the filter chain immediately. I changed it like this: (incremental patch with diff -wu to hide the re-indenting) --- mod_disk_cache.c.prev 2006-10-26 16:39:17.000000000 +0100 +++ mod_disk_cache.c 2006-10-26 16:32:16.000000000 +0100 @@ -1003,11 +1003,8 @@ const char *str; apr_size_t length, written; - if (APR_BUCKET_IS_METADATA(e)) { - e = APR_BUCKET_NEXT(e); - continue; - } - + /* Store contents of non-metadata buckets to disk. */ + if (!APR_BUCKET_IS_METADATA(e)) { rv = apr_bucket_read(e, &str, &length, APR_BLOCK_READ); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, @@ -1036,21 +1033,23 @@ file_cache_errorcleanup(dobj, r); return APR_EGENERAL; } + } next = APR_BUCKET_NEXT(e); - /* Move the bucket to the temp brigade and flush it up the + /* Move the bucket to the temp brigade and pass it down the * filter chain. */ APR_BUCKET_REMOVE(e); APR_BRIGADE_INSERT_HEAD(tmpbb, e); + + if (!r->connection->aborted) { rv = ap_pass_brigade(f_next, tmpbb); if (rv) { + r->connection->aborted = 1; ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, r->server, "disk_cache: failed to flush brigade for URL %s", h->cache_obj->key); - /* Remove the intermediate cache file and return non-APR_SUCCESS */ - file_cache_errorcleanup(dobj, r); - return rv; + } } /* Discard the bucket and move on. */ @@ -1059,19 +1058,29 @@ e = next; } - /* Was this the final bucket? If yes, close the temp file and perform - * sanity checks. - */ - if (e != APR_BRIGADE_SENTINEL(bb) && APR_BUCKET_IS_EOS(e)) { - if (r->connection->aborted || r->no_cache) { + if (r->no_cache) { + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "disk_cache: Discarding body for URL %s, " + "no-cache flag set", h->cache_obj->key); + /* Remove the intermediate cache file and return non-APR_SUCCESS */ + file_cache_errorcleanup(dobj, r); + return APR_SUCCESS; + } + + if (r->connection->aborted) { ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, "disk_cache: Discarding body for URL %s " "because connection has been aborted.", h->cache_obj->key); /* Remove the intermediate cache file and return non-APR_SUCCESS */ file_cache_errorcleanup(dobj, r); - return APR_EGENERAL; + return APR_ECONNABORTED; } + + /* Was this the final bucket? If yes, close the temp file and perform + * sanity checks. + */ + if (e != APR_BRIGADE_SENTINEL(bb) && APR_BUCKET_IS_EOS(e)) { if (dobj->file_size < conf->minfs) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "disk_cache: URL %s failed the size check "