void writeGetTile( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response ) { Q_UNUSED( version ); const QgsWmtsParameters params( QUrlQuery( request.url() ) ); // WMS query QUrlQuery query = translateWmtsParamToWmsQueryItem( QStringLiteral( "GetMap" ), params, project, serverIface ); // Get cached image QgsAccessControl *accessControl = serverIface->accessControls(); QgsServerCacheManager *cacheManager = serverIface->cacheManager(); if ( cacheManager ) { QgsWmtsParameters::Format f = params.format(); QString contentType; QString saveFormat; std::unique_ptr<QImage> image; if ( f == QgsWmtsParameters::Format::JPG ) { contentType = QStringLiteral( "image/jpeg" ); saveFormat = QStringLiteral( "JPEG" ); image = qgis::make_unique<QImage>( 256, 256, QImage::Format_RGB32 ); } else { contentType = QStringLiteral( "image/png" ); saveFormat = QStringLiteral( "PNG" ); image = qgis::make_unique<QImage>( 256, 256, QImage::Format_ARGB32_Premultiplied ); } QByteArray content = cacheManager->getCachedImage( project, request, accessControl ); if ( !content.isEmpty() && image->loadFromData( content ) ) { response.setHeader( QStringLiteral( "Content-Type" ), contentType ); image->save( response.io(), qPrintable( saveFormat ) ); return; } } QgsServerParameters wmsParams( query ); QgsServerRequest wmsRequest( "?" + query.query( QUrl::FullyDecoded ) ); QgsService *service = serverIface->serviceRegistry()->getService( wmsParams.service(), wmsParams.version() ); service->executeRequest( wmsRequest, response, project ); if ( cacheManager ) { QByteArray content = response.data(); if ( !content.isEmpty() ) cacheManager->setCachedImage( &content, project, request, accessControl ); } }
void writeGetFeatureInfo( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response ) { Q_UNUSED( version ); const QgsWmtsParameters params( QUrlQuery( request.url() ) ); // WMS query QUrlQuery query = translateWmtsParamToWmsQueryItem( QStringLiteral( "GetFeatureInfo" ), params, project, serverIface ); // GetFeatureInfo query items query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::QUERY_LAYERS ), params.layer() ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::I ), params.i() ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::J ), params.j() ); query.addQueryItem( QgsWmsParameterForWmts::name( QgsWmsParameterForWmts::INFO_FORMAT ), params.infoFormatAsString() ); QgsServerParameters wmsParams( query ); QgsServerRequest wmsRequest( "?" + query.query( QUrl::FullyDecoded ) ); QgsService *service = serverIface->serviceRegistry()->getService( wmsParams.service(), wmsParams.version() ); service->executeRequest( wmsRequest, response, project ); }
void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project ) { Qgis::MessageLevel logLevel = QgsServerLogger::instance()->logLevel(); QTime time; //used for measuring request time if loglevel < 1 qApp->processEvents(); if ( logLevel == Qgis::Info ) { time.start(); } // Pass the filters to the requestHandler, this is needed for the following reasons: // Allow server request to call sendResponse plugin hook if enabled QgsFilterResponseDecorator responseDecorator( sServerInterface->filters(), response ); //Request handler QgsRequestHandler requestHandler( request, response ); try { // TODO: split parse input into plain parse and processing from specific services requestHandler.parseInput(); } catch ( QgsMapServiceException &e ) { QgsMessageLog::logMessage( "Parse input exception: " + e.message(), QStringLiteral( "Server" ), Qgis::Critical ); requestHandler.setServiceException( e ); } // Set the request handler into the interface for plugins to manipulate it sServerInterface->setRequestHandler( &requestHandler ); // Call requestReady() method (if enabled) responseDecorator.start(); // Plugins may have set exceptions if ( !requestHandler.exceptionRaised() ) { try { const QgsServerParameters params = request.serverParameters(); printRequestParameters( params.toMap(), logLevel ); //Config file path if ( ! project ) { QString configFilePath = configPath( *sConfigFilePath, params.map() ); // load the project if needed and not empty project = mConfigCache->project( configFilePath ); if ( ! project ) { throw QgsServerException( QStringLiteral( "Project file error" ) ); } sServerInterface->setConfigFilePath( configFilePath ); } else { sServerInterface->setConfigFilePath( project->fileName() ); } if ( ! params.fileName().isEmpty() ) { const QString value = QString( "attachment; filename=\"%1\"" ).arg( params.fileName() ); requestHandler.setResponseHeader( QStringLiteral( "Content-Disposition" ), value ); } // Lookup for service QgsService *service = sServiceRegistry->getService( params.service(), params.version() ); if ( service ) { service->executeRequest( request, responseDecorator, project ); } else { throw QgsOgcServiceException( QStringLiteral( "Service configuration error" ), QStringLiteral( "Service unknown or unsupported" ) ); } } catch ( QgsServerException &ex ) { responseDecorator.write( ex ); } catch ( QgsException &ex ) { // Internal server error response.sendError( 500, ex.what() ); } } // Terminate the response responseDecorator.finish(); // We are done using requestHandler in plugins, make sure we don't access // to a deleted request handler from Python bindings sServerInterface->clearRequestHandler(); if ( logLevel == Qgis::Info ) { QgsMessageLog::logMessage( "Request finished in " + QString::number( time.elapsed() ) + " ms", QStringLiteral( "Server" ), Qgis::Info ); } }
void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &response ) { QgsMessageLog::MessageLevel logLevel = QgsServerLogger::instance()->logLevel(); QTime time; //used for measuring request time if loglevel < 1 QgsProject::instance()->removeAllMapLayers(); qApp->processEvents(); if ( logLevel == QgsMessageLog::INFO ) { time.start(); } // Pass the filters to the requestHandler, this is needed for the following reasons: // Allow server request to call sendResponse plugin hook if enabled QgsFilterResponseDecorator responseDecorator( sServerInterface->filters(), response ); //Request handler QgsRequestHandler requestHandler( request, response ); try { // TODO: split parse input into plain parse and processing from specific services requestHandler.parseInput(); } catch ( QgsMapServiceException &e ) { QgsMessageLog::logMessage( "Parse input exception: " + e.message(), QStringLiteral( "Server" ), QgsMessageLog::CRITICAL ); requestHandler.setServiceException( e ); } // Set the request handler into the interface for plugins to manipulate it sServerInterface->setRequestHandler( &requestHandler ); // Call requestReady() method (if enabled) responseDecorator.start(); // Plugins may have set exceptions if ( !requestHandler.exceptionRaised() ) { try { QMap<QString, QString> parameterMap = request.parameters(); printRequestParameters( parameterMap, logLevel ); //Config file path QString configFilePath = configPath( *sConfigFilePath, parameterMap ); // load the project if needed and not empty const QgsProject *project = mConfigCache->project( configFilePath ); if ( ! project ) { throw QgsServerException( QStringLiteral( "Project file error" ) ); } sServerInterface->setConfigFilePath( configFilePath ); //Service parameter QString serviceString = parameterMap.value( QStringLiteral( "SERVICE" ) ); if ( serviceString.isEmpty() ) { // SERVICE not mandatory for WMS 1.3.0 GetMap & GetFeatureInfo QString requestString = parameterMap.value( QStringLiteral( "REQUEST" ) ); if ( requestString == QLatin1String( "GetMap" ) || requestString == QLatin1String( "GetFeatureInfo" ) ) { serviceString = QStringLiteral( "WMS" ); } } QString versionString = parameterMap.value( QStringLiteral( "VERSION" ) ); //possibility for client to suggest a download filename QString outputFileName = parameterMap.value( QStringLiteral( "FILE_NAME" ) ); if ( !outputFileName.isEmpty() ) { requestHandler.setResponseHeader( QStringLiteral( "Content-Disposition" ), "attachment; filename=\"" + outputFileName + "\"" ); } // Lookup for service QgsService *service = sServiceRegistry.getService( serviceString, versionString ); if ( service ) { service->executeRequest( request, responseDecorator, project ); } else { throw QgsOgcServiceException( QStringLiteral( "Service configuration error" ), QStringLiteral( "Service unknown or unsupported" ) ) ; } } catch ( QgsServerException &ex ) { responseDecorator.write( ex ); } catch ( QgsException &ex ) { // Internal server error response.sendError( 500, ex.what() ); } } // Terminate the response responseDecorator.finish(); // We are done using requestHandler in plugins, make sure we don't access // to a deleted request handler from Python bindings sServerInterface->clearRequestHandler(); if ( logLevel == QgsMessageLog::INFO ) { QgsMessageLog::logMessage( "Request finished in " + QString::number( time.elapsed() ) + " ms", QStringLiteral( "Server" ), QgsMessageLog::INFO ); } }