QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 "qgsversion.h"
24 #include "qgsserver.h"
25 #include "qgsauthmanager.h"
26 #include "qgscapabilitiescache.h"
27 #include "qgsfontutils.h"
28 #include "qgsrequesthandler.h"
29 #include "qgsproject.h"
30 #include "qgsproviderregistry.h"
31 #include "qgslogger.h"
32 #include "qgsmapserviceexception.h"
34 #include "qgsserverlogger.h"
35 #include "qgsserverrequest.h"
37 #include "qgsservice.h"
38 #include "qgsserverapi.h"
39 #include "qgsserverapicontext.h"
40 #include "qgsserverparameters.h"
41 #include "qgsapplication.h"
42 #include "qgsruntimeprofiler.h"
43 #include "qgscoordinatetransform.h"
44 
45 #include <QDomDocument>
46 #include <QNetworkDiskCache>
47 #include <QSettings>
48 #include <QElapsedTimer>
49 
50 // TODO: remove, it's only needed by a single debug message
51 #include <fcgi_stdio.h>
52 #include <cstdlib>
53 
54 
55 // Server status static initializers.
56 // Default values are for C++, SIP bindings will override their
57 // options in in init()
58 
59 QString *QgsServer::sConfigFilePath = nullptr;
60 QgsCapabilitiesCache *QgsServer::sCapabilitiesCache = nullptr;
61 QgsServerInterfaceImpl *QgsServer::sServerInterface = nullptr;
62 // Initialization must run once for all servers
63 bool QgsServer::sInitialized = false;
64 
65 QgsServiceRegistry *QgsServer::sServiceRegistry = nullptr;
66 
68 
70 {
71  // QgsApplication must exist
72  if ( qobject_cast<QgsApplication *>( qApp ) == nullptr )
73  {
74  qFatal( "A QgsApplication must exist before a QgsServer instance can be created." );
75  abort();
76  }
77  init();
78  mConfigCache = QgsConfigCache::instance();
79 }
80 
81 QFileInfo QgsServer::defaultAdminSLD()
82 {
83  return QFileInfo( QStringLiteral( "admin.sld" ) );
84 }
85 
86 void QgsServer::setupNetworkAccessManager()
87 {
88  const QSettings settings;
90  QNetworkDiskCache *cache = new QNetworkDiskCache( nullptr );
91  const qint64 cacheSize = sSettings()->cacheSize();
92  const QString cacheDirectory = sSettings()->cacheDirectory();
93  cache->setCacheDirectory( cacheDirectory );
94  cache->setMaximumCacheSize( cacheSize );
95  QgsMessageLog::logMessage( QStringLiteral( "cacheDirectory: %1" ).arg( cache->cacheDirectory() ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
96  QgsMessageLog::logMessage( QStringLiteral( "maximumCacheSize: %1" ).arg( cache->maximumCacheSize() ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
97  nam->setCache( cache );
98 }
99 
100 QFileInfo QgsServer::defaultProjectFile()
101 {
102  const QDir currentDir;
103  fprintf( FCGI_stderr, "current directory: %s\n", currentDir.absolutePath().toUtf8().constData() );
104  QStringList nameFilterList;
105  nameFilterList << QStringLiteral( "*.qgs" )
106  << QStringLiteral( "*.qgz" );
107  const QFileInfoList projectFiles = currentDir.entryInfoList( nameFilterList, QDir::Files, QDir::Name );
108  for ( int x = 0; x < projectFiles.size(); x++ )
109  {
110  QgsMessageLog::logMessage( projectFiles.at( x ).absoluteFilePath(), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
111  }
112  if ( projectFiles.isEmpty() )
113  {
114  return QFileInfo();
115  }
116  return projectFiles.at( 0 );
117 }
118 
119 void QgsServer::printRequestParameters( const QMap< QString, QString> &parameterMap, Qgis::MessageLevel logLevel )
120 {
121  if ( logLevel > Qgis::MessageLevel::Info )
122  {
123  return;
124  }
125 
126  QMap< QString, QString>::const_iterator pIt = parameterMap.constBegin();
127  for ( ; pIt != parameterMap.constEnd(); ++pIt )
128  {
129  QgsMessageLog::logMessage( pIt.key() + ":" + pIt.value(), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
130  }
131 }
132 
133 QString QgsServer::configPath( const QString &defaultConfigPath, const QString &configPath )
134 {
135  QString cfPath( defaultConfigPath );
136  const QString projectFile = sSettings()->projectFile();
137  if ( !projectFile.isEmpty() )
138  {
139  cfPath = projectFile;
140  QgsDebugMsg( QStringLiteral( "QGIS_PROJECT_FILE:%1" ).arg( cfPath ) );
141  }
142  else
143  {
144  if ( configPath.isEmpty() )
145  {
146  // Read it from the environment, because a rewrite rule may have rewritten it
147  if ( getenv( "QGIS_PROJECT_FILE" ) )
148  {
149  cfPath = getenv( "QGIS_PROJECT_FILE" );
150  QgsMessageLog::logMessage( QStringLiteral( "Using configuration file path from environment: %1" ).arg( cfPath ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
151  }
152  else if ( ! defaultConfigPath.isEmpty() )
153  {
154  QgsMessageLog::logMessage( QStringLiteral( "Using default configuration file path: %1" ).arg( defaultConfigPath ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
155  }
156  }
157  else
158  {
159  cfPath = configPath;
160  QgsDebugMsg( QStringLiteral( "MAP:%1" ).arg( cfPath ) );
161  }
162  }
163  return cfPath;
164 }
165 
166 void QgsServer::initLocale()
167 {
168  // System locale override
169  if ( ! sSettings()->overrideSystemLocale().isEmpty() )
170  {
171  QLocale::setDefault( QLocale( sSettings()->overrideSystemLocale() ) );
172  }
173  // Number group separator settings
174  QLocale currentLocale;
175  if ( sSettings()->showGroupSeparator() )
176  {
177  currentLocale.setNumberOptions( currentLocale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
178  }
179  else
180  {
181  currentLocale.setNumberOptions( currentLocale.numberOptions() |= QLocale::NumberOption::OmitGroupSeparator );
182  }
183  QLocale::setDefault( currentLocale );
184 }
185 
186 bool QgsServer::init()
187 {
188  if ( sInitialized )
189  {
190  return false;
191  }
192 
193  QCoreApplication::setOrganizationName( QgsApplication::QGIS_ORGANIZATION_NAME );
194  QCoreApplication::setOrganizationDomain( QgsApplication::QGIS_ORGANIZATION_DOMAIN );
195  QCoreApplication::setApplicationName( QgsApplication::QGIS_APPLICATION_NAME );
196 
197  // TODO: remove QGIS_OPTIONS_PATH from settings and rely on QgsApplication's env var QGIS_CUSTOM_CONFIG_PATH
198  // Note that QGIS_CUSTOM_CONFIG_PATH gives /tmp/qt_temp-rUpsId/profiles/default/QGIS/QGIS3.ini
199  // while QGIS_OPTIONS_PATH gives /tmp/qt_temp-rUpsId/QGIS/QGIS3.ini
200  QgsApplication::init( qgetenv( "QGIS_OPTIONS_PATH" ) );
201 
202 #if defined(SERVER_SKIP_ECW)
203  QgsMessageLog::logMessage( "Skipping GDAL ECW drivers in server.", "Server", Qgis::MessageLevel::Info );
205  QgsApplication::skipGdalDriver( "JP2ECW" );
206 #endif
207 
208  // reload settings to take into account QCoreApplication and QgsApplication
209  // configuration
210  sSettings()->load();
211 
212  // init and configure logger
214  QgsServerLogger::instance()->setLogLevel( sSettings()->logLevel() );
215  if ( ! sSettings()->logFile().isEmpty() )
216  {
217  QgsServerLogger::instance()->setLogFile( sSettings()->logFile() );
218  }
219  else if ( sSettings()->logStderr() )
220  {
222  }
223 
224  // Logging handlers for CRS grid issues
226  const QgsCoordinateReferenceSystem & destinationCrs,
227  const QgsDatumTransform::GridDetails & grid )
228  {
229  QgsServerLogger::instance()->logMessage( QStringLiteral( "Cannot use project transform between %1 and %2 - missing grid %3" )
232  grid.shortName ),
233  QStringLiteral( "QGIS Server" ), Qgis::MessageLevel::Warning );
234  } );
235 
236 
238  const QgsCoordinateReferenceSystem & destinationCrs,
239  const QgsDatumTransform::TransformDetails & details )
240  {
241  QString gridMessage;
242  for ( const QgsDatumTransform::GridDetails &grid : details.grids )
243  {
244  if ( !grid.isAvailable )
245  {
246  gridMessage.append( QStringLiteral( "This transformation requires the grid file '%1', which is not available for use on the system.\n" ).arg( grid.shortName ) );
247  }
248  }
249  QgsServerLogger::instance()->logMessage( QStringLiteral( "Cannot use project transform between %1 and %2 - %3.\n%4" )
252  details.name,
253  gridMessage ),
254  QStringLiteral( "QGIS Server" ), Qgis::MessageLevel::Warning );
255  } );
256 
257 
259  const QgsCoordinateReferenceSystem & destinationCrs,
260  const QgsDatumTransform::TransformDetails & preferredOperation,
261  const QgsDatumTransform::TransformDetails & availableOperation )
262  {
263 
264  QString gridMessage;
265  for ( const QgsDatumTransform::GridDetails &grid : preferredOperation.grids )
266  {
267  if ( !grid.isAvailable )
268  {
269  gridMessage.append( QStringLiteral( "This transformation requires the grid file '%1', which is not available for use on the system.\n" ).arg( grid.shortName ) );
270  if ( !grid.url.isEmpty() )
271  {
272  if ( !grid.packageName.isEmpty() )
273  {
274  gridMessage.append( QStringLiteral( "This grid is part of the '%1' package, available for download from %2.\n" ).arg( grid.packageName, grid.url ) );
275  }
276  else
277  {
278  gridMessage.append( QStringLiteral( "This grid is available for download from %1.\n" ).arg( grid.url ) );
279  }
280  }
281  }
282  }
283 
284  QString accuracyMessage;
285  if ( availableOperation.accuracy >= 0 && preferredOperation.accuracy >= 0 )
286  accuracyMessage = QStringLiteral( "Current transform '%1' has an accuracy of %2 meters, while the preferred transformation '%3' has accuracy %4 meters.\n" ).arg( availableOperation.name )
287  .arg( availableOperation.accuracy ).arg( preferredOperation.name ).arg( preferredOperation.accuracy );
288  else if ( preferredOperation.accuracy >= 0 )
289  accuracyMessage = QStringLiteral( "Current transform '%1' has an unknown accuracy, while the preferred transformation '%2' has accuracy %3 meters.\n" )
290  .arg( availableOperation.name, preferredOperation.name )
291  .arg( preferredOperation.accuracy );
292 
293  const QString longMessage = QStringLiteral( "The preferred transform between '%1' and '%2' is not available for use on the system.\n" ).arg( sourceCrs.userFriendlyIdentifier(),
294  destinationCrs.userFriendlyIdentifier() )
295  + gridMessage + accuracyMessage;
296 
297  QgsServerLogger::instance()->logMessage( longMessage, QStringLiteral( "QGIS Server" ), Qgis::MessageLevel::Warning );
298 
299  } );
300 
302  {
303  const QString longMessage = QStringLiteral( "No transform is available between %1 and %2: %3" )
304  .arg( sourceCrs.userFriendlyIdentifier(), destinationCrs.userFriendlyIdentifier(), error );
305  QgsServerLogger::instance()->logMessage( longMessage, QStringLiteral( "QGIS Server" ), Qgis::MessageLevel::Warning );
306  } );
307 
308  // Configure locale
309  initLocale();
310 
311  QgsMessageLog::logMessage( QStringLiteral( "QGIS Server Starting : %1 (%2)" ).arg( _QGIS_VERSION, QGSVERSION ), "Server", Qgis::MessageLevel::Info );
312 
313  // log settings currently used
314  sSettings()->logSummary();
315 
316  setupNetworkAccessManager();
317  QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
318 
319  // Instantiate the plugin directory so that providers are loaded
321  QgsMessageLog::logMessage( "Prefix PATH: " + QgsApplication::prefixPath(), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
322  QgsMessageLog::logMessage( "Plugin PATH: " + QgsApplication::pluginPath(), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
323  QgsMessageLog::logMessage( "PkgData PATH: " + QgsApplication::pkgDataPath(), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
324  QgsMessageLog::logMessage( "User DB PATH: " + QgsApplication::qgisUserDatabaseFilePath(), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
325  QgsMessageLog::logMessage( "Auth DB PATH: " + QgsApplication::qgisAuthDatabaseFilePath(), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
326  QgsMessageLog::logMessage( "SVG PATHS: " + QgsApplication::svgPaths().join( QDir::listSeparator() ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
327 
328  QgsApplication::createDatabase(); //init qgis.db (e.g. necessary for user crs)
329 
330  // Initialize the authentication system
331  // creates or uses qgis-auth.db in ~/.qgis3/ or directory defined by QGIS_AUTH_DB_DIR_PATH env variable
332  // set the master password as first line of file defined by QGIS_AUTH_PASSWORD_FILE env variable
333  // (QGIS_AUTH_PASSWORD_FILE variable removed from environment after accessing)
335 
336  QString defaultConfigFilePath;
337  const QFileInfo projectFileInfo = defaultProjectFile(); //try to find a .qgs/.qgz file in the server directory
338  if ( projectFileInfo.exists() )
339  {
340  defaultConfigFilePath = projectFileInfo.absoluteFilePath();
341  QgsMessageLog::logMessage( "Using default project file: " + defaultConfigFilePath, QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
342  }
343  else
344  {
345  const QFileInfo adminSLDFileInfo = defaultAdminSLD();
346  if ( adminSLDFileInfo.exists() )
347  {
348  defaultConfigFilePath = adminSLDFileInfo.absoluteFilePath();
349  }
350  }
351  // Store the config file path
352  sConfigFilePath = new QString( defaultConfigFilePath );
353 
354  //create cache for capabilities XML
355  sCapabilitiesCache = new QgsCapabilitiesCache();
356 
357  QgsFontUtils::loadStandardTestFonts( QStringList() << QStringLiteral( "Roman" ) << QStringLiteral( "Bold" ) );
358 
359  sServiceRegistry = new QgsServiceRegistry();
360 
361  sServerInterface = new QgsServerInterfaceImpl( sCapabilitiesCache, sServiceRegistry, sSettings() );
362 
363  // Load service module
364  const QString modulePath = QgsApplication::libexecPath() + "server";
365  // qDebug() << QStringLiteral( "Initializing server modules from: %1" ).arg( modulePath );
366  sServiceRegistry->init( modulePath, sServerInterface );
367 
368  // Initialize config cache
369  QgsConfigCache::initialize( sSettings );
370 
371  sInitialized = true;
372  QgsMessageLog::logMessage( QStringLiteral( "Server initialized" ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
373  return true;
374 }
375 
376 
377 
378 void QgsServer::putenv( const QString &var, const QString &val )
379 {
380  if ( val.isEmpty() )
381  {
382  qunsetenv( var.toUtf8().data() );
383  }
384  else
385  {
386  qputenv( var.toUtf8().data(), val.toUtf8() );
387  }
388  sSettings()->load( var );
389 }
390 
391 void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project )
392 {
394  {
395 
396  const QgsScopedRuntimeProfile profiler { QStringLiteral( "handleRequest" ), QStringLiteral( "server" ) };
397 
398  qApp->processEvents();
399 
400  response.clear();
401 
402  // Pass the filters to the requestHandler, this is needed for the following reasons:
403  // Allow server request to call sendResponse plugin hook if enabled
404  QgsFilterResponseDecorator responseDecorator( sServerInterface->filters(), response );
405 
406  //Request handler
407  QgsRequestHandler requestHandler( request, response );
408 
409  try
410  {
411  // TODO: split parse input into plain parse and processing from specific services
412  requestHandler.parseInput();
413  }
414  catch ( QgsMapServiceException &e )
415  {
416  QgsMessageLog::logMessage( "Parse input exception: " + e.message(), QStringLiteral( "Server" ), Qgis::MessageLevel::Critical );
417  requestHandler.setServiceException( e );
418  }
419 
420  // Set the request handler into the interface for plugins to manipulate it
421  sServerInterface->setRequestHandler( &requestHandler );
422 
423  // Initialize configfilepath so that is is available
424  // before calling plugin methods
425  // Note that plugins may still change that value using
426  // setConfigFilePath() interface method
427  if ( ! project )
428  {
429  const QString configFilePath = configPath( *sConfigFilePath, request.serverParameters().map() );
430  sServerInterface->setConfigFilePath( configFilePath );
431  }
432  else
433  {
434  sServerInterface->setConfigFilePath( project->fileName() );
435  }
436 
437  // Call requestReady() method (if enabled)
438  // This may also throw exceptions if there are errors in python plugins code
439  try
440  {
441  responseDecorator.start();
442  }
443  catch ( QgsException &ex )
444  {
445  // Internal server error
446  response.sendError( 500, QStringLiteral( "Internal Server Error" ) );
447  QgsMessageLog::logMessage( ex.what(), QStringLiteral( "Server" ), Qgis::MessageLevel::Critical );
448  }
449 
450  // Plugins may have set exceptions
451  if ( !requestHandler.exceptionRaised() )
452  {
453  try
454  {
455  const QgsServerParameters params = request.serverParameters();
456  printRequestParameters( params.toMap(), logLevel );
457 
458  // Setup project (config file path)
459  if ( !project )
460  {
461  const QString configFilePath = configPath( *sConfigFilePath, params.map() );
462 
463  // load the project if needed and not empty
464  if ( ! configFilePath.isEmpty() )
465  {
466  // Note that QgsConfigCache::project( ... ) call QgsProject::setInstance(...)
467  project = mConfigCache->project( configFilePath, sServerInterface->serverSettings() );
468  }
469  }
470 
471  // Set the current project instance
472  QgsProject::setInstance( const_cast<QgsProject *>( project ) );
473 
474  if ( project )
475  {
476  sServerInterface->setConfigFilePath( project->fileName() );
477  }
478  else
479  {
480  sServerInterface->setConfigFilePath( QString() );
481  }
482 
483  // Note that at this point we still might not have set a valid project.
484  // There are APIs that work without a project (e.g. the landing page catalog API that
485  // lists the available projects metadata).
486 
487  // Dispatcher: if SERVICE is set, we assume a OWS service, if not, let's try an API
488  // TODO: QGIS 4 fix the OWS services and treat them as APIs
489  QgsServerApi *api = nullptr;
490 
491  if ( params.service().isEmpty() && ( api = sServiceRegistry->apiForRequest( request ) ) )
492  {
493  const QgsServerApiContext context { api->rootPath(), &request, &responseDecorator, project, sServerInterface };
494  api->executeRequest( context );
495  }
496  else
497  {
498  // Project is mandatory for OWS at this point
499  if ( ! project )
500  {
501  throw QgsServerException( QStringLiteral( "Project file error. For OWS services: please provide a SERVICE and a MAP parameter pointing to a valid QGIS project file" ) );
502  }
503 
504  if ( ! params.fileName().isEmpty() )
505  {
506  const QString value = QString( "attachment; filename=\"%1\"" ).arg( params.fileName() );
507  requestHandler.setResponseHeader( QStringLiteral( "Content-Disposition" ), value );
508  }
509 
510  // Lookup for service
511  QgsService *service = sServiceRegistry->getService( params.service(), params.version() );
512  if ( service )
513  {
514  service->executeRequest( request, responseDecorator, project );
515  }
516  else
517  {
518  throw QgsOgcServiceException( QStringLiteral( "Service configuration error" ),
519  QStringLiteral( "Service unknown or unsupported. Current supported services (case-sensitive): WMS WFS WCS WMTS SampleService, or use a WFS3 (OGC API Features) endpoint" ) );
520  }
521  }
522  }
523  catch ( QgsServerException &ex )
524  {
525  responseDecorator.write( ex );
526  QString format;
527  QgsMessageLog::logMessage( ex.formatResponse( format ), QStringLiteral( "Server" ), Qgis::MessageLevel::Warning );
528  }
529  catch ( QgsException &ex )
530  {
531  // Internal server error
532  response.sendError( 500, QStringLiteral( "Internal Server Error" ) );
533  QgsMessageLog::logMessage( ex.what(), QStringLiteral( "Server" ), Qgis::MessageLevel::Critical );
534  }
535  }
536 
537  // Terminate the response
538  // This may also throw exceptions if there are errors in python plugins code
539  try
540  {
541  responseDecorator.finish();
542  }
543  catch ( QgsException &ex )
544  {
545  // Internal server error
546  response.sendError( 500, QStringLiteral( "Internal Server Error" ) );
547  QgsMessageLog::logMessage( ex.what(), QStringLiteral( "Server" ), Qgis::MessageLevel::Critical );
548  }
549 
550  // We are done using requestHandler in plugins, make sure we don't access
551  // to a deleted request handler from Python bindings
552  sServerInterface->clearRequestHandler();
553  }
554 
555  if ( logLevel == Qgis::MessageLevel::Info )
556  {
557  QgsMessageLog::logMessage( "Request finished in " + QString::number( QgsApplication::profiler()->profileTime( QStringLiteral( "handleRequest" ), QStringLiteral( "server" ) ) * 1000.0 ) + " ms", QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
558  if ( sSettings->logProfile() )
559  {
560  std::function <void( const QModelIndex &, int )> profileFormatter;
561  profileFormatter = [ &profileFormatter ]( const QModelIndex & idx, int level )
562  {
563  QgsMessageLog::logMessage( QStringLiteral( "Profile: %1%2, %3 : %4 ms" )
564  .arg( level > 0 ? QString().fill( '-', level ) + ' ' : QString() )
565  .arg( QgsApplication::profiler()->data( idx, QgsRuntimeProfilerNode::Roles::Group ).toString() )
566  .arg( QgsApplication::profiler()->data( idx, QgsRuntimeProfilerNode::Roles::Name ).toString() )
567  .arg( QString::number( QgsApplication::profiler()->data( idx, QgsRuntimeProfilerNode::Roles::Elapsed ).toDouble() * 1000.0 ) ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
568 
569  for ( int subRow = 0; subRow < QgsApplication::profiler()->rowCount( idx ); subRow++ )
570  {
571  const auto subIdx { QgsApplication::profiler()->index( subRow, 0, idx ) };
572  profileFormatter( subIdx, level + 1 );
573  }
574 
575  };
576 
577  for ( int row = 0; row < QgsApplication::profiler()->rowCount( ); row++ )
578  {
579  const auto idx { QgsApplication::profiler()->index( row, 0 ) };
580  profileFormatter( idx, 0 );
581  }
582  }
583  }
584 
585 
586  // Clear the profiler server section after each request
587  QgsApplication::profiler()->clear( QStringLiteral( "server" ) );
588 
589 }
590 
591 
592 #ifdef HAVE_SERVER_PYTHON_PLUGINS
593 void QgsServer::initPython()
594 {
595  // Init plugins
596  if ( ! QgsServerPlugins::initPlugins( sServerInterface ) )
597  {
598  QgsMessageLog::logMessage( QStringLiteral( "No server python plugins are available" ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
599  }
600  else
601  {
602  QgsMessageLog::logMessage( QStringLiteral( "Server python plugins loaded" ), QStringLiteral( "Server" ), Qgis::MessageLevel::Info );
603  }
604 }
605 #endif
606 
QgsServiceRegistry::getService
QgsService * getService(const QString &name, const QString &version=QString())
Retrieve a service from its name.
Definition: qgsserviceregistry.cpp:89
QgsApplication::QGIS_ORGANIZATION_NAME
static const char * QGIS_ORGANIZATION_NAME
Definition: qgsapplication.h:160
QgsServerInterfaceImpl::serverSettings
QgsServerSettings * serverSettings() override
Returns the server settings.
Definition: qgsserverinterfaceimpl.cpp:117
QgsCoordinateTransform::setCustomMissingPreferredGridHandler
static void setCustomMissingPreferredGridHandler(const std::function< void(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QgsDatumTransform::TransformDetails &preferredOperation, const QgsDatumTransform::TransformDetails &availableOperation)> &handler)
Sets a custom handler to use when a coordinate transform is created between sourceCrs and destination...
Definition: qgscoordinatetransform.cpp:1115
QgsServerInterfaceImpl::setRequestHandler
void setRequestHandler(QgsRequestHandler *requestHandler) override
Set the request handler.
Definition: qgsserverinterfaceimpl.cpp:56
QgsException
Defines a QGIS exception class.
Definition: qgsexception.h:34
QgsCoordinateTransform::setCustomCoordinateOperationCreationErrorHandler
static void setCustomCoordinateOperationCreationErrorHandler(const std::function< void(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QString &error)> &handler)
Sets a custom handler to use when a coordinate transform was required between sourceCrs and destinati...
Definition: qgscoordinatetransform.cpp:1120
QgsMapServiceException
Exception class for WMS service exceptions (for compatibility only).
Definition: qgsmapserviceexception.h:43
qgsruntimeprofiler.h
QgsServerApiContext
The QgsServerApiContext class encapsulates the resources for a particular client request: the request...
Definition: qgsserverapicontext.h:38
QgsCapabilitiesCache
A cache for capabilities xml documents (by configuration file path)
Definition: qgscapabilitiescache.h:34
QgsServerParameters::toMap
QMap< QString, QString > toMap() const
Returns all parameters in a map.
Definition: qgsserverparameters.cpp:602
QgsCoordinateReferenceSystem::userFriendlyIdentifier
QString userFriendlyIdentifier(IdentifierType type=MediumString) const
Returns a user friendly identifier for the CRS.
Definition: qgscoordinatereferencesystem.cpp:1212
QgsFilterResponseDecorator::start
void start() SIP_THROW(QgsServerException)
Call filters requestReady() method.
Definition: qgsfilterresponsedecorator.cpp:29
qgsserverparameters.h
qgsauthmanager.h
QgsServer::handleRequest
void handleRequest(QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project=nullptr)
Handles the request.
Definition: qgsserver.cpp:391
QgsRuntimeProfiler::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: qgsruntimeprofiler.cpp:325
QgsServer::putenv
void putenv(const QString &var, const QString &val)
Set environment variable.
Definition: qgsserver.cpp:378
QgsService
QgsService Class defining interfaces for QGIS server services.
Definition: qgsservice.h:39
QgsConfigCache::instance
static QgsConfigCache * instance()
Returns the current instance.
Definition: qgsconfigcache.cpp:70
QgsApplication::prefixPath
static QString prefixPath()
Returns the path to the application prefix directory.
Definition: qgsapplication.cpp:622
QgsServerApi::rootPath
virtual const QString rootPath() const =0
Returns the root path for the API.
QgsApplication::init
static void init(QString profileFolder=QString())
This method initializes paths etc for QGIS.
Definition: qgsapplication.cpp:242
QgsApplication::qgisAuthDatabaseFilePath
static QString qgisAuthDatabaseFilePath()
Returns the path to the user authentication database file: qgis-auth.db.
Definition: qgsapplication.cpp:1109
QgsApplication::svgPaths
static QStringList svgPaths()
Returns the paths to svg directories.
Definition: qgsapplication.cpp:1153
qgsservice.h
QgsServerResponse::clear
virtual void clear()=0
Reset all headers and content for this response.
qgsmapserviceexception.h
QgsServerRequest
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
Definition: qgsserverrequest.h:38
QgsCoordinateTransform::setCustomMissingGridUsedByContextHandler
static void setCustomMissingGridUsedByContextHandler(const std::function< void(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QgsDatumTransform::TransformDetails &desiredOperation)> &handler)
Sets a custom handler to use when a coordinate operation was specified for use between sourceCrs and ...
Definition: qgscoordinatetransform.cpp:1125
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
qgsfontutils.h
QgsServerInterfaceImpl::filters
QgsServerFiltersMap filters() override
Returns the list of current QgsServerFilter.
Definition: qgsserverinterfaceimpl.h:53
QgsFilterResponseDecorator::finish
void finish() override
Finish the response, ending the transaction.
Definition: qgsfilterresponsedecorator.cpp:44
QgsService::executeRequest
virtual void executeRequest(const QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project)=0
Execute the requests and set result in QgsServerRequest.
QgsServerInterfaceImpl
Interfaces exposed by QGIS Server and made available to plugins.
Definition: qgsserverinterfaceimpl.h:35
QgsDatumTransform::GridDetails
Contains information about a projection transformation grid file.
Definition: qgsdatumtransform.h:132
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:103
QgsServerLogger::setLogLevel
void setLogLevel(Qgis::MessageLevel level)
Set the current log level.
Definition: qgsserverlogger.cpp:54
QgsServerLogger::logMessage
void logMessage(const QString &message, const QString &tag, Qgis::MessageLevel level) override
Log a message from the server context.
Definition: qgsserverlogger.cpp:36
QgsApplication::skipGdalDriver
static void skipGdalDriver(const QString &driver)
Sets the GDAL_SKIP environment variable to include the specified driver and then calls GDALDriverMana...
Definition: qgsapplication.cpp:1818
QgsApplication::authManager
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
Definition: qgsapplication.cpp:1436
qgsapplication.h
QgsServerResponse::write
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
Definition: qgsserverresponse.cpp:25
QgsServerSettings
Provides a way to retrieve settings by prioritizing according to environment variables,...
Definition: qgsserversettings.h:92
QgsServiceRegistry::apiForRequest
QgsServerApi * apiForRequest(const QgsServerRequest &request) const
Searches the API register for an API matching the request and returns a (possibly NULL) pointer to it...
Definition: qgsserviceregistry.cpp:233
QgsServerParameters::version
virtual QString version() const
Returns VERSION parameter as a string or an empty string if not defined.
Definition: qgsserverparameters.cpp:575
QgsDatumTransform::TransformDetails::grids
QList< QgsDatumTransform::GridDetails > grids
Contains a list of transform grids used by the operation.
Definition: qgsdatumtransform.h:248
QgsServerLogger::instance
static QgsServerLogger * instance()
Gets the singleton instance.
Definition: qgsserverlogger.cpp:22
qgscapabilitiescache.h
QgsServerRequest::serverParameters
QgsServerParameters serverParameters() const
Returns parameters.
Definition: qgsserverrequest.cpp:121
qgsserverrequest.h
qgsproviderregistry.h
qgsserverapi.h
QgsDatumTransform::TransformDetails::accuracy
double accuracy
Transformation accuracy (in meters)
Definition: qgsdatumtransform.h:187
qgsnetworkaccessmanager.h
QgsProject::setInstance
static void setInstance(QgsProject *project)
Set the current project singleton instance to project.
Definition: qgsproject.cpp:474
QgsServerPlugins::initPlugins
static bool initPlugins(QgsServerInterface *interface)
Initializes the Python plugins.
Definition: qgsserverplugins.cpp:39
QgsException::what
QString what() const
Definition: qgsexception.h:48
QgsRequestHandler::parseInput
void parseInput()
Parses the input and creates a request neutral Parameter/Value map.
Definition: qgsrequesthandler.cpp:193
QgsCoordinateTransform::setCustomMissingRequiredGridHandler
static void setCustomMissingRequiredGridHandler(const std::function< void(const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QgsDatumTransform::GridDetails &grid)> &handler)
Sets a custom handler to use when a coordinate transform is created between sourceCrs and destination...
Definition: qgscoordinatetransform.cpp:1110
QgsApplication::createDatabase
static bool createDatabase(QString *errorMessage=nullptr)
initialize qgis.db
Definition: qgsapplication.cpp:2047
qgsserver.h
QgsMessageLog::logMessage
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Definition: qgsmessagelog.cpp:27
QgsApplication::profiler
static QgsRuntimeProfiler * profiler()
Returns the application runtime profiler.
Definition: qgsapplication.cpp:549
qgscoordinatetransform.h
QgsApplication::QGIS_APPLICATION_NAME
static const char * QGIS_APPLICATION_NAME
Definition: qgsapplication.h:162
QgsRuntimeProfiler::clear
void clear(const QString &group="startup")
clear Clear all profile data.
Definition: qgsruntimeprofiler.cpp:273
QgsServerParameters::service
QString service() const
Returns SERVICE parameter as a string or an empty string if not defined.
Definition: qgsserverparameters.cpp:585
QgsApplication::pkgDataPath
static QString pkgDataPath()
Returns the common root path of all application data directories.
Definition: qgsapplication.cpp:645
QgsDatumTransform::GridDetails::shortName
QString shortName
Short name of transform grid.
Definition: qgsdatumtransform.h:135
QgsProject::fileName
QString fileName
Definition: qgsproject.h:107
QgsRequestHandler::setResponseHeader
void setResponseHeader(const QString &name, const QString &value)
Sets an HTTP response header.
Definition: qgsrequesthandler.cpp:47
qgsserverlogger.h
QgsNetworkAccessManager
network access manager for QGIS
Definition: qgsnetworkaccessmanager.h:269
QgsOgcServiceException
Exception base class for service exceptions.
Definition: qgsserverexception.h:82
QgsNetworkAccessManager::instance
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
Definition: qgsnetworkaccessmanager.cpp:202
QgsDatumTransform::TransformDetails
Contains information about a coordinate transformation operation.
Definition: qgsdatumtransform.h:180
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:211
QgsFilterResponseDecorator
Class defining decorator for calling filter's hooks.
Definition: qgsfilterresponsedecorator.h:35
QgsServerLogger::setLogFile
void setLogFile(const QString &filename=QString())
Set the current log file.
Definition: qgsserverlogger.cpp:59
QgsServerParameters::map
QString map() const
Returns MAP parameter as a string or an empty string if not defined.
Definition: qgsserverparameters.cpp:570
QgsServerApi::executeRequest
virtual void executeRequest(const QgsServerApiContext &context) const =0
Executes a request by passing the given context to the API handlers.
QgsCoordinateReferenceSystem::ShortString
@ ShortString
A heavily abbreviated string, for use when a compact representation is required.
Definition: qgscoordinatereferencesystem.h:632
QgsDatumTransform::TransformDetails::name
QString name
Display name of transform operation.
Definition: qgsdatumtransform.h:185
QgsRequestHandler::exceptionRaised
bool exceptionRaised() const
Pointer to last raised exception.
Definition: qgsrequesthandler.cpp:42
Q_GLOBAL_STATIC
Q_GLOBAL_STATIC(QgsServerSettings, sSettings)
QgsRuntimeProfiler::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: qgsruntimeprofiler.cpp:310
QgsFontUtils::loadStandardTestFonts
static bool loadStandardTestFonts(const QStringList &loadstyles)
Loads standard test fonts from filesystem or qrc resource.
Definition: qgsfontutils.cpp:256
QgsServerLogger::setLogStderr
void setLogStderr()
Activates logging to stderr.
Definition: qgsserverlogger.cpp:71
QgsRequestHandler::setServiceException
void setServiceException(const QgsServerException &ex)
Allow plugins to return a QgsMapServiceException.
Definition: qgsrequesthandler.cpp:145
Qgis::MessageLevel
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition: qgis.h:114
QgsOgcServiceException::message
QString message() const
Returns the exception message.
Definition: qgsserverexception.h:94
QgsApplication::libexecPath
static QString libexecPath()
Returns the path with utility executables (help viewer, crssync, ...)
Definition: qgsapplication.cpp:1394
QgsServerException
Exception base class for server exceptions.
Definition: qgsserverexception.h:42
QgsScopedRuntimeProfile
Scoped object for logging of the runtime for a single operation or group of operations.
Definition: qgsruntimeprofiler.h:327
QgsServerInterfaceImpl::setConfigFilePath
void setConfigFilePath(const QString &configFilePath) override
Set the configuration file path.
Definition: qgsserverinterfaceimpl.cpp:61
QgsServiceRegistry
QgsServiceRegistry Class defining the registry manager for QGIS server services.
Definition: qgsserviceregistry.h:49
QgsServerLogger::logLevel
Qgis::MessageLevel logLevel() const
Gets the current log level.
Definition: qgsserverlogger.h:63
QgsApplication::qgisUserDatabaseFilePath
static QString qgisUserDatabaseFilePath()
Returns the path to the user qgis.db file.
Definition: qgsapplication.cpp:1104
QgsServer::QgsServer
QgsServer()
Creates the server instance.
Definition: qgsserver.cpp:69
QgsServerException::formatResponse
virtual QByteArray formatResponse(QString &responseFormat) const
Formats the exception for sending to client.
Definition: qgsserverexception.cpp:30
QgsServerParameters
QgsServerParameters provides an interface to retrieve and manipulate global parameters received from ...
Definition: qgsserverparameters.h:242
QgsRequestHandler
This class is an interface hiding the details of reading input and writing output from/to a wms reque...
Definition: qgsrequesthandler.h:38
QgsServerApi
Server generic API endpoint abstract base class.
Definition: qgsserverapi.h:80
qgsrequesthandler.h
qgslogger.h
QgsServerParameters::fileName
QString fileName() const
Returns FILE_NAME parameter as a string or an empty string if not defined.
Definition: qgsserverparameters.cpp:580
QgsAuthManager::init
bool init(const QString &pluginPath=QString(), const QString &authDatabasePath=QString())
init initialize QCA, prioritize qca-ossl plugin and optionally set up the authentication database
Definition: qgsauthmanager.cpp:180
QgsProviderRegistry::instance
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Definition: qgsproviderregistry.cpp:73
QgsApplication::QGIS_ORGANIZATION_DOMAIN
static const char * QGIS_ORGANIZATION_DOMAIN
Definition: qgsapplication.h:161
qgsproject.h
QgsServerInterfaceImpl::clearRequestHandler
void clearRequestHandler() override
Clear the request handler.
Definition: qgsserverinterfaceimpl.cpp:51
QgsServerResponse::sendError
virtual void sendError(int code, const QString &message)=0
Send error This method delegates error handling at the server level.
QgsServerResponse
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
Definition: qgsserverresponse.h:43
qgsserverapicontext.h
QgsApplication::pluginPath
static QString pluginPath()
Returns the path to the application plugin directory.
Definition: qgsapplication.cpp:640
QgsConfigCache::project
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.
Definition: qgsconfigcache.cpp:97
qgsfilterresponsedecorator.h
QgsConfigCache::initialize
static void initialize(QgsServerSettings *settings)
Initialize from settings.
Definition: qgsconfigcache.cpp:57