[mod_deflate] mod_deflate subsumes mod_compress

translate config server.modules "mod_compress" to "mod_deflate"
accept compress.* directives, but issue DEPRECATED warning trace

mod_deflate differences from mod_compress:
- mod_compress compress.filetype was exact match; deflate.mimetypes is
  prefix match (behavior change might compress longer mimetype matches,
  which are likely of similar type and compressability)
- mod_compress always sent entire (compressed) file for Range request
  mod_deflate will stream compress range result (not stored in cache)
- mod_compress would short-circuit request with 403 Forbidden error
  if request file did not exist (stat() failed) (This behavior was
  unfriendly to other handlers)
- mod_compress compress.cache-dir layout differs from deflate.cache-dir
  layout; file cache should be cleared (or renamed) when migrating from
  mod_compress to mod_deflate
- mod_deflate does not issue Vary: Accept-Encoding if request does not
  contain Accept-Encoding.  The identity response can be cache by
  proxies and served to clients.  Historically, some proxies disabled
  caching if any Vary: response was seen.  If the Vary header is
  desirable, mod_deflate code which checks for Accept-Encoding and
  compression type can be moved down a few lines to be below the
  setting of the Vary response header.
personal/stbuehler/tests-path
Glenn Strauss 2020-07-20 03:40:50 -04:00
parent be6da785c5
commit 8dd33a72dd
7 changed files with 134 additions and 12 deletions

View File

