QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgsserver.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsserver.cpp
3  A server application supporting WMS / WFS / WCS
4  -------------------
5  begin : July 04, 2006
6  copyright : (C) 2006 by Marco Hugentobler & Ionut Iosifescu Enescu
7  : (C) 2015 by Alessandro Pasotti
8  email : marco dot hugentobler at karto dot baug dot ethz dot ch
9  : elpaso at itopen dot it
10  ***************************************************************************/
11 
12 /***************************************************************************
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * *
19  ***************************************************************************/
20 
21 //for CMAKE_INSTALL_PREFIX
22 #include "qgsconfig.h"
23 #include "qgsserver.h"
24 #include "qgsauthmanager.h"
25 #include "qgscapabilitiescache.h"
26 #include "qgsfontutils.h"
27 #include "qgsrequesthandler.h"
28 #include "qgsproject.h"
29 #include "qgsproviderregistry.h"
30 #include "qgslogger.h"
31 #include "qgsmapserviceexception.h"
33 #include "qgsserverlogger.h"
34 #include "qgsserverrequest.h"
36 #include "qgsservice.h"
37 #include "qgsserverapi.h"
38 #include "qgsserverapicontext.h"
39 #include "qgsserverparameters.h"
40 #include "qgsapplication.h"
41 #include "qgsruntimeprofiler.h"
42 
43 #include <QDomDocument>
44 #include <QNetworkDiskCache>
45 #include <QSettings>
46 #include <QElapsedTimer>
47 
48 // TODO: remove, it's only needed by a single debug message
49 #include <fcgi_stdio.h>
50 #include <cstdlib>
51 
52 
53 // Server status static initializers.
54 // Default values are for C++, SIP bindings will override their
55 // options in in init()
56 
57 QString *QgsServer::sConfigFilePath = nullptr;
58 QgsCapabilitiesCache *QgsServer::sCapabilitiesCache = nullptr;
59 QgsServerInterfaceImpl *QgsServer::sServerInterface = nullptr;
60 // Initialization must run once for all servers
61 bool QgsServer::sInitialized = false;
62 
63 QgsServiceRegistry *QgsServer::sServiceRegistry = nullptr;
64 
66 
68 {
69  // QgsApplication must exist
70  if ( qobject_cast<QgsApplication *>( qApp ) == nullptr )
71  {
72  qFatal( "A QgsApplication must exist before a QgsServer instance can be created." );
73  abort();
74  }
75  init();
76  mConfigCache = QgsConfigCache::instance();
77 }
78 
79 QFileInfo QgsServer::defaultAdminSLD()
80 {
81  return QFileInfo( QStringLiteral( "admin.sld" ) );
82 }
83 
84 void QgsServer::setupNetworkAccessManager()
85 {
86  QSettings settings;
88  QNetworkDiskCache *cache = new QNetworkDiskCache( nullptr );
89  qint64 cacheSize = sSettings()->cacheSize();
90  QString cacheDirectory = sSettings()->cacheDirectory();
91  cache->setCacheDirectory( cacheDirectory );
92  cache->setMaximumCacheSize( cacheSize );
93  QgsMessageLog::logMessage( QStringLiteral( "cacheDirectory: %1" ).arg( cache->cacheDirectory() ), QStringLiteral( "Server" ), Qgis::Info );
94  QgsMessageLog::logMessage( QStringLiteral( "maximumCacheSize: %1" ).arg( cache->maximumCacheSize() ), QStringLiteral( "Server" ), Qgis::Info );
95  nam->setCache( cache );
96 }
97 
98 QFileInfo QgsServer::defaultProjectFile()
99 {
100  QDir currentDir;
101  fprintf( FCGI_stderr, "current directory: %s\n", currentDir.absolutePath().toUtf8().constData() );
102  QStringList nameFilterList;
103  nameFilterList << QStringLiteral( "*.qgs" )
104  << QStringLiteral( "*.qgz" );
105  QFileInfoList projectFiles = currentDir.entryInfoList( nameFilterList, QDir::Files, QDir::Name );
106  for ( int x = 0; x < projectFiles.size(); x++ )
107  {
108  QgsMessageLog::logMessage( projectFiles.at( x ).absoluteFilePath(), QStringLiteral( "Server" ), Qgis::Info );
109  }
110  if ( projectFiles.isEmpty() )
111  {
112  return QFileInfo();
113  }
114  return projectFiles.at( 0 );
115 }
116 
117 void QgsServer::printRequestParameters( const QMap< QString, QString> &parameterMap, Qgis::MessageLevel logLevel )
118 {
119  if ( logLevel > Qgis::Info )
120  {
121  return;
122  }
123 
124  QMap< QString, QString>::const_iterator pIt = parameterMap.constBegin();
125  for ( ; pIt != parameterMap.constEnd(); ++pIt )
126  {
127  QgsMessageLog::logMessage( pIt.key() + ":" + pIt.value(), QStringLiteral( "Server" ), Qgis::Info );
128  }
129 }
130 
131 QString QgsServer::configPath( const QString &defaultConfigPath, const QString &configPath )
132 {
133  QString cfPath( defaultConfigPath );
134  QString projectFile = sSettings()->projectFile();
135  if ( !projectFile.isEmpty() )
136  {
137  cfPath = projectFile;
138  QgsDebugMsg( QStringLiteral( "QGIS_PROJECT_FILE:%1" ).arg( cfPath ) );
139  }
140  else
141  {
142  if ( configPath.isEmpty() )
143  {
144  // Read it from the environment, because a rewrite rule may have rewritten it
145  if ( getenv( "QGIS_PROJECT_FILE" ) )
146  {
147  cfPath = getenv( "QGIS_PROJECT_FILE" );
148  QgsMessageLog::logMessage( QStringLiteral( "Using configuration file path from environment: %1" ).arg( cfPath ), QStringLiteral( "Server" ), Qgis::Info );
149  }
150  else if ( ! defaultConfigPath.isEmpty() )
151  {
152  QgsMessageLog::logMessage( QStringLiteral( "Using default configuration file path: %1" ).arg( defaultConfigPath ), QStringLiteral( "Server" ), Qgis::Info );
153  }
154  }
155  else
156  {
157  cfPath = configPath;
158  QgsDebugMsg( QStringLiteral( "MAP:%1" ).arg( cfPath ) );
159  }
160  }
161  return cfPath;
162 }
163 
164 void QgsServer::initLocale()
165 {
166  // System locale override
167  if ( ! sSettings()->overrideSystemLocale().isEmpty() )
168  {
169  QLocale::setDefault( QLocale( sSettings()->overrideSystemLocale() ) );
170  }
171  // Number group separator settings
172  QLocale currentLocale;
173  if ( sSettings()->showGroupSeparator() )
174  {
175  currentLocale.setNumberOptions( currentLocale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
176  }
177  else
178  {
179  currentLocale.setNumberOptions( currentLocale.numberOptions() |= QLocale::NumberOption::OmitGroupSeparator );
180  }
181  QLocale::setDefault( currentLocale );
182 }
183 
184 bool QgsServer::init()
185 {
186  if ( sInitialized )
187  {
188  return false;
189  }
190 
191  QCoreApplication::setOrganizationName( QgsApplication::QGIS_ORGANIZATION_NAME );
192  QCoreApplication::setOrganizationDomain( QgsApplication::QGIS_ORGANIZATION_DOMAIN );
193  QCoreApplication::setApplicationName( QgsApplication::QGIS_APPLICATION_NAME );
194 
196 
197 #if defined(SERVER_SKIP_ECW)
198  QgsMessageLog::logMessage( "Skipping GDAL ECW drivers in server.", "Server", Qgis::Info );
200  QgsApplication::skipGdalDriver( "JP2ECW" );
201 #endif
202 
203  // reload settings to take into account QCoreApplication and QgsApplication
204  // configuration
205  sSettings()->load();
206 
207  // init and configure logger
209  QgsServerLogger::instance()->setLogLevel( sSettings()->logLevel() );
210  if ( ! sSettings()->logFile().isEmpty() )
211  {
212  QgsServerLogger::instance()->setLogFile( sSettings()->logFile() );
213  }
214  else if ( sSettings()->logStderr() )
215  {
217  }
218 
219  // Configure locale
220  initLocale();
221 
222  // log settings currently used
223  sSettings()->logSummary();
224 
225  setupNetworkAccessManager();
226  QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
227 
228  // Instantiate the plugin directory so that providers are loaded
230  QgsMessageLog::logMessage( "Prefix PATH: " + QgsApplication::prefixPath(), QStringLiteral( "Server" ), Qgis::Info );
231  QgsMessageLog::logMessage( "Plugin PATH: " + QgsApplication::pluginPath(), QStringLiteral( "Server" ), Qgis::Info );
232  QgsMessageLog::logMessage( "PkgData PATH: " + QgsApplication::pkgDataPath(), QStringLiteral( "Server" ), Qgis::Info );
233  QgsMessageLog::logMessage( "User DB PATH: " + QgsApplication::qgisUserDatabaseFilePath(), QStringLiteral( "Server" ), Qgis::Info );
234  QgsMessageLog::logMessage( "Auth DB PATH: " + QgsApplication::qgisAuthDatabaseFilePath(), QStringLiteral( "Server" ), Qgis::Info );
235  QgsMessageLog::logMessage( "SVG PATHS: " + QgsApplication::svgPaths().join( QDir::listSeparator() ), QStringLiteral( "Server" ), Qgis::Info );
236 
237  QgsApplication::createDatabase(); //init qgis.db (e.g. necessary for user crs)
238 
239  // Initialize the authentication system
240  // creates or uses qgis-auth.db in ~/.qgis3/ or directory defined by QGIS_AUTH_DB_DIR_PATH env variable
241  // set the master password as first line of file defined by QGIS_AUTH_PASSWORD_FILE env variable
242  // (QGIS_AUTH_PASSWORD_FILE variable removed from environment after accessing)
244 
245  QString defaultConfigFilePath;
246  QFileInfo projectFileInfo = defaultProjectFile(); //try to find a .qgs/.qgz file in the server directory
247  if ( projectFileInfo.exists() )
248  {
249  defaultConfigFilePath = projectFileInfo.absoluteFilePath();
250  QgsMessageLog::logMessage( "Using default project file: " + defaultConfigFilePath, QStringLiteral( "Server" ), Qgis::Info );
251  }
252  else
253  {
254  QFileInfo adminSLDFileInfo = defaultAdminSLD();
255  if ( adminSLDFileInfo.exists() )
256  {
257  defaultConfigFilePath = adminSLDFileInfo.absoluteFilePath();
258  }
259  }
260  // Store the config file path
261  sConfigFilePath = new QString( defaultConfigFilePath );
262 
263  //create cache for capabilities XML
264  sCapabilitiesCache = new QgsCapabilitiesCache();
265 
266  QgsFontUtils::loadStandardTestFonts( QStringList() << QStringLiteral( "Roman" ) << QStringLiteral( "Bold" ) );
267 
268  sServiceRegistry = new QgsServiceRegistry();
269 
270  sServerInterface = new QgsServerInterfaceImpl( sCapabilitiesCache, sServiceRegistry, sSettings() );
271 
272  // Load service module
273  QString modulePath = QgsApplication::libexecPath() + "server";
274  // qDebug() << QStringLiteral( "Initializing server modules from: %1" ).arg( modulePath );
275  sServiceRegistry->init( modulePath, sServerInterface );
276 
277  sInitialized = true;
278  QgsMessageLog::logMessage( QStringLiteral( "Server initialized" ), QStringLiteral( "Server" ), Qgis::Info );
279  return true;
280 }
281 
282 
283 
284 void QgsServer::putenv( const QString &var, const QString &val )
285 {
286  if ( val.isEmpty() )
287  {
288  qunsetenv( var.toUtf8().data() );
289  }
290  else
291  {
292  qputenv( var.toUtf8().data(), val.toUtf8() );
293  }
294  sSettings()->load( var );
295 }
296 
297 void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project )
298 {
300  {
301 
302  QgsScopedRuntimeProfile profiler { QStringLiteral( "handleRequest" ), QStringLiteral( "server" ) };
303 
304  qApp->processEvents();
305 
306  response.clear();
307 
308  // Pass the filters to the requestHandler, this is needed for the following reasons:
309  // Allow server request to call sendResponse plugin hook if enabled
310  QgsFilterResponseDecorator responseDecorator( sServerInterface->filters(), response );
311 
312  //Request handler
313  QgsRequestHandler requestHandler( request, response );
314 
315  try
316  {
317  // TODO: split parse input into plain parse and processing from specific services
318  requestHandler.parseInput();
319  }
320  catch ( QgsMapServiceException &e )
321  {
322  QgsMessageLog::logMessage( "Parse input exception: " + e.message(), QStringLiteral( "Server" ), Qgis::Critical );
323  requestHandler.setServiceException( e );
324  }
325 
326  // Set the request handler into the interface for plugins to manipulate it
327  sServerInterface->setRequestHandler( &requestHandler );
328 
329  // Initialize configfilepath so that is is available
330  // before calling plugin methods
331  // Note that plugins may still change that value using
332  // setConfigFilePath() interface method
333  if ( ! project )
334  {
335  QString configFilePath = configPath( *sConfigFilePath, request.serverParameters().map() );
336  sServerInterface->setConfigFilePath( configFilePath );
337  }
338  else
339  {
340  sServerInterface->setConfigFilePath( project->fileName() );
341  }
342 
343  // Call requestReady() method (if enabled)
344  // This may also throw exceptions if there are errors in python plugins code
345  try
346  {
347  responseDecorator.start();
348  }
349  catch ( QgsException &ex )
350  {
351  // Internal server error
352  response.sendError( 500, QStringLiteral( "Internal Server Error" ) );
353  QgsMessageLog::logMessage( ex.what(), QStringLiteral( "Server" ), Qgis::Critical );
354  }
355 
356  // Plugins may have set exceptions
357  if ( !requestHandler.exceptionRaised() )
358  {
359  try
360  {
361  const QgsServerParameters params = request.serverParameters();
362  printRequestParameters( params.toMap(), logLevel );
363 
364  // Setup project (config file path)
365  if ( ! project )
366  {
367  QString configFilePath = configPath( *sConfigFilePath, params.map() );
368 
369  // load the project if needed and not empty
370  if ( ! configFilePath.isEmpty() )
371  {
372  project = mConfigCache->project( configFilePath, sServerInterface->serverSettings() );
373  }
374  }
375 
376  // Set the current project instance
377  QgsProject::setInstance( const_cast<QgsProject *>( project ) );
378 
379  if ( project )
380  {
381  sServerInterface->setConfigFilePath( project->fileName() );
382  }
383  else
384  {
385  sServerInterface->setConfigFilePath( QString() );
386  }
387 
388  // Note that at this point we still might not have set a valid project.
389  // There are APIs that work without a project (e.g. the landing page catalog API that
390  // lists the available projects metadata).
391 
392  // Dispatcher: if SERVICE is set, we assume a OWS service, if not, let's try an API
393  // TODO: QGIS 4 fix the OWS services and treat them as APIs
394  QgsServerApi *api = nullptr;
395  if ( params.service().isEmpty() && ( api = sServiceRegistry->apiForRequest( request ) ) )
396  {
397  QgsServerApiContext context { api->rootPath(), &request, &responseDecorator, project, sServerInterface };
398  api->executeRequest( context );
399  }
400  else
401  {
402 
403  // Project is mandatory for OWS at this point
404  if ( ! project )
405  {
406  throw QgsServerException( QStringLiteral( "Project file error. For OWS services: please provide a SERVICE and a MAP parameter pointing to a valid QGIS project file" ) );
407  }
408 
409  if ( ! params.fileName().isEmpty() )
410  {
411  const QString value = QString( "attachment; filename=\"%1\"" ).arg( params.fileName() );
412  requestHandler.setResponseHeader( QStringLiteral( "Content-Disposition" ), value );
413  }
414 
415  // Lookup for service
416  QgsService *service = sServiceRegistry->getService( params.service(), params.version() );
417  if ( service )
418  {
419  service->executeRequest( request, responseDecorator, project );
420  }
421  else
422  {
423  throw QgsOgcServiceException( QStringLiteral( "Service configuration error" ),
424  QStringLiteral( "Service unknown or unsupported. Current supported services (case-sensitive): WMS WFS WCS WMTS SampleService, or use a WFS3 (OGC API Features) endpoint" ) );
425  }
426  }
427  }
428  catch ( QgsServerException &ex )
429  {
430  responseDecorator.write( ex );
431  QString format;
432  QgsMessageLog::logMessage( ex.formatResponse( format ), QStringLiteral( "Server" ), Qgis::Warning );
433  }
434  catch ( QgsException &ex )
435  {
436  // Internal server error
437  response.sendError( 500, QStringLiteral( "Internal Server Error" ) );
438  QgsMessageLog::logMessage( ex.what(), QStringLiteral( "Server" ), Qgis::Critical );
439  }
440  }
441 
442  // Terminate the response
443  // This may also throw exceptions if there are errors in python plugins code
444  try
445  {
446  responseDecorator.finish();
447  }
448  catch ( QgsException &ex )
449  {
450  // Internal server error
451  response.sendError( 500, QStringLiteral( "Internal Server Error" ) );
452  QgsMessageLog::logMessage( ex.what(), QStringLiteral( "Server" ), Qgis::Critical );
453  }
454 
455  // We are done using requestHandler in plugins, make sure we don't access
456  // to a deleted request handler from Python bindings
457  sServerInterface->clearRequestHandler();
458  }
459 
460  if ( logLevel == Qgis::Info )
461  {
462  QgsMessageLog::logMessage( "Request finished in " + QString::number( QgsApplication::profiler()->profileTime( QStringLiteral( "handleRequest" ), QStringLiteral( "server" ) ) * 1000.0 ) + " ms", QStringLiteral( "Server" ), Qgis::Info );
463  if ( sSettings->logProfile() )
464  {
465  std::function <void( const QModelIndex &, int )> profileFormatter;
466  profileFormatter = [ &profileFormatter ]( const QModelIndex & idx, int level )
467  {
468  QgsMessageLog::logMessage( QStringLiteral( "Profile: %1%2, %3 : %4 ms" )
469  .arg( level > 0 ? QString().fill( '-', level ) + ' ' : QString() )
470  .arg( QgsApplication::profiler()->data( idx, QgsRuntimeProfilerNode::Roles::Group ).toString() )
471  .arg( QgsApplication::profiler()->data( idx, QgsRuntimeProfilerNode::Roles::Name ).toString() )
472  .arg( QString::number( QgsApplication::profiler()->data( idx, QgsRuntimeProfilerNode::Roles::Elapsed ).toDouble() * 1000.0 ) ), QStringLiteral( "Server" ), Qgis::Info );
473 
474  for ( int subRow = 0; subRow < QgsApplication::profiler()->rowCount( idx ); subRow++ )
475  {
476  const auto subIdx { QgsApplication::profiler()->index( subRow, 0, idx ) };
477  profileFormatter( subIdx, level + 1 );
478  }
479 
480  };
481 
482  for ( int row = 0; row < QgsApplication::profiler()->rowCount( ); row++ )
483  {
484  const auto idx { QgsApplication::profiler()->index( row, 0 ) };
485  profileFormatter( idx, 0 );
486  }
487  }
488  }
489 
490 
491  // Clear the profiler server section after each request
492  QgsApplication::profiler()->clear( QStringLiteral( "server" ) );
493 
494 }
495 
496 
497 #ifdef HAVE_SERVER_PYTHON_PLUGINS
498 void QgsServer::initPython()
499 {
500  // Init plugins
501  if ( ! QgsServerPlugins::initPlugins( sServerInterface ) )
502  {
503  QgsMessageLog::logMessage( QStringLiteral( "No server python plugins are available" ), QStringLiteral( "Server" ), Qgis::Info );
504  }
505  else
506  {
507  QgsMessageLog::logMessage( QStringLiteral( "Server python plugins loaded" ), QStringLiteral( "Server" ), Qgis::Info );
508  }
509 }
510 #endif
511 
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition: qgis.h:89
@ Warning
Definition: qgis.h:91
@ Critical
Definition: qgis.h:92
@ Info
Definition: qgis.h:90
static void skipGdalDriver(const QString &driver)
Sets the GDAL_SKIP environment variable to include the specified driver and then calls GDALDriverMana...
static QString pluginPath()
Returns the path to the application plugin directory.
static bool createDatabase(QString *errorMessage=nullptr)
initialize qgis.db
static void init(QString profileFolder=QString())
This method initializes paths etc for QGIS.
static QString pkgDataPath()
Returns the common root path of all application data directories.
static QString libexecPath()
Returns the path with utility executables (help viewer, crssync, ...)
static QStringList svgPaths()
Returns the paths to svg directories.
static QgsRuntimeProfiler * profiler()
Returns the application runtime profiler.
static const char * QGIS_APPLICATION_NAME
static const char * QGIS_ORGANIZATION_DOMAIN
static QString prefixPath()
Returns the path to the application prefix directory.
static const char * QGIS_ORGANIZATION_NAME
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
static QString qgisAuthDatabaseFilePath()
Returns the path to the user authentication database file: qgis-auth.db.
static QString qgisUserDatabaseFilePath()
Returns the path to the user qgis.db file.
bool init(const QString &pluginPath=QString(), const QString &authDatabasePath=QString())
init initialize QCA, prioritize qca-ossl plugin and optionally set up the authentication database
A cache for capabilities xml documents (by configuration file path)
static QgsConfigCache * instance()
Returns the current instance.
const QgsProject * project(const QString &path, const QgsServerSettings *settings=nullptr)
If the project is not cached yet, then the project is read from the path.
Defines a QGIS exception class.
Definition: qgsexception.h:35
QString what() const
Definition: qgsexception.h:48
Class defining decorator for calling filter's hooks.
void finish() override
Finish the response, ending the transaction.
void start() SIP_THROW(QgsServerException)
Call filters requestReady() method.
static bool loadStandardTestFonts(const QStringList &loadstyles)
Loads standard test fonts from filesystem or qrc resource.
Exception class for WMS service exceptions (for compatibility only).
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
network access manager for QGIS
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
Exception base class for service exceptions.
QString message() const
Returns the exception message.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:99
static void setInstance(QgsProject *project)
Set the current project singleton instance to project.
Definition: qgsproject.cpp:495
QString fileName
Definition: qgsproject.h:102
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
This class is an interface hiding the details of reading input and writing output from/to a wms reque...
bool exceptionRaised() const
Pointer to last raised exception.
void parseInput()
Parses the input and creates a request neutral Parameter/Value map.
void setServiceException(const QgsServerException &ex)
Allow plugins to return a QgsMapServiceException.
void setResponseHeader(const QString &name, const QString &value)
Sets an HTTP response header.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
void clear(const QString &group="startup")
clear Clear all profile data.
Scoped object for logging of the runtime for a single operation or group of operations.
The QgsServerApiContext class encapsulates the resources for a particular client request: the request...
Server generic API endpoint abstract base class.
Definition: qgsserverapi.h:81
virtual void executeRequest(const QgsServerApiContext &context) const =0
Executes a request by passing the given context to the API handlers.
virtual const QString rootPath() const =0
Returns the root path for the API.
Exception base class for server exceptions.
virtual QByteArray formatResponse(QString &responseFormat) const
Formats the exception for sending to client.
Interfaces exposed by QGIS Server and made available to plugins.
QgsServerSettings * serverSettings() override
Returns the server settings.
void setRequestHandler(QgsRequestHandler *requestHandler) override
Set the request handler.
void clearRequestHandler() override
Clear the request handler.
QgsServerFiltersMap filters() override
Returns the list of current QgsServerFilter.
void setConfigFilePath(const QString &configFilePath) override
Set the configuration file path.
static QgsServerLogger * instance()
Gets the singleton instance.
Qgis::MessageLevel logLevel() const
Gets the current log level.
void setLogLevel(Qgis::MessageLevel level)
Set the current log level.
void setLogFile(const QString &filename=QString())
Set the current log file.
void setLogStderr()
Activates logging to stderr.
QgsServerParameters provides an interface to retrieve and manipulate global parameters received from ...
QMap< QString, QString > toMap() const
Returns all parameters in a map.
QString map() const
Returns MAP parameter as a string or an empty string if not defined.
QString service() const
Returns SERVICE parameter as a string or an empty string if not defined.
QString fileName() const
Returns FILE_NAME parameter as a string or an empty string if not defined.
QString version() const
Returns VERSION parameter as a string or an empty string if not defined.
static bool initPlugins(QgsServerInterface *interface)
Initializes the Python plugins.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
QgsServerParameters serverParameters() const
Returns parameters.
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
virtual void clear()=0
Reset all headers and content for this response.
virtual void sendError(int code, const QString &message)=0
Send error This method delegates error handling at the server level.
Provides a way to retrieve settings by prioritizing according to environment variables,...
QgsServer()
Creates the server instance.
Definition: qgsserver.cpp:67
void handleRequest(QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project=nullptr)
Handles the request.
Definition: qgsserver.cpp:297
void putenv(const QString &var, const QString &val)
Set environment variable.
Definition: qgsserver.cpp:284
QgsServiceRegistry Class defining the registry manager for QGIS server services.
QgsServerApi * apiForRequest(const QgsServerRequest &request) const
Searches the API register for an API matching the request and returns a (possibly NULL) pointer to it...
void init(const QString &nativeModulepath, QgsServerInterface *serverIface=nullptr)
Initialize registry, load modules and auto register services.
QgsService * getService(const QString &name, const QString &version=QString())
Retrieve a service from its name.
QgsService Class defining interfaces for QGIS server services.
Definition: qgsservice.h:40
virtual void executeRequest(const QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project)=0
Execute the requests and set result in QgsServerRequest.
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
Q_GLOBAL_STATIC(QgsServerSettings, sSettings)