Ejemplo n.º 1
0
  /**
   * Output WCS  GetCapabilities response
   */
  void writeGetCapabilities( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
                             const QgsServerRequest &request, QgsServerResponse &response )
  {
#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsAccessControl *accessControl = serverIface->accessControls();
#endif
    QDomDocument doc;
    const QDomDocument *capabilitiesDocument = nullptr;

#ifdef HAVE_SERVER_PYTHON_PLUGINS
    QgsServerCacheManager *cacheManager = serverIface->cacheManager();
    if ( cacheManager && cacheManager->getCachedDocument( &doc, project, request, accessControl ) )
    {
      capabilitiesDocument = &doc;
    }
    else //capabilities xml not in cache. Create a new one
    {
      doc = createGetCapabilitiesDocument( serverIface, project, version, request );

      if ( cacheManager )
      {
        cacheManager->setCachedDocument( &doc, project, request, accessControl );
      }
      capabilitiesDocument = &doc;
    }
#else
    doc = createGetCapabilitiesDocument( serverIface, project, version, request );
#endif
    response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
    response.write( capabilitiesDocument->toByteArray() );
  }
Ejemplo n.º 2
0
  /**
   * Output WCS DescribeCoverage response
   */
  void writeDescribeCoverage( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
                              const QgsServerRequest &request, QgsServerResponse &response )
  {
    QgsAccessControl *accessControl = nullptr;
#ifdef HAVE_SERVER_PYTHON_PLUGINS
    accessControl = serverIface->accessControls();
#endif
    QDomDocument doc;
    const QDomDocument *describeDocument = nullptr;

    QgsServerCacheManager *cacheManager = nullptr;
#ifdef HAVE_SERVER_PYTHON_PLUGINS
    cacheManager = serverIface->cacheManager();
#endif
    if ( cacheManager && cacheManager->getCachedDocument( &doc, project, request, accessControl ) )
    {
      describeDocument = &doc;
    }
    else //describe feature xml not in cache. Create a new one
    {
      doc = createDescribeCoverageDocument( serverIface, project, version, request );

      if ( cacheManager )
      {
        cacheManager->setCachedDocument( &doc, project, request, accessControl );
      }
      describeDocument = &doc;
    }

    response.setHeader( "Content-Type", "text/xml; charset=utf-8" );
    response.write( describeDocument->toByteArray() );
  }
Ejemplo n.º 3
0
 void writeGetSchemaExtension( QgsServerInterface* serverIface, const QString& version,
                               const QgsServerRequest& request, QgsServerResponse& response )
 {
   QDomDocument doc = getSchemaExtension( serverIface, version, request );
   response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
   response.write( doc.toByteArray() );
 }
Ejemplo n.º 4
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 );
  }
Ejemplo n.º 5
0
 void writeDescribeLayer( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
                          const QgsServerRequest &request, QgsServerResponse &response )
 {
   QDomDocument doc = describeLayer( serverIface, project, version, request );
   response.setHeader( QStringLiteral( "Content-Type" ), QStringLiteral( "text/xml; charset=utf-8" ) );
   response.write( doc.toByteArray() );
 }
Ejemplo n.º 6
0
  // Write image response
  void writeImage( QgsServerResponse &response, QImage &img, const QString &formatStr,
                   int imageQuality )
  {
    ImageOutputFormat outputFormat = parseImageFormat( formatStr );
    QImage  result;
    QString saveFormat;
    QString contentType;
    switch ( outputFormat )
    {
      case PNG:
        result = img;
        contentType = "image/png";
        saveFormat = "PNG";
        break;
      case PNG8:
      {
        QVector<QRgb> colorTable;
        medianCut( colorTable, 256, img );
        result = img.convertToFormat( QImage::Format_Indexed8, colorTable,
                                      Qt::ColorOnly | Qt::ThresholdDither |
                                      Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection );
      }
      contentType = "image/png";
      saveFormat = "PNG";
      break;
      case PNG16:
        result = img.convertToFormat( QImage::Format_ARGB4444_Premultiplied );
        contentType = "image/png";
        saveFormat = "PNG";
        break;
      case PNG1:
        result = img.convertToFormat( QImage::Format_Mono,
                                      Qt::MonoOnly | Qt::ThresholdDither |
                                      Qt::ThresholdAlphaDither | Qt::NoOpaqueDetection );
        contentType = "image/png";
        saveFormat = "PNG";
        break;
      case JPEG:
        result = img;
        contentType = "image/jpeg";
        saveFormat = "JPEG";
        break;
      default:
        QgsMessageLog::logMessage( QString( "Unsupported format string %1" ).arg( formatStr ) );
        saveFormat = UNKN;
        break;
    }

    if ( outputFormat != UNKN )
    {
      response.setHeader( "Content-Type", contentType );
      result.save( response.io(), qPrintable( saveFormat ), imageQuality );
    }
    else
    {
      throw QgsServiceException( "InvalidFormat",
                                 QString( "Output format '%1' is not supported in the GetMap request" ).arg( formatStr ) );
    }
  }
Ejemplo n.º 7
0
  /**
   * Output WFS  GetCapabilities response
   */
  void writeGetCapabilities( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
                             const QgsServerRequest &request, QgsServerResponse &response )
  {
    QDomDocument doc = createGetCapabilitiesDocument( serverIface, project, version, request );

    response.setHeader( "Content-Type", "text/xml; charset=utf-8" );
    response.write( doc.toByteArray() );
  }
Ejemplo n.º 8
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 );
    }
  }
Ejemplo n.º 9
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() );
  }
Ejemplo n.º 10
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() );
  }
Ejemplo n.º 11
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() );
}
Ejemplo n.º 12
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 ) );
  }
Ejemplo n.º 13
0
  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 ) );
  }
Ejemplo n.º 14
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 );
  }
}
Ejemplo n.º 15
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 );
  }
}