Skip to content

Commit

Permalink
WMS run as a module service !
Browse files Browse the repository at this point in the history
  • Loading branch information
dmarteau committed Jan 10, 2017
1 parent c793e66 commit dc211f8
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 47 deletions.
2 changes: 1 addition & 1 deletion src/server/CMakeLists.txt
Expand Up @@ -25,7 +25,7 @@ SET ( qgis_mapserv_SRCS
qgsconfigcache.cpp
qgsrequesthandler.cpp
qgsowsserver.cpp
qgswmsserver.cpp
# qgswmsserver.cpp
qgswfsserver.cpp
qgswcsserver.cpp
qgsmapserviceexception.cpp
Expand Down
2 changes: 1 addition & 1 deletion src/server/qgsfcgiserverresponse.h
Expand Up @@ -85,7 +85,7 @@ class QgsFcgiServerRequest: public QgsServerRequest
virtual QByteArray data() const override;

/**
* Return true if an error occured during initialization
* Return true if an error occurred during initialization
*/
bool hasError() const { return mHasError; }

Expand Down
24 changes: 18 additions & 6 deletions src/server/qgsserver.cpp
Expand Up @@ -30,7 +30,7 @@
#include "qgsproject.h"
#include "qgsproviderregistry.h"
#include "qgslogger.h"
#include "qgswmsserver.h"
//#include "qgswmsserver.h"
#include "qgswfsserver.h"
#include "qgswcsserver.h"
#include "qgsmapserviceexception.h"
Expand All @@ -41,6 +41,7 @@
#include "qgsserverrequest.h"
#include "qgsbufferserverresponse.h"
#include "qgsfilterresponsedecorator.h"
#include "qgsservice.h"

#include <QDomDocument>
#include <QNetworkDiskCache>
Expand Down Expand Up @@ -387,7 +388,7 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
// Call requestReady() method (if enabled)
theResponse.start();

QMap<QString, QString> parameterMap = theRequestHandler.parameterMap();
QMap<QString, QString> parameterMap = request.parameters();
printRequestParameters( parameterMap, logLevel );

const QgsAccessControl* accessControl = sServerInterface->accessControls();
Expand All @@ -401,20 +402,22 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
#endif

//Service parameter
QString serviceString = theRequestHandler.parameter( QStringLiteral( "SERVICE" ) );
QString serviceString = parameterMap.value( QStringLiteral( "SERVICE" ) );

if ( serviceString.isEmpty() )
{
// SERVICE not mandatory for WMS 1.3.0 GetMap & GetFeatureInfo
QString requestString = theRequestHandler.parameter( QStringLiteral( "REQUEST" ) );
QString requestString = parameterMap.value( QStringLiteral( "REQUEST" ) );
if ( requestString == QLatin1String( "GetMap" ) || requestString == QLatin1String( "GetFeatureInfo" ) )
{
serviceString = QStringLiteral( "WMS" );
}
}

QString versionString = parameterMap.value( QStringLiteral( "VERSION" ) );

//possibility for client to suggest a download filename
QString outputFileName = theRequestHandler.parameter( QStringLiteral( "FILE_NAME" ) );
QString outputFileName = parameterMap.value( QStringLiteral( "FILE_NAME" ) );
if ( !outputFileName.isEmpty() )
{
theRequestHandler.setHeader( QStringLiteral( "Content-Disposition" ), "attachment; filename=\"" + outputFileName + "\"" );
Expand All @@ -423,7 +426,14 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
// Enter core services main switch
if ( !theRequestHandler.exceptionRaised() )
{
if ( serviceString == QLatin1String( "WCS" ) )
// Lookup for service

QgsService* service = sServiceRegistry.getService( serviceString, versionString );
if ( service )
{
service->executeRequest( request, theResponse );
}
else if ( serviceString == QLatin1String( "WCS" ) )
{
QgsWCSProjectParser* p = QgsConfigCache::instance()->wcsConfiguration(
configFilePath
Expand Down Expand Up @@ -467,6 +477,7 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
wfsServer.executeRequest();
}
}
/*
else if ( serviceString == QLatin1String( "WMS" ) )
{
QgsWmsConfigParser* p = QgsConfigCache::instance()->wmsConfiguration(
Expand All @@ -490,6 +501,7 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
wmsServer.executeRequest();
}
}
*/
else
{
theRequestHandler.setServiceException( QgsMapServiceException( QStringLiteral( "Service configuration error" ), QStringLiteral( "Service unknown or unsupported" ) ) );
Expand Down
1 change: 0 additions & 1 deletion src/server/qgsserver.h
Expand Up @@ -130,7 +130,6 @@ class SERVER_EXPORT QgsServer
#endif
//! Initialization must run once for all servers
static bool sInitialised;
static bool sCaptureOutput;

//! service registry
static QgsServiceRegistry sServiceRegistry;
Expand Down
1 change: 0 additions & 1 deletion src/server/qgsservicenativeloader.cpp
Expand Up @@ -98,7 +98,6 @@ QgsServiceModule* QgsServiceNativeLoader::loadNativeModule( const QString& locat
qDebug() << QString( "Loading native module %1" ).arg( location );
if ( !lib.load() )
{
qDebug() << QString( "Failed to load library %1: %2" ).arg( lib.fileName(), lib.errorString() );
QgsMessageLog::logMessage( QString( "Failed to load library %1: %2" ).arg( lib.fileName(), lib.errorString() ) );
return nullptr;
}
Expand Down
21 changes: 18 additions & 3 deletions src/server/qgsserviceregistry.cpp
Expand Up @@ -75,6 +75,9 @@ namespace
return false;
}

// Check that two versions are c


} // namespace

QgsServiceRegistry::QgsServiceRegistry()
Expand Down Expand Up @@ -104,7 +107,9 @@ QgsService* QgsServiceRegistry::getService( const QString& name, const QString&
}
else
{
QgsMessageLog::logMessage( QString( "Service %1 %2 not found" ).arg( name, version ) );
// Return the dofault version
QgsMessageLog::logMessage( QString( "Service %1 %2 not found, returning default" ).arg( name, version ) );
service = mServices[v->second].get();
}
}
else
Expand All @@ -131,8 +136,17 @@ void QgsServiceRegistry::registerService( QgsService* service )
mServices.insert( key, std::shared_ptr<QgsService>( service ) );

// Check the default version
// and replace with te new one if it has a higher version
// The first inserted service of a given name
// is the default one.
// this will ensure that native services are always
// the defaults.
VersionTable::const_iterator v = mVersions.constFind( name );
if ( v == mVersions.constEnd() )
{
// Insert the service as the default one
mVersions.insert( name, VersionTable::mapped_type( version, key ) );
}
/*
if ( v != mVersions.constEnd() )
{
if ( isVersionGreater( version, v->first ) )
Expand All @@ -145,7 +159,8 @@ void QgsServiceRegistry::registerService( QgsService* service )
{
// Insert the service as the default one
mVersions.insert( name, VersionTable::mapped_type( version, key ) );
}
}*/

}

int QgsServiceRegistry::unregisterService( const QString& name, const QString& version )
Expand Down
53 changes: 29 additions & 24 deletions src/server/services/wms/qgswms.cpp
Expand Up @@ -61,8 +61,21 @@ namespace QgsWms
{
Q_UNUSED( project );

// Get the request
QgsServerRequest::Parameters params = request.parameters();
QString versionString = params.value( "VERSION" );
if ( versionString.isEmpty() )
{
//WMTVER needs to be supported by WMS 1.1.1 for backwards compatibility with WMS 1.0.0
versionString = params.value( "WMTVER" );
}

// Set the default version
if ( versionString.isEmpty() )
{
versionString = mVersion;
}

// Get the request
QString req = params.value( QStringLiteral( "REQUEST" ) );
if ( req.isEmpty() )
{
Expand All @@ -72,66 +85,59 @@ namespace QgsWms
}

if (( QSTR_COMPARE( mVersion, "1.1.1" ) && QSTR_COMPARE( req, "capabilities" ) )
|| QSTR_COMPARE( req, "GetCapabilites" ) )
|| QSTR_COMPARE( req, "GetCapabilities" ) )
{
//TODO GetCapabilities
writeGetCapabilities( mServerIface, mVersion, request, response, false );
writeGetCapabilities( mServerIface, versionString, request, response, false );
}
else if QSTR_COMPARE( req, "GetProjectSettings" )
{
//Ensure that we are supporting 1.3.0
if ( mVersion.compare( "1.3.0" ) != 0 )
{
writeError( response, QStringLiteral( "OperationNotSupported" ),
QStringLiteral( "GetProjectSettings is not supported" ) );
return;
}
writeGetCapabilities( mServerIface, mVersion, request, response, true );
// TODO GetProjectSettings
//getProjectSettings extends WMS 1.3.0 capabilities
versionString = QStringLiteral( "1.3.0" );
writeGetCapabilities( mServerIface, versionString, request, response, true );
}
else if QSTR_COMPARE( req, "GetMap" )
{
QString format = params.value( QStringLiteral( "FORMAT" ) );
if QSTR_COMPARE( format, "application/dxf" )
{
writeAsDxf( mServerIface, mVersion, request, response );
writeAsDxf( mServerIface, versionString, request, response );
}
else
{
writeGetMap( mServerIface, mVersion, request, response );
writeGetMap( mServerIface, versionString, request, response );
}
}
else if QSTR_COMPARE( req, "GetFeatureInfo" )
{
writeGetFeatureInfo( mServerIface, mVersion, request, response );
writeGetFeatureInfo( mServerIface, versionString, request, response );
}
else if QSTR_COMPARE( req, "GetContext" )
{
writeGetContext( mServerIface, mVersion, request, response );
writeGetContext( mServerIface, versionString, request, response );
}
else if QSTR_COMPARE( req, "GetSchemaExtension" )
{
writeGetSchemaExtension( mServerIface, mVersion, request, response );
writeGetSchemaExtension( mServerIface, versionString, request, response );
}
else if QSTR_COMPARE( req, "GetStyle" )
{
writeGetStyle( mServerIface, mVersion, request, response );
writeGetStyle( mServerIface, versionString, request, response );
}
else if QSTR_COMPARE( req, "GetStyles" )
{
writeGetStyles( mServerIface, mVersion, request, response );
writeGetStyles( mServerIface, versionString, request, response );
}
else if QSTR_COMPARE( req, "DescribeLayer" )
{
writeDescribeLayer( mServerIface, mVersion, request, response );
writeDescribeLayer( mServerIface, versionString, request, response );
}
else if ( QSTR_COMPARE( req, "GetLegendGraphic" ) || QSTR_COMPARE( req, "GetLegendGraphics" ) )
{
writeGetLegendGraphics( mServerIface, mVersion, request, response );
writeGetLegendGraphics( mServerIface, versionString, request, response );
}
else if QSTR_COMPARE( req, "GetPrint" )
{
writeDescribeLayer( mServerIface, mVersion, request, response );
writeGetPrint( mServerIface, versionString, request, response );
}
else
{
Expand Down Expand Up @@ -159,7 +165,6 @@ class QgsWmsModule: public QgsServiceModule
{
QgsDebugMsg( "WMSModule::registerSelf called" );
registry.registerService( new QgsWms::Service( "1.3.0", serverIface ) );
registry.registerService( new QgsWms::Service( "1.1.1", serverIface ) );
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/server/services/wms/qgswmsgetcapabilities.cpp
Expand Up @@ -76,7 +76,7 @@ namespace QgsWms
QgsMessageLog::logMessage( QStringLiteral( "Found capabilities document in cache" ) );
}

response.setHeader( QStringLiteral( "Contente-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
response.write( capabilitiesDocument->toByteArray() );
}

Expand Down
2 changes: 1 addition & 1 deletion src/server/services/wms/qgswmsgetfeatureinfo.cpp
Expand Up @@ -151,7 +151,7 @@ namespace QgsWms
return;
}

response.setHeader( QStringLiteral( "Content-Type" ), infoFormat );
response.setHeader( QStringLiteral( "Content-Type" ), infoFormat + QStringLiteral( "; charset=utf-8" ) );
response.write( ba );
}

Expand Down
11 changes: 10 additions & 1 deletion src/server/services/wms/qgswmsutils.cpp
Expand Up @@ -38,7 +38,16 @@ namespace QgsWms
QgsWmsConfigParser* getConfigParser( QgsServerInterface* serverIface )
{
QString configFilePath = serverIface->configFilePath();
return QgsConfigCache::instance()->wmsConfiguration( configFilePath, serverIface->accessControls() );

QgsWmsConfigParser* parser = QgsConfigCache::instance()->wmsConfiguration( configFilePath, serverIface->accessControls() );
if ( !parser )
{
throw QgsMapServiceException(
QStringLiteral( "WMS configuration error" ),
QStringLiteral( "There was an error reading the project file or the SLD configuration" ) );

}
return parser;
}

// Output a wms standard error
Expand Down
20 changes: 13 additions & 7 deletions tests/src/python/test_qgsserver_services.py
Expand Up @@ -100,8 +100,8 @@ def test_register(self):
def test_0_version_registration(self):

reg = QgsServiceRegistry()
myserv1 = MyService("TEST", "1.0", "Hello")
myserv2 = MyService("TEST", "1.1", "Hello")
myserv1 = MyService("TEST", "1.1", "Hello")
myserv2 = MyService("TEST", "1.0", "Hello")

reg.registerService( myserv1 )
reg.registerService( myserv2)
Expand All @@ -111,7 +111,13 @@ def test_0_version_registration(self):
self.assertEqual(service.version(), "1.1")

service = reg.getService("TEST", "2.0")
self.assertIsNone(service)
self.assertIsNotNone(service)
self.assertEqual(service.version(), "1.1")

service = reg.getService("TEST", "1.0")
self.assertIsNotNone(service)
self.assertEqual(service.version(), "1.0")


def test_1_unregister_services(self):

Expand All @@ -124,17 +130,17 @@ def test_1_unregister_services(self):
reg.registerService(serv2)
reg.registerService(serv3)

# Check we get the highest version
# Check we get the default version
service = reg.getService("TEST")
self.assertEqual( service.version(), "1.0c" )
self.assertEqual( service.version(), "1.0a" )

# Remove one service
removed = reg.unregisterService("TEST", "1.0c")
removed = reg.unregisterService("TEST", "1.0a")
self.assertEqual( removed, 1 )

# Check that we get the highest version
service = reg.getService("TEST")
self.assertEqual( service.version(), "1.0b" )
self.assertEqual( service.version(), "1.0c" )

# Remove all services
removed = reg.unregisterService("TEST")
Expand Down

0 comments on commit dc211f8

Please sign in to comment.