Example #1
0
  void writeAsDxf( QgsServerInterface *serverIface, const QgsProject *project,
                   const QString &version,  const QgsServerRequest &request,
                   QgsServerResponse &response )
  {
    Q_UNUSED( version );

    QgsServerRequest::Parameters params = request.parameters();

    QgsWmsParameters wmsParameters( QUrlQuery( request.url() ) );
    QgsRenderer renderer( serverIface, project, wmsParameters );

    QMap<QString, QString> formatOptionsMap = parseFormatOptions( params.value( QStringLiteral( "FORMAT_OPTIONS" ) ) );

    QgsDxfExport dxf = renderer.getDxf( formatOptionsMap );

    QString codec = QStringLiteral( "ISO-8859-1" );
    QMap<QString, QString>::const_iterator codecIt = formatOptionsMap.find( QStringLiteral( "CODEC" ) );
    if ( codecIt != formatOptionsMap.constEnd() )
    {
      codec = formatOptionsMap.value( QStringLiteral( "CODEC" ) );
    }

    // Write output
    response.setHeader( "Content-Type", "application/dxf" );
    dxf.writeToFile( response.io(), codec );
  }
Example #2
0
  QString serviceUrl( const QgsServerRequest &request, const QgsProject *project )
  {
    QString href;
    if ( project )
    {
      href = QgsServerProjectUtils::wmtsServiceUrl( *project );
    }

    // Build default url
    if ( href.isEmpty() )
    {
      QUrl url = request.originalUrl();

      QgsWmtsParameters params;
      params.load( QUrlQuery( url ) );
      params.remove( QgsServerParameter::REQUEST );
      params.remove( QgsServerParameter::VERSION_SERVICE );
      params.remove( QgsServerParameter::SERVICE );

      url.setQuery( params.urlQuery() );
      href = url.toString();
    }

    return  href;
  }
Example #3
0
  QUrl serviceUrl( const QgsServerRequest &request, const QgsProject *project )
  {
    QUrl href;
    if ( project )
    {
      href.setUrl( QgsServerProjectUtils::wmsServiceUrl( *project ) );
    }

    // Build default url
    if ( href.isEmpty() )
    {
      href = request.url();
      QUrlQuery q( href );

      q.removeAllQueryItems( QStringLiteral( "REQUEST" ) );
      q.removeAllQueryItems( QStringLiteral( "VERSION" ) );
      q.removeAllQueryItems( QStringLiteral( "SERVICE" ) );
      q.removeAllQueryItems( QStringLiteral( "LAYERS" ) );
      q.removeAllQueryItems( QStringLiteral( "SLD_VERSION" ) );
      q.removeAllQueryItems( QStringLiteral( "_DC" ) );

      href.setQuery( q );
    }

    return  href;
  }
Example #4
0
  void writeGetMap( QgsServerInterface* serverIface, const QString& version,
                    const QgsServerRequest& request,
                    QgsServerResponse& response )
  {
    Q_UNUSED( version );

    QgsServerRequest::Parameters params = request.parameters();
    QgsWmsConfigParser* parser = getConfigParser( serverIface );

    QgsWmsServer server( serverIface->configFilePath(),
                         *serverIface->serverSettings(), params, parser,
                         serverIface->accessControls() );

    QScopedPointer<QImage> result( server.getMap() );
    if ( !result.isNull() )
    {
      QString format = params.value( QStringLiteral( "FORMAT" ), QStringLiteral( "PNG" ) );
      writeImage( response, *result, format, server.getImageQuality() );
    }
    else
    {
      throw QgsServiceException( QStringLiteral( "UnknownError" ),
                                 QStringLiteral( "Failed to compute GetMap image" ) );
    }
  }
Example #5
0
  QString serviceUrl( const QgsServerRequest &request, const QgsProject *project )
  {
    QUrl href;
    if ( project )
    {
      href.setUrl( QgsServerProjectUtils::wfsServiceUrl( *project ) );
    }

    // Build default url
    if ( href.isEmpty() )
    {

      static QSet<QString> sFilter
      {
        QStringLiteral( "REQUEST" ),
        QStringLiteral( "VERSION" ),
        QStringLiteral( "SERVICE" ),
      };

      href = request.originalUrl();
      QUrlQuery q( href );

      for ( auto param : q.queryItems() )
      {
        if ( sFilter.contains( param.first.toUpper() ) )
          q.removeAllQueryItems( param.first );
      }

      href.setQuery( q );
    }

    return  href.toString();
  }
Example #6
0
  QDomDocument getStyle( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
                         const QgsServerRequest &request )
  {
    Q_UNUSED( version );

    QgsServerRequest::Parameters parameters = request.parameters();

    QDomDocument doc;

    QString styleName = parameters.value( QStringLiteral( "STYLE" ) );
    QString layerName = parameters.value( QStringLiteral( "LAYER" ) );

    if ( styleName.isEmpty() )
    {
      throw QgsBadRequestException( QgsServiceException::QGIS_MissingParameterValue,
                                    QgsWmsParameter::STYLE );
    }

    if ( layerName.isEmpty() )
    {
      throw QgsBadRequestException( QgsServiceException::QGIS_MissingParameterValue,
                                    QgsWmsParameter::LAYERS );
    }

    QStringList layerList;
    layerList.append( layerName );
    return getStyledLayerDescriptorDocument( serverIface, project, layerList );
  }
Example #7
0
  QString serviceUrl( const QgsServerRequest& request, const QgsProject* project )
  {
    QString href;
    if ( project )
    {
      href = QgsServerProjectUtils::wfsServiceUrl( *project );
    }

    // Build default url
    if ( href.isEmpty() )
    {
      QUrl url = request.url();
      QUrlQuery q( url );

      q.removeAllQueryItems( QStringLiteral( "REQUEST" ) );
      q.removeAllQueryItems( QStringLiteral( "VERSION" ) );
      q.removeAllQueryItems( QStringLiteral( "SERVICE" ) );
      q.removeAllQueryItems( QStringLiteral( "_DC" ) );

      url.setQuery( q );
      href = url.toString( QUrl::FullyDecoded );
    }

    return  href;
  }
Example #8
0
  void writeGetPrint( QgsServerInterface *serverIface, const QgsProject *project,
                      const QString &version, const QgsServerRequest &request,
                      QgsServerResponse &response )
  {
    QgsServerRequest::Parameters params = request.parameters();

    Q_UNUSED( version );

    QgsWmsParameters wmsParameters( QUrlQuery( request.url() ) );
    QgsRenderer renderer( serverIface, project, wmsParameters );

    QString format = params.value( "FORMAT" );
    QString contentType;

    // GetPrint supports svg/png/pdf
    if ( format.compare( QLatin1String( "image/png" ), Qt::CaseInsensitive ) == 0 ||
         format.compare( QLatin1String( "png" ), Qt::CaseInsensitive ) == 0 )
    {
      format   = "png";
      contentType = "image/png";
    }
    else if ( format.compare( QLatin1String( "image/svg" ), Qt::CaseInsensitive ) == 0 ||
              format.compare( QLatin1String( "image/svg+xml" ), Qt::CaseInsensitive ) == 0 ||
              format.compare( QLatin1String( "svg" ), Qt::CaseInsensitive ) == 0 )
    {
      format   = "svg";
      contentType = "image/svg+xml";
    }
    else if ( format.compare( QLatin1String( "application/pdf" ), Qt::CaseInsensitive ) == 0 ||
              format.compare( QLatin1String( "pdf" ), Qt::CaseInsensitive ) == 0 )
    {
      format = "pdf";
      contentType = "application/pdf";
    }
    else
    {
      throw QgsServiceException( QStringLiteral( "InvalidFormat" ),
                                 QString( "Output format %1 is not supported by the GetPrint request" ).arg( format ) );
    }

    response.setHeader( QStringLiteral( "Content-Type" ), contentType );
    response.write( renderer.getPrint( format ) );
  }
