QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
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
25#include "qgsapplication.h"
26#include "qgsauthmanager.h"
30#include "qgsfontutils.h"
31#include "qgslogger.h"
34#include "qgsnetworkdiskcache.h"
35#include "qgsproject.h"
36#include "qgsproviderregistry.h"
37#include "qgsrequesthandler.h"
38#include "qgsruntimeprofiler.h"
39#include "qgsserverapi.h"
40#include "qgsserverapicontext.h"
41#include "qgsserverlogger.h"
42#include "qgsserverparameters.h"
43#include "qgsserverrequest.h"
44#include "qgsservice.h"
45#include "qgsversion.h"
46
47#include <QDomDocument>
48#include <QElapsedTimer>
49#include <QNetworkDiskCache>
50#include <QSettings>
51#include <QString>
52
53using namespace Qt::StringLiterals;
54
55// TODO: remove, it's only needed by a single debug message
56#include <fcgi_stdio.h>
57#include <cstdlib>
58
59
60// Server status static initializers.
61// Default values are for C++, SIP bindings will override their
62// options in in init()
63
64QString *QgsServer::sConfigFilePath = nullptr;
65QgsCapabilitiesCache *QgsServer::sCapabilitiesCache = nullptr;
66QgsServerInterfaceImpl *QgsServer::sServerInterface = nullptr;
67// Initialization must run once for all servers
68bool QgsServer::sInitialized = false;
69
70QgsServiceRegistry *QgsServer::sServiceRegistry = nullptr;
71
73
75{
76 // QgsApplication must exist
77 if ( !qobject_cast<QgsApplication *>( qApp ) )
78 {
79 qFatal( "A QgsApplication must exist before a QgsServer instance can be created." );
80 abort();
81 }
82 init();
83 mConfigCache = QgsConfigCache::instance();
84}
85
86QFileInfo QgsServer::defaultAdminSLD()
87{
88 return QFileInfo( u"admin.sld"_s );
89}
90
91void QgsServer::setupNetworkAccessManager()
92{
93 const QSettings settings;
94 QgsNetworkAccessManager *nam = QgsNetworkAccessManager::instance();
95 QNetworkDiskCache *cache = new QNetworkDiskCache( nullptr );
96 const QString cacheDirectory = sSettings()->cacheDirectory();
97 cache->setCacheDirectory( cacheDirectory );
98 qint64 cacheSize = sSettings()->cacheSize();
99 cache->setMaximumCacheSize( cacheSize );
100 QgsMessageLog::logMessage( u"cacheDirectory: %1"_s.arg( cache->cacheDirectory() ), u"Server"_s, Qgis::MessageLevel::Info );
101 QgsMessageLog::logMessage( u"maximumCacheSize: %1"_s.arg( cache->maximumCacheSize() ), u"Server"_s, Qgis::MessageLevel::Info );
102 nam->setCache( cache );
103}
104
105QFileInfo QgsServer::defaultProjectFile()
106{
107 const QDir currentDir;
108 fprintf( FCGI_stderr, "current directory: %s\n", currentDir.absolutePath().toUtf8().constData() );
109 QStringList nameFilterList;
110 nameFilterList << u"*.qgs"_s << u"*.qgz"_s;
111 const QFileInfoList projectFiles = currentDir.entryInfoList( nameFilterList, QDir::Files, QDir::Name );
112 for ( int x = 0; x < projectFiles.size(); x++ )
113 {
114 QgsMessageLog::logMessage( projectFiles.at( x ).absoluteFilePath(), u"Server"_s, Qgis::MessageLevel::Info );
115 }
116 if ( projectFiles.isEmpty() )
117 {
118 return QFileInfo();
119 }
120 return projectFiles.at( 0 );
121}
122
123void QgsServer::printRequestParameters( const QMap<QString, QString> &parameterMap, Qgis::MessageLevel logLevel )
124{
125 if ( logLevel > Qgis::MessageLevel::Info )
126 {
127 return;
128 }
129
130 QMap<QString, QString>::const_iterator pIt = parameterMap.constBegin();
131 for ( ; pIt != parameterMap.constEnd(); ++pIt )
132 {
133 QgsMessageLog::logMessage( pIt.key() + ":" + pIt.value(), u"Server"_s, Qgis::MessageLevel::Info );
134 }
135}
136
137QString QgsServer::configPath( const QString &defaultConfigPath, const QString &configPath )
138{
139 QString cfPath( defaultConfigPath );
140 const QString projectFile = sSettings()->projectFile();
141 if ( !projectFile.isEmpty() )
142 {
143 cfPath = projectFile;
144 QgsDebugMsgLevel( u"QGIS_PROJECT_FILE:%1"_s.arg( cfPath ), 2 );
145 }
146 else
147 {
148 if ( configPath.isEmpty() )
149 {
150 // Read it from the environment, because a rewrite rule may have rewritten it
151 if ( getenv( "QGIS_PROJECT_FILE" ) )
152 {
153 cfPath = getenv( "QGIS_PROJECT_FILE" );
154 QgsMessageLog::logMessage( u"Using configuration file path from environment: %1"_s.arg( cfPath ), u"Server"_s, Qgis::MessageLevel::Info );
155 }
156 else if ( !defaultConfigPath.isEmpty() )
157 {
158 QgsMessageLog::logMessage( u"Using default configuration file path: %1"_s.arg( defaultConfigPath ), u"Server"_s, Qgis::MessageLevel::Info );
159 }
160 }
161 else
162 {
163 cfPath = configPath;
164 QgsDebugMsgLevel( u"MAP:%1"_s.arg( cfPath ), 2 );
165 }
166 }
167 return cfPath;
168}
169
170void QgsServer::initLocale()
171{
172 // System locale override
173 if ( !sSettings()->overrideSystemLocale().isEmpty() )
174 {
175 QLocale::setDefault( QLocale( sSettings()->overrideSystemLocale() ) );
176 }
177 // Number group separator settings
178 QLocale currentLocale;
179 if ( sSettings()->showGroupSeparator() )
180 {
181 currentLocale.setNumberOptions( currentLocale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
182 }
183 else
184 {
185 currentLocale.setNumberOptions( currentLocale.numberOptions() |= QLocale::NumberOption::OmitGroupSeparator );
186 }
187 QLocale::setDefault( currentLocale );
188}
189
190bool QgsServer::init()
191{
192 if ( sInitialized )
193 {
194 return false;
195 }
196
197 QCoreApplication::setOrganizationName( QgsApplication::QGIS_ORGANIZATION_NAME );
198 QCoreApplication::setOrganizationDomain( QgsApplication::QGIS_ORGANIZATION_DOMAIN );
199 QCoreApplication::setApplicationName( QgsApplication::QGIS_APPLICATION_NAME );
200
201 // TODO: remove QGIS_OPTIONS_PATH from settings and rely on QgsApplication's env var QGIS_CUSTOM_CONFIG_PATH
202 // Note that QGIS_CUSTOM_CONFIG_PATH gives /tmp/qt_temp-rUpsId/profiles/default/QGIS/QGIS3.ini
203 // while QGIS_OPTIONS_PATH gives /tmp/qt_temp-rUpsId/QGIS/QGIS3.ini
204 QgsApplication::init( qgetenv( "QGIS_OPTIONS_PATH" ) );
205
206#if defined( SERVER_SKIP_ECW )
207 QgsMessageLog::logMessage( "Skipping GDAL ECW drivers in server.", "Server", Qgis::MessageLevel::Info );
210#endif
211
212 // reload settings to take into account QCoreApplication and QgsApplication
213 // configuration
214 sSettings()->load();
215
216 // init and configure logger
218 QgsServerLogger::instance()->setLogLevel( sSettings()->logLevel() );
219 if ( !sSettings()->logFile().isEmpty() )
220 {
221 QgsServerLogger::instance()->setLogFile( sSettings()->logFile() );
222 }
223 else if ( sSettings()->logStderr() )
224 {
226 }
227
228 // Logging handlers for CRS grid issues
230 []( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QgsDatumTransform::GridDetails &grid ) {
232 u"Cannot use project transform between %1 and %2 - missing grid %3"_s
234 u"QGIS Server"_s,
236 );
237 }
238 );
239
240
242 []( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QgsDatumTransform::TransformDetails &details ) {
243 QString gridMessage;
244 for ( const QgsDatumTransform::GridDetails &grid : details.grids )
245 {
246 if ( !grid.isAvailable )
247 {
248 gridMessage.append( u"This transformation requires the grid file '%1', which is not available for use on the system.\n"_s.arg( grid.shortName ) );
249 }
250 }
252 u"Cannot use project transform between %1 and %2 - %3.\n%4"_s
254 u"QGIS Server"_s,
256 );
257 }
258 );
259
260
262 []( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QgsDatumTransform::TransformDetails &preferredOperation, const QgsDatumTransform::TransformDetails &availableOperation ) {
263 QString gridMessage;
264 for ( const QgsDatumTransform::GridDetails &grid : preferredOperation.grids )
265 {
266 if ( !grid.isAvailable )
267 {
268 gridMessage.append( u"This transformation requires the grid file '%1', which is not available for use on the system.\n"_s.arg( grid.shortName ) );
269 if ( !grid.url.isEmpty() )
270 {
271 if ( !grid.packageName.isEmpty() )
272 {
273 gridMessage.append( u"This grid is part of the '%1' package, available for download from %2.\n"_s.arg( grid.packageName, grid.url ) );
274 }
275 else
276 {
277 gridMessage.append( u"This grid is available for download from %1.\n"_s.arg( grid.url ) );
278 }
279 }
280 }
281 }
282
283 QString accuracyMessage;
284 if ( availableOperation.accuracy >= 0 && preferredOperation.accuracy >= 0 )
285 accuracyMessage = u"Current transform '%1' has an accuracy of %2 meters, while the preferred transformation '%3' has accuracy %4 meters.\n"_s.arg( availableOperation.name )
286 .arg( availableOperation.accuracy )
287 .arg( preferredOperation.name )
288 .arg( preferredOperation.accuracy );
289 else if ( preferredOperation.accuracy >= 0 )
290 accuracyMessage = u"Current transform '%1' has an unknown accuracy, while the preferred transformation '%2' has accuracy %3 meters.\n"_s.arg( availableOperation.name, preferredOperation.name )
291 .arg( preferredOperation.accuracy );
292
293 const QString longMessage
294 = u"The preferred transform between '%1' and '%2' is not available for use on the system.\n"_s.arg( sourceCrs.userFriendlyIdentifier(), destinationCrs.userFriendlyIdentifier() )
295 + gridMessage
296 + accuracyMessage;
297
298 QgsServerLogger::instance()->logMessage( longMessage, u"QGIS Server"_s, Qgis::MessageLevel::Warning );
299 }
300 );
301
302 QgsCoordinateTransform::setCustomCoordinateOperationCreationErrorHandler( []( const QgsCoordinateReferenceSystem &sourceCrs, const QgsCoordinateReferenceSystem &destinationCrs, const QString &error ) {
303 const QString longMessage = u"No transform is available between %1 and %2: %3"_s.arg( sourceCrs.userFriendlyIdentifier(), destinationCrs.userFriendlyIdentifier(), error );
304 QgsServerLogger::instance()->logMessage( longMessage, u"QGIS Server"_s, Qgis::MessageLevel::Warning );
305 } );
306
307 // Configure locale
308 initLocale();
309
310 QgsMessageLog::logMessage( u"QGIS Server Starting : %1 (%2)"_s.arg( _QGIS_VERSION, QGSVERSION ), "Server", Qgis::MessageLevel::Info );
311
312 // log settings currently used
313 sSettings()->logSummary();
314
315 setupNetworkAccessManager();
316 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
317
318 // Instantiate the plugin directory so that providers are loaded
325 QgsMessageLog::logMessage( "SVG PATHS: " + QgsApplication::svgPaths().join( QDir::listSeparator() ), u"Server"_s, Qgis::MessageLevel::Info );
326
327 QgsApplication::createDatabase(); //init qgis.db (e.g. necessary for user crs)
328
329 // Sets up the authentication system
330 // creates or uses qgis-auth.db in ~/.qgis3/ or directory defined by QGIS_AUTH_DB_DIR_PATH env variable
331 // or QGIS_AUTH_DB_URI 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, u"Server"_s, 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( sSettings()->capabilitiesCacheSize() );
356
357 QgsFontUtils::loadStandardTestFonts( QStringList() << u"Roman"_s << u"Bold"_s );
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() << u"Initializing server modules from: %1"_s.arg( modulePath );
366 sServiceRegistry->init( modulePath, sServerInterface );
367
368 // Initialize config cache
369 QgsConfigCache::initialize( sSettings );
370
372
373 sInitialized = true;
374 QgsMessageLog::logMessage( u"Server initialized"_s, u"Server"_s, Qgis::MessageLevel::Info );
375 return true;
376}
377
378
379void QgsServer::putenv( const QString &var, const QString &val )
380{
381 if ( val.isEmpty() )
382 {
383 qunsetenv( var.toUtf8().data() );
384 }
385 else
386 {
387 qputenv( var.toUtf8().data(), val.toUtf8() );
388 }
389 sSettings()->load( var );
390}
391
393{
395 {
396 const QgsScopedRuntimeProfile profiler { u"handleRequest"_s, u"server"_s };
397
398 qApp->processEvents();
399
400 response.clear();
401
402 // Clean up qgis access control filter's cache to prevent side effects
403 // across requests
404#ifdef HAVE_SERVER_PYTHON_PLUGINS
405 QgsAccessControl *accessControls = sServerInterface->accessControls();
406 if ( accessControls )
407 {
408 accessControls->unresolveFilterFeatures();
409 }
410#endif
411
412 // Pass the filters to the requestHandler, this is needed for the following reasons:
413 // Allow server request to call sendResponse plugin hook if enabled
414 QgsFilterResponseDecorator responseDecorator( sServerInterface->filters(), response );
415
416 //Request handler
417 QgsRequestHandler requestHandler( request, response );
418
419 if ( !response.feedback() || !response.feedback()->isCanceled() ) // to avoid to much log when request is canceled
420 {
421 try
422 {
423 // TODO: split parse input into plain parse and processing from specific services
424 requestHandler.parseInput();
425 }
426 catch ( QgsMapServiceException &e )
427 {
428 QgsMessageLog::logMessage( "Parse input exception: " + e.message(), u"Server"_s, Qgis::MessageLevel::Critical );
429 requestHandler.setServiceException( e );
430 }
431 }
432
433 // Set the request handler into the interface for plugins to manipulate it
434 sServerInterface->setRequestHandler( &requestHandler );
435
436 // Initialize configfilepath so that it is available
437 // before calling plugin methods
438 // Note that plugins may still change that value using
439 // setConfigFilePath() interface method
440 if ( !project )
441 {
442 const QString configFilePath = configPath( *sConfigFilePath, request.serverParameters().map() );
443 sServerInterface->setConfigFilePath( configFilePath );
444 }
445 else
446 {
447 sServerInterface->setConfigFilePath( project->fileName() );
448 }
449
450 // Call requestReady() method (if enabled)
451 // This may also throw exceptions if there are errors in python plugins code
452 try
453 {
454 responseDecorator.start();
455 }
456 catch ( QgsException &ex )
457 {
458 // Internal server error
459 response.sendError( 500, u"Internal Server Error"_s );
461 }
462
463 // Plugins may have set exceptions
464 if ( !requestHandler.exceptionRaised() && ( !response.feedback() || !response.feedback()->isCanceled() ) )
465 {
466 try
467 {
468 const QgsServerParameters params = request.serverParameters();
469 printRequestParameters( params.toMap(), logLevel );
470
471 // Setup project (config file path)
472 if ( !project )
473 {
474 const QString configFilePath = configPath( *sConfigFilePath, params.map() );
475
476 // load the project if needed and not empty
477 if ( !configFilePath.isEmpty() )
478 {
479 // Note that QgsConfigCache::project( ... ) call QgsProject::setInstance(...)
480 project = mConfigCache->project( configFilePath, sServerInterface->serverSettings() );
481 }
482 }
483
484 // Set the current project instance
485 QgsProject::setInstance( const_cast<QgsProject *>( project ) );
486
487 if ( project )
488 {
489 sServerInterface->setConfigFilePath( project->fileName() );
490 }
491 else
492 {
493 sServerInterface->setConfigFilePath( QString() );
494 }
495
496 // Call projectReady() method (if enabled)
497 // This may also throw exceptions if there are errors in python plugins code
498 responseDecorator.ready();
499
500 // Note that at this point we still might not have set a valid project.
501 // There are APIs that work without a project (e.g. the landing page catalog API that
502 // lists the available projects metadata).
503
504 // Dispatcher: if SERVICE is set, we assume a OWS service, if not, let's try an API
505 // TODO: QGIS 5 fix the OWS services and treat them as APIs
506 if ( !response.feedback() || !response.feedback()->isCanceled() )
507 {
508 if ( params.service().isEmpty() )
509 {
510 QgsServerApi *api = sServiceRegistry->apiForRequest( request );
511 if ( api )
512 {
513 const QgsServerApiContext context { api->rootPath(), &request, &responseDecorator, project, sServerInterface };
514 api->executeRequest( context );
515 }
516 else
517 {
519 u"Service configuration error"_s,
520 QStringLiteral(
521 "Service unknown or unsupported. Current supported services "
522 "(case-sensitive): WMS WFS WCS WMTS SampleService, or use a WFS3 "
523 "(OGC API Features) endpoint"
524 )
525 );
526 }
527 }
528 else
529 {
530 // Project is mandatory for OWS at this point
531 if ( !project )
532 {
533 throw QgsServerException( QStringLiteral(
534 "Project file error. For OWS services: please provide a SERVICE "
535 "and a MAP parameter pointing to a valid QGIS project file"
536 ) );
537 }
538
539 if ( !params.fileName().isEmpty() )
540 {
541 const QString value = QString( "attachment; filename=\"%1\"" ).arg( params.fileName() );
542 requestHandler.setResponseHeader( u"Content-Disposition"_s, value );
543 }
544
545 // Lookup for service
546 QgsService *service = sServiceRegistry->getService( params.service(), params.version() );
547 if ( service )
548 {
549 service->executeRequest( request, responseDecorator, project );
550 }
551 else
552 {
554 u"Service configuration error"_s,
555 QStringLiteral(
556 "Service unknown or unsupported. Current supported services "
557 "(case-sensitive): WMS WFS WCS WMTS SampleService, or use a WFS3 "
558 "(OGC API Features) endpoint"
559 )
560 );
561 }
562 }
563 }
564 }
565 catch ( QgsServerException &ex )
566 {
567 responseDecorator.write( ex );
568 QString format;
570 }
571 catch ( QgsException &ex )
572 {
573 // Internal server error
574 response.sendError( 500, u"Internal Server Error"_s );
576 }
577 }
578
579 // Terminate the response
580 // This may also throw exceptions if there are errors in python plugins code
581 try
582 {
583 responseDecorator.finish();
584 }
585 catch ( QgsException &ex )
586 {
587 // Internal server error
588 response.sendError( 500, u"Internal Server Error"_s );
590 }
591
592 // We are done using requestHandler in plugins, make sure we don't access
593 // to a deleted request handler from Python bindings
594 sServerInterface->clearRequestHandler();
595 }
596
597 if ( logLevel == Qgis::MessageLevel::Info )
598 {
599 QgsMessageLog::logMessage( "Request finished in " + QString::number( QgsApplication::profiler()->profileTime( u"handleRequest"_s, u"server"_s ) * 1000.0 ) + " ms", u"Server"_s, Qgis::MessageLevel::Info );
600 if ( sSettings->logProfile() )
601 {
602 std::function<void( const QModelIndex &, int )> profileFormatter;
603 profileFormatter = [&profileFormatter]( const QModelIndex &idx, int level ) {
605 u"Profile: %1%2, %3 : %4 ms"_s.arg( level > 0 ? QString().fill( '-', level ) + ' ' : QString() )
606 .arg( QgsApplication::profiler()->data( idx, static_cast<int>( QgsRuntimeProfilerNode::CustomRole::Group ) ).toString() )
607 .arg( QgsApplication::profiler()->data( idx, static_cast<int>( QgsRuntimeProfilerNode::CustomRole::Name ) ).toString() )
608 .arg( QString::number( QgsApplication::profiler()->data( idx, static_cast<int>( QgsRuntimeProfilerNode::CustomRole::Elapsed ) ).toDouble() * 1000.0 ) ),
609 u"Server"_s,
611 );
612
613 for ( int subRow = 0; subRow < QgsApplication::profiler()->rowCount( idx ); subRow++ )
614 {
615 const auto subIdx { QgsApplication::profiler()->index( subRow, 0, idx ) };
616 profileFormatter( subIdx, level + 1 );
617 }
618 };
619
620 for ( int row = 0; row < QgsApplication::profiler()->rowCount(); row++ )
621 {
622 const auto idx { QgsApplication::profiler()->index( row, 0 ) };
623 profileFormatter( idx, 0 );
624 }
625 }
626 }
627
628
629 // Clear the profiler content after each request
630 QgsApplication::profiler()->clear( u"startup"_s );
631 QgsApplication::profiler()->clear( u"projectload"_s );
632 QgsApplication::profiler()->clear( u"rendering"_s );
633 QgsApplication::profiler()->clear( u"server"_s );
634}
635
636
637#ifdef HAVE_SERVER_PYTHON_PLUGINS
638void QgsServer::initPython()
639{
640 // Init plugins
641 if ( !QgsServerPlugins::initPlugins( sServerInterface ) )
642 {
643 QgsMessageLog::logMessage( u"No server python plugins are available"_s, u"Server"_s, Qgis::MessageLevel::Info );
644 }
645 else
646 {
647 QgsMessageLog::logMessage( u"Server python plugins loaded"_s, u"Server"_s, Qgis::MessageLevel::Info );
648 }
649}
650#endif
@ ShortString
A heavily abbreviated string, for use when a compact representation is required.
Definition qgis.h:2500
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:160
@ Warning
Warning message.
Definition qgis.h:162
@ Critical
Critical/error message.
Definition qgis.h:163
@ Info
Information message.
Definition qgis.h:161
A helper class that centralizes restrictions given by all the access control filter plugins.
void unresolveFilterFeatures()
Clear expression's cache computed from resolveFilterFeatures.
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 QString qgisAuthDatabaseUri()
Returns the URI to the user authentication database.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
static QString qgisUserDatabaseFilePath()
Returns the path to the user qgis.db file.
void setup(const QString &pluginPath=QString(), const QString &authDatabasePath=QString())
Sets up the authentication manager configuration.
A cache for capabilities xml documents (by configuration file path).
void removeCapabilitiesDocument(const QString &path)
Removes capabilities document.
static QgsConfigCache * instance()
Returns the current instance.
static void initialize(QgsServerSettings *settings)
Initialize from settings.
void projectRemovedFromCache(const QString &path)
Emitted whenever a project is removed from the cache.
QString userFriendlyIdentifier(Qgis::CrsIdentifierType type=Qgis::CrsIdentifierType::MediumString) const
Returns a user friendly identifier for the CRS.
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...
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...
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...
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 ...
Defines a QGIS exception class.
QString what() const
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:56
A decorator for calling filter's hooks.
void start()
Call filters requestReady() method.
void finish() override
Finish the response, ending the transaction.
void ready()
Call filters projectReady() 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::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
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:113
static void setInstance(QgsProject *project)
Set the current project singleton instance to project.
QString fileName
Definition qgsproject.h:117
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
An interface hiding the details of reading input and writing output from/to a wms request mechanism.
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.
Encapsulates the resources for a particular client request.
Server generic API endpoint abstract base class.
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.
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.
void logMessage(const QString &message, const QString &tag, Qgis::MessageLevel level) override
Provides an interface to retrieve and manipulate global parameters received from the client.
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.
virtual 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.
Defines requests passed to QgsService classes.
QgsServerParameters serverParameters() const
Returns parameters.
Defines the response interface passed to QgsService.
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
virtual QgsFeedback * feedback() const
Returns the socket feedback if any.
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:74
void handleRequest(QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project=nullptr)
Handles the request.
void putenv(const QString &var, const QString &val)
Set environment variable.
A registry manager for QGIS server services.
Defines interfaces for QGIS server services.
Definition qgsservice.h:38
virtual void executeRequest(const QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project)=0
Executes the requests and sets result in QgsServerRequest.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63
Q_GLOBAL_STATIC(QgsServerSettings, sSettings)
QString shortName
Short name of transform grid.
bool isAvailable
true if grid is currently available for use
QString packageName
Name of package the grid is included within.
QString url
Url to download grid from.
double accuracy
Transformation accuracy (in meters).
QString name
Display name of transform operation.
QList< QgsDatumTransform::GridDetails > grids
Contains a list of transform grids used by the operation.