Skip to content

Commit

Permalink
fix server access control tests on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
jef-n committed Jan 7, 2016
1 parent a2a1b79 commit f8f056e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 58 deletions.
37 changes: 30 additions & 7 deletions python/server/qgsserver.sip
@@ -1,11 +1,11 @@
/***************************************************************************
qgsserver.sip
Qgis Mapserver
-------------------
QGIS Server main class.
-------------------
begin : 2015-05-21
copyright : (C) 2015 by Alessandro Pasotti
email : a dot pasotti at itopen dot it
***************************************************************************/
***************************************************************************/

/***************************************************************************
* *
Expand Down Expand Up @@ -161,10 +161,33 @@ class QgsServer
public:
QgsServer();
~QgsServer();
// Original init for the fcgi application:
//void init( int argc, char* argv[] );
// init for python bindings:
void init( );
/** Server initialisation: intialise QGIS ang QT core application.
* This method is automatically called by handleRequest if it wasn't
* explicitly called before
* @note Not available in Python bindings
*/
//void init( int argc, char ** argv );
//! The following is mainly for python bindings, that do not pass argc/argv
void init();

/** Set environment variable
* @param var environment variable name
* @param val value
* @note added in 2.14
*/
void putenv( const QString &var, const QString &val );

/** Handles the request. The output is normally printed trough FCGI printf
* by the request handler or, in case the server has been invoked from python
* bindings, a flag is set that captures all the output headers and body, instead
* of printing it returns the output as a QPair of QByteArray.
* The query string is normally read from environment
* but can be also passed in args and in this case overrides the environment
* variable
*
* @param queryString optional QString containing the query string
* @return the response headers and body QPair of QByteArray if called from python bindings, empty otherwise
*/
QPair<QByteArray, QByteArray> handleRequest( const QString queryString = QString( ) );
/* The following code was used to test type conversion in python bindings
QPair<QByteArray, QByteArray> testQPair( QPair<QByteArray, QByteArray> pair );
Expand Down
7 changes: 5 additions & 2 deletions src/server/qgsmslayercache.cpp
Expand Up @@ -23,8 +23,10 @@

QgsMSLayerCache* QgsMSLayerCache::instance()
{
static QgsMSLayerCache mInstance;
return &mInstance;
static QgsMSLayerCache *mInstance = 0;
if ( !mInstance )
mInstance = new QgsMSLayerCache();
return mInstance;
}

QgsMSLayerCache::QgsMSLayerCache()
Expand Down Expand Up @@ -52,6 +54,7 @@ QgsMSLayerCache::~QgsMSLayerCache()
{
delete entry.layerPointer;
}
mEntries.clear();
}

void QgsMSLayerCache::insertLayer( const QString& url, const QString& layerName, QgsMapLayer* layer, const QString& configFile, const QList<QString>& tempFiles )
Expand Down
17 changes: 9 additions & 8 deletions src/server/qgsserver.cpp
Expand Up @@ -420,7 +420,14 @@ bool QgsServer::init( int & argc, char ** argv )
return true;
}


void QgsServer::putenv( const QString &var, const QString &val )
{
#ifdef _MSC_VER
_putenv_s( var.toUtf8().data(), val.toUtf8().data() );
#else
setenv( var.toUtf8().data(), val.toUtf8().data(), 1 );
#endif
}

/**
* @brief Handles the request
Expand All @@ -441,13 +448,7 @@ QPair<QByteArray, QByteArray> QgsServer::handleRequest( const QString& queryStri
* to handleRequest without using os.environment
*/
if ( ! queryString.isEmpty() )
{
#ifdef _MSC_VER
_putenv_s( "QUERY_STRING", queryString.toUtf8().data() );
#else
setenv( "QUERY_STRING", queryString.toUtf8().data(), 1 );
#endif
}
putenv( "QUERY_STRING", queryString );

int logLevel = QgsServerLogger::instance()->logLevel();
QTime time; //used for measuring request time if loglevel < 1
Expand Down
7 changes: 7 additions & 0 deletions src/server/qgsserver.h
Expand Up @@ -58,6 +58,13 @@ class SERVER_EXPORT QgsServer
//! The following is mainly for python bindings, that do not pass argc/argv
static bool init();