Example #9
0
  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 )
  {
    // get wms parameters from query
    QgsWmsParameters parameters( QUrlQuery( request.url() ) );

    // prepare render context
    QgsWmsRenderContext context( project, serverIface );
    context.setFlag( QgsWmsRenderContext::AddQueryLayers );
    context.setFlag( QgsWmsRenderContext::UseFilter );
    context.setFlag( QgsWmsRenderContext::UseScaleDenominator );
    context.setFlag( QgsWmsRenderContext::SetAccessControl );
    context.setParameters( parameters );

    const QString infoFormat = request.parameters().value( QStringLiteral( "INFO_FORMAT" ), QStringLiteral( "text/plain" ) );
    response.setHeader( QStringLiteral( "Content-Type" ), infoFormat + QStringLiteral( "; charset=utf-8" ) );

    QgsRenderer renderer( context );
    response.write( renderer.getFeatureInfo( version ) );
  }
Example #11
0
  void writeGetCapabilities( QgsServerInterface* serverIface, const QString& version,
                             const QgsServerRequest& request, QgsServerResponse& response,
                             bool projectSettings )
  {
    QgsServerRequest::Parameters params = request.parameters();
    QString configFilePath = serverIface->configFilePath();
    QgsServerSettings* serverSettings = serverIface->serverSettings();
    QgsAccessControl* accessControl = serverIface->accessControls();
    QgsCapabilitiesCache* capabilitiesCache = serverIface->capabilitiesCache();

    QStringList cacheKeyList;
    cacheKeyList << ( projectSettings ? QStringLiteral( "projectSettings" ) : version );
    cacheKeyList << getenv( "SERVER_NAME" );
    bool cache = true;

    if ( accessControl )
      cache = accessControl->fillCacheKey( cacheKeyList );

    QString cacheKey = cacheKeyList.join( QStringLiteral( "-" ) );
    const QDomDocument* capabilitiesDocument = capabilitiesCache->searchCapabilitiesDocument( configFilePath, cacheKey );
    if ( !capabilitiesDocument ) //capabilities xml not in cache. Create a new one
    {
      QgsMessageLog::logMessage( QStringLiteral( "Capabilities document not found in cache" ) );
      QDomDocument doc;
      QgsWmsServer server( configFilePath,
                           *serverSettings,
                           params,
                           getConfigParser( serverIface ),
                           accessControl );

      doc = server.getCapabilities( version, projectSettings );

      if ( cache )
      {
        capabilitiesCache->insertCapabilitiesDocument( configFilePath, cacheKey, &doc );
        capabilitiesDocument = capabilitiesCache->searchCapabilitiesDocument( configFilePath, cacheKey );
      }
      else
      {
        doc = doc.cloneNode().toDocument();
        capabilitiesDocument = &doc;
      }
    }
    else
    {
      QgsMessageLog::logMessage( QStringLiteral( "Found capabilities document in cache" ) );
    }

    response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
    response.write( capabilitiesDocument->toByteArray() );
  }
Example #12
0
  void writeGetSchemaExtension( QgsServerInterface* serverIface, const QString& version,
                                const QgsServerRequest& request, QgsServerResponse& response )
  {
    Q_UNUSED( version );
    QgsServerRequest::Parameters params = request.parameters();

    QgsWmsServer server( serverIface->configFilePath(),
                         *serverIface->serverSettings(), params,
                         getConfigParser( serverIface ),
                         serverIface->accessControls() );

    QDomDocument doc = server.getSchemaExtension();
    response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
    response.write( doc.toByteArray() );
  }
  void writeGetLegendGraphics( QgsServerInterface *serverIface, const QgsProject *project,
                               const QString &version, const QgsServerRequest &request,
                               QgsServerResponse &response )
  {
    Q_UNUSED( version );

    QgsServerRequest::Parameters params = request.parameters();

    QgsWmsParameters wmsParameters( QUrlQuery( request.url() ) );
    QgsRenderer renderer( serverIface, project, wmsParameters );

    std::unique_ptr<QImage> result( renderer.getLegendGraphics() );

    if ( result )
    {
      QString format = params.value( QStringLiteral( "FORMAT" ), QStringLiteral( "PNG" ) );
      writeImage( response, *result,  format, renderer.getImageQuality() );
    }
    else
    {
      throw QgsServiceException( QStringLiteral( "UnknownError" ),
                                 QStringLiteral( "Failed to compute GetLegendGraphics image" ) );
    }
  }
  QDomDocument getSchemaExtension( QgsServerInterface *serverIface, const QString &version,
                                   const QgsServerRequest &request )
  {
    Q_UNUSED( version );
    Q_UNUSED( serverIface );

    QgsServerRequest::Parameters parameters = request.parameters();

    QDomDocument xsdDoc;

    QDir resourcesDir = QFileInfo( QgsApplication::serverResourcesPath() ).absoluteDir();
    QFileInfo xsdFileInfo( resourcesDir, QStringLiteral( "schemaExtension.xsd" ) );

    if ( !xsdFileInfo.exists() )
    {
      QgsMessageLog::logMessage( QStringLiteral( "Error, xsd file 'schemaExtension.xsd' does not exist" ),
                                 QStringLiteral( "Server" ), QgsMessageLog::CRITICAL );
      return xsdDoc;
    }

    QString xsdFilePath = xsdFileInfo.absoluteFilePath();
    QFile xsdFile( xsdFilePath );
    if ( !xsdFile.exists() )
    {
      QgsMessageLog::logMessage( QStringLiteral( "Error, xsd file 'schemaExtension.xsd' does not exist" ),
                                 QStringLiteral( "Server" ), QgsMessageLog::CRITICAL );
      return xsdDoc;
    }

    if ( !xsdFile.open( QIODevice::ReadOnly ) )
    {
      QgsMessageLog::logMessage( QStringLiteral( "Error, cannot open xsd file 'schemaExtension.xsd' does not exist" ),
                                 QStringLiteral( "Server" ), QgsMessageLog::CRITICAL );
      return xsdDoc;
    }

    QString errorMsg;
    int line, column;
    if ( !xsdDoc.setContent( &xsdFile, true, &errorMsg, &line, &column ) )
    {
      QgsMessageLog::logMessage( QStringLiteral( "Error parsing file 'schemaExtension.xsd" ) +
                                 QStringLiteral( "': parse error %1 at row %2, column %3" ).arg( errorMsg ).arg( line ).arg( column ),
                                 QStringLiteral( "Server" ), QgsMessageLog::CRITICAL );
    }

    return xsdDoc;
  }
