1 /***************************************************************************
2                               qgs_map_serv.cpp
3  A server application supporting WMS / WFS / WCS
4                               -------------------
5   begin                : July 04, 2006
6   copyright            : (C) 2006 by Marco Hugentobler & Ionut Iosifescu Enescu
7   email                : marco dot hugentobler at karto dot baug dot ethz dot ch
8  ***************************************************************************/
9 
10 /***************************************************************************
11  *                                                                         *
12  *   This program is free software; you can redistribute it and/or modify  *
13  *   it under the terms of the GNU General Public License as published by  *
14  *   the Free Software Foundation; either version 2 of the License, or     *
15  *   (at your option) any later version.                                   *
16  *                                                                         *
17  ***************************************************************************/
18 
19 //for CMAKE_INSTALL_PREFIX
20 #include "qgsconfig.h"
21 #include "qgsserver.h"
22 #include "qgsfcgiserverresponse.h"
23 #include "qgsfcgiserverrequest.h"
24 #include "qgsapplication.h"
25 #include "qgscommandlineutils.h"
26 
27 #include <fcgi_stdio.h>
28 #include <cstdlib>
29 
30 #include <QFontDatabase>
31 #include <QString>
32 
fcgi_accept()33 int fcgi_accept()
34 {
35 #ifdef Q_OS_WIN
36   if ( FCGX_IsCGI() )
37     return FCGI_Accept();
38   else
39     return FCGX_Accept( &FCGI_stdin->fcgx_stream, &FCGI_stdout->fcgx_stream, &FCGI_stderr->fcgx_stream, &environ );
40 #else
41   return FCGI_Accept();
42 #endif
43 }
44 
main(int argc,char * argv[])45 int main( int argc, char *argv[] )
46 {
47   if ( argc >= 2 )
48   {
49     if ( argv[1] == QLatin1String( "--version" ) || argv[1] == QLatin1String( "-v" ) )
50     {
51       std::cout << QgsCommandLineUtils::allVersions().toStdString();
52       return 0;
53     }
54   }
55 
56   // Test if the environ variable DISPLAY is defined
57   // if it's not, the server is running in offscreen mode
58   // Qt supports using various QPA (Qt Platform Abstraction) back ends
59   // for rendering. You can specify the back end to use with the environment
60   // variable QT_QPA_PLATFORM when invoking a Qt-based application.
61   // Available platform plugins are: directfbegl, directfb, eglfs, linuxfb,
62   // minimal, minimalegl, offscreen, wayland-egl, wayland, xcb.
63   // https://www.ics.com/blog/qt-tips-and-tricks-part-1
64   // http://doc.qt.io/qt-5/qpa.html
65   const char *display = getenv( "DISPLAY" );
66   bool withDisplay = true;
67   if ( !display )
68   {
69     withDisplay = false;
70     qputenv( "QT_QPA_PLATFORM", "offscreen" );
71     QgsMessageLog::logMessage( "DISPLAY not set, running in offscreen mode, all printing capabilities will not be available.", "Server", Qgis::MessageLevel::Info );
72   }
73   // since version 3.0 QgsServer now needs a qApp so initialize QgsApplication
74   const QgsApplication app( argc, argv, withDisplay, QString(), QStringLiteral( "server" ) );
75   QgsServer server;
76 #ifdef HAVE_SERVER_PYTHON_PLUGINS
77   server.initPython();
78 #endif
79 
80 #ifdef Q_OS_WIN
81   // Initialize font database before fcgi_accept.
82   // When using FCGI with IIS, environment variables (QT_QPA_FONTDIR in this case) are lost after fcgi_accept().
83   QFontDatabase fontDB;
84 #endif
85 
86   // Starts FCGI loop
87   while ( fcgi_accept() >= 0 )
88   {
89     QgsFcgiServerRequest  request;
90     QgsFcgiServerResponse response( request.method() );
91     if ( ! request.hasError() )
92     {
93       server.handleRequest( request, response );
94     }
95     else
96     {
97       response.sendError( 400, "Bad request" );
98     }
99   }
100   app.exitQgis();
101   return 0;
102 }
103 
104