From 54aa067d2e7d37faea1a86eb45b0729bdbfa6ffc Mon Sep 17 00:00:00 2001 From: manu Date: Mon, 9 Jan 2023 14:52:27 +0000 Subject: [PATCH] *) mod_dav: DAVlockDiscovery option to disable WebDAV lock discovery This is a game changer for performances if client use PROPFIND a lot, PR: 66313 Submited by: manu Reviewed by: manu, covener, gbechis git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1906506 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 +++ STATUS | 11 ------- docs/manual/mod/mod_dav_fs.html.en | 21 +++++++++++++ docs/manual/mod/mod_dav_fs.html.fr.utf8 | 22 ++++++++++++++ docs/manual/mod/mod_dav_fs.html.ja.utf8 | 14 +++++++++ docs/manual/mod/mod_dav_fs.html.ko.euc-kr | 14 +++++++++ docs/manual/mod/mod_dav_fs.xml | 26 ++++++++++++++++ docs/manual/mod/mod_dav_fs.xml.fr | 27 +++++++++++++++++ modules/dav/main/mod_dav.c | 36 +++++++++++++++++++++-- modules/dav/main/mod_dav.h | 7 +++-- modules/dav/main/props.c | 16 ++++++++-- 11 files changed, 179 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index a37e62414a4..f5ec9b556d1 100644 --- a/CHANGES +++ b/CHANGES @@ -43,6 +43,10 @@ Changes with Apache 2.4.55 HeartbeatMaxServers default to the documented value 10 in 2.4.54. PR 66131. [Jérôme Billiras] + *) mod_dav: DAVlockDiscovery option to disable WebDAV lock discovery + This is a game changer for performances if client use PROPFIND a lot, + PR 66313. [Emmanuel Dreyfus] + Changes with Apache 2.4.54 *) SECURITY: CVE-2022-31813: mod_proxy X-Forwarded-For dropped by diff --git a/STATUS b/STATUS index dfe525e2081..5e444229883 100644 --- a/STATUS +++ b/STATUS @@ -149,17 +149,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - *) mod_dav: DAVlockDiscovery option to disable WebDAV lock discovery - This is a game changer for performances if client use PROPFIND a lot, - trunk patch: http://svn.apache.org/r1904638 - http://svn.apache.org/r1904662 - http://svn.apache.org/r1905170 - http://svn.apache.org/r1905206 - http://svn.apache.org/r1905230 - 2.4.x patch: svn merge -c 1904638,1904662,1905170,1905206,1905230 ^/httpd/httpd/trunk . - +1: manu, covener, gbechis - covener: xml needs doc tweak after backport - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/docs/manual/mod/mod_dav_fs.html.en b/docs/manual/mod/mod_dav_fs.html.en index 5f4a55a1ac9..4864937f0b2 100644 --- a/docs/manual/mod/mod_dav_fs.html.en +++ b/docs/manual/mod/mod_dav_fs.html.en @@ -53,6 +53,7 @@
Support Apache!

Directives

Bugfix checklist

See also

+
top
+

DavLockDiscovery Directive

+ + + + + + + + +
Description:Enable lock discovery
Syntax:DavLockDiscovery on|off
Default:DavLockDiscovery on
Context:server config, virtual host, directory, .htaccess
Status:Extension
Module:mod_dav_fs
Compatibility:Available from Apache 2.5.0 and later.
+

DavLockDiscovery controls if the lock + discovery feature is enabled for PROPFIND method. + When disabled, PROPFIND always returns an empty + lockdiscovery section. This improves performance + if clients use PROPFIND a lot.

+

Example

DavLockDiscovery off
+
+
diff --git a/docs/manual/mod/mod_dav_fs.html.fr.utf8 b/docs/manual/mod/mod_dav_fs.html.fr.utf8 index 41da4bb0a57..471e17008d8 100644 --- a/docs/manual/mod/mod_dav_fs.html.fr.utf8 +++ b/docs/manual/mod/mod_dav_fs.html.fr.utf8 @@ -55,6 +55,7 @@
Support Apache!

Directives

Traitement des bugs