Example #15
0
void writeGetCapabilities( QgsServerInterface* serverIface, const QString& version,
                           const QgsServerRequest& request, QgsServerResponse& response,
                           bool projectSettings )
{
    QString configFilePath = serverIface->configFilePath();
    QgsCapabilitiesCache* capabilitiesCache = serverIface->capabilitiesCache();

    QStringList cacheKeyList;
    cacheKeyList << ( projectSettings ? QStringLiteral( "projectSettings" ) : version );
    cacheKeyList << request.url().host();
    bool cache = true;

#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsAccessControl* accessControl = serverIface->accessControls();
    if ( accessControl )
        cache = accessControl->fillCacheKey( cacheKeyList );
#endif

    QString cacheKey = cacheKeyList.join( QStringLiteral( "-" ) );
    const QDomDocument* capabilitiesDocument = capabilitiesCache->searchCapabilitiesDocument( configFilePath, cacheKey );
    if ( !capabilitiesDocument ) //capabilities xml not in cache. Create a new one
    {
        QgsMessageLog::logMessage( QStringLiteral( "Capabilities document not found in cache" ) );
        QDomDocument doc;

        doc = getCapabilities( serverIface, version, request, projectSettings );

        if ( cache )
        {
            capabilitiesCache->insertCapabilitiesDocument( configFilePath, cacheKey, &doc );
            capabilitiesDocument = capabilitiesCache->searchCapabilitiesDocument( configFilePath, cacheKey );
        }
        else
        {
            doc = doc.cloneNode().toDocument();
            capabilitiesDocument = &doc;
        }
    }
    else
    {
        QgsMessageLog::logMessage( QStringLiteral( "Found capabilities document in cache" ) );
    }

    response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
    response.write( capabilitiesDocument->toByteArray() );
}
Example #16
0
      void executeRequest( const QgsServerRequest& request, QgsServerResponse& response,
                           const QgsProject* project )
      {
        QgsServerRequest::Parameters params = request.parameters();
        QString versionString = params.value( "VERSION" );

        // Set the default version
        if ( versionString.isEmpty() )
        {
          versionString = version(); // defined in qgswfsutils.h
        }

        // Get the request
        QString req = params.value( QStringLiteral( "REQUEST" ) );
        if ( req.isEmpty() )
        {
          throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
                                     QStringLiteral( "Please check the value of the REQUEST parameter" ) );
        }

        if ( QSTR_COMPARE( req, "GetCapabilities" ) )
        {
          writeGetCapabilities( mServerIface, project, versionString, request, response );
        }
        else if ( QSTR_COMPARE( req, "GetFeature" ) )
        {
          writeGetFeature( mServerIface, project, versionString, request, response );
        }
        else if ( QSTR_COMPARE( req, "DescribeFeatureType" ) )
        {
          writeDescribeFeatureType( mServerIface, versionString, request, response );
        }
        else if ( QSTR_COMPARE( req, "Transaction" ) )
        {
          writeTransaction( mServerIface, versionString, request, response );
        }
        else
        {
          // Operation not supported
          throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
                                     QStringLiteral( "Request %1 is not supported" ).arg( req ) );
        }
      }
Example #17
0
      void executeRequest( const QgsServerRequest &request, QgsServerResponse &response,
                           const QgsProject *project ) override
      {
        Q_UNUSED( project );

        const QgsWmtsParameters params( QUrlQuery( request.url() ) );

        // Set the default version
        QString versionString = params.version();
        if ( versionString.isEmpty() )
        {
          versionString = version(); // defined in qgswfsutils.h
        }

        // Get the request
        QString req = params.value( QgsServerParameter::name( QgsServerParameter::REQUEST ) );
        if ( req.isEmpty() )
        {
          throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
                                     QStringLiteral( "Please check the value of the REQUEST parameter" ), 501 );
        }

        if ( QSTR_COMPARE( req, "GetCapabilities" ) )
        {
          writeGetCapabilities( mServerIface, project, versionString, request, response );
        }
        else if ( QSTR_COMPARE( req, "GetTile" ) )
        {
          writeGetTile( mServerIface, project, versionString, request, response );
        }
        else if ( QSTR_COMPARE( req, "GetFeatureInfo" ) )
        {
          writeGetFeatureInfo( mServerIface, project, versionString, request, response );
        }
        else
        {
          // Operation not supported
          throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
                                     QStringLiteral( "Request %1 is not supported" ).arg( req ), 501 );
        }
      }
Example #18
0
  void writeGetLegendGraphics( QgsServerInterface* serverIface, const QString& version,
                               const QgsServerRequest& request, QgsServerResponse& response )
  {
    Q_UNUSED( version );

    QgsServerRequest::Parameters params = request.parameters();
    QgsRenderer renderer( serverIface, params, getConfigParser( serverIface ) );

    QScopedPointer<QImage> result( renderer.getLegendGraphics() );

    if ( !result.isNull() )
    {
      QString format = params.value( QStringLiteral( "FORMAT" ), QStringLiteral( "PNG" ) );
      writeImage( response, *result,  format, renderer.getImageQuality() );
    }
    else
    {
      throw QgsServiceException( QStringLiteral( "UnknownError" ),
                                 QStringLiteral( "Failed to compute GetLegendGraphics image" ) );
    }
  }
Example #19
0
  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 );
  }
Example #20
0
  QDomDocument getStyles( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
                          const QgsServerRequest &request )
  {
    Q_UNUSED( version );

    QgsServerRequest::Parameters parameters = request.parameters();

    QString layersName = parameters.value( "LAYERS" );

    if ( layersName.isEmpty() )
    {
      throw QgsBadRequestException( QgsServiceException::QGIS_MissingParameterValue,
                                    QgsWmsParameter::LAYERS );
    }

    QStringList layerList = layersName.split( ',', QString::SkipEmptyParts );
    if ( layerList.isEmpty() )
    {
      throw QgsBadRequestException( QgsServiceException::QGIS_MissingParameterValue,
                                    QgsWmsParameter::LAYERS );
    }

    return getStyledLayerDescriptorDocument( serverIface, project, layerList );
  }
