From 7ce5fb2d023034fd8b370d8c07c346401070809d Mon Sep 17 00:00:00 2001 From: David Marteau Date: Thu, 11 Apr 2019 09:56:57 +0200 Subject: [PATCH] Set config path before calling plugin method --- src/server/qgsrequesthandler.cpp | 7 ++++ src/server/qgsserver.cpp | 24 +++++++----- tests/src/python/test_qgsserver_plugins.py | 45 ++++++++++++++++++++++ 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/src/server/qgsrequesthandler.cpp b/src/server/qgsrequesthandler.cpp index 18f96f441804..3faacd826e51 100644 --- a/src/server/qgsrequesthandler.cpp +++ b/src/server/qgsrequesthandler.cpp @@ -259,6 +259,13 @@ void QgsRequestHandler::setParameter( const QString &key, const QString &value ) { if ( !( key.isEmpty() || value.isEmpty() ) ) { + // Warn for potential breaking change if plugin set the MAP parameter + // expecting changing the config file path, see PR #9773 + if ( key.compare( QLatin1String( "MAP" ), Qt::CaseInsensitive ) == 0 ) + { + QgsMessageLog::logMessage( QStringLiteral( "Changing the 'MAP' parameter will have no effect on config path: use QgsSerververInterface::setConfigFilePath instead" ), + "Server", Qgis::Warning ); + } mRequest.setParameter( key, value ); } } diff --git a/src/server/qgsserver.cpp b/src/server/qgsserver.cpp index 3ccb18575f2e..5173e92a9eb3 100644 --- a/src/server/qgsserver.cpp +++ b/src/server/qgsserver.cpp @@ -319,6 +319,20 @@ void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &res // Set the request handler into the interface for plugins to manipulate it sServerInterface->setRequestHandler( &requestHandler ); + // Initialize configfilepath so that is is available + // before calling plugin methods + // Note that plugins may still change that value using + // setConfigFilePath() interface method + if ( ! project ) + { + QString configFilePath = configPath( *sConfigFilePath, request.serverParameters().map() ); + sServerInterface->setConfigFilePath( configFilePath ); + } + else + { + sServerInterface->setConfigFilePath( project->fileName() ); + } + // Call requestReady() method (if enabled) responseDecorator.start(); @@ -333,20 +347,12 @@ void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &res //Config file path if ( ! project ) { - QString configFilePath = configPath( *sConfigFilePath, params.map() ); - // load the project if needed and not empty - project = mConfigCache->project( configFilePath ); + project = mConfigCache->project( sServerInterface->configFilePath() ); if ( ! project ) { throw QgsServerException( QStringLiteral( "Project file error" ) ); } - - sServerInterface->setConfigFilePath( configFilePath ); - } - else - { - sServerInterface->setConfigFilePath( project->fileName() ); } if ( ! params.fileName().isEmpty() ) diff --git a/tests/src/python/test_qgsserver_plugins.py b/tests/src/python/test_qgsserver_plugins.py index a5302f2b38bd..7109bd03cbcf 100644 --- a/tests/src/python/test_qgsserver_plugins.py +++ b/tests/src/python/test_qgsserver_plugins.py @@ -177,6 +177,51 @@ def responseComplete(self): self.assertEqual(response, expected) self.assertEqual(headers2, {'Content-type': 'text/plain'}) + def test_configpath(self): + """ Test plugin can read confif path + """ + try: + from qgis.server import QgsServerFilter + from qgis.core import QgsProject + except ImportError: + print("QGIS Server plugins are not compiled. Skipping test") + return + + d = unitTestDataPath('qgis_server_accesscontrol') + '/' + self.projectPath = os.path.join(d, "project.qgs") + self.server = QgsServer() + + # global to be modified inside plugin filters + globals()['configFilePath2'] = None + + class Filter0(QgsServerFilter): + """Body setter, clear body, keep headers""" + + def requestReady(self): + global configFilePath2 + configFilePath2 = self.serverInterface().configFilePath() + + serverIface = self.server.serverInterface() + serverIface.registerFilter(Filter0(serverIface), 100) + + # Test using MAP + self._execute_request('?service=simple&MAP=%s' % self.projectPath) + + # Check config file path + self.assertEqual(configFilePath2, self.projectPath) + + # Reset result + globals()['configFilePath2'] = None + + # Test with prqject as argument + project = QgsProject() + project.read(self.projectPath) + + self._execute_request_project('?service=simple', project=project) + + # Check config file path + self.assertEqual(configFilePath2, project.fileName()) + if __name__ == '__main__': unittest.main()