/** Set environment variable
* @param var environment variable name
* @param val value
* @note added in 2.14
*/
void putenv( const QString &var, const QString &val );

/** Handles the request. The output is normally printed trough FCGI printf
* by the request handler or, in case the server has been invoked from python
* bindings, a flag is set that captures all the output headers and body, instead
Expand Down
81 changes: 40 additions & 41 deletions tests/src/python/test_qgsserver_accesscontrol.py
Expand Up @@ -170,7 +170,6 @@ def setUp(self):

self.projectPath = os.path.join(self.testdata_path, "project.qgs")
self.assertTrue(os.path.isfile(self.projectPath), 'Could not find project file "{}"'.format(self.projectPath))
self.projectPath = urllib.quote(self.projectPath)

def tearDown(self):
copyfile(os.path.join(self.testdata_path, "_helloworld.db"), os.path.join(self.testdata_path, "helloworld.db"))
Expand All @@ -179,7 +178,7 @@ def tearDown(self):

def test_wms_getcapabilities(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetCapabilities"
Expand All @@ -203,7 +202,7 @@ def test_wms_getcapabilities(self):

def test_wms_describelayer_hello(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "DescribeLayer",
Expand All @@ -223,7 +222,7 @@ def test_wms_describelayer_hello(self):

def test_wms_describelayer_country(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "DescribeLayer",
Expand All @@ -243,7 +242,7 @@ def test_wms_describelayer_country(self):

def test_wms_getlegendgraphic_hello(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetLegendGraphic",
Expand All @@ -259,7 +258,7 @@ def test_wms_getlegendgraphic_hello(self):

def test_wms_getlegendgraphic_country(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetLegendGraphic",
Expand All @@ -281,7 +280,7 @@ def test_wms_getlegendgraphic_country(self):

def test_wms_getmap(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
Expand All @@ -298,7 +297,7 @@ def test_wms_getmap(self):
self._img_diff_error(response, headers, "WMS_GetMap")

query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
Expand All @@ -314,7 +313,7 @@ def test_wms_getmap(self):
self._img_diff_error(response, headers, "Restricted_WMS_GetMap")

query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
Expand All @@ -337,7 +336,7 @@ def test_wms_getmap(self):

def test_wms_getfeatureinfo_hello(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetFeatureInfo",
Expand Down Expand Up @@ -376,7 +375,7 @@ def test_wms_getfeatureinfo_hello(self):

def test_wms_getfeatureinfo_hello2(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetFeatureInfo",
Expand Down Expand Up @@ -406,7 +405,7 @@ def test_wms_getfeatureinfo_hello2(self):

def test_wms_getfeatureinfo_country(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetFeatureInfo",
Expand Down Expand Up @@ -438,7 +437,7 @@ def test_wms_getfeatureinfo_country(self):

def test_wfs_getcapabilities(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WFS",
"VERSION": "1.1.0",
"REQUEST": "GetCapabilities"
Expand All @@ -462,7 +461,7 @@ def test_wfs_getcapabilities(self):

def test_wfs_describefeaturetype_hello(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WFS",
"VERSION": "1.1.0",
"REQUEST": "DescribeFeatureType",
Expand All @@ -481,7 +480,7 @@ def test_wfs_describefeaturetype_hello(self):

def test_wfs_describefeaturetype_country(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WFS",
"VERSION": "1.1.0",
"REQUEST": "DescribeFeatureType",
Expand Down Expand Up @@ -569,7 +568,7 @@ def test_wfs_getfeature_country(self):

def test_wcs_getcapabilities(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WCS",
"VERSION": "1.0.0",
"REQUEST": "GetCapabilities",
Expand All @@ -586,7 +585,7 @@ def test_wcs_getcapabilities(self):
"No dem layer in WCS/GetCapabilities\n%s" % response)

query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WCS",
"VERSION": "1.0.0",
"REQUEST": "GetCapabilities",
Expand All @@ -600,7 +599,7 @@ def test_wcs_getcapabilities(self):

def test_wcs_describecoverage(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WCS",
"VERSION": "1.0.0",
"REQUEST": "DescribeCoverage",
Expand All @@ -618,7 +617,7 @@ def test_wcs_describecoverage(self):
"No dem layer in DescribeCoverage\n%s" % response)

query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WCS",
"VERSION": "1.0.0",
"REQUEST": "DescribeCoverage",
Expand All @@ -633,7 +632,7 @@ def test_wcs_describecoverage(self):

def test_wcs_getcoverage(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WCS",
"VERSION": "1.0.0",
"REQUEST": "GetCoverage",
Expand Down Expand Up @@ -662,7 +661,7 @@ def test_wcs_getcoverage(self):
"Image for GetCoverage is wrong")

query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WCS",
"VERSION": "1.0.0",
"REQUEST": "GetCoverage",
Expand Down Expand Up @@ -829,7 +828,7 @@ def test_wfstransaction_delete_restricted(self):
# # WMS # # WMS # # WMS # #
def test_wms_getmap_subsetstring(self):
query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
Expand All @@ -846,7 +845,7 @@ def test_wms_getmap_subsetstring(self):
self._img_diff_error(response, headers, "WMS_GetMap")

query_string = "&".join(["%s=%s" % i for i in {
"MAP": self.projectPath,
"MAP": urllib.quote(self.projectPath),
"SERVICE": "WMS",
"VERSION": "1.1.1",
"REQUEST": "GetMap",
Expand Down Expand Up @@ -879,7 +878,7 @@ def test_wms_getfeatureinfo_subsetstring(self):
"INFO_FORMAT": "application/vnd.ogc.gml",
"X": "56",
"Y": "144",
"MAP": self.projectPath
"MAP": urllib.quote(self.projectPath)
}.items()])

response, headers = self._get_fullaccess(query_string)
Expand Down Expand Up @@ -915,7 +914,7 @@ def test_wms_getfeatureinfo_subsetstring2(self):
"INFO_FORMAT": "application/vnd.ogc.gml",
"X": "146",
"Y": "160",
"MAP": self.projectPath
"MAP": urllib.quote(self.projectPath)
}.items()])

response, headers = self._get_fullaccess(query_string)
Expand Down Expand Up @@ -997,35 +996,35 @@ def _result(self, data):
return data[1], headers

def _get_fullaccess(self, query_string):
os.environ["REQUEST_METHOD"] = "GET"
server.putenv("REQUEST_METHOD", "GET")
result = self._handle_request(False, query_string)
del os.environ["REQUEST_METHOD"]
server.putenv("REQUEST_METHOD", '')
return result

def _get_restricted(self, query_string):
os.environ["REQUEST_METHOD"] = "GET"
server.putenv("REQUEST_METHOD", "GET")
result = self._handle_request(True, query_string)
del os.environ["REQUEST_METHOD"]
server.putenv("REQUEST_METHOD", '')
return result

def _post_fullaccess(self, data, query_string=None):
os.environ["REQUEST_METHOD"] = "POST"
os.environ["REQUEST_BODY"] = data
os.environ["QGIS_PROJECT_FILE"] = self.projectPath
server.putenv("REQUEST_METHOD", "POST")
server.putenv("REQUEST_BODY", data)
server.putenv("QGIS_PROJECT_FILE", self.projectPath)
result = self._handle_request(False, query_string)
del os.environ["REQUEST_METHOD"]
del os.environ["REQUEST_BODY"]
del os.environ["QGIS_PROJECT_FILE"]
server.putenv("REQUEST_METHOD", '')
server.putenv("REQUEST_BODY", '')
server.putenv("QGIS_PROJECT_FILE", '')
return result

def _post_restricted(self, data, query_string=None):
os.environ["REQUEST_METHOD"] = "POST"
os.environ["REQUEST_BODY"] = data
os.environ["QGIS_PROJECT_FILE"] = self.projectPath
server.putenv("REQUEST_METHOD", "POST")
server.putenv("REQUEST_BODY", data)
server.putenv("QGIS_PROJECT_FILE", self.projectPath)
result = self._handle_request(True, query_string)
del os.environ["REQUEST_METHOD"]
del os.environ["REQUEST_BODY"]
del os.environ["QGIS_PROJECT_FILE"]
server.putenv("REQUEST_METHOD", '')
server.putenv("REQUEST_BODY", '')
server.putenv("QGIS_PROJECT_FILE", '')
return result

def _img_diff(self, image, control_image, max_diff, max_size_diff=QSize()):
Expand Down

0 comments on commit f8f056e

Please sign in to comment.