Example #21
0
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 );
  }
}
Example #22
0
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 );
  }
}
  QDomDocument createDescribeFeatureTypeDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
      const QgsServerRequest &request )
  {
    Q_UNUSED( version );

    QDomDocument doc;

    QgsServerRequest::Parameters parameters = request.parameters();
    QgsWfsParameters wfsParameters( parameters );
    QgsWfsParameters::Format oFormat = wfsParameters.outputFormat();

    // test oFormat
    if ( oFormat == QgsWfsParameters::Format::NONE )
      throw QgsBadRequestException( QStringLiteral( "Invalid WFS Parameter" ),
                                    "OUTPUTFORMAT " + wfsParameters.outputFormatAsString() + "is not supported" );

    QgsAccessControl *accessControl = serverIface->accessControls();

    //xsd:schema
    QDomElement schemaElement = doc.createElement( QStringLiteral( "schema" )/*xsd:schema*/ );
    schemaElement.setAttribute( QStringLiteral( "xmlns" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema" ) );
    schemaElement.setAttribute( QStringLiteral( "xmlns:xsd" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema" ) );
    schemaElement.setAttribute( QStringLiteral( "xmlns:ogc" ), OGC_NAMESPACE );
    schemaElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
    schemaElement.setAttribute( QStringLiteral( "xmlns:qgs" ), QGS_NAMESPACE );
    schemaElement.setAttribute( QStringLiteral( "targetNamespace" ), QGS_NAMESPACE );
    schemaElement.setAttribute( QStringLiteral( "elementFormDefault" ), QStringLiteral( "qualified" ) );
    schemaElement.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0" ) );
    doc.appendChild( schemaElement );

    //xsd:import
    QDomElement importElement = doc.createElement( QStringLiteral( "import" )/*xsd:import*/ );
    importElement.setAttribute( QStringLiteral( "namespace" ),  GML_NAMESPACE );
    if ( oFormat == QgsWfsParameters::Format::GML2 )
      importElement.setAttribute( QStringLiteral( "schemaLocation" ), QStringLiteral( "http://schemas.opengis.net/gml/2.1.2/feature.xsd" ) );
    else if ( oFormat == QgsWfsParameters::Format::GML3 )
      importElement.setAttribute( QStringLiteral( "schemaLocation" ), QStringLiteral( "http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" ) );
    schemaElement.appendChild( importElement );

    QStringList typeNameList;
    QDomDocument queryDoc;
    QString errorMsg;
    if ( queryDoc.setContent( parameters.value( QStringLiteral( "REQUEST_BODY" ) ), true, &errorMsg ) )
    {
      //read doc
      QDomElement queryDocElem = queryDoc.documentElement();
      QDomNodeList docChildNodes = queryDocElem.childNodes();
      if ( docChildNodes.size() )
      {
        for ( int i = 0; i < docChildNodes.size(); i++ )
        {
          QDomElement docChildElem = docChildNodes.at( i ).toElement();
          if ( docChildElem.tagName() == QLatin1String( "TypeName" ) )
          {
            QString typeName = docChildElem.text().trimmed();
            if ( typeName.contains( ':' ) )
              typeNameList << typeName.section( ':', 1, 1 );
            else
              typeNameList << typeName;
          }
        }
      }
    }
    else
    {
      QString typeNames = request.parameter( QStringLiteral( "TYPENAME" ) );
      if ( !typeNames.isEmpty() )
      {
        QStringList typeNameSplit = typeNames.split( ',' );
        for ( int i = 0; i < typeNameSplit.size(); ++i )
        {
          QString typeName = typeNameSplit.at( i ).trimmed();
          if ( typeName.contains( ':' ) )
            typeNameList << typeName.section( ':', 1, 1 );
          else
            typeNameList << typeName;
        }
      }
    }

    QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
    for ( int i = 0; i < wfsLayerIds.size(); ++i )
    {
      QgsMapLayer *layer = project->mapLayer( wfsLayerIds.at( i ) );
      if ( layer->type() != QgsMapLayer::LayerType::VectorLayer )
      {
        continue;
      }

      QString name = layer->name();
      if ( !layer->shortName().isEmpty() )
        name = layer->shortName();
      name = name.replace( ' ', '_' );

      if ( !typeNameList.isEmpty() && !typeNameList.contains( name ) )
      {
        continue;
      }

      if ( accessControl && !accessControl->layerReadPermission( layer ) )
      {
        if ( !typeNameList.isEmpty() )
        {
          throw QgsSecurityAccessException( QStringLiteral( "Feature access permission denied" ) );
        }
        else
        {
          continue;
        }
      }

      QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( layer );
      QgsVectorDataProvider *provider = vLayer->dataProvider();
      if ( !provider )
      {
        continue;
      }
      setSchemaLayer( schemaElement, doc, const_cast<QgsVectorLayer *>( vLayer ) );
    }
    return doc;
  }
  QDomDocument createDescribeCoverageDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
      const QgsServerRequest &request )
  {
    Q_UNUSED( version );

    QDomDocument doc;

    QgsServerRequest::Parameters parameters = request.parameters();

#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsAccessControl *accessControl = serverIface->accessControls();
#endif

    //wcs:WCS_Capabilities element
    QDomElement coveDescElement = doc.createElement( QStringLiteral( "CoverageDescription" )/*wcs:CoverageDescription*/ );
    coveDescElement.setAttribute( QStringLiteral( "xmlns" ), WCS_NAMESPACE );
    coveDescElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    coveDescElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/describeCoverage.xsd" );
    coveDescElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
    coveDescElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
    coveDescElement.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) );
    coveDescElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) );
    doc.appendChild( coveDescElement );

    //defining coverage name
    QString coveNames;
    //read COVERAGE
    QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "COVERAGE" ) );
    if ( cove_name_it != parameters.constEnd() )
    {
      coveNames = cove_name_it.value();
    }
    if ( coveNames.isEmpty() )
    {
      QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "IDENTIFIER" ) );
      if ( cove_name_it != parameters.constEnd() )
      {
        coveNames = cove_name_it.value();
      }
    }

    QStringList coveNameList;
    if ( !coveNames.isEmpty() )
    {
      coveNameList = coveNames.split( ',' );
      for ( int i = 0; i < coveNameList.size(); ++i )
      {
        coveNameList.replace( i, coveNameList.at( i ).trimmed() );
      }
    }

    QStringList wcsLayersId = QgsServerProjectUtils::wcsLayerIds( *project );
    for ( int i = 0; i < wcsLayersId.size(); ++i )
    {
      QgsMapLayer *layer = project->mapLayer( wcsLayersId.at( i ) );
      if ( !layer )
      {
        continue;
      }
      if ( layer->type() != QgsMapLayer::LayerType::RasterLayer )
      {
        continue;
      }
#ifdef HAVE_SERVER_PYTHON_PLUGINS
      if ( !accessControl->layerReadPermission( layer ) )
      {
        continue;
      }
#endif
      QString name = layer->name();
      if ( !layer->shortName().isEmpty() )
        name = layer->shortName();
      name = name.replace( ' ', '_' );

      if ( coveNameList.size() == 0 || coveNameList.contains( name ) )
      {
        QgsRasterLayer *rLayer = qobject_cast<QgsRasterLayer *>( layer );
        coveDescElement.appendChild( getCoverageOffering( doc, const_cast<QgsRasterLayer *>( rLayer ), project ) );
      }
    }
    return doc;
  }
