DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://issues.apache.org/bugzilla/show_bug.cgi?id=31385>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://issues.apache.org/bugzilla/show_bug.cgi?id=31385 mod_cache skipping start of file if recaching already cached file Summary: mod_cache skipping start of file if recaching already cached file Product: Apache httpd-2.0 Version: 2.0.51 Platform: All OS/Version: All Status: NEW Severity: Normal Priority: Other Component: mod_cache AssignedTo: [email protected] ReportedBy: [EMAIL PROTECTED] Hi, I found some weird behaviour in mod_cache which I believe to be a bug. First of all my environment: I. Environment Apache: 2.0.51 OS: Linux Excerpt from my Apache configuration: <VirtualHost 192.168.2.4:80> ServerName www.something.de ServerAdmin [EMAIL PROTECTED] DocumentRoot "/var/httpd/test/www.something.de/docs" ErrorLog "|/opt/apache-2.0.51/bin/rotatelogs /var/httpd/test/www.something.de/logs/error_log 86400" CustomLog "|/opt/apache-2.0.51/bin/rotatelogs /var/httpd/test/www.something.de/logs/access_log 86400" combined <Directory /var/httpd/test/www.something.de/docs> Options None AllowOverride None </Directory> JkMount /* worker_ajp13 CacheRoot /var/httpd/test/cache/cache CacheMaxFileSize 10000000 CacheSize 256000 CacheEnable disk /jsp-examples CacheDirLevels 5 CacheDirLength 3 CacheMaxExpire 120 CacheIgnoreNoLastMod On CacheIgnoreCacheControl On CacheDefaultExpire 120 </VirtualHost> II. Problem description As you can see from my configuration excerpt I use mod_cache to cache answers delivered by a Tomcat in the backend. If I cache a large file from Tomcat at first glance everything seems to work fine. The file gets cached and delivered (1st request). If I wait until this file is expired and request it again the file is delivered correctly but it can be noticed that the cached file is about 8 KB shorter then the previous one (2nd request). If I do another request shortly afterwards (so that the file is not expired) the start of the file is missing (3rd request). III. Problem analysis I set the loglevel to debug and noticed that during the second request the CACHE_CONDITIONAL filter is used as seen from the error log: [Thu Sep 23 10:35:55 2004] [debug] /usr/src/redhat/BUILD/apache-2.0.51/httpd-2.0.51/modules/experimental/mod_cache.c(293): cache: running CACHE_CONDITIONAL filter IV. Conclusion As the missing data is about 8 Kb I think the first bucket of the brigade is not running through the CACHE_SAVE filter and thus does not get saved to the cache file. Having a look in cache_conditional_filter in modules/experimental/mod_cache.c I noticed that after adding the appropriate filter (either CACHE_OUT or CACHE_SAVE) ap_pass_brigade is called in line 300 with f->next as filter parameter. I believe that this is wrong, because f->next points to the next filter after the CACHE_CONDITIONAL filter and not to the newly added filter whichs ->next pointer points to f->next after the deletion of the CACHE_CONDITIONAL filter. V. Solution proposal I think the filter returned by ap_add_output_filter_handle should be used in the call of ap_pass_brigade instead of f->next. This results in the following patch (which I will attach to this bug report): --- httpd-2.0.51.orig/modules/experimental/mod_cache.c 2004-08-26 18:59:44.000000000 +0200 +++ httpd-2.0.51/modules/experimental/mod_cache.c 2004-09-23 09:00:58.000000000 +0200 @@ -282,22 +282,24 @@ static int cache_out_filter(ap_filter_t static int cache_conditional_filter(ap_filter_t *f, apr_bucket_brigade *in) { + ap_filter_t *replaced_filter; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, f->r->server, "cache: running CACHE_CONDITIONAL filter"); if (f->r->status == HTTP_NOT_MODIFIED) { /* replace ourselves with CACHE_OUT filter */ - ap_add_output_filter_handle(cache_out_filter_handle, NULL, - f->r, f->r->connection); + replaced_filter = ap_add_output_filter_handle(cache_out_filter_handle, NULL, + f->r, f->r->connection); } else { /* replace ourselves with CACHE_SAVE filter */ - ap_add_output_filter_handle(cache_save_filter_handle, NULL, - f->r, f->r->connection); + replaced_filter = ap_add_output_filter_handle(cache_save_filter_handle, NULL, + f->r, f->r->connection); } ap_remove_output_filter(f); - return ap_pass_brigade(f->next, in); + return ap_pass_brigade(replaced_filter, in); } I applied this patch and the problem was gone afterwards. Regards Rüdiger Plüm --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