Voir aussi

    @@ -95,6 +96,27 @@ serveur.

    +
+
top
+

Directive DavLockDiscovery

+ + + + + + + + +
Description:Active la découverte des verrous
Syntaxe:DavLockDiscovery on|off
Défaut:DavLockDiscovery on
Contexte:configuration globale, serveur virtuel, répertoire, .htaccess
Statut:Extension
Module:mod_dav_fs
Compatibilité:Disponible à partir de Apache 2.5.0.
+

DavLockDiscovery contrôle la + découverte des verrous par la méthode PROPFIND. + Lorsqu'elle est désactivée, PROPFIND renvoie + toujours une section lockdiscovery vide. Ce + réglage améliore les performances dans le cas où des + clients utilisent beaucoup PROPFIND.

+

Example

DavLockDiscovery off
+
+
diff --git a/docs/manual/mod/mod_dav_fs.html.ja.utf8 b/docs/manual/mod/mod_dav_fs.html.ja.utf8 index 418909e586f..8d99fe8be39 100644 --- a/docs/manual/mod/mod_dav_fs.html.ja.utf8 +++ b/docs/manual/mod/mod_dav_fs.html.ja.utf8 @@ -60,6 +60,7 @@
Support Apache!

ディレクティブ

Bugfix checklist

参照

    @@ -88,6 +89,19 @@

+
top
+

DavLockDiscovery ディレクティブ

+ + + + + + + + +
説明:Enable lock discovery
構文:DavLockDiscovery on|off
デフォルト:DavLockDiscovery on
コンテキスト:サーバ設定ファイル, バーチャルホスト, ディレクトリ, .htaccess
ステータス:Extension
モジュール:mod_dav_fs
互換性:Available from Apache 2.5.0 and later.

このディレクティブの解説文書は + まだ翻訳されていません。英語版をご覧ください。 +

翻訳済み言語:  en  | diff --git a/docs/manual/mod/mod_dav_fs.html.ko.euc-kr b/docs/manual/mod/mod_dav_fs.html.ko.euc-kr index 0212cab2bc1..8e5f04881ee 100644 --- a/docs/manual/mod/mod_dav_fs.html.ko.euc-kr +++ b/docs/manual/mod/mod_dav_fs.html.ko.euc-kr @@ -55,6 +55,7 @@

Support Apache!

Áö½Ã¾îµé

Bugfix checklist

Âü°í

    @@ -93,6 +94,19 @@
+
top
+

DavLockDiscovery Áö½Ã¾î

+ + + + + + + + +
¼³¸í:Enable lock discovery
¹®¹ý:DavLockDiscovery on|off
±âº»°ª:DavLockDiscovery on
»ç¿ëÀå¼Ò:ÁÖ¼­¹ö¼³Á¤, °¡»óÈ£½ºÆ®, directory, .htaccess
»óÅÂ:Extension
¸ðµâ:mod_dav_fs
Áö¿ø:Available from Apache 2.5.0 and later.

The documentation for this directive has + not been translated yet. Please have a look at the English + version.

°¡´ÉÇÑ ¾ð¾î:  en  | diff --git a/docs/manual/mod/mod_dav_fs.xml b/docs/manual/mod/mod_dav_fs.xml index 224bdd05c53..6bdf0a5100a 100644 --- a/docs/manual/mod/mod_dav_fs.xml +++ b/docs/manual/mod/mod_dav_fs.xml @@ -87,5 +87,31 @@ + +DavLockDiscovery +Enable lock discovery +DavLockDiscovery on|off +DavLockDiscovery on +server config +virtual host +directory +.htaccess + +Available from Apache 2.5.0 and later. + + +

DavLockDiscovery controls if the lock + discovery feature is enabled for PROPFIND method. + When disabled, PROPFIND always returns an empty + lockdiscovery section. This improves performance + if clients use PROPFIND a lot.