Example #25
0
QDomDocument getCapabilities( QgsServerInterface* serverIface, const QString& version,
                              const QgsServerRequest& request, bool projectSettings )
{
    QDomDocument doc;
    QDomElement wmsCapabilitiesElement;

    QgsWmsConfigParser* configParser = getConfigParser( serverIface );

    QgsServerRequest::Parameters parameters = request.parameters();

    // Get service URL
    QUrl href = serviceUrl( request, configParser );

    //href needs to be a prefix
    QString hrefString = href.toString( QUrl::FullyDecoded );
    hrefString.append( href.hasQuery() ? "&" : "?" );

    // XML declaration
    QDomProcessingInstruction xmlDeclaration = doc.createProcessingInstruction( QStringLiteral( "xml" ),
            QStringLiteral( "version=\"1.0\" encoding=\"utf-8\"" ) );

    // Append format helper
    std::function < void ( QDomElement&, const QString& ) > appendFormat = [&doc]( QDomElement & elem, const QString & format )
    {
        QDomElement formatElem = doc.createElement( QStringLiteral( "Format" )/*wms:Format*/ );
        formatElem.appendChild( doc.createTextNode( format ) );
        elem.appendChild( formatElem );
    };

    if ( version == QLatin1String( "1.1.1" ) )
    {
        doc = QDomDocument( QStringLiteral( "WMT_MS_Capabilities SYSTEM 'http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd'" ) );  //WMS 1.1.1 needs DOCTYPE  "SYSTEM http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd"
        doc.appendChild( xmlDeclaration );
        wmsCapabilitiesElement = doc.createElement( QStringLiteral( "WMT_MS_Capabilities" )/*wms:WMS_Capabilities*/ );
    }
    else // 1.3.0 as default
    {
        doc.appendChild( xmlDeclaration );
        wmsCapabilitiesElement = doc.createElement( QStringLiteral( "WMS_Capabilities" )/*wms:WMS_Capabilities*/ );
        wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns" ), QStringLiteral( "http://www.opengis.net/wms" ) );
        wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:sld" ), QStringLiteral( "http://www.opengis.net/sld" ) );
        wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:qgs" ), QStringLiteral( "http://www.qgis.org/wms" ) );
        wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
        QString schemaLocation = QStringLiteral( "http://www.opengis.net/wms" );
        schemaLocation += QLatin1String( " http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd" );
        schemaLocation += QLatin1String( " http://www.opengis.net/sld" );
        schemaLocation += QLatin1String( " http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd" );
        schemaLocation += QLatin1String( " http://www.qgis.org/wms" );
        if ( configParser && configParser->wmsInspireActivated() )
        {
            wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:inspire_common" ), QStringLiteral( "http://inspire.ec.europa.eu/schemas/common/1.0" ) );
            wmsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:inspire_vs" ), QStringLiteral( "http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" ) );
            schemaLocation += QLatin1String( " http://inspire.ec.europa.eu/schemas/inspire_vs/1.0" );
            schemaLocation += QLatin1String( " http://inspire.ec.europa.eu/schemas/inspire_vs/1.0/inspire_vs.xsd" );
        }

        schemaLocation += " " + hrefString + "SERVICE=WMS&REQUEST=GetSchemaExtension";
        wmsCapabilitiesElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), schemaLocation );
    }
    wmsCapabilitiesElement.setAttribute( QStringLiteral( "version" ), version );
    doc.appendChild( wmsCapabilitiesElement );

    configParser->serviceCapabilities( wmsCapabilitiesElement, doc );

    //wms:Capability element
    QDomElement capabilityElement = doc.createElement( QStringLiteral( "Capability" )/*wms:Capability*/ );
    wmsCapabilitiesElement.appendChild( capabilityElement );
    //wms:Request element
    QDomElement requestElement = doc.createElement( QStringLiteral( "Request" )/*wms:Request*/ );
    capabilityElement.appendChild( requestElement );

    QDomElement dcpTypeElement = doc.createElement( QStringLiteral( "DCPType" )/*wms:DCPType*/ );
    QDomElement httpElement = doc.createElement( QStringLiteral( "HTTP" )/*wms:HTTP*/ );
    dcpTypeElement.appendChild( httpElement );

    QDomElement elem;

    //wms:GetCapabilities
    elem = doc.createElement( QStringLiteral( "GetCapabilities" )/*wms:GetCapabilities*/ );
    appendFormat( elem, ( version == QLatin1String( "1.1.1" ) ? "application/vnd.ogc.wms_xml" : "text/xml" ) );
    elem.appendChild( dcpTypeElement );
    requestElement.appendChild( elem );

    // SOAP platform
    //only give this information if it is not a WMS request to be in sync with the WMS capabilities schema
    // XXX Not even sure that cam be ever true
    if ( parameters.value( QStringLiteral( "SERVICE" ) ).compare( QLatin1String( "WMS" ), Qt::CaseInsensitive ) != 0 )
    {
        QDomElement soapElement = doc.createElement( QStringLiteral( "SOAP" )/*wms:SOAP*/ );
        httpElement.appendChild( soapElement );
        QDomElement soapResourceElement = doc.createElement( QStringLiteral( "OnlineResource" )/*wms:OnlineResource*/ );
        soapResourceElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
        soapResourceElement.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
        soapResourceElement.setAttribute( QStringLiteral( "xlink:href" ), hrefString );
        soapElement.appendChild( soapResourceElement );
    }

    //only Get supported for the moment
    QDomElement getElement = doc.createElement( QStringLiteral( "Get" )/*wms:Get*/ );
    httpElement.appendChild( getElement );
    QDomElement olResourceElement = doc.createElement( QStringLiteral( "OnlineResource" )/*wms:OnlineResource*/ );
    olResourceElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
    olResourceElement.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
    olResourceElement.setAttribute( QStringLiteral( "xlink:href" ), hrefString );
    getElement.appendChild( olResourceElement );

    //wms:GetMap
    elem = doc.createElement( QStringLiteral( "GetMap" )/*wms:GetMap*/ );
    appendFormat( elem, QStringLiteral( "image/jpeg" ) );
    appendFormat( elem, QStringLiteral( "image/png" ) );
    appendFormat( elem, QStringLiteral( "image/png; mode=16bit" ) );
    appendFormat( elem, QStringLiteral( "image/png; mode=8bit" ) );
    appendFormat( elem, QStringLiteral( "image/png; mode=1bit" ) );
    appendFormat( elem, QStringLiteral( "application/dxf" ) );
    elem.appendChild( dcpTypeElement.cloneNode().toElement() ); //this is the same as for 'GetCapabilities'
    requestElement.appendChild( elem );

    //wms:GetFeatureInfo
    elem = doc.createElement( QStringLiteral( "GetFeatureInfo" ) );
    appendFormat( elem, QStringLiteral( "text/plain" ) );
    appendFormat( elem, QStringLiteral( "text/html" ) );
    appendFormat( elem, QStringLiteral( "text/xml" ) );
    appendFormat( elem, QStringLiteral( "application/vnd.ogc.gml" ) );
    appendFormat( elem, QStringLiteral( "application/vnd.ogc.gml/3.1.1" ) );
    elem.appendChild( dcpTypeElement.cloneNode().toElement() ); //this is the same as for 'GetCapabilities'
    requestElement.appendChild( elem );

    //wms:GetLegendGraphic
    elem = doc.createElement(( version == QLatin1String( "1.1.1" ) ? "GetLegendGraphic" : "sld:GetLegendGraphic" )/*wms:GetLegendGraphic*/ );
    appendFormat( elem, QStringLiteral( "image/jpeg" ) );
    appendFormat( elem, QStringLiteral( "image/png" ) );
    elem.appendChild( dcpTypeElement.cloneNode().toElement() ); // this is the same as for 'GetCapabilities'
    requestElement.appendChild( elem );

    //wms:DescribeLayer
    elem = doc.createElement(( version == QLatin1String( "1.1.1" ) ? "DescribeLayer" : "sld:DescribeLayer" )/*wms:GetLegendGraphic*/ );
    appendFormat( elem, QStringLiteral( "text/xml" ) );
    elem.appendChild( dcpTypeElement.cloneNode().toElement() ); // this is the same as for 'GetCapabilities'
    requestElement.appendChild( elem );

    //wms:GetStyles
    elem = doc.createElement(( version == QLatin1String( "1.1.1" ) ? "GetStyles" : "qgs:GetStyles" )/*wms:GetStyles*/ );
    appendFormat( elem, QStringLiteral( "text/xml" ) );
    elem.appendChild( dcpTypeElement.cloneNode().toElement() ); //this is the same as for 'GetCapabilities'
    requestElement.appendChild( elem );

    if ( projectSettings ) //remove composer templates from GetCapabilities in the long term
    {
        //wms:GetPrint
        elem = doc.createElement( QStringLiteral( "GetPrint" ) /*wms:GetPrint*/ );
        appendFormat( elem, QStringLiteral( "svg" ) );
        appendFormat( elem, QStringLiteral( "png" ) );
        appendFormat( elem, QStringLiteral( "pdf" ) );
        elem.appendChild( dcpTypeElement.cloneNode().toElement() ); //this is the same as for 'GetCapabilities'
        requestElement.appendChild( elem );
    }

    //Exception element is mandatory
    elem = doc.createElement( QStringLiteral( "Exception" ) );
    appendFormat( elem, ( version == QLatin1String( "1.1.1" ) ? "application/vnd.ogc.se_xml" : "XML" ) );
    capabilityElement.appendChild( elem );

    //UserDefinedSymbolization element
    if ( version == QLatin1String( "1.3.0" ) )
    {
        elem = doc.createElement( QStringLiteral( "sld:UserDefinedSymbolization" ) );
        elem.setAttribute( QStringLiteral( "SupportSLD" ), QStringLiteral( "1" ) );
        elem.setAttribute( QStringLiteral( "UserLayer" ), QStringLiteral( "0" ) );
        elem.setAttribute( QStringLiteral( "UserStyle" ), QStringLiteral( "1" ) );
        elem.setAttribute( QStringLiteral( "RemoteWFS" ), QStringLiteral( "0" ) );
        elem.setAttribute( QStringLiteral( "InlineFeature" ), QStringLiteral( "0" ) );
        elem.setAttribute( QStringLiteral( "RemoteWCS" ), QStringLiteral( "0" ) );
        capabilityElement.appendChild( elem );

        if ( configParser->wmsInspireActivated() )
        {
            configParser->inspireCapabilities( capabilityElement, doc );
        }
    }

    if ( projectSettings )
    {
        //Insert <ComposerTemplate> elements derived from wms:_ExtendedCapabilities
        configParser->printCapabilities( capabilityElement, doc );

        //WFS layers
        QStringList wfsLayers = configParser->wfsLayerNames();
        if ( !wfsLayers.isEmpty() )
        {
            QDomElement wfsLayersElem = doc.createElement( QStringLiteral( "WFSLayers" ) );
            for ( auto wfsIt = wfsLayers.constBegin() ; wfsIt != wfsLayers.constEnd(); ++wfsIt )
            {
                QDomElement wfsLayerElem = doc.createElement( QStringLiteral( "WFSLayer" ) );
                wfsLayerElem.setAttribute( QStringLiteral( "name" ), *wfsIt );
                wfsLayersElem.appendChild( wfsLayerElem );
            }
            capabilityElement.appendChild( wfsLayersElem );
        }
    }

    //add the xml content for the individual layers/styles
    configParser->layersAndStylesCapabilities( capabilityElement, doc, version, projectSettings );

    return doc;
}
Example #26
0
  QDomDocument createTransactionDocument( QgsServerInterface* serverIface, const QString& version,
                                          const QgsServerRequest& request )
  {
    Q_UNUSED( version );

    QDomDocument doc;

    QgsWfsProjectParser* configParser = getConfigParser( serverIface );
#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsAccessControl* accessControl = serverIface->accessControls();
#endif
    const QString requestBody = request.getParameter( QStringLiteral( "REQUEST_BODY" ) );

    QString errorMsg;
    if ( !doc.setContent( requestBody, true, &errorMsg ) )
    {
      throw QgsRequestNotWellFormedException( errorMsg );
    }

    QDomElement docElem = doc.documentElement();
    QDomNodeList docChildNodes = docElem.childNodes();

    // Re-organize the transaction document
    QDomDocument mDoc;
    QDomElement mDocElem = mDoc.createElement( QStringLiteral( "myTransactionDocument" ) );
    mDocElem.setAttribute( QStringLiteral( "xmlns" ), QGS_NAMESPACE );
    mDocElem.setAttribute( QStringLiteral( "xmlns:wfs" ), WFS_NAMESPACE );
    mDocElem.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
    mDocElem.setAttribute( QStringLiteral( "xmlns:ogc" ), OGC_NAMESPACE );
    mDocElem.setAttribute( QStringLiteral( "xmlns:qgs" ), QGS_NAMESPACE );
    mDocElem.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    mDoc.appendChild( mDocElem );

    QDomElement actionElem;
    QString actionName;
    QDomElement typeNameElem;
    QString typeName;

    for ( int i = docChildNodes.count(); 0 < i; --i )
    {
      actionElem = docChildNodes.at( i - 1 ).toElement();
      actionName = actionElem.localName();

      if ( actionName == QLatin1String( "Insert" ) )
      {
        QDomElement featureElem = actionElem.firstChild().toElement();
        typeName = featureElem.localName();
      }
      else if ( actionName == QLatin1String( "Update" ) )
      {
        typeName = actionElem.attribute( QStringLiteral( "typeName" ) );
      }
      else if ( actionName == QLatin1String( "Delete" ) )
      {
        typeName = actionElem.attribute( QStringLiteral( "typeName" ) );
      }

      if ( typeName.contains( QLatin1String( ":" ) ) )
        typeName = typeName.section( QStringLiteral( ":" ), 1, 1 );

      QDomNodeList typeNameList = mDocElem.elementsByTagName( typeName );
      if ( typeNameList.count() == 0 )
      {
        typeNameElem = mDoc.createElement( typeName );
        mDocElem.appendChild( typeNameElem );
      }
      else
        typeNameElem = typeNameList.at( 0 ).toElement();

      typeNameElem.appendChild( actionElem );
    }

    // It's time to make the transaction
    // Create the response document
    QDomDocument resp;
    //wfs:WFS_TransactionRespone element
    QDomElement respElem = resp.createElement( QStringLiteral( "WFS_TransactionResponse" )/*wfs:WFS_TransactionResponse*/ );
    respElem.setAttribute( QStringLiteral( "xmlns" ), WFS_NAMESPACE );
    respElem.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    respElem.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WFS_NAMESPACE + " http://schemas.opengis.net/wfs/1.0.0/wfs.xsd" );
    respElem.setAttribute( QStringLiteral( "xmlns:ogc" ), OGC_NAMESPACE );
    respElem.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) );
    resp.appendChild( respElem );

    // Store the created feature id for WFS
    QStringList insertResults;
    // Get the WFS layers id
    QStringList wfsLayersId = configParser->wfsLayers();;

    QList<QgsMapLayer*> layerList;
    QgsMapLayer* currentLayer = nullptr;

    // Loop through the layer transaction elements
    docChildNodes = mDocElem.childNodes();
    for ( int i = 0; i < docChildNodes.count(); ++i )
    {
      // Get the vector layer
      typeNameElem = docChildNodes.at( i ).toElement();
      typeName = typeNameElem.tagName();

      layerList = configParser->mapLayerFromTypeName( typeName );
      // Could be empty!
      if ( layerList.count() > 0 )
      {
        currentLayer = layerList.at( 0 );
      }
      else
      {
        throw QgsRequestNotWellFormedException( QStringLiteral( "Wrong TypeName: %1" ).arg( typeName ) );
      }

      QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( currentLayer );
      // it's a vectorlayer and defined by the administrator as a WFS layer
      if ( layer && wfsLayersId.contains( layer->id() ) )
      {
#ifdef HAVE_SERVER_PYTHON_PLUGINS
        if ( actionName == QLatin1String( "Insert" ) )
        {
          if ( !accessControl->layerInsertPermission( layer ) )
          {
            throw QgsSecurityAccessException( QStringLiteral( "Feature insert permission denied" ) );
          }
        }
        else if ( actionName == QLatin1String( "Update" ) )
        {
          if ( !accessControl->layerUpdatePermission( layer ) )
          {
            throw QgsSecurityAccessException( QStringLiteral( "Feature update permission denied" ) );
          }
        }
        else if ( actionName == QLatin1String( "Delete" ) )
        {
          if ( !accessControl->layerDeletePermission( layer ) )
          {
            throw QgsSecurityAccessException( QStringLiteral( "Feature delete permission denied" ) );
          }
        }
#endif

        // Get the provider and it's capabilities
        QgsVectorDataProvider* provider = layer->dataProvider();
        if ( !provider )
        {
          continue;
        }

        int cap = provider->capabilities();

        // Start the update transaction
        layer->startEditing();
        if (( cap & QgsVectorDataProvider::ChangeAttributeValues ) && ( cap & QgsVectorDataProvider::ChangeGeometries ) )
        {
          // Loop through the update elements for this layer
          QDomNodeList upNodeList = typeNameElem.elementsByTagNameNS( WFS_NAMESPACE, QStringLiteral( "Update" ) );
          for ( int j = 0; j < upNodeList.count(); ++j )
          {
            if ( !configParser->wfstUpdateLayers().contains( layer->id() ) )
            {
              //no wfs permissions to do updates
              QString errorMsg = "No permissions to do WFS updates on layer '" + layer->name() + "'";
              QgsMessageLog::logMessage( errorMsg, QStringLiteral( "Server" ), QgsMessageLog::CRITICAL );
              addTransactionResult( resp, respElem, QStringLiteral( "FAILED" ), QStringLiteral( "Update" ), errorMsg );
              return resp;
            }

            actionElem = upNodeList.at( j ).toElement();

            // Get the Feature Ids for this filter on the layer
            QDomElement filterElem = actionElem.elementsByTagName( QStringLiteral( "Filter" ) ).at( 0 ).toElement();
            QgsFeatureIds fids = getFeatureIdsFromFilter( filterElem, layer );

            // Loop through the property elements
            // Store properties and the geometry element
            QDomNodeList propertyNodeList = actionElem.elementsByTagName( QStringLiteral( "Property" ) );
            QMap<QString, QString> propertyMap;
            QDomElement propertyElem;
            QDomElement nameElem;
            QDomElement valueElem;
            QDomElement geometryElem;

            for ( int l = 0; l < propertyNodeList.count(); ++l )
            {
              propertyElem = propertyNodeList.at( l ).toElement();
              nameElem = propertyElem.elementsByTagName( QStringLiteral( "Name" ) ).at( 0 ).toElement();
              valueElem = propertyElem.elementsByTagName( QStringLiteral( "Value" ) ).at( 0 ).toElement();
              if ( nameElem.text() != QLatin1String( "geometry" ) )
              {
                propertyMap.insert( nameElem.text(), valueElem.text() );
              }
              else
              {
                geometryElem = valueElem;
              }
            }

            // Update the features
            QgsFields fields = provider->fields();
            QMap<QString, int> fieldMap = provider->fieldNameMap();
            QMap<QString, int>::const_iterator fieldMapIt;
            QString fieldName;
            bool conversionSuccess;

            QgsFeatureIds::const_iterator fidIt = fids.constBegin();
            for ( ; fidIt != fids.constEnd(); ++fidIt )
            {
#ifdef HAVE_SERVER_PYTHON_PLUGINS
              QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest( *fidIt ) );
              QgsFeature feature;
              while ( fit.nextFeature( feature ) )
              {
                if ( !accessControl->allowToEdit( layer, feature ) )
                {
                  throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) );
                }
              }
#endif

              QMap< QString, QString >::const_iterator it = propertyMap.constBegin();
              for ( ; it != propertyMap.constEnd(); ++it )
              {
                fieldName = it.key();
                fieldMapIt = fieldMap.find( fieldName );
                if ( fieldMapIt == fieldMap.constEnd() )
                {
                  continue;
                }
                QgsField field = fields.at( fieldMapIt.value() );
                if ( field.type() == 2 )
                  layer->changeAttributeValue( *fidIt, fieldMapIt.value(), it.value().toInt( &conversionSuccess ) );
                else if ( field.type() == 6 )
                  layer->changeAttributeValue( *fidIt, fieldMapIt.value(), it.value().toDouble( &conversionSuccess ) );
                else
                  layer->changeAttributeValue( *fidIt, fieldMapIt.value(), it.value() );
              }

              if ( !geometryElem.isNull() )
              {
                QgsGeometry g = QgsOgcUtils::geometryFromGML( geometryElem );
                if ( !layer->changeGeometry( *fidIt, g ) )
                {
                  throw QgsRequestNotWellFormedException( QStringLiteral( "Error in change geometry" ) );
                }
              }

#ifdef HAVE_SERVER_PYTHON_PLUGINS
              fit = layer->getFeatures( QgsFeatureRequest( *fidIt ) );
              while ( fit.nextFeature( feature ) )
              {
                if ( !accessControl->allowToEdit( layer, feature ) )
                {
                  layer->rollBack();
                  throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) );
                }
              }
