From bb6b061d9fdcd2a5b75712177b187a12e844a786 Mon Sep 17 00:00:00 2001 From: rldhont Date: Wed, 12 Aug 2020 09:40:48 +0200 Subject: [PATCH 1/4] Fix: QGIS_SERVER_TRUST_LAYER_METADATA --- src/server/qgsconfigcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/qgsconfigcache.cpp b/src/server/qgsconfigcache.cpp index ff3ae4bd173..328c8c34b2e 100644 --- a/src/server/qgsconfigcache.cpp +++ b/src/server/qgsconfigcache.cpp @@ -49,7 +49,7 @@ const QgsProject *QgsConfigCache::project( const QString &path, QgsServerSetting prj->setBadLayerHandler( badLayerHandler ); QgsProject::ReadFlags readFlags = QgsProject::ReadFlag(); - if ( ! settings || ! settings->trustLayerMetadata() ) + if ( settings && settings->trustLayerMetadata() ) { readFlags |= QgsProject::ReadFlag::FlagTrustLayerMetadata; } From fa7da5a68b2d37f92705d12c7d98a779983766f4 Mon Sep 17 00:00:00 2001 From: rldhont Date: Wed, 12 Aug 2020 10:31:54 +0200 Subject: [PATCH 2/4] New QGIS Server setting environement to do not load layouts Defined a new QGIS Server setting environnement `QGIS_SERVER_DONT_LOAD_LAYOUTS` to do not load layouts when QGIS Server reads projects. This variable will disable QGIS Server GetPrint capabilities. --- .../auto_generated/qgsserversettings.sip.in | 10 ++++++++++ src/server/qgsconfigcache.cpp | 13 +++++++++++-- src/server/qgsserversettings.cpp | 16 ++++++++++++++++ src/server/qgsserversettings.h | 13 ++++++++++++- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/python/server/auto_generated/qgsserversettings.sip.in b/python/server/auto_generated/qgsserversettings.sip.in index c300c46379f..50d01b113e4 100644 --- a/python/server/auto_generated/qgsserversettings.sip.in +++ b/python/server/auto_generated/qgsserversettings.sip.in @@ -193,6 +193,16 @@ Returns ``True`` if the reading flag trust layer metadata is activated. The default value is ``False``, this value can be changed by setting the environment variable QGIS_SERVER_TRUST_LAYER_METADATA. +.. versionadded:: 3.16 +%End + + bool dontLoadLayouts() const; +%Docstring +Returns ``True`` if the reading flag don't load layouts is activated. + +The default value is ``False``, this value can be changed by setting the environment +variable QGIS_SERVER_DONT_LOAD_LAYOUTS. + .. versionadded:: 3.16 %End diff --git a/src/server/qgsconfigcache.cpp b/src/server/qgsconfigcache.cpp index 328c8c34b2e..0c2ea841a6a 100644 --- a/src/server/qgsconfigcache.cpp +++ b/src/server/qgsconfigcache.cpp @@ -49,9 +49,18 @@ const QgsProject *QgsConfigCache::project( const QString &path, QgsServerSetting prj->setBadLayerHandler( badLayerHandler ); QgsProject::ReadFlags readFlags = QgsProject::ReadFlag(); - if ( settings && settings->trustLayerMetadata() ) + if ( settings ) { - readFlags |= QgsProject::ReadFlag::FlagTrustLayerMetadata; + // Activate trust layer metadata flag + if ( settings->trustLayerMetadata() ) + { + readFlags |= QgsProject::ReadFlag::FlagTrustLayerMetadata; + } + // Activate don't load layouts flag + else if ( settings->dontLoadLayouts() ) + { + readFlags |= QgsProject::ReadFlag::FlagDontLoadLayouts; + } } if ( prj->read( path, readFlags ) ) diff --git a/src/server/qgsserversettings.cpp b/src/server/qgsserversettings.cpp index 5231b8fa97f..25bee2a97c6 100644 --- a/src/server/qgsserversettings.cpp +++ b/src/server/qgsserversettings.cpp @@ -174,6 +174,17 @@ void QgsServerSettings::initSettings() }; mSettings[ sTrustLayerMetadata.envVar ] = sTrustLayerMetadata; + // don't load layouts + const Setting sDontLoadLayouts = { QgsServerSettingsEnv::QGIS_SERVER_DONT_LOAD_LAYOUTS, + QgsServerSettingsEnv::DEFAULT_VALUE, + QStringLiteral( "Don't load layouts" ), + QString(), + QVariant::Bool, + QVariant( false ), + QVariant() + }; + mSettings[ sDontLoadLayouts.envVar ] = sDontLoadLayouts; + // show group separator const Setting sShowGroupSeparator = { QgsServerSettingsEnv::QGIS_SERVER_SHOW_GROUP_SEPARATOR, QgsServerSettingsEnv::DEFAULT_VALUE, @@ -450,3 +461,8 @@ bool QgsServerSettings::trustLayerMetadata() const { return value( QgsServerSettingsEnv::QGIS_SERVER_TRUST_LAYER_METADATA ).toBool(); } + +bool QgsServerSettings::dontLoadLayouts() const +{ + return value( QgsServerSettingsEnv::QGIS_SERVER_DONT_LOAD_LAYOUTS ).toBool(); +} diff --git a/src/server/qgsserversettings.h b/src/server/qgsserversettings.h index e4012c0595b..c5cdbcfaa0f 100644 --- a/src/server/qgsserversettings.h +++ b/src/server/qgsserversettings.h @@ -68,7 +68,8 @@ class SERVER_EXPORT QgsServerSettingsEnv : public QObject QGIS_SERVER_WMS_MAX_WIDTH, //!< Maximum width for a WMS request. The most conservative between this and the project one is used (since QGIS 3.6.2) QGIS_SERVER_API_RESOURCES_DIRECTORY, //!< Base directory where HTML templates and static assets (e.g. images, js and css files) are searched for (since QGIS 3.10). QGIS_SERVER_API_WFS3_MAX_LIMIT, //!< Maximum value for "limit" in a features request, defaults to 10000 (since QGIS 3.10). - QGIS_SERVER_TRUST_LAYER_METADATA //!< Trust layer metadata (since QGIS 3.16). + QGIS_SERVER_TRUST_LAYER_METADATA, //!< Trust layer metadata (since QGIS 3.16). + QGIS_SERVER_DONT_LOAD_LAYOUTS //!< Don't load layouts, this deactivated GetPrint capabilities (since QGIS 3.16). }; Q_ENUM( EnvVar ) }; @@ -245,6 +246,16 @@ class SERVER_EXPORT QgsServerSettings */ bool trustLayerMetadata() const; + /** + * Returns TRUE if the reading flag don't load layouts is activated. + * + * The default value is FALSE, this value can be changed by setting the environment + * variable QGIS_SERVER_DONT_LOAD_LAYOUTS. + * + * \since QGIS 3.16 + */ + bool dontLoadLayouts() const; + private: void initSettings(); QVariant value( QgsServerSettingsEnv::EnvVar envVar ) const; From c1a9d948e15a261e77b142e3cb00ca75c8dc0522 Mon Sep 17 00:00:00 2001 From: rldhont Date: Wed, 12 Aug 2020 19:27:48 +0200 Subject: [PATCH 3/4] Test: QGIS Server setting environement to do not load layouts --- tests/src/python/test_qgsserver_settings.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/src/python/test_qgsserver_settings.py b/tests/src/python/test_qgsserver_settings.py index fa03f9ad087..5f2f2221317 100644 --- a/tests/src/python/test_qgsserver_settings.py +++ b/tests/src/python/test_qgsserver_settings.py @@ -146,6 +146,21 @@ class TestQgsServerSettings(unittest.TestCase): self.assertFalse(self.settings.trustLayerMetadata()) os.environ.pop(env) + def test_env_dont_load_layouts(self): + env = "QGIS_SERVER_DONT_LOAD_LAYOUTS" + + self.assertFalse(self.settings.dontLoadLayouts()) + + os.environ[env] = "1" + self.settings.load() + self.assertTrue(self.settings.dontLoadLayouts()) + os.environ.pop(env) + + os.environ[env] = "0" + self.settings.load() + self.assertFalse(self.settings.dontLoadLayouts()) + os.environ.pop(env) + def test_priority(self): env = "QGIS_OPTIONS_PATH" dpath = "conf0" From 98741cb91fc6397bf4c7b92b2ff9a119fcb8784b Mon Sep 17 00:00:00 2001 From: rldhont Date: Thu, 13 Aug 2020 11:28:03 +0200 Subject: [PATCH 4/4] Change to QGIS_SERVER_DISABLE_GETPRINT --- python/server/auto_generated/qgsserversettings.sip.in | 7 ++++--- src/server/qgsconfigcache.cpp | 2 +- src/server/qgsserversettings.cpp | 6 +++--- src/server/qgsserversettings.h | 11 ++++++----- src/server/services/wms/qgswms.cpp | 7 +++++++ src/server/services/wms/qgswmsgetcapabilities.cpp | 7 ++++--- src/server/services/wms/qgswmsgetcapabilities.h | 3 ++- tests/src/python/test_qgsserver_settings.py | 8 ++++---- 8 files changed, 31 insertions(+), 20 deletions(-) diff --git a/python/server/auto_generated/qgsserversettings.sip.in b/python/server/auto_generated/qgsserversettings.sip.in index 50d01b113e4..961ed8b4632 100644 --- a/python/server/auto_generated/qgsserversettings.sip.in +++ b/python/server/auto_generated/qgsserversettings.sip.in @@ -196,12 +196,13 @@ variable QGIS_SERVER_TRUST_LAYER_METADATA. .. versionadded:: 3.16 %End - bool dontLoadLayouts() const; + bool getPrintDisabled() const; %Docstring -Returns ``True`` if the reading flag don't load layouts is activated. +Returns ``True`` if WMS GetPrint request is disabled and the project's +reading flag DONT_LOAD_LAYOUTS is activated. The default value is ``False``, this value can be changed by setting the environment -variable QGIS_SERVER_DONT_LOAD_LAYOUTS. +variable QGIS_SERVER_DISABLE_GETPRINT. .. versionadded:: 3.16 %End diff --git a/src/server/qgsconfigcache.cpp b/src/server/qgsconfigcache.cpp index 0c2ea841a6a..638ff69a249 100644 --- a/src/server/qgsconfigcache.cpp +++ b/src/server/qgsconfigcache.cpp @@ -57,7 +57,7 @@ const QgsProject *QgsConfigCache::project( const QString &path, QgsServerSetting readFlags |= QgsProject::ReadFlag::FlagTrustLayerMetadata; } // Activate don't load layouts flag - else if ( settings->dontLoadLayouts() ) + if ( settings->getPrintDisabled() ) { readFlags |= QgsProject::ReadFlag::FlagDontLoadLayouts; } diff --git a/src/server/qgsserversettings.cpp b/src/server/qgsserversettings.cpp index 25bee2a97c6..4de979e4f68 100644 --- a/src/server/qgsserversettings.cpp +++ b/src/server/qgsserversettings.cpp @@ -175,7 +175,7 @@ void QgsServerSettings::initSettings() mSettings[ sTrustLayerMetadata.envVar ] = sTrustLayerMetadata; // don't load layouts - const Setting sDontLoadLayouts = { QgsServerSettingsEnv::QGIS_SERVER_DONT_LOAD_LAYOUTS, + const Setting sDontLoadLayouts = { QgsServerSettingsEnv::QGIS_SERVER_DISABLE_GETPRINT, QgsServerSettingsEnv::DEFAULT_VALUE, QStringLiteral( "Don't load layouts" ), QString(), @@ -462,7 +462,7 @@ bool QgsServerSettings::trustLayerMetadata() const return value( QgsServerSettingsEnv::QGIS_SERVER_TRUST_LAYER_METADATA ).toBool(); } -bool QgsServerSettings::dontLoadLayouts() const +bool QgsServerSettings::getPrintDisabled() const { - return value( QgsServerSettingsEnv::QGIS_SERVER_DONT_LOAD_LAYOUTS ).toBool(); + return value( QgsServerSettingsEnv::QGIS_SERVER_DISABLE_GETPRINT ).toBool(); } diff --git a/src/server/qgsserversettings.h b/src/server/qgsserversettings.h index c5cdbcfaa0f..ad6a0f3935a 100644 --- a/src/server/qgsserversettings.h +++ b/src/server/qgsserversettings.h @@ -68,8 +68,8 @@ class SERVER_EXPORT QgsServerSettingsEnv : public QObject QGIS_SERVER_WMS_MAX_WIDTH, //!< Maximum width for a WMS request. The most conservative between this and the project one is used (since QGIS 3.6.2) QGIS_SERVER_API_RESOURCES_DIRECTORY, //!< Base directory where HTML templates and static assets (e.g. images, js and css files) are searched for (since QGIS 3.10). QGIS_SERVER_API_WFS3_MAX_LIMIT, //!< Maximum value for "limit" in a features request, defaults to 10000 (since QGIS 3.10). - QGIS_SERVER_TRUST_LAYER_METADATA, //!< Trust layer metadata (since QGIS 3.16). - QGIS_SERVER_DONT_LOAD_LAYOUTS //!< Don't load layouts, this deactivated GetPrint capabilities (since QGIS 3.16). + QGIS_SERVER_TRUST_LAYER_METADATA, //!< Trust layer metadata. Improves project read time. (since QGIS 3.16). + QGIS_SERVER_DISABLE_GETPRINT //!< Disabled WMS GetPrint request and don't load layouts. Improves project read time. (since QGIS 3.16). }; Q_ENUM( EnvVar ) }; @@ -247,14 +247,15 @@ class SERVER_EXPORT QgsServerSettings bool trustLayerMetadata() const; /** - * Returns TRUE if the reading flag don't load layouts is activated. + * Returns TRUE if WMS GetPrint request is disabled and the project's + * reading flag DONT_LOAD_LAYOUTS is activated. * * The default value is FALSE, this value can be changed by setting the environment - * variable QGIS_SERVER_DONT_LOAD_LAYOUTS. + * variable QGIS_SERVER_DISABLE_GETPRINT. * * \since QGIS 3.16 */ - bool dontLoadLayouts() const; + bool getPrintDisabled() const; private: void initSettings(); diff --git a/src/server/services/wms/qgswms.cpp b/src/server/services/wms/qgswms.cpp index 28cd8af228d..d15b164426c 100644 --- a/src/server/services/wms/qgswms.cpp +++ b/src/server/services/wms/qgswms.cpp @@ -143,6 +143,13 @@ namespace QgsWms } else if ( QSTR_COMPARE( req, "GetPrint" ) ) { + if ( mServerIface->serverSettings() && mServerIface->serverSettings()->getPrintDisabled() ) + { + // GetPrint has been disabled + QgsDebugMsg( QStringLiteral( "WMS GetPrint request called, but it has been disabled." ) ); + throw QgsServiceException( QgsServiceException::OGC_OperationNotSupported, + QStringLiteral( "Request %1 is not supported" ).arg( req ), 501 ); + } writeGetPrint( mServerIface, project, version, request, response ); } else diff --git a/src/server/services/wms/qgswmsgetcapabilities.cpp b/src/server/services/wms/qgswmsgetcapabilities.cpp index f3eedb8114b..28706fb3b4d 100644 --- a/src/server/services/wms/qgswmsgetcapabilities.cpp +++ b/src/server/services/wms/qgswmsgetcapabilities.cpp @@ -230,7 +230,7 @@ namespace QgsWms wmsCapabilitiesElement.appendChild( getServiceElement( doc, project, version, request ) ); //wms:Capability element - QDomElement capabilityElement = getCapabilityElement( doc, project, version, request, projectSettings ); + QDomElement capabilityElement = getCapabilityElement( doc, project, version, request, projectSettings, serverIface ); wmsCapabilitiesElement.appendChild( capabilityElement ); if ( projectSettings ) @@ -431,7 +431,7 @@ namespace QgsWms QDomElement getCapabilityElement( QDomDocument &doc, const QgsProject *project, const QString &version, const QgsServerRequest &request, - bool projectSettings ) + bool projectSettings, QgsServerInterface *serverIface ) { QgsServerRequest::Parameters parameters = request.parameters(); @@ -534,7 +534,8 @@ namespace QgsWms elem.appendChild( dcpTypeElem.cloneNode().toElement() ); //this is the same as for 'GetCapabilities' requestElem.appendChild( elem ); - if ( projectSettings ) //remove composer templates from GetCapabilities in the long term + if ( ( !serverIface->serverSettings() || !serverIface->serverSettings()->getPrintDisabled() ) && + projectSettings ) //remove composer templates from GetCapabilities in the long term { //wms:GetPrint elem = doc.createElement( QStringLiteral( "GetPrint" ) /*wms:GetPrint*/ ); diff --git a/src/server/services/wms/qgswmsgetcapabilities.h b/src/server/services/wms/qgswmsgetcapabilities.h index 8af886b4e48..59f42fa7151 100644 --- a/src/server/services/wms/qgswmsgetcapabilities.h +++ b/src/server/services/wms/qgswmsgetcapabilities.h @@ -55,7 +55,8 @@ namespace QgsWms * Create Capability element for get capabilities document */ QDomElement getCapabilityElement( QDomDocument &doc, const QgsProject *project, const QString &version, - const QgsServerRequest &request, bool projectSettings ); + const QgsServerRequest &request, bool projectSettings, + QgsServerInterface *serverIface ); /** * Create Service element for get capabilities document diff --git a/tests/src/python/test_qgsserver_settings.py b/tests/src/python/test_qgsserver_settings.py index 5f2f2221317..280675d8040 100644 --- a/tests/src/python/test_qgsserver_settings.py +++ b/tests/src/python/test_qgsserver_settings.py @@ -147,18 +147,18 @@ class TestQgsServerSettings(unittest.TestCase): os.environ.pop(env) def test_env_dont_load_layouts(self): - env = "QGIS_SERVER_DONT_LOAD_LAYOUTS" + env = "QGIS_SERVER_DISABLE_GETPRINT" - self.assertFalse(self.settings.dontLoadLayouts()) + self.assertFalse(self.settings.getPrintDisabled()) os.environ[env] = "1" self.settings.load() - self.assertTrue(self.settings.dontLoadLayouts()) + self.assertTrue(self.settings.getPrintDisabled()) os.environ.pop(env) os.environ[env] = "0" self.settings.load() - self.assertFalse(self.settings.dontLoadLayouts()) + self.assertFalse(self.settings.getPrintDisabled()) os.environ.pop(env) def test_priority(self):