+ Example + + DavLockDiscovery off + + + + + diff --git a/docs/manual/mod/mod_dav_fs.xml.fr b/docs/manual/mod/mod_dav_fs.xml.fr index 2a3ff9dc377..9a498e1ec98 100644 --- a/docs/manual/mod/mod_dav_fs.xml.fr +++ b/docs/manual/mod/mod_dav_fs.xml.fr @@ -97,5 +97,32 @@ host + +DavLockDiscovery +Active la découverte des verrous +DavLockDiscovery on|off +DavLockDiscovery on +server config +virtual host +directory +.htaccess + +Disponible à partir de Apache 2.5.0. + + +

DavLockDiscovery contrôle la + découverte des verrous par la méthode PROPFIND. + Lorsqu'elle est désactivée, PROPFIND renvoie + toujours une section lockdiscovery vide. Ce + réglage améliore les performances dans le cas où des + clients utilisent beaucoup PROPFIND.

+ Example + + DavLockDiscovery off + + +
+
+ diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c index 7795e1ea803..d16ab4a1b27 100644 --- a/modules/dav/main/mod_dav.c +++ b/modules/dav/main/mod_dav.c @@ -83,6 +83,7 @@ typedef struct { const char *dir; int locktimeout; int allow_depthinfinity; + int allow_lockdiscovery; } dav_dir_conf; @@ -197,6 +198,8 @@ static void *dav_merge_dir_config(apr_pool_t *p, void *base, void *overrides) newconf->dir = DAV_INHERIT_VALUE(parent, child, dir); newconf->allow_depthinfinity = DAV_INHERIT_VALUE(parent, child, allow_depthinfinity); + newconf->allow_lockdiscovery = DAV_INHERIT_VALUE(parent, child, + allow_lockdiscovery); return newconf; } @@ -294,6 +297,21 @@ static const char *dav_cmd_davdepthinfinity(cmd_parms *cmd, void *config, return NULL; } +/* + * Command handler for the DAVLockDiscovery directive, which is FLAG. + */ +static const char *dav_cmd_davlockdiscovery(cmd_parms *cmd, void *config, + int arg) +{ + dav_dir_conf *conf = (dav_dir_conf *)config; + + if (arg) + conf->allow_lockdiscovery = DAV_ENABLED_ON; + else + conf->allow_lockdiscovery = DAV_ENABLED_OFF; + return NULL; +} + /* * Command handler for DAVMinTimeout directive, which is TAKE1 */ @@ -1419,7 +1437,7 @@ static dav_error *dav_gen_supported_live_props(request_rec *r, } /* open the property database (readonly) for the resource */ - if ((err = dav_open_propdb(r, lockdb, resource, 1, NULL, + if ((err = dav_open_propdb(r, lockdb, resource, DAV_PROPDB_RO, NULL, &propdb)) != NULL) { if (lockdb != NULL) (*lockdb->hooks->close_lockdb)(lockdb); @@ -2014,6 +2032,8 @@ static void dav_cache_badprops(dav_walker_ctx *ctx) static dav_error * dav_propfind_walker(dav_walk_resource *wres, int calltype) { dav_walker_ctx *ctx = wres->walk_ctx; + dav_dir_conf *conf; + int flags = DAV_PROPDB_RO; dav_error *err; dav_propdb *propdb; dav_get_props_result propstats = { 0 }; @@ -2025,6 +2045,10 @@ static dav_error * dav_propfind_walker(dav_walk_resource *wres, int calltype) return NULL; } + conf = ap_get_module_config(ctx->r->per_dir_config, &dav_module); + if (conf && conf->allow_lockdiscovery == DAV_ENABLED_OFF) + flags |= DAV_PROPDB_DISABLE_LOCKDISCOVERY; + /* ** Note: ctx->doc can only be NULL for DAV_PROPFIND_IS_ALLPROP. Since ** dav_get_allprops() does not need to do namespace translation, @@ -2034,7 +2058,7 @@ static dav_error * dav_propfind_walker(dav_walk_resource *wres, int calltype) ** the resource, however, since we are opening readonly. */ err = dav_popen_propdb(ctx->scratchpool, - ctx->r, ctx->w.lockdb, wres->resource, 1, + ctx->r, ctx->w.lockdb, wres->resource, flags, ctx->doc ? ctx->doc->namespaces : NULL, &propdb); if (err != NULL) { /* ### do something with err! */ @@ -2419,7 +2443,8 @@ static int dav_method_proppatch(request_rec *r) return dav_handle_err(r, err, NULL); } - if ((err = dav_open_propdb(r, NULL, resource, 0, doc->namespaces, + if ((err = dav_open_propdb(r, NULL, resource, + DAV_PROPDB_NONE, doc->namespaces, &propdb)) != NULL) { /* undo any auto-checkout */ dav_auto_checkin(r, resource, 1 /*undo*/, 0 /*unlock*/, &av_info); @@ -5149,6 +5174,11 @@ static const command_rec dav_cmds[] = ACCESS_CONF|RSRC_CONF, "allow Depth infinity PROPFIND requests"), + /* per directory/location, or per server */ + AP_INIT_FLAG("DAVLockDiscovery", dav_cmd_davlockdiscovery, NULL, + ACCESS_CONF|RSRC_CONF, + "allow lock discovery by PROPFIND requests"), + { NULL } }; diff --git a/modules/dav/main/mod_dav.h b/modules/dav/main/mod_dav.h index 198489fe2c5..eca34a26dbe 100644 --- a/modules/dav/main/mod_dav.h +++ b/modules/dav/main/mod_dav.h @@ -1685,12 +1685,15 @@ struct dav_hooks_locks typedef struct dav_propdb dav_propdb; +#define DAV_PROPDB_NONE 0 +#define DAV_PROPDB_RO 1 +#define DAV_PROPDB_DISABLE_LOCKDISCOVERY 2 DAV_DECLARE(dav_error *) dav_open_propdb( request_rec *r, dav_lockdb *lockdb, const dav_resource *resource, - int ro, + int flags, apr_array_header_t *ns_xlate, dav_propdb **propdb); @@ -1699,7 +1702,7 @@ DAV_DECLARE(dav_error *) dav_popen_propdb( request_rec *r, dav_lockdb *lockdb, const dav_resource *resource, - int ro, + int flags, apr_array_header_t *ns_xlate, dav_propdb **propdb); diff --git a/modules/dav/main/props.c b/modules/dav/main/props.c index 9ad6d6db584..c320f8ab9fb 100644 --- a/modules/dav/main/props.c +++ b/modules/dav/main/props.c @@ -185,6 +185,8 @@ struct dav_propdb { dav_buffer wb_lock; /* work buffer for lockdiscovery property */ + int flags; /* ro, disable lock discovery */ + /* if we ever run a GET subreq, it will be stored here */ request_rec *subreq; @@ -351,6 +353,11 @@ static dav_error * dav_insert_coreprop(dav_propdb *propdb, switch (propid) { case DAV_PROPID_CORE_lockdiscovery: + if (propdb->flags & DAV_PROPDB_DISABLE_LOCKDISCOVERY) { + value = ""; + break; + } + if (propdb->lockdb != NULL) { dav_lock *locks; @@ -522,17 +529,18 @@ static dav_error *dav_really_open_db(dav_propdb *propdb, int ro) DAV_DECLARE(dav_error *)dav_open_propdb(request_rec *r, dav_lockdb *lockdb, const dav_resource *resource, - int ro, + int flags, apr_array_header_t * ns_xlate, dav_propdb **p_propdb) { - return dav_popen_propdb(r->pool, r, lockdb, resource, ro, ns_xlate, p_propdb); + return dav_popen_propdb(r->pool, r, lockdb, resource, + flags, ns_xlate, p_propdb); } DAV_DECLARE(dav_error *)dav_popen_propdb(apr_pool_t *p, request_rec *r, dav_lockdb *lockdb, const dav_resource *resource, - int ro, + int flags, apr_array_header_t * ns_xlate, dav_propdb **p_propdb) { @@ -559,6 +567,8 @@ DAV_DECLARE(dav_error *)dav_popen_propdb(apr_pool_t *p, propdb->lockdb = lockdb; + propdb->flags = flags; + /* always defer actual open, to avoid expense of accessing db * when only live properties are involved */ -- 2.47.2