#endif
            }
          }
        }
        // Commit the changes of the update elements
        if ( !layer->commitChanges() )
        {
          addTransactionResult( resp, respElem, QStringLiteral( "PARTIAL" ), QStringLiteral( "Update" ), layer->commitErrors().join( QStringLiteral( "\n  " ) ) );
          return resp;
        }
        // Start the delete transaction
        layer->startEditing();
        if (( cap & QgsVectorDataProvider::DeleteFeatures ) )
        {
          // Loop through the delete elements
          QDomNodeList delNodeList = typeNameElem.elementsByTagNameNS( WFS_NAMESPACE, QStringLiteral( "Delete" ) );
          for ( int j = 0; j < delNodeList.count(); ++j )
          {
            if ( !configParser->wfstDeleteLayers().contains( layer->id() ) )
            {
              //no wfs permissions to do updates
              QString errorMsg = "No permissions to do WFS deletes on layer '" + layer->name() + "'";
              QgsMessageLog::logMessage( errorMsg, QStringLiteral( "Server" ), QgsMessageLog::CRITICAL );
              addTransactionResult( resp, respElem, QStringLiteral( "FAILED" ), QStringLiteral( "Delete" ), errorMsg );
              return resp;
            }

            actionElem = delNodeList.at( j ).toElement();
            QDomElement filterElem = actionElem.firstChild().toElement();
            // Get Feature Ids for the Filter element
            QgsFeatureIds fids = getFeatureIdsFromFilter( filterElem, layer );

#ifdef HAVE_SERVER_PYTHON_PLUGINS
            QgsFeatureIds::const_iterator fidIt = fids.constBegin();
            for ( ; fidIt != fids.constEnd(); ++fidIt )
            {
              QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest( *fidIt ) );
              QgsFeature feature;
              while ( fit.nextFeature( feature ) )
              {
                if ( !accessControl->allowToEdit( layer, feature ) )
                {
                  throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) );
                }
              }
            }