@ -388,6 +388,57 @@ static void config_compat_module_load (server *srv) {
}
}
static void config_deprecate_module_compress (server *srv) {
int mod_compress_idx = -1;
int mod_deflate_idx = -1;
for (uint32_t i = 0; i < srv->srvconf.modules->used; ++i) {
buffer *m = &((data_string *)srv->srvconf.modules->data[i])->value;
if (buffer_eq_slen(m, CONST_STR_LEN("mod_compress")))
mod_compress_idx = (int)i;
else if (buffer_eq_slen(m, CONST_STR_LEN("mod_deflate")))
mod_deflate_idx = (int)i;
}
if (mod_compress_idx < 0) return;
int has_compress_directive = 0;
for (uint32_t i = 0; i < srv->config_context->used; ++i) {
const data_config *config =
(data_config const *)srv->config_context->data[i];
for (uint32_t j = 0; j < config->value->used; ++j) {
buffer *k = &config->value->data[j]->key;
if (0 == strncmp(k->ptr, "compress.", sizeof("compress.")-1)) {
has_compress_directive = 1;
break;
}
}
if (has_compress_directive) {
log_error(srv->errh, __FILE__, __LINE__,
"Warning: \"mod_compress\" is DEPRECATED and has been replaced "
"with \"mod_deflate\". A future release of lighttpd 1.4.x will "
"not contain mod_compress and lighttpd may fail to start up");
break;
}
}
if (mod_deflate_idx >= 0 || !has_compress_directive) {
/* create new modules value list without mod_compress */
array *a = array_init(srv->srvconf.modules->used-1);
for (uint32_t i = 0; i < srv->srvconf.modules->used; ++i) {
buffer *m = &((data_string *)srv->srvconf.modules->data[i])->value;
if (buffer_eq_slen(m, CONST_STR_LEN("mod_compress")))
continue;
array_insert_value(a, CONST_BUF_LEN(m));
}
array_free(srv->srvconf.modules);
srv->srvconf.modules = a;
}
else {
/* replace "mod_compress" value with "mod_deflate" value */
buffer *m = &((data_string *)srv->srvconf.modules->data[mod_compress_idx])->value;
buffer_copy_string_len(m, CONST_STR_LEN("mod_deflate"));
}
}
static int config_http_parseopts (server *srv, const array *a) {
unsigned short int opts = srv->srvconf.http_url_normalize;
unsigned short int decode_2f = 1;
@ -740,6 +791,8 @@ static int config_insert_srvconf(server *srv) {
if (srv->srvconf.compat_module_load)
config_compat_module_load(srv);
config_deprecate_module_compress(srv);
if (srv->srvconf.http_url_normalize && !config_burl_normalize_cond(srv))
rc = HANDLER_ERROR;

View File

@ -491,8 +491,6 @@ void http_response_send_file (request_st * const r, buffer * const path) {
return;
}
/* mod_compress might set several data directly, don't overwrite them */
/* set response content-type, if not set already */
if (NULL == http_header_response_get(r, HTTP_HEADER_CONTENT_TYPE, CONST_STR_LEN("Content-Type"))) {

View File

@ -85,7 +85,6 @@
* - might add deflate.mimetypes-exclude = ( ... ) for list of mimetypes
* to avoid compressing, even if a broader deflate.mimetypes matched,
* e.g. to compress all "text/" except "text/special".
* - mod_compress and mod_deflate might merge overlapping feature sets
*
* Implementation notes:
* - http_chunk_append_mem() used instead of http_chunk_append_buffer()
@ -351,6 +350,21 @@ static void mod_deflate_merge_config_cpv(plugin_config * const pconf, const conf
case 8: /* deflate.cache-dir */
pconf->cache_dir = cpv->v.b;
break;
case 9: /* compress.filetype */
pconf->mimetypes = cpv->v.a;
break;
case 10:/* compress.allowed-encodings */
pconf->allowed_encodings = (short)cpv->v.shrt;
break;
case 11:/* compress.cache-dir */
pconf->cache_dir = cpv->v.b;
break;
case 12:/* compress.max-filesize */
pconf->max_compress_size = cpv->v.u;
break;
case 13:/* compress.max-loadavg */
pconf->max_loadavg = cpv->v.d;
break;
default:/* should not happen */
return;
}
@ -450,6 +464,21 @@ SETDEFAULTS_FUNC(mod_deflate_set_defaults) {
,{ CONST_STR_LEN("deflate.cache-dir"),
T_CONFIG_STRING,
T_CONFIG_SCOPE_CONNECTION }
,{ CONST_STR_LEN("compress.filetype"),
T_CONFIG_ARRAY_VLIST,
T_CONFIG_SCOPE_CONNECTION }
,{ CONST_STR_LEN("compress.allowed-encodings"),
T_CONFIG_ARRAY_VLIST,
T_CONFIG_SCOPE_CONNECTION }
,{ CONST_STR_LEN("compress.cache-dir"),
T_CONFIG_STRING,
T_CONFIG_SCOPE_CONNECTION }
,{ CONST_STR_LEN("compress.max-filesize"),
T_CONFIG_INT,
T_CONFIG_SCOPE_CONNECTION }
,{ CONST_STR_LEN("compress.max-loadavg"),
T_CONFIG_STRING,
T_CONFIG_SCOPE_CONNECTION }
,{ NULL, 0,
T_CONFIG_UNSET,
T_CONFIG_SCOPE_UNSET }
@ -517,6 +546,50 @@ SETDEFAULTS_FUNC(mod_deflate_set_defaults) {
}
}
break;
case 9: /* compress.filetype */
log_error(srv->errh, __FILE__, __LINE__,
"DEPRECATED: %s replaced with deflate.mimetypes",
cpk[cpv->k_id].k);
break;
case 10:/* compress.allowed-encodings */
log_error(srv->errh, __FILE__, __LINE__,
"DEPRECATED: %s replaced with deflate.allowed-encodings",
cpk[cpv->k_id].k);
cpv->v.shrt = (unsigned short)
mod_deflate_encodings_to_flags(cpv->v.a);
cpv->vtype = T_CONFIG_SHORT;
break;
case 11:/* compress.cache-dir */
log_error(srv->errh, __FILE__, __LINE__,
"DEPRECATED: %s replaced with deflate.cache-dir",
cpk[cpv->k_id].k);
if (!buffer_string_is_empty(cpv->v.b)) {
buffer *b;
*(const buffer **)&b = cpv->v.b;
const uint32_t len = buffer_string_length(b);
if (len > 0 && '/' == b->ptr[len-1])
buffer_string_set_length(b, len-1); /*remove end slash*/
struct stat st;
if (0 != stat(b->ptr,&st) && 0 != mkdir_recursive(b->ptr)) {
log_perror(srv->errh, __FILE__, __LINE__,
"can't stat %s %s", cpk[cpv->k_id].k, b->ptr);
return HANDLER_ERROR;
}
}
break;
case 12:/* compress.max-filesize */
log_error(srv->errh, __FILE__, __LINE__,
"DEPRECATED: %s replaced with deflate.max-compress-size",
cpk[cpv->k_id].k);
break;
case 13:/* compress.max-loadavg */
log_error(srv->errh, __FILE__, __LINE__,
"DEPRECATED: %s replaced with deflate.max-loadavg",
cpk[cpv->k_id].k);
cpv->v.d = (!buffer_string_is_empty(cpv->v.b))
? strtod(cpv->v.b->ptr, NULL)
: 0.0;
break;
default:/* should not happen */
break;
}
@ -1197,6 +1270,7 @@ static int mod_deflate_choose_encoding (const char *value, plugin_data *p, const
int accept_encoding = 0;
#if !defined(USE_ZLIB) && !defined(USE_BZ2LIB) && !defined(USE_BROTLI)
UNUSED(value);
UNUSED(label);
#else
for (; *value; ++value) {
const char *v;

View File

@ -349,9 +349,6 @@ handler_t http_response_prepare(request_st * const r) {
*
* fastcgi-auth might lead to a COMEBACK too
* fastcgi again dead server too
*
* mod_compress might add headers twice too
*
*/
if (r->conf.log_request_handling) {

View File

@ -170,5 +170,5 @@ $HTTP["host"] =~ "allow\.example\.org$" {
$HTTP["host"] == "etag.example.org" {
static-file.etags = "disable"
compress.filetype = ()
deflate.filetype = ()
}

View File

@ -15,7 +15,7 @@ server.breakagelog = env.SRCDIR + "/tmp/lighttpd/logs/lighttpd.breakage.
server.name = "www.example.org"
server.modules = (
"mod_compress",
"mod_deflate",
)
mimetype.assign = (
@ -24,15 +24,15 @@ mimetype.assign = (
)
$HTTP["host"] == "cache.example.org" {
compress.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
deflate.cache-dir = env.SRCDIR + "/tmp/lighttpd/cache/compress/"
}
compress.filetype = (
deflate.mimetypes = (
"text/plain",
"text/html",
)
compress.allowed-encodings = (
deflate.allowed-encodings = (
"gzip",
"deflate",
)

View File

@ -87,7 +87,7 @@ User-Agent: MYOB/6.66 (AN/ON)
Connection: close
EOF
);
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '+Vary' => '', 'Content-Type' => "text/plain; charset=utf-8" } ];
$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, '-Content-Encoding' => '', 'Content-Type' => "text/plain; charset=utf-8" } ];
ok($tf->handle_http($t) == 0, 'Empty Accept-Encoding');
$t->{REQUEST} = ( <<EOF