mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Revisit server exceptions
- Add server exception base class - Enable per service exception definition - Handle QgsException gracefully (error 500) - Handle OGC exception versioning
This commit is contained in:
parent
c128d13ddf
commit
8b0526d678
@ -20,45 +20,14 @@
|
||||
class QgsRequestHandler /Abstract/
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include "qgsmapserviceexception.h"
|
||||
#include "qgsserverexception.h"
|
||||
#include "qgsrequesthandler.h"
|
||||
%End
|
||||
|
||||
public:
|
||||
|
||||
/** Parses the input and creates a request neutral Parameter/Value map
|
||||
* @note not available in Python bindings
|
||||
*/
|
||||
// virtual void parseInput() = 0;
|
||||
|
||||
/** Sends the map image back to the client
|
||||
* @note not available in Python bindings
|
||||
*/
|
||||
// virtual void setGetMapResponse( const QString& service, QImage* img, int imageQuality ) = 0;
|
||||
|
||||
//! @note not available in Python bindings
|
||||
// virtual void setGetCapabilitiesResponse( const QDomDocument& doc ) = 0;
|
||||
|
||||
//! @note not available in Python bindings
|
||||
// virtual void setGetFeatureInfoResponse( const QDomDocument& infoDoc, const QString& infoFormat ) = 0;
|
||||
|
||||
/** Allow plugins to return a QgsMapServiceException*/
|
||||
void setServiceException( const QgsMapServiceException& ex /Transfer/ );
|
||||
|
||||
//! @note not available in Python bindings
|
||||
// virtual void setXmlResponse( const QDomDocument& doc ) = 0;
|
||||
|
||||
//! @note not available in Python bindings
|
||||
// virtual void setXmlResponse( const QDomDocument& doc, const QString& mimeType ) = 0;
|
||||
|
||||
//! @note not available in Python bindings
|
||||
// virtual void setGetPrintResponse( QByteArray* b ) = 0;
|
||||
|
||||
//! @note not available in Python bindings
|
||||
// virtual bool startGetFeatureResponse( QByteArray* ba, const QString& infoFormat ) = 0;
|
||||
|
||||
//! @note not available in Python bindings
|
||||
// virtual void setGetFeatureResponse( QByteArray* ba ) = 0;
|
||||
/** Allow plugins to return a QgsServerException*/
|
||||
void setServiceException( const QgsServerException& ex );
|
||||
|
||||
//! @note not available in Python bindings
|
||||
void endGetFeatureResponse( QByteArray* ba );
|
||||
@ -116,12 +85,4 @@ class QgsRequestHandler /Abstract/
|
||||
|
||||
/** Return true if the HTTP headers were already sent to the client*/
|
||||
bool headersSent() const;
|
||||
|
||||
|
||||
//! @note not available in Python bindings
|
||||
// virtual QPair<QByteArray, QByteArray> getResponse() = 0;
|
||||
|
||||
private:
|
||||
/** Parses the input and creates a request neutral Parameter/Value map*/
|
||||
void parseInput();
|
||||
};
|
||||
|
56
python/server/qgsserverexception.sip
Normal file
56
python/server/qgsserverexception.sip
Normal file
@ -0,0 +1,56 @@
|
||||
/***************************************************************************
|
||||
qgsserverexception.sip
|
||||
------------------------
|
||||
begin : January 11 2017
|
||||
copyright : (C) 2017 by David Marteau
|
||||
email : david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/** \ingroup server
|
||||
* \class QgsServerException
|
||||
* \brief server Exception base class.
|
||||
*/
|
||||
|
||||
class QgsServerException
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsserverexception.h>
|
||||
%End
|
||||
public:
|
||||
QgsServerException( const QString& message, int responseCode = 500 );
|
||||
|
||||
int responseCode() const;
|
||||
|
||||
virtual QByteArray formatResponse( QString& responseFormat ) const;
|
||||
};
|
||||
|
||||
|
||||
class QgsOgcServiceException
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsserverexception.h>
|
||||
%End
|
||||
public:
|
||||
QgsOgcServiceException( const QString& code, const QString& message, const QString& locator = QString(),
|
||||
int responseCode = 200, const QString& version = "1.3.0" );
|
||||
|
||||
QString message() const;
|
||||
QString code() const;
|
||||
QString locator() const;
|
||||
|
||||
virtual QByteArray formatResponse( QString& responseFormat / Out / ) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -92,6 +92,11 @@ class QgsServerResponse
|
||||
*/
|
||||
virtual qint64 write( const QByteArray& byteArray );
|
||||
|
||||
/**
|
||||
* Write server exception
|
||||
*/
|
||||
virtual void write( const QgsServerException& ex );
|
||||
|
||||
/**
|
||||
* Return the underlying QIODevice
|
||||
*/
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
%Include qgsserverrequest.sip
|
||||
%Include qgsserverresponse.sip
|
||||
%Include qgsserverexception.sip
|
||||
%Include qgsservice.sip
|
||||
%Include qgsservicemodule.sip
|
||||
%Include qgsserviceregistry.sip
|
||||
|
@ -28,7 +28,7 @@ SET ( qgis_mapserv_SRCS
|
||||
qgswfsserver.cpp
|
||||
qgswcsserver.cpp
|
||||
qgsserversettings.cpp
|
||||
qgsmapserviceexception.cpp
|
||||
qgsserverexception.cpp
|
||||
qgsmslayercache.cpp
|
||||
qgsmslayerbuilder.cpp
|
||||
qgshostedvdsbuilder.cpp
|
||||
|
@ -30,16 +30,14 @@
|
||||
//
|
||||
|
||||
QgsFcgiServerResponse::QgsFcgiServerResponse( QgsServerRequest::Method method )
|
||||
: mMethod( method )
|
||||
{
|
||||
mBuffer.open( QIODevice::ReadWrite );
|
||||
mHeadersSent = false;
|
||||
mFinished = false;
|
||||
mMethod = method;
|
||||
setDefaultHeaders();
|
||||
}
|
||||
|
||||
QgsFcgiServerResponse::~QgsFcgiServerResponse()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QgsFcgiServerResponse::clearHeader( const QString& key )
|
||||
@ -82,7 +80,6 @@ void QgsFcgiServerResponse::sendError( int code, const QString& message )
|
||||
}
|
||||
|
||||
clear();
|
||||
setDefaultHeaders();
|
||||
setReturnCode( code );
|
||||
setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/html;charset=utf-8" ) );
|
||||
write( QStringLiteral( "<html><body>%1</body></html>" ).arg( message ) );
|
||||
@ -157,6 +154,9 @@ void QgsFcgiServerResponse::clear()
|
||||
mHeaders.clear();
|
||||
mBuffer.seek( 0 );
|
||||
mBuffer.buffer().clear();
|
||||
|
||||
// Restore default headers
|
||||
setDefaultHeaders();
|
||||
}
|
||||
|
||||
void QgsFcgiServerResponse::setDefaultHeaders()
|
||||
|
@ -61,13 +61,13 @@ class QgsFcgiServerResponse: public QgsServerResponse
|
||||
/**
|
||||
* Set the default headers
|
||||
*/
|
||||
virtual void setDefaultHeaders();
|
||||
void setDefaultHeaders();
|
||||
|
||||
private:
|
||||
QMap<QString, QString> mHeaders;
|
||||
QBuffer mBuffer;
|
||||
bool mFinished;
|
||||
bool mHeadersSent;
|
||||
QBuffer mBuffer;
|
||||
bool mFinished = false;
|
||||
bool mHeadersSent = false;
|
||||
QgsServerRequest::Method mMethod;
|
||||
};
|
||||
|
||||
|
@ -20,12 +20,14 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "qgsexception.h"
|
||||
#include "qgsserverexception.h"
|
||||
#include "qgis_server.h"
|
||||
|
||||
/** \ingroup server
|
||||
* \class QgsMapServiceException
|
||||
* \brief Exception class for WMS service exceptions.
|
||||
* \brief Exception class for WMS service exceptions (for compatibility only).
|
||||
*
|
||||
* \deprecated Use QsgServerException
|
||||
*
|
||||
* The most important codes are:
|
||||
* * "InvalidFormat"
|
||||
@ -34,15 +36,12 @@
|
||||
* * "OperationNotSupported"
|
||||
*/
|
||||
|
||||
class SERVER_EXPORT QgsMapServiceException : public QgsException
|
||||
class SERVER_EXPORT QgsMapServiceException : public QgsOgcServiceException
|
||||
{
|
||||
public:
|
||||
QgsMapServiceException( const QString& code, const QString& message );
|
||||
QString code() const {return mCode;}
|
||||
QString message() const {return mMessage;}
|
||||
private:
|
||||
QString mCode;
|
||||
QString mMessage;
|
||||
QgsMapServiceException( const QString& code, const QString& message )
|
||||
: QgsOgcServiceException( code, message )
|
||||
{}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "qgshttptransaction.h"
|
||||
#endif
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsmapserviceexception.h"
|
||||
#include "qgsserverexception.h"
|
||||
#include "qgsserverrequest.h"
|
||||
#include "qgsserverresponse.h"
|
||||
#include <QBuffer>
|
||||
@ -38,7 +38,7 @@
|
||||
#include <QUrlQuery>
|
||||
|
||||
QgsRequestHandler::QgsRequestHandler( QgsServerRequest& request, QgsServerResponse& response )
|
||||
: mException( nullptr )
|
||||
: mExceptionRaised( false )
|
||||
, mRequest( request )
|
||||
, mResponse( response )
|
||||
{
|
||||
@ -46,7 +46,6 @@ QgsRequestHandler::QgsRequestHandler( QgsServerRequest& request, QgsServerRespon
|
||||
|
||||
QgsRequestHandler::~QgsRequestHandler()
|
||||
{
|
||||
delete mException;
|
||||
}
|
||||
|
||||
QMap<QString, QString> QgsRequestHandler::parameterMap() const
|
||||
@ -70,7 +69,7 @@ void QgsRequestHandler::setHttpResponse( const QByteArray& ba, const QString &fo
|
||||
|
||||
bool QgsRequestHandler::exceptionRaised() const
|
||||
{
|
||||
return mException;
|
||||
return mExceptionRaised;
|
||||
}
|
||||
|
||||
void QgsRequestHandler::setHeader( const QString &name, const QString &value )
|
||||
@ -169,28 +168,11 @@ void QgsRequestHandler::setXmlResponse( const QDomDocument& doc, const QString&
|
||||
setHttpResponse( ba, mimeType );
|
||||
}
|
||||
|
||||
void QgsRequestHandler::setServiceException( const QgsMapServiceException& ex )
|
||||
void QgsRequestHandler::setServiceException( const QgsServerException& ex )
|
||||
{
|
||||
// Safety measure to avoid potential leaks if called repeatedly
|
||||
delete mException;
|
||||
mException = new QgsMapServiceException( ex );
|
||||
//create Exception DOM document
|
||||
QDomDocument exceptionDoc;
|
||||
QDomElement serviceExceptionReportElem = exceptionDoc.createElement( QStringLiteral( "ServiceExceptionReport" ) );
|
||||
serviceExceptionReportElem.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.3.0" ) );
|
||||
serviceExceptionReportElem.setAttribute( QStringLiteral( "xmlns" ), QStringLiteral( "http://www.opengis.net/ogc" ) );
|
||||
exceptionDoc.appendChild( serviceExceptionReportElem );
|
||||
QDomElement serviceExceptionElem = exceptionDoc.createElement( QStringLiteral( "ServiceException" ) );
|
||||
serviceExceptionElem.setAttribute( QStringLiteral( "code" ), ex.code() );
|
||||
QDomText messageText = exceptionDoc.createTextNode( ex.message() );
|
||||
serviceExceptionElem.appendChild( messageText );
|
||||
serviceExceptionReportElem.appendChild( serviceExceptionElem );
|
||||
|
||||
QByteArray ba = exceptionDoc.toByteArray();
|
||||
// Clear response headers and body and set new exception
|
||||
// TODO: check for headersSent()
|
||||
clear();
|
||||
setHttpResponse( ba, QStringLiteral( "text/xml" ) );
|
||||
mExceptionRaised = true;
|
||||
mResponse.write( ex );
|
||||
}
|
||||
|
||||
bool QgsRequestHandler::startGetFeatureResponse( QByteArray* ba, const QString& infoFormat )
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
class QDomDocument;
|
||||
class QImage;
|
||||
class QgsMapServiceException;
|
||||
class QgsServerException;
|
||||
class QgsServerRequest;
|
||||
class QgsServerResponse;
|
||||
|
||||
@ -58,7 +58,7 @@ class SERVER_EXPORT QgsRequestHandler
|
||||
void setGetCapabilitiesResponse( const QDomDocument& doc );
|
||||
|
||||
//! Allow plugins to return a QgsMapServiceException
|
||||
void setServiceException( const QgsMapServiceException &ex );
|
||||
void setServiceException( const QgsServerException &ex );
|
||||
|
||||
//! @note not available in Python bindings
|
||||
void setXmlResponse( const QDomDocument& doc );
|
||||
@ -154,7 +154,7 @@ class SERVER_EXPORT QgsRequestHandler
|
||||
QString mFormatString; //format string as it is passed in the request (with base)
|
||||
QString mService;
|
||||
QString mInfoFormat;
|
||||
QgsMapServiceException* mException; // Stores the exception
|
||||
bool mExceptionRaised;
|
||||
|
||||
QgsServerRequest& mRequest;
|
||||
QgsServerResponse& mResponse;
|
||||
|
@ -396,100 +396,114 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
|
||||
// Call requestReady() method (if enabled)
|
||||
theResponse.start();
|
||||
|
||||
QMap<QString, QString> parameterMap = request.parameters();
|
||||
printRequestParameters( parameterMap, logLevel );
|
||||
|
||||
QgsAccessControl* accessControl = sServerInterface->accessControls();
|
||||
|
||||
//Config file path
|
||||
QString configFilePath = configPath( *sConfigFilePath, parameterMap );
|
||||
|
||||
sServerInterface->setConfigFilePath( configFilePath );
|
||||
|
||||
//Service parameter
|
||||
QString serviceString = parameterMap.value( QStringLiteral( "SERVICE" ) );
|
||||
|
||||
if ( serviceString.isEmpty() )
|
||||
{
|
||||
// SERVICE not mandatory for WMS 1.3.0 GetMap & GetFeatureInfo
|
||||
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 = parameterMap.value( QStringLiteral( "FILE_NAME" ) );
|
||||
if ( !outputFileName.isEmpty() )
|
||||
{
|
||||
theRequestHandler.setHeader( QStringLiteral( "Content-Disposition" ), "attachment; filename=\"" + outputFileName + "\"" );
|
||||
}
|
||||
|
||||
// Enter core services main switch
|
||||
// Plugins may have set exceptions
|
||||
if ( !theRequestHandler.exceptionRaised() )
|
||||
{
|
||||
// Lookup for service
|
||||
try
|
||||
{
|
||||
QMap<QString, QString> parameterMap = request.parameters();
|
||||
printRequestParameters( parameterMap, logLevel );
|
||||
|
||||
QgsService* service = sServiceRegistry.getService( serviceString, versionString );
|
||||
if ( service )
|
||||
{
|
||||
service->executeRequest( request, theResponse );
|
||||
}
|
||||
else if ( serviceString == QLatin1String( "WCS" ) )
|
||||
{
|
||||
QgsWCSProjectParser* p = QgsConfigCache::instance()->wcsConfiguration(
|
||||
configFilePath
|
||||
, accessControl
|
||||
);
|
||||
if ( !p )
|
||||
QgsAccessControl* accessControl = sServerInterface->accessControls();
|
||||
|
||||
//Config file path
|
||||
QString configFilePath = configPath( *sConfigFilePath, parameterMap );
|
||||
|
||||
sServerInterface->setConfigFilePath( configFilePath );
|
||||
|
||||
//Service parameter
|
||||
QString serviceString = parameterMap.value( QStringLiteral( "SERVICE" ) );
|
||||
|
||||
if ( serviceString.isEmpty() )
|
||||
{
|
||||
theRequestHandler.setServiceException( QgsMapServiceException( QStringLiteral( "Project file error" ), QStringLiteral( "Error reading the project file" ) ) );
|
||||
// SERVICE not mandatory for WMS 1.3.0 GetMap & GetFeatureInfo
|
||||
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 = parameterMap.value( QStringLiteral( "FILE_NAME" ) );
|
||||
if ( !outputFileName.isEmpty() )
|
||||
{
|
||||
theRequestHandler.setHeader( QStringLiteral( "Content-Disposition" ), "attachment; filename=\"" + outputFileName + "\"" );
|
||||
}
|
||||
|
||||
// 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
|
||||
, accessControl
|
||||
);
|
||||
if ( !p )
|
||||
{
|
||||
theRequestHandler.setServiceException( QgsMapServiceException( QStringLiteral( "Project file error" ),
|
||||
QStringLiteral( "Error reading the project file" ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsWCSServer wcsServer(
|
||||
configFilePath
|
||||
, sSettings
|
||||
, parameterMap
|
||||
, p
|
||||
, &theRequestHandler
|
||||
, accessControl
|
||||
);
|
||||
wcsServer.executeRequest();
|
||||
}
|
||||
}
|
||||
else if ( serviceString == QLatin1String( "WFS" ) )
|
||||
{
|
||||
QgsWfsProjectParser* p = QgsConfigCache::instance()->wfsConfiguration(
|
||||
configFilePath
|
||||
, accessControl
|
||||
);
|
||||
if ( !p )
|
||||
{
|
||||
theRequestHandler.setServiceException( QgsMapServiceException( QStringLiteral( "Project file error" ),
|
||||
QStringLiteral( "Error reading the project file" ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsWfsServer wfsServer(
|
||||
configFilePath
|
||||
, sSettings
|
||||
, parameterMap
|
||||
, p
|
||||
, &theRequestHandler
|
||||
, accessControl
|
||||
);
|
||||
wfsServer.executeRequest();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsWCSServer wcsServer(
|
||||
configFilePath
|
||||
, sSettings
|
||||
, parameterMap
|
||||
, p
|
||||
, &theRequestHandler
|
||||
, accessControl
|
||||
);
|
||||
wcsServer.executeRequest();
|
||||
throw QgsOgcServiceException( QStringLiteral( "Service configuration error" ),
|
||||
QStringLiteral( "Service unknown or unsupported" ) ) ;
|
||||
}
|
||||
}
|
||||
else if ( serviceString == QLatin1String( "WFS" ) )
|
||||
catch ( QgsServerException& ex )
|
||||
{
|
||||
QgsWfsProjectParser* p = QgsConfigCache::instance()->wfsConfiguration(
|
||||
configFilePath
|
||||
, accessControl
|
||||
);
|
||||
if ( !p )
|
||||
{
|
||||
theRequestHandler.setServiceException( QgsMapServiceException( QStringLiteral( "Project file error" ), QStringLiteral( "Error reading the project file" ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsWfsServer wfsServer(
|
||||
configFilePath
|
||||
, sSettings
|
||||
, parameterMap
|
||||
, p
|
||||
, &theRequestHandler
|
||||
, accessControl
|
||||
);
|
||||
wfsServer.executeRequest();
|
||||
}
|
||||
theResponse.write( ex );
|
||||
}
|
||||
else
|
||||
catch ( QgsException& ex )
|
||||
{
|
||||
theRequestHandler.setServiceException( QgsMapServiceException( QStringLiteral( "Service configuration error" ), QStringLiteral( "Service unknown or unsupported" ) ) );
|
||||
} // end switch
|
||||
} // end if not exception raised
|
||||
|
||||
// Internal server error
|
||||
theResponse.sendError( 500, ex.what() );
|
||||
}
|
||||
}
|
||||
// Terminate the response
|
||||
theResponse.finish();
|
||||
|
||||
@ -497,7 +511,6 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
|
||||
// to a deleted request handler from Python bindings
|
||||
sServerInterface->clearRequestHandler();
|
||||
|
||||
|
||||
if ( logLevel == QgsMessageLog::INFO )
|
||||
{
|
||||
QgsMessageLog::logMessage( "Request finished in " + QString::number( time.elapsed() ) + " ms", QStringLiteral( "Server" ), QgsMessageLog::INFO );
|
||||
|
77
src/server/qgsserverexception.cpp
Normal file
77
src/server/qgsserverexception.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
/***************************************************************************
|
||||
qgsservervexception.h
|
||||
-------------------
|
||||
begin : January 11, 2017
|
||||
copyright : (C) 2017 David Marteau
|
||||
email : david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsserverexception.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
|
||||
// QgsServerException
|
||||
QgsServerException::QgsServerException( const QString& message, int responseCode )
|
||||
: QgsException( message )
|
||||
, mResponseCode( responseCode )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QByteArray QgsServerException::formatResponse( QString& responseFormat ) const
|
||||
{
|
||||
QDomDocument doc;
|
||||
QDomElement root = doc.createElement( QStringLiteral( "ServerException" ) );
|
||||
doc.appendChild( root );
|
||||
root.appendChild( doc.createTextNode( what() ) );
|
||||
|
||||
responseFormat = QStringLiteral( "text/xml; charset=utf-8" );
|
||||
return doc.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
// QgsOgcServiceException
|
||||
QgsOgcServiceException:: QgsOgcServiceException( const QString& code, const QString& message, const QString& locator,
|
||||
int responseCode, const QString& version )
|
||||
: QgsServerException( message, responseCode )
|
||||
, mCode( code )
|
||||
, mMessage( message )
|
||||
, mLocator( locator )
|
||||
, mVersion( version )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QByteArray QgsOgcServiceException::formatResponse( QString& responseFormat ) const
|
||||
{
|
||||
QDomDocument doc;
|
||||
QDomElement root = doc.createElement( QStringLiteral( "ServiceExceptionReport" ) );
|
||||
root.setAttribute( QStringLiteral( "version" ), mVersion );
|
||||
root.setAttribute( QStringLiteral( "xmlns" ) , QStringLiteral( "http://www.opengis.net/ogc" ) );
|
||||
doc.appendChild( root );
|
||||
|
||||
QDomElement elem = doc.createElement( QStringLiteral( "ServiceException" ) );
|
||||
elem.setAttribute( QStringLiteral( "code" ), mCode );
|
||||
elem.appendChild( doc.createTextNode( mMessage ) );
|
||||
root.appendChild( elem );
|
||||
|
||||
if ( ! mLocator.isEmpty() )
|
||||
{
|
||||
elem.setAttribute( QStringLiteral( "locator" ), mLocator );
|
||||
}
|
||||
|
||||
responseFormat = QStringLiteral( "text/xml; charset=utf-8" );
|
||||
return doc.toByteArray();
|
||||
}
|
||||
|
||||
|
||||
|
84
src/server/qgsserverexception.h
Normal file
84
src/server/qgsserverexception.h
Normal file
@ -0,0 +1,84 @@
|
||||
/***************************************************************************
|
||||
qgserverexception.h
|
||||
------------------------
|
||||
begin : January 11, 2017
|
||||
copyright : (C) 2017 by David Marteau
|
||||
email : david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSSERVEREXCEPTION_H
|
||||
#define QGSSERVEREXCEPTION_H
|
||||
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
|
||||
#include "qgsexception.h"
|
||||
#include "qgis_server.h"
|
||||
|
||||
/** \ingroup server
|
||||
* \class QgsServerException
|
||||
* \brief Exception base class for server exceptions.
|
||||
*/
|
||||
class SERVER_EXPORT QgsServerException : public QgsException
|
||||
{
|
||||
public:
|
||||
QgsServerException( const QString& message, int responseCode = 500 );
|
||||
|
||||
/**
|
||||
* @return the return HTTP response code associated with this exception
|
||||
*/
|
||||
int responseCode() const { return mResponseCode; }
|
||||
|
||||
/** Format the exception for sending to client
|
||||
*
|
||||
* @param responseFormat QString to store the content type of the response format.
|
||||
* @return QByteArray the fermatted response.
|
||||
*
|
||||
* The defaolt implementation return text/xml format.
|
||||
*/
|
||||
virtual QByteArray formatResponse( QString& responseFormat ) const;
|
||||
|
||||
private:
|
||||
int mResponseCode;
|
||||
};
|
||||
|
||||
/** \ingroup server
|
||||
* \class QgsOcgServiceException
|
||||
* \brief Exception base class for service exceptions.
|
||||
*
|
||||
* Note that this exeception is assaciated with a default return code 200 which may be
|
||||
* not appropriate in some situations.
|
||||
*/
|
||||
class SERVER_EXPORT QgsOgcServiceException : public QgsServerException
|
||||
{
|
||||
public:
|
||||
QgsOgcServiceException( const QString& code, const QString& message, const QString& locator = QString(),
|
||||
int responseCode = 200, const QString& version = QStringLiteral( "1.3.0" ) );
|
||||
|
||||
QString message() const { return mMessage; }
|
||||
QString code() const { return mCode; }
|
||||
QString locator() const { return mLocator; }
|
||||
QString version() const { return mVersion; }
|
||||
|
||||
virtual QByteArray formatResponse( QString& responseFormat ) const override;
|
||||
|
||||
private:
|
||||
QString mCode;
|
||||
QString mMessage;
|
||||
QString mLocator;
|
||||
QString mVersion;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "qgsserverresponse.h"
|
||||
#include "qgsmessagelog.h"
|
||||
//#include <QTextStream>
|
||||
#include "qgsserverexception.h"
|
||||
|
||||
//! constructor
|
||||
QgsServerResponse::QgsServerResponse()
|
||||
@ -75,3 +75,21 @@ qint64 QgsServerResponse::write( const char* data )
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QgsServerResponse::write( const QgsServerException& ex )
|
||||
{
|
||||
QString responseFormat;
|
||||
QByteArray ba = ex.formatResponse( responseFormat );
|
||||
|
||||
if ( headersSent() )
|
||||
{
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Error: Cannot write exception after header sent !" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
clear();
|
||||
setReturnCode( ex.responseCode() );
|
||||
setHeader( "Content-Type", responseFormat );
|
||||
write( ba );
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <QString>
|
||||
#include <QIODevice>
|
||||
|
||||
class QgsServerException;
|
||||
|
||||
/**
|
||||
* \ingroup server
|
||||
* QgsServerResponse
|
||||
@ -126,6 +128,11 @@ class SERVER_EXPORT QgsServerResponse
|
||||
*/
|
||||
virtual qint64 write( const char* data );
|
||||
|
||||
/**
|
||||
* Write server exception
|
||||
*/
|
||||
virtual void write( const QgsServerException& ex );
|
||||
|
||||
/**
|
||||
* Return the underlying QIODevice
|
||||
*/
|
||||
|
@ -79,9 +79,8 @@ namespace QgsWms
|
||||
QString req = params.value( QStringLiteral( "REQUEST" ) );
|
||||
if ( req.isEmpty() )
|
||||
{
|
||||
writeError( response, QStringLiteral( "OperationNotSupported" ),
|
||||
QStringLiteral( "Please check the value of the REQUEST parameter" ) );
|
||||
return;
|
||||
throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
|
||||
QStringLiteral( "Please check the value of the REQUEST parameter" ) );
|
||||
}
|
||||
|
||||
if (( QSTR_COMPARE( mVersion, "1.1.1" ) && QSTR_COMPARE( req, "capabilities" ) )
|
||||
@ -142,9 +141,8 @@ namespace QgsWms
|
||||
else
|
||||
{
|
||||
// Operation not supported
|
||||
writeError( response, QStringLiteral( "OperationNotSupported" ),
|
||||
QString( "Request %1 is not supported" ).arg( req ) );
|
||||
return;
|
||||
throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
|
||||
QString( "Request %1 is not supported" ).arg( req ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,21 +30,15 @@ namespace QgsWms
|
||||
{
|
||||
Q_UNUSED( version );
|
||||
QgsServerRequest::Parameters params = request.parameters();
|
||||
try
|
||||
{
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(),
|
||||
params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
QDomDocument doc = server.describeLayer();
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
{
|
||||
writeError( response, ex.code(), ex.message() );
|
||||
}
|
||||
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(),
|
||||
params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
QDomDocument doc = server.describeLayer();
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,20 +49,14 @@ namespace QgsWms
|
||||
{
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Capabilities document not found in cache" ) );
|
||||
QDomDocument doc;
|
||||
try
|
||||
{
|
||||
QgsWmsServer server( configFilePath,
|
||||
*serverSettings,
|
||||
params,
|
||||
getConfigParser( serverIface ),
|
||||
accessControl );
|
||||
doc = server.getCapabilities( version, projectSettings );
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
{
|
||||
writeError( response, ex.code(), ex.message() );
|
||||
return;
|
||||
}
|
||||
QgsWmsServer server( configFilePath,
|
||||
*serverSettings,
|
||||
params,
|
||||
getConfigParser( serverIface ),
|
||||
accessControl );
|
||||
|
||||
doc = server.getCapabilities( version, projectSettings );
|
||||
|
||||
if ( cache )
|
||||
{
|
||||
capabilitiesCache->insertCapabilitiesDocument( configFilePath, cacheKey, &doc );
|
||||
|
@ -29,22 +29,17 @@ namespace QgsWms
|
||||
const QgsServerRequest& request, QgsServerResponse& response )
|
||||
{
|
||||
QgsServerRequest::Parameters params = request.parameters();
|
||||
try
|
||||
{
|
||||
Q_UNUSED( version );
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(),
|
||||
params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
QDomDocument doc = server.getContext();
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
{
|
||||
writeError( response, ex.code(), ex.message() );
|
||||
}
|
||||
Q_UNUSED( version );
|
||||
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(),
|
||||
params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
|
||||
QDomDocument doc = server.getContext();
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -146,9 +146,8 @@ namespace QgsWms
|
||||
}
|
||||
else //unsupported format, set exception
|
||||
{
|
||||
writeError( response, QStringLiteral( "InvalidFormat" ),
|
||||
QString( "Feature info format '%1' is not supported. Possibilities are 'text/plain', 'text/html' or 'text/xml'." ).arg( infoFormat ) );
|
||||
return;
|
||||
throw QgsServiceException( QStringLiteral( "InvalidFormat" ),
|
||||
QString( "Feature info format '%1' is not supported. Possibilities are 'text/plain', 'text/html' or 'text/xml'." ).arg( infoFormat ) );
|
||||
}
|
||||
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), infoFormat + QStringLiteral( "; charset=utf-8" ) );
|
||||
@ -165,17 +164,10 @@ namespace QgsWms
|
||||
*serverIface->serverSettings(), params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
try
|
||||
{
|
||||
QDomDocument doc = server.getFeatureInfo( version );
|
||||
QString outputFormat = params.value( QStringLiteral( "INFO_FORMAT" ), QStringLiteral( "text/plain" ) );
|
||||
writeInfoResponse( doc, response, outputFormat );
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
{
|
||||
writeError( response, ex.code(), ex.message() );
|
||||
}
|
||||
|
||||
QDomDocument doc = server.getFeatureInfo( version );
|
||||
QString outputFormat = params.value( QStringLiteral( "INFO_FORMAT" ), QStringLiteral( "text/plain" ) );
|
||||
writeInfoResponse( doc, response, outputFormat );
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,25 +33,22 @@ namespace QgsWms
|
||||
QgsServerRequest::Parameters params = request.parameters();
|
||||
QgsWmsConfigParser* parser = getConfigParser( serverIface );
|
||||
|
||||
QgsWmsServer server( serverIface->configFilePath(), *serverIface->serverSettings(),
|
||||
params, parser, serverIface->accessControls() );
|
||||
try
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(),
|
||||
params, parser,
|
||||
serverIface->accessControls() );
|
||||
|
||||
QScopedPointer<QImage> result( server.getLegendGraphics() );
|
||||
|
||||
if ( !result.isNull() )
|
||||
{
|
||||
QScopedPointer<QImage> result( server.getLegendGraphics() );
|
||||
if ( !result.isNull() )
|
||||
{
|
||||
QString format = params.value( QStringLiteral( "FORMAT" ), QStringLiteral( "PNG" ) );
|
||||
writeImage( response, *result, format, server.getImageQuality() );
|
||||
}
|
||||
else
|
||||
{
|
||||
writeError( response, QStringLiteral( "UnknownError" ),
|
||||
QStringLiteral( "Failed to compute GetLegendGraphics image" ) );
|
||||
}
|
||||
QString format = params.value( QStringLiteral( "FORMAT" ), QStringLiteral( "PNG" ) );
|
||||
writeImage( response, *result, format, server.getImageQuality() );
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
else
|
||||
{
|
||||
writeError( response, ex.code(), ex.message() );
|
||||
throw QgsServiceException( QStringLiteral( "UnknownError" ),
|
||||
QStringLiteral( "Failed to compute GetLegendGraphics image" ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,23 +37,17 @@ namespace QgsWms
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(), params, parser,
|
||||
serverIface->accessControls() );
|
||||
try
|
||||
|
||||
QScopedPointer<QImage> result( server.getMap() );
|
||||
if ( !result.isNull() )
|
||||
{
|
||||
QScopedPointer<QImage> result( server.getMap() );
|
||||
if ( !result.isNull() )
|
||||
{
|
||||
QString format = params.value( QStringLiteral( "FORMAT" ), QStringLiteral( "PNG" ) );
|
||||
writeImage( response, *result, format, server.getImageQuality() );
|
||||
}
|
||||
else
|
||||
{
|
||||
writeError( response, QStringLiteral( "UnknownError" ),
|
||||
QStringLiteral( "Failed to compute GetMap image" ) );
|
||||
}
|
||||
QString format = params.value( QStringLiteral( "FORMAT" ), QStringLiteral( "PNG" ) );
|
||||
writeImage( response, *result, format, server.getImageQuality() );
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
else
|
||||
{
|
||||
writeError( response, ex.code(), ex.message() );
|
||||
throw QgsServiceException( QStringLiteral( "UnknownError" ),
|
||||
QStringLiteral( "Failed to compute GetMap image" ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,51 +28,46 @@ namespace QgsWms
|
||||
const QgsServerRequest& request, QgsServerResponse& response )
|
||||
{
|
||||
QgsServerRequest::Parameters params = request.parameters();
|
||||
try
|
||||
|
||||
Q_UNUSED( version );
|
||||
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(), params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
|
||||
QString format = params.value( "FORMAT" );
|
||||
QString contentType;
|
||||
|
||||
// GetPrint supports svg/png/pdf
|
||||
if ( format.compare( QStringLiteral( "image/png" ), Qt::CaseInsensitive ) == 0 ||
|
||||
format.compare( QStringLiteral( "png" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
Q_UNUSED( version );
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(), params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
|
||||
QString format = params.value( "FORMAT" );
|
||||
QString contentType;
|
||||
|
||||
// GetPrint supports svg/png/pdf
|
||||
if ( format.compare( QStringLiteral( "image/png" ), Qt::CaseInsensitive ) == 0 ||
|
||||
format.compare( QStringLiteral( "png" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
format = "png";
|
||||
contentType = "image/png";
|
||||
}
|
||||
else if ( format.compare( QStringLiteral( "image/svg" ), Qt::CaseInsensitive ) == 0 ||
|
||||
format.compare( QStringLiteral( "image/svg+xml" ), Qt::CaseInsensitive ) == 0 ||
|
||||
format.compare( QStringLiteral( "svg" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
format = "svg";
|
||||
contentType = "image/svg+xml";
|
||||
}
|
||||
else if ( format.compare( QStringLiteral( "application/pdf" ), Qt::CaseInsensitive ) == 0 ||
|
||||
format.compare( QStringLiteral( "pdf" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
format = "pdf";
|
||||
contentType = "application/pdf";
|
||||
}
|
||||
else
|
||||
{
|
||||
writeError( response, QStringLiteral( "InvalidFormat" ),
|
||||
QString( "Output format %1 is not supported by the GetPrint request" ).arg( format ) );
|
||||
}
|
||||
|
||||
QScopedPointer<QByteArray> result( server.getPrint( format ) );
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), contentType );
|
||||
response.write( *result );
|
||||
format = "png";
|
||||
contentType = "image/png";
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
else if ( format.compare( QStringLiteral( "image/svg" ), Qt::CaseInsensitive ) == 0 ||
|
||||
format.compare( QStringLiteral( "image/svg+xml" ), Qt::CaseInsensitive ) == 0 ||
|
||||
format.compare( QStringLiteral( "svg" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
writeError( response, ex.code(), ex.message() );
|
||||
format = "svg";
|
||||
contentType = "image/svg+xml";
|
||||
}
|
||||
else if ( format.compare( QStringLiteral( "application/pdf" ), Qt::CaseInsensitive ) == 0 ||
|
||||
format.compare( QStringLiteral( "pdf" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
format = "pdf";
|
||||
contentType = "application/pdf";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw QgsServiceException( QStringLiteral( "InvalidFormat" ),
|
||||
QString( "Output format %1 is not supported by the GetPrint request" ).arg( format ) );
|
||||
}
|
||||
|
||||
QScopedPointer<QByteArray> result( server.getPrint( format ) );
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), contentType );
|
||||
response.write( *result );
|
||||
}
|
||||
|
||||
} // samespace QgsWms
|
||||
|
@ -30,22 +30,16 @@ namespace QgsWms
|
||||
{
|
||||
Q_UNUSED( version );
|
||||
QgsServerRequest::Parameters params = request.parameters();
|
||||
try
|
||||
{
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(), params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
QDomDocument doc = server.getSchemaExtension();
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
{
|
||||
writeError( response, ex.code(), ex.message() );
|
||||
}
|
||||
}
|
||||
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(), params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
|
||||
QDomDocument doc = server.getSchemaExtension();
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
|
||||
} // samespace QgsWms
|
||||
|
||||
|
@ -30,23 +30,17 @@ namespace QgsWms
|
||||
{
|
||||
QgsServerRequest::Parameters params = request.parameters();
|
||||
|
||||
try
|
||||
{
|
||||
Q_UNUSED( version );
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(), params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
QDomDocument doc = server.getStyle();
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
{
|
||||
writeError( response, ex.code(), ex.message() );
|
||||
}
|
||||
}
|
||||
Q_UNUSED( version );
|
||||
|
||||
QgsWmsServer server( serverIface->configFilePath(),
|
||||
*serverIface->serverSettings(), params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
|
||||
QDomDocument doc = server.getStyle();
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
|
||||
} // samespace QgsWms
|
||||
|
||||
|
@ -34,16 +34,10 @@ namespace QgsWms
|
||||
*serverIface->serverSettings(), params,
|
||||
getConfigParser( serverIface ),
|
||||
serverIface->accessControls() );
|
||||
try
|
||||
{
|
||||
QDomDocument doc = server.getStyles();
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
{
|
||||
writeError( response, ex.code(), ex.message() );
|
||||
}
|
||||
|
||||
QDomDocument doc = server.getStyles();
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsmapserviceexception.h"
|
||||
#include "qgssldconfigparser.h"
|
||||
#include "qgssymbol.h"
|
||||
#include "qgsrenderer.h"
|
||||
@ -53,6 +52,7 @@
|
||||
#include "qgsaccesscontrol.h"
|
||||
#include "qgsfeaturerequest.h"
|
||||
#include "qgsmaprendererjobproxy.h"
|
||||
#include "qgswmsserviceexception.h"
|
||||
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
@ -405,7 +405,7 @@ namespace QgsWms
|
||||
ok = true;
|
||||
if ( d[2] <= d[0] || d[3] <= d[1] )
|
||||
{
|
||||
throw QgsMapServiceException( "InvalidParameterValue", "BBOX is empty" );
|
||||
throw QgsServiceException( "InvalidParameterValue", "BBOX is empty" );
|
||||
}
|
||||
return QgsRectangle( d[0], d[1], d[2], d[3] );
|
||||
}
|
||||
@ -419,11 +419,11 @@ namespace QgsWms
|
||||
}
|
||||
if ( !mParameters.contains( QStringLiteral( "LAYER" ) ) && !mParameters.contains( QStringLiteral( "LAYERS" ) ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "LayerNotSpecified" ), QStringLiteral( "LAYER is mandatory for GetLegendGraphic operation" ) );
|
||||
throw QgsServiceException( QStringLiteral( "LayerNotSpecified" ), QStringLiteral( "LAYER is mandatory for GetLegendGraphic operation" ) );
|
||||
}
|
||||
if ( !mParameters.contains( QStringLiteral( "FORMAT" ) ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "FormatNotSpecified" ), QStringLiteral( "FORMAT is mandatory for GetLegendGraphic operation" ) );
|
||||
throw QgsServiceException( QStringLiteral( "FormatNotSpecified" ), QStringLiteral( "FORMAT is mandatory for GetLegendGraphic operation" ) );
|
||||
}
|
||||
|
||||
bool contentBasedLegend = false;
|
||||
@ -436,10 +436,10 @@ namespace QgsWms
|
||||
bool bboxOk;
|
||||
contentBasedLegendExtent = _parseBBOX( mParameters[QStringLiteral( "BBOX" )], bboxOk );
|
||||
if ( !bboxOk || contentBasedLegendExtent.isEmpty() )
|
||||
throw QgsMapServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Invalid BBOX parameter" ) );
|
||||
throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Invalid BBOX parameter" ) );
|
||||
|
||||
if ( mParameters.contains( QStringLiteral( "RULE" ) ) )
|
||||
throw QgsMapServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "BBOX parameter cannot be combined with RULE" ) );
|
||||
throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "BBOX parameter cannot be combined with RULE" ) );
|
||||
}
|
||||
|
||||
QStringList layersList, stylesList;
|
||||
@ -635,7 +635,7 @@ namespace QgsWms
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
if ( !mAccessControl->layerReadPermission( nodeLayer->layer() ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "Security" ), "You are not allowed to access to the layer: " + nodeLayer->layer()->name() );
|
||||
throw QgsServiceException( QStringLiteral( "Security" ), "You are not allowed to access to the layer: " + nodeLayer->layer()->name() );
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -877,12 +877,12 @@ namespace QgsWms
|
||||
QDomDocument doc;
|
||||
if ( !mParameters.contains( QStringLiteral( "STYLE" ) ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "StyleNotSpecified" ), QStringLiteral( "Style is mandatory for GetStyle operation" ) );
|
||||
throw QgsServiceException( QStringLiteral( "StyleNotSpecified" ), QStringLiteral( "Style is mandatory for GetStyle operation" ) );
|
||||
}
|
||||
|
||||
if ( !mParameters.contains( QStringLiteral( "LAYER" ) ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "LayerNotSpecified" ), QStringLiteral( "Layer is mandatory for GetStyle operation" ) );
|
||||
throw QgsServiceException( QStringLiteral( "LayerNotSpecified" ), QStringLiteral( "Layer is mandatory for GetStyle operation" ) );
|
||||
}
|
||||
|
||||
QString styleName = mParameters[ QStringLiteral( "STYLE" )];
|
||||
@ -897,13 +897,13 @@ namespace QgsWms
|
||||
QDomDocument doc;
|
||||
if ( !mParameters.contains( QStringLiteral( "LAYERS" ) ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "LayerNotSpecified" ), QStringLiteral( "Layers is mandatory for GetStyles operation" ) );
|
||||
throw QgsServiceException( QStringLiteral( "LayerNotSpecified" ), QStringLiteral( "Layers is mandatory for GetStyles operation" ) );
|
||||
}
|
||||
|
||||
QStringList layersList = mParameters[ QStringLiteral( "LAYERS" )].split( QStringLiteral( "," ), QString::SkipEmptyParts );
|
||||
if ( layersList.size() < 1 )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "LayerNotSpecified" ), QStringLiteral( "Layers is mandatory for GetStyles operation" ) );
|
||||
throw QgsServiceException( QStringLiteral( "LayerNotSpecified" ), QStringLiteral( "Layers is mandatory for GetStyles operation" ) );
|
||||
}
|
||||
|
||||
return mConfigParser->getStyles( layersList );
|
||||
@ -914,22 +914,22 @@ namespace QgsWms
|
||||
{
|
||||
if ( !mParameters.contains( QStringLiteral( "SLD_VERSION" ) ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "MissingParameterValue" ), QStringLiteral( "SLD_VERSION is mandatory for DescribeLayer operation" ) );
|
||||
throw QgsServiceException( QStringLiteral( "MissingParameterValue" ), QStringLiteral( "SLD_VERSION is mandatory for DescribeLayer operation" ) );
|
||||
}
|
||||
if ( mParameters[ QStringLiteral( "SLD_VERSION" )] != QLatin1String( "1.1.0" ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "SLD_VERSION = %1 is not supported" ).arg( mParameters[ QStringLiteral( "SLD_VERSION" )] ) );
|
||||
throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "SLD_VERSION = %1 is not supported" ).arg( mParameters[ QStringLiteral( "SLD_VERSION" )] ) );
|
||||
}
|
||||
|
||||
if ( !mParameters.contains( QStringLiteral( "LAYERS" ) ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "MissingParameterValue" ), QStringLiteral( "LAYERS is mandatory for DescribeLayer operation" ) );
|
||||
throw QgsServiceException( QStringLiteral( "MissingParameterValue" ), QStringLiteral( "LAYERS is mandatory for DescribeLayer operation" ) );
|
||||
}
|
||||
|
||||
QStringList layersList = mParameters[ QStringLiteral( "LAYERS" )].split( QStringLiteral( "," ), QString::SkipEmptyParts );
|
||||
if ( layersList.size() < 1 )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Layers is empty" ) );
|
||||
throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Layers is empty" ) );
|
||||
}
|
||||
|
||||
//Prepare url
|
||||
@ -958,7 +958,7 @@ namespace QgsWms
|
||||
{
|
||||
if ( !mAccessControl->layerReadPermission( layer ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "Security" ), "You are not allowed to access to the layer: " + layer->name() );
|
||||
throw QgsServiceException( QStringLiteral( "Security" ), "You are not allowed to access to the layer: " + layer->name() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -979,7 +979,7 @@ namespace QgsWms
|
||||
if ( !mParameters.contains( QStringLiteral( "TEMPLATE" ) ) )
|
||||
{
|
||||
clearFeatureSelections( selectedLayerIdList );
|
||||
throw QgsMapServiceException( QStringLiteral( "ParameterMissing" ), QStringLiteral( "The TEMPLATE parameter is required for the GetPrint request" ) );
|
||||
throw QgsServiceException( QStringLiteral( "ParameterMissing" ), QStringLiteral( "The TEMPLATE parameter is required for the GetPrint request" ) );
|
||||
}
|
||||
|
||||
QList< QPair< QgsVectorLayer*, QgsFeatureRenderer*> > bkVectorRenderers;
|
||||
@ -1056,7 +1056,7 @@ namespace QgsWms
|
||||
{
|
||||
restoreOpacities( bkVectorRenderers, bkRasterRenderers, labelTransparencies, labelBufferTransparencies );
|
||||
clearFeatureSelections( selectedLayerIdList );
|
||||
throw QgsMapServiceException( QStringLiteral( "InvalidFormat" ), "Output format '" + formatString + "' is not supported in the GetPrint request" );
|
||||
throw QgsServiceException( QStringLiteral( "InvalidFormat" ), "Output format '" + formatString + "' is not supported in the GetPrint request" );
|
||||
}
|
||||
|
||||
restoreOpacities( bkVectorRenderers, bkRasterRenderers, labelTransparencies, labelBufferTransparencies );
|
||||
@ -1095,7 +1095,7 @@ namespace QgsWms
|
||||
{
|
||||
if ( !checkMaximumWidthHeight() )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "Size error" ), QStringLiteral( "The requested map size is too large" ) );
|
||||
throw QgsServiceException( QStringLiteral( "Size error" ), QStringLiteral( "The requested map size is too large" ) );
|
||||
}
|
||||
QStringList layersList, stylesList, layerIdList;
|
||||
QImage* theImage = initializeRendering( layersList, stylesList, layerIdList, mapSettings );
|
||||
@ -1116,7 +1116,7 @@ namespace QgsWms
|
||||
{
|
||||
if ( !mAccessControl->layerReadPermission( layer ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "Security" ), "You are not allowed to access to the layer: " + layer->name() );
|
||||
throw QgsServiceException( QStringLiteral( "Security" ), "You are not allowed to access to the layer: " + layer->name() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1193,7 +1193,7 @@ namespace QgsWms
|
||||
//check if i, j are in the pixel range of the image
|
||||
if ( i < 0 || i > mapSettings.outputSize().width() || j < 0 || j > mapSettings.outputSize().height() )
|
||||
{
|
||||
throw QgsMapServiceException( "InvalidPoint", "I/J parameters not within the pixel range" );
|
||||
throw QgsServiceException( "InvalidPoint", "I/J parameters not within the pixel range" );
|
||||
}
|
||||
|
||||
double xRes = mapSettings.extent().width() / mapSettings.outputSize().width();
|
||||
@ -1250,13 +1250,13 @@ namespace QgsWms
|
||||
//read QUERY_LAYERS
|
||||
if ( !mParameters.contains( QStringLiteral( "QUERY_LAYERS" ) ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "ParameterMissing" ), QStringLiteral( "No QUERY_LAYERS" ) );
|
||||
throw QgsServiceException( QStringLiteral( "ParameterMissing" ), QStringLiteral( "No QUERY_LAYERS" ) );
|
||||
}
|
||||
|
||||
QStringList queryLayerList = mParameters[ QStringLiteral( "QUERY_LAYERS" )].split( QStringLiteral( "," ), QString::SkipEmptyParts );
|
||||
if ( queryLayerList.size() < 1 )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Malformed QUERY_LAYERS" ) );
|
||||
throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Malformed QUERY_LAYERS" ) );
|
||||
}
|
||||
|
||||
//read I,J resp. X,Y
|
||||
@ -1297,7 +1297,7 @@ namespace QgsWms
|
||||
}
|
||||
else
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "ParameterMissing" ), QStringLiteral( "I/J parameters are required for GetFeatureInfo" ) );
|
||||
throw QgsServiceException( QStringLiteral( "ParameterMissing" ), QStringLiteral( "I/J parameters are required for GetFeatureInfo" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1388,7 +1388,7 @@ namespace QgsWms
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
if ( !mAccessControl->layerReadPermission( currentLayer ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "Security" ), "You are not allowed to access to the layer: " + currentLayer->name() );
|
||||
throw QgsServiceException( QStringLiteral( "Security" ), "You are not allowed to access to the layer: " + currentLayer->name() );
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1706,12 +1706,12 @@ namespace QgsWms
|
||||
if ( !bboxOk )
|
||||
{
|
||||
//throw a service exception
|
||||
throw QgsMapServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Invalid BBOX parameter" ) );
|
||||
throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Invalid BBOX parameter" ) );
|
||||
}
|
||||
|
||||
if ( mParameters.contains( "BBOX" ) && mapExtent.isEmpty() )
|
||||
{
|
||||
throw QgsMapServiceException( "InvalidParameterValue", "BBOX is empty" );
|
||||
throw QgsServiceException( "InvalidParameterValue", "BBOX is empty" );
|
||||
}
|
||||
|
||||
QgsUnitTypes::DistanceUnit mapUnits = QgsUnitTypes::DistanceDegrees;
|
||||
@ -1743,7 +1743,7 @@ namespace QgsWms
|
||||
if ( !outputCRS.isValid() )
|
||||
{
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Error, could not create output CRS from EPSG" ) );
|
||||
throw QgsMapServiceException( QStringLiteral( "InvalidCRS" ), QStringLiteral( "Could not create output CRS" ) );
|
||||
throw QgsServiceException( QStringLiteral( "InvalidCRS" ), QStringLiteral( "Could not create output CRS" ) );
|
||||
}
|
||||
|
||||
//then set destinationCrs
|
||||
@ -2220,7 +2220,7 @@ namespace QgsWms
|
||||
else
|
||||
{
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Layer or style not defined, aborting" ) );
|
||||
throw QgsMapServiceException( QStringLiteral( "LayerNotDefined" ), "Layer '" + *llstIt + "' and/or style '" + styleName + "' not defined" );
|
||||
throw QgsServiceException( QStringLiteral( "LayerNotDefined" ), "Layer '" + *llstIt + "' and/or style '" + styleName + "' not defined" );
|
||||
}
|
||||
}
|
||||
|
||||
@ -2256,10 +2256,10 @@ namespace QgsWms
|
||||
//filter string could be unsafe (danger of sql injection)
|
||||
if ( !testFilterStringSafety( eqSplit.at( 1 ) ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "Filter string rejected" ), "The filter string " + eqSplit.at( 1 ) +
|
||||
" has been rejected because of security reasons. Note: Text strings have to be enclosed in single or double quotes. " +
|
||||
"A space between each word / special character is mandatory. Allowed Keywords and special characters are " +
|
||||
"AND,OR,IN,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX. Not allowed are semicolons in the filter expression." );
|
||||
throw QgsServiceException( QStringLiteral( "Filter string rejected" ), "The filter string " + eqSplit.at( 1 ) +
|
||||
" has been rejected because of security reasons. Note: Text strings have to be enclosed in single or double quotes. " +
|
||||
"A space between each word / special character is mandatory. Allowed Keywords and special characters are " +
|
||||
"AND,OR,IN,<,>=,>,>=,!=,',',(,),DMETAPHONE,SOUNDEX. Not allowed are semicolons in the filter expression." );
|
||||
}
|
||||
|
||||
//we need to find the maplayer objects matching the layer name
|
||||
|
@ -1,6 +1,6 @@
|
||||
/***************************************************************************
|
||||
qgsmapserviceexception.h
|
||||
-------------------
|
||||
qgsserviceexception.h
|
||||
------------------------
|
||||
begin : June 13, 2006
|
||||
copyright : (C) 2006 by Marco Hugentobler
|
||||
email : marco dot hugentobler at karto dot baug dot ethz dot ch
|
||||
@ -15,11 +15,36 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsmapserviceexception.h"
|
||||
#ifndef QGSWMSSERVICEEXCEPTION_H
|
||||
#define QGSWMSSERVICEEXCEPTION_H
|
||||
|
||||
QgsMapServiceException::QgsMapServiceException( const QString& code, const QString& message ):
|
||||
QgsException( message ),
|
||||
mCode( code ), mMessage( message )
|
||||
#include <QString>
|
||||
|
||||
#include "qgsserverexception.h"
|
||||
|
||||
namespace QgsWms
|
||||
{
|
||||
|
||||
}
|
||||
/** \ingroup server
|
||||
* \class QgsserviceException
|
||||
* \brief Exception class for WMS service exceptions.
|
||||
*
|
||||
* The most important codes are:
|
||||
* * "InvalidFormat"
|
||||
* * "Invalid CRS"
|
||||
* * "LayerNotDefined" / "StyleNotDefined"
|
||||
* * "OperationNotSupported"
|
||||
*/
|
||||
class QgsServiceException : public QgsOgcServiceException
|
||||
{
|
||||
public:
|
||||
QgsServiceException( const QString& code, const QString& message, const QString& locator = QString(),
|
||||
int responseCode = 200 )
|
||||
: QgsOgcServiceException( code, message, locator, responseCode, QStringLiteral( "1.3.0" ) )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
} // namespace QgsWms
|
||||
|
||||
#endif
|
@ -25,7 +25,6 @@
|
||||
|
||||
namespace QgsWms
|
||||
{
|
||||
|
||||
typedef QList< QPair<QRgb, int> > QgsColorBox; //Color / number of pixels
|
||||
typedef QMultiMap< int, QgsColorBox > QgsColorBoxMap; // sum of pixels / color box
|
||||
|
||||
@ -42,35 +41,13 @@ namespace QgsWms
|
||||
QgsWmsConfigParser* parser = QgsConfigCache::instance()->wmsConfiguration( configFilePath, serverIface->accessControls() );
|
||||
if ( !parser )
|
||||
{
|
||||
throw QgsMapServiceException(
|
||||
throw QgsServiceException(
|
||||
QStringLiteral( "WMS configuration error" ),
|
||||
QStringLiteral( "There was an error reading the project file or the SLD configuration" ) );
|
||||
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
|
||||
// Output a wms standard error
|
||||
void writeError( QgsServerResponse& response, const QString& code, const QString& message )
|
||||
{
|
||||
// WMS errors return erros with http 200
|
||||
// XXX Do we really need to use a QDomDocument here ?
|
||||
QDomDocument doc;
|
||||
QDomElement root = doc.createElement( QStringLiteral( "ServiceExceptionReport" ) );
|
||||
root.setAttribute( QStringLiteral( "version" ), ImplementationVersion() );
|
||||
root.setAttribute( QStringLiteral( "xmlns" ) , QStringLiteral( "http://www.opengis.net/ogc" ) );
|
||||
doc.appendChild( root );
|
||||
|
||||
QDomElement elem = doc.createElement( QStringLiteral( "ServiceException" ) );
|
||||
elem.setAttribute( QStringLiteral( "code" ), code );
|
||||
QDomText messageText = doc.createTextNode( message );
|
||||
elem.appendChild( messageText );
|
||||
root.appendChild( elem );
|
||||
|
||||
response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
|
||||
ImageOutputFormat parseImageFormat( const QString& format )
|
||||
{
|
||||
if ( format.compare( QLatin1String( "png" ), Qt::CaseInsensitive ) == 0 ||
|
||||
@ -164,8 +141,8 @@ namespace QgsWms
|
||||
}
|
||||
else
|
||||
{
|
||||
writeError( response, "InvalidFormat",
|
||||
QString( "Output format '%1' is not supported in the GetMap request" ).arg( formatStr ) );
|
||||
throw QgsServiceException( "InvalidFormat",
|
||||
QString( "Output format '%1' is not supported in the GetMap request" ).arg( formatStr ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include "qgsmodule.h"
|
||||
#include "qgswmsconfigparser.h"
|
||||
#include "qgsmapserviceexception.h"
|
||||
#include "qgswmsserviceexception.h"
|
||||
|
||||
/**
|
||||
* \ingroup server
|
||||
@ -51,10 +51,6 @@ namespace QgsWms
|
||||
*/
|
||||
QString ImplementationVersion();
|
||||
|
||||
/** Send WMS standard XML Error respons
|
||||
*/
|
||||
void writeError( QgsServerResponse& response, const QString& code, const QString& message );
|
||||
|
||||
/** Parse image format parameter
|
||||
* @return OutputFormat
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user