#endif

            layer->selectByIds( fids );
            layer->deleteSelectedFeatures();
          }
        }
        // Commit the changes of the delete elements
        if ( !layer->commitChanges() )
        {
          addTransactionResult( resp, respElem, QStringLiteral( "PARTIAL" ), QStringLiteral( "Delete" ), layer->commitErrors().join( QStringLiteral( "\n  " ) ) );
          return resp;
        }

        // Store the inserted features
        QgsFeatureList inFeatList;
        if ( cap & QgsVectorDataProvider::AddFeatures )
        {
          // Get Layer Field Information
          QgsFields fields = provider->fields();
          QMap<QString, int> fieldMap = provider->fieldNameMap();
          QMap<QString, int>::const_iterator fieldMapIt;

          // Loop through the insert elements
          QDomNodeList inNodeList = typeNameElem.elementsByTagNameNS( WFS_NAMESPACE, QStringLiteral( "Insert" ) );
          for ( int j = 0; j < inNodeList.count(); ++j )
          {
            if ( !configParser->wfstInsertLayers().contains( layer->id() ) )
            {
              //no wfs permissions to do updates
              QString errorMsg = "No permissions to do WFS inserts on layer '" + layer->name() + "'";
              QgsMessageLog::logMessage( errorMsg, QStringLiteral( "Server" ), QgsMessageLog::CRITICAL );
              addTransactionResult( resp, respElem, QStringLiteral( "FAILED" ), QStringLiteral( "Insert" ), errorMsg );
              return resp;
            }

            actionElem = inNodeList.at( j ).toElement();
            // Loop through the feature element
            QDomNodeList featNodes = actionElem.childNodes();
            for ( int l = 0; l < featNodes.count(); l++ )
            {
              // Add the feature to the layer
              // and store it to put it's Feature Id in the response
              inFeatList << QgsFeature( fields );

              // Create feature for this layer
              QDomElement featureElem = featNodes.at( l ).toElement();

              QDomNode currentAttributeChild = featureElem.firstChild();

              while ( !currentAttributeChild.isNull() )
              {
                QDomElement currentAttributeElement = currentAttributeChild.toElement();
                QString attrName = currentAttributeElement.localName();

                if ( attrName != QLatin1String( "boundedBy" ) )
                {
                  if ( attrName != QLatin1String( "geometry" ) ) //a normal attribute
                  {
                    fieldMapIt = fieldMap.find( attrName );
                    if ( fieldMapIt == fieldMap.constEnd() )
                    {
                      continue;
                    }
                    QgsField field = fields.at( fieldMapIt.value() );
                    QString attrValue = currentAttributeElement.text();
                    int attrType = field.type();
                    QgsMessageLog::logMessage( QStringLiteral( "attr: name=%1 idx=%2 value=%3" ).arg( attrName ).arg( fieldMapIt.value() ).arg( attrValue ) );
                    if ( attrType == QVariant::Int )
                      inFeatList.last().setAttribute( fieldMapIt.value(), attrValue.toInt() );
                    else if ( attrType == QVariant::Double )
                      inFeatList.last().setAttribute( fieldMapIt.value(), attrValue.toDouble() );
                    else
                      inFeatList.last().setAttribute( fieldMapIt.value(), attrValue );
                  }
                  else //a geometry attribute
                  {
                    QgsGeometry g = QgsOgcUtils::geometryFromGML( currentAttributeElement );
                    inFeatList.last().setGeometry( g );
                  }
                }
                currentAttributeChild = currentAttributeChild.nextSibling();
              }
            }
          }
        }
