From f0bbc7468c445b02bd37ae27b33b24e9436a0dc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Wed, 4 Feb 2009 17:30:18 +0000 Subject: [PATCH] Use modified etags in mod_compress (fixes #1800) git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2386 152afb58-edef-0310-8abb-c4023f1b3aa9 --- NEWS | 1 + src/mod_compress.c | 58 +++++++++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/NEWS b/NEWS index 5ff1fd2d..a9ba3aa5 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,7 @@ NEWS * Use/enforce sane max-connection values (fixes #1803) * Allow mod_compress to return 304 (Not Modified); compress ignores the static-file.etags option.(fixes #1884) * Add option to ignore the "Expect: 100-continue" header instead of returning 417 Expectation failed (closes #1017) + * Use modified etags in mod_compress (fixes #1800) - 1.4.20 - 2008-09-30 diff --git a/src/mod_compress.c b/src/mod_compress.c index 71ab206d..2127ad3b 100644 --- a/src/mod_compress.c +++ b/src/mod_compress.c @@ -726,16 +726,6 @@ PHYSICALPATH_FUNC(mod_compress_physical) { /* mimetype found */ data_string *ds; - etag_mutate(con->physical.etag, sce->etag); - mtime = strftime_cache_get(srv, sce->st.st_mtime); - - if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) { - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); - response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); - response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); - return HANDLER_FINISHED; - } - /* the response might change according to Accept-Encoding */ response_header_insert(srv, con, CONST_STR_LEN("Vary"), CONST_STR_LEN("Accept-Encoding")); @@ -766,6 +756,17 @@ PHYSICALPATH_FUNC(mod_compress_physical) { const char *compression_name = NULL; int compression_type = 0; + mtime = strftime_cache_get(srv, sce->st.st_mtime); + + /* try matching original etag of uncompressed version */ + etag_mutate(con->physical.etag, sce->etag); + if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) { + response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); + response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); + response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); + return HANDLER_FINISHED; + } + /* select best matching encoding */ if (matched_encodings & HTTP_ACCEPT_ENCODING_BZIP2) { compression_type = HTTP_ACCEPT_ENCODING_BZIP2; @@ -778,25 +779,34 @@ PHYSICALPATH_FUNC(mod_compress_physical) { compression_name = dflt_deflate; } - /* deflate it */ - if (p->conf.compress_cache_dir->used) { - if (0 == deflate_file_to_file(srv, con, p, - con->physical.path, sce, compression_type)) { - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name)); - response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); - response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); - return HANDLER_GO_ON; - } - } else if (0 == deflate_file_to_buffer(srv, con, p, - con->physical.path, sce, compression_type)) { + /* try matching etag of compressed version */ + buffer_copy_string_buffer(srv->tmp_buf, sce->etag); + buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("-")); + buffer_append_string(srv->tmp_buf, compression_name); + etag_mutate(con->physical.etag, srv->tmp_buf); + + if (HANDLER_FINISHED == http_response_handle_cachable(srv, con, mtime)) { response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name)); + response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); - response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); return HANDLER_FINISHED; } - break; + + /* deflate it */ + if (p->conf.compress_cache_dir->used) { + if (0 != deflate_file_to_file(srv, con, p, con->physical.path, sce, compression_type)) + return HANDLER_GO_ON; + } else { + if (0 != deflate_file_to_buffer(srv, con, p, con->physical.path, sce, compression_type)) + return HANDLER_GO_ON; + } + response_header_overwrite(srv, con, CONST_STR_LEN("Content-Encoding"), compression_name, strlen(compression_name)); + response_header_overwrite(srv, con, CONST_STR_LEN("Last-Modified"), CONST_BUF_LEN(mtime)); + response_header_overwrite(srv, con, CONST_STR_LEN("ETag"), CONST_BUF_LEN(con->physical.etag)); + response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_BUF_LEN(sce->content_type)); + /* let mod_staticfile handle the cached compressed files, physical path was modified */ + return p->conf.compress_cache_dir->used ? HANDLER_GO_ON : HANDLER_FINISHED; } } }