#ifdef HAVE_SERVER_PYTHON_PLUGINS
        QgsFeatureList::iterator featureIt = inFeatList.begin();
        while ( featureIt != inFeatList.end() )
        {
          if ( !accessControl->allowToEdit( layer, *featureIt ) )
          {
            throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) );
          }
          featureIt++;
        }
#endif

        // add the features
        if ( !provider->addFeatures( inFeatList ) )
        {
          addTransactionResult( resp, respElem, QStringLiteral( "Partial" ), QStringLiteral( "Insert" ), layer->commitErrors().join( QStringLiteral( "\n  " ) ) );
          if ( provider->hasErrors() )
          {
            provider->clearErrors();
          }
          return resp;
        }
        // Get the Feature Ids of the inserted feature
        for ( int j = 0; j < inFeatList.size(); j++ )
        {
          insertResults << typeName + "." + QString::number( inFeatList[j].id() );
        }
      }
    }

    // Put the Feature Ids of the inserted feature
    if ( !insertResults.isEmpty() )
    {
      Q_FOREACH ( const QString &fidStr, insertResults )
      {
        QDomElement irElem = doc.createElement( QStringLiteral( "InsertResult" ) );
        QDomElement fiElem = doc.createElement( QStringLiteral( "ogc:FeatureId" ) );
        fiElem.setAttribute( QStringLiteral( "fid" ), fidStr );
        irElem.appendChild( fiElem );
        respElem.appendChild( irElem );
      }
  // DescribeLayer is defined for WMS1.1.1/SLD1.0 and in WMS 1.3.0 SLD Extension
  QDomDocument describeLayer( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
                              const QgsServerRequest &request )
  {
    Q_UNUSED( version );

    QgsServerRequest::Parameters parameters = request.parameters();

    if ( !parameters.contains( QStringLiteral( "SLD_VERSION" ) ) )
    {
      throw QgsServiceException( QStringLiteral( "MissingParameterValue" ),
                                 QStringLiteral( "SLD_VERSION is mandatory for DescribeLayer operation" ), 400 );
    }
    if ( parameters[ QStringLiteral( "SLD_VERSION" )] != QLatin1String( "1.1.0" ) )
    {
      throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ),
                                 QStringLiteral( "SLD_VERSION = %1 is not supported" ).arg( parameters[ QStringLiteral( "SLD_VERSION" )] ), 400 );
    }

    if ( !parameters.contains( QStringLiteral( "LAYERS" ) ) )
    {
      throw QgsServiceException( QStringLiteral( "MissingParameterValue" ),
                                 QStringLiteral( "LAYERS is mandatory for DescribeLayer operation" ), 400 );
    }

    QStringList layersList = parameters[ QStringLiteral( "LAYERS" )].split( ',', QString::SkipEmptyParts );
    if ( layersList.isEmpty() )
    {
      throw QgsServiceException( QStringLiteral( "InvalidParameterValue" ), QStringLiteral( "Layers is empty" ), 400 );
    }
    QDomDocument myDocument = QDomDocument();

    QDomNode header = myDocument.createProcessingInstruction( QStringLiteral( "xml" ), QStringLiteral( "version=\"1.0\" encoding=\"UTF-8\"" ) );
    myDocument.appendChild( header );

    // Create the root element
    QDomElement root = myDocument.createElementNS( QStringLiteral( "http://www.opengis.net/sld" ), QStringLiteral( "DescribeLayerResponse" ) );
    root.setAttribute( QStringLiteral( "xsi:schemaLocation" ), QStringLiteral( "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/DescribeLayer.xsd" ) );
    root.setAttribute( QStringLiteral( "xmlns:ows" ), QStringLiteral( "http://www.opengis.net/ows" ) );
    root.setAttribute( QStringLiteral( "xmlns:se" ), QStringLiteral( "http://www.opengis.net/se" ) );
    root.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
    root.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
    myDocument.appendChild( root );

    // store the Version element
    QDomElement versionNode = myDocument.createElement( QStringLiteral( "Version" ) );
    versionNode.appendChild( myDocument.createTextNode( QStringLiteral( "1.1.0" ) ) );
    root.appendChild( versionNode );

    // get the wms service url defined in project or keep the one from the
    // request url
    QString wmsHrefString = serviceUrl( request, project ).toString();

    // get the wfs service url defined in project or take the same as the
    // wms service url
    QString wfsHrefString = QgsServerProjectUtils::wfsServiceUrl( *project );
    if ( wfsHrefString.isEmpty() )
    {
      wfsHrefString = wmsHrefString;
    }

    // get the wcs service url defined in project or take the same as the
    // wms service url
    QString wcsHrefString = QgsServerProjectUtils::wcsServiceUrl( *project );
    if ( wcsHrefString.isEmpty() )
    {
      wcsHrefString = wmsHrefString;
    }

    // access control
#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsAccessControl *accessControl = serverIface->accessControls();
#endif
    // Use layer ids
    bool useLayerIds = QgsServerProjectUtils::wmsUseLayerIds( *project );
    // WMS restricted layers
    QStringList restrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers( *project );
    // WFS layers
    QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
    // WCS layers
    QStringList wcsLayerIds = QgsServerProjectUtils::wcsLayerIds( *project );

    for ( QgsMapLayer *layer : project->mapLayers() )
    {
      QString name = layer->name();
      if ( useLayerIds )
        name = layer->id();
      else if ( !layer->shortName().isEmpty() )
        name = layer->shortName();

      if ( !layersList.contains( name ) )
      {
        continue;
      }

      //unpublished layer
      if ( restrictedLayers.contains( layer->name() ) )
      {
        throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
      }

#ifdef HAVE_SERVER_PYTHON_PLUGINS
      if ( accessControl && !accessControl->layerReadPermission( layer ) )
      {
        throw QgsSecurityException( QStringLiteral( "You are not allowed to access to this layer" ) );
      }
#endif

      // Create the NamedLayer element
      QDomElement layerNode = myDocument.createElement( QStringLiteral( "LayerDescription" ) );
      root.appendChild( layerNode );

      // store the owsType element
      QDomElement typeNode = myDocument.createElement( QStringLiteral( "owsType" ) );
      // store the se:OnlineResource element
      QDomElement oResNode = myDocument.createElement( QStringLiteral( "se:OnlineResource" ) );
      oResNode.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
      // store the TypeName element
      QDomElement nameNode = myDocument.createElement( QStringLiteral( "TypeName" ) );
      switch ( layer->type() )
      {
        case QgsMapLayer::VectorLayer:
        {
          typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wfs" ) ) );

          if ( wfsLayerIds.indexOf( layer->id() ) != -1 )
          {
            oResNode.setAttribute( QStringLiteral( "xlink:href" ), wfsHrefString );
          }

          // store the se:FeatureTypeName element
          QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:FeatureTypeName" ) );
          typeNameNode.appendChild( myDocument.createTextNode( name ) );
          nameNode.appendChild( typeNameNode );
          break;
        }
        case QgsMapLayer::RasterLayer:
        {
          typeNode.appendChild( myDocument.createTextNode( QStringLiteral( "wcs" ) ) );

          if ( wcsLayerIds.indexOf( layer->id() ) != -1 )
          {
            oResNode.setAttribute( QStringLiteral( "xlink:href" ), wcsHrefString );
          }

          // store the se:CoverageTypeName element
          QDomElement typeNameNode = myDocument.createElement( QStringLiteral( "se:CoverageTypeName" ) );
          typeNameNode.appendChild( myDocument.createTextNode( name ) );
          nameNode.appendChild( typeNameNode );
          break;
        }

        case QgsMapLayer::MeshLayer:
        case QgsMapLayer::PluginLayer:
          break;
      }
      layerNode.appendChild( typeNode );
      layerNode.appendChild( oResNode );
      layerNode.appendChild( nameNode );
    }

    return myDocument;
  }