mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
[Server][FEATURE] Handle request from QgsServer with a QgsProject
With this commit, it's posssible to handle a request from a QgsProject without writing it to the disk. ```python server = QgsServer() project = QgsProject() vlayer = QgsVectorLayer("/path/to/shapefile/file.shp", "layer_name_you_like", "ogr") project.addMapLayer(vlayer) query_string = 'https://www.qgis.org/?SERVICE=WMS&VERSION=1.3&REQUEST=GetCapabilities' request = QgsBufferServerRequest(query_string, QgsServerRequest.GetMethod, {}, data) response = QgsBufferServerResponse() server.handleRequest(request, response, project) ```
This commit is contained in:
parent
13a00aae30
commit
7b455d8700
@ -35,7 +35,7 @@ class QgsServer
|
||||
.. versionadded:: 2.14
|
||||
%End
|
||||
|
||||
void handleRequest( QgsServerRequest &request, QgsServerResponse &response );
|
||||
void handleRequest( QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project = 0 );
|
||||
%Docstring
|
||||
Handles the request.
|
||||
The query string is normally read from environment
|
||||
@ -44,6 +44,9 @@ class QgsServer
|
||||
|
||||
\param request a QgsServerRequest holding request parameters
|
||||
\param response a QgsServerResponse for handling response I/O)
|
||||
\param project a QgsProject or None, if it is None the project
|
||||
is created from the MAP param specified in request or from
|
||||
the QGIS_PROJECT_FILE setting
|
||||
%End
|
||||
|
||||
|
||||
|
@ -300,8 +300,7 @@ void QgsServer::putenv( const QString &var, const QString &val )
|
||||
* @param queryString
|
||||
* @return response headers and body
|
||||
*/
|
||||
|
||||
void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &response )
|
||||
void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project )
|
||||
{
|
||||
QgsMessageLog::MessageLevel logLevel = QgsServerLogger::instance()->logLevel();
|
||||
QTime time; //used for measuring request time if loglevel < 1
|
||||
@ -346,16 +345,23 @@ void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &res
|
||||
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" ) );
|
||||
}
|
||||
QString configFilePath = configPath( *sConfigFilePath, parameterMap );
|
||||
|
||||
sServerInterface->setConfigFilePath( configFilePath );
|
||||
// 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() );
|
||||
}
|
||||
|
||||
//Service parameter
|
||||
QString serviceString = parameterMap.value( QStringLiteral( "SERVICE" ) );
|
||||
|
@ -75,8 +75,11 @@ class SERVER_EXPORT QgsServer
|
||||
*
|
||||
* \param request a QgsServerRequest holding request parameters
|
||||
* \param response a QgsServerResponse for handling response I/O)
|
||||
* \param project a QgsProject or nullptr, if it is nullptr the project
|
||||
* is created from the MAP param specified in request or from
|
||||
* the QGIS_PROJECT_FILE setting
|
||||
*/
|
||||
void handleRequest( QgsServerRequest &request, QgsServerResponse &response );
|
||||
void handleRequest( QgsServerRequest &request, QgsServerResponse &response, const QgsProject *project = nullptr );
|
||||
|
||||
|
||||
//! Returns a pointer to the server interface
|
||||
|
@ -214,6 +214,17 @@ class QgsServerTestBase(unittest.TestCase):
|
||||
headers.append(("%s: %s" % (k, rh[k])).encode('utf-8'))
|
||||
return b"\n".join(headers) + b"\n\n", bytes(response.body())
|
||||
|
||||
def _execute_request_project(self, qs, project, requestMethod=QgsServerRequest.GetMethod, data=None):
|
||||
request = QgsBufferServerRequest(qs, requestMethod, {}, data)
|
||||
response = QgsBufferServerResponse()
|
||||
self.server.handleRequest(request, response, project)
|
||||
headers = []
|
||||
rh = response.headers()
|
||||
rk = sorted(rh.keys())
|
||||
for k in rk:
|
||||
headers.append(("%s: %s" % (k, rh[k])).encode('utf-8'))
|
||||
return b"\n".join(headers) + b"\n\n", bytes(response.body())
|
||||
|
||||
|
||||
class TestQgsServerTestBase(unittest.TestCase):
|
||||
|
||||
@ -285,6 +296,16 @@ class TestQgsServer(QgsServerTestBase):
|
||||
self.assertEqual(response.headers(), {'Content-Length': '54', 'Content-Type': 'text/xml; charset=utf-8'})
|
||||
self.assertEqual(response.statusCode(), 500)
|
||||
|
||||
def test_requestHandlerProject(self):
|
||||
"""Test request handler with none project"""
|
||||
headers = {'header-key-1': 'header-value-1', 'header-key-2': 'header-value-2'}
|
||||
request = QgsBufferServerRequest('http://somesite.com/somepath', QgsServerRequest.GetMethod, headers)
|
||||
response = QgsBufferServerResponse()
|
||||
self.server.handleRequest(request, response, None)
|
||||
self.assertEqual(bytes(response.body()), b'<ServerException>Project file error</ServerException>\n')
|
||||
self.assertEqual(response.headers(), {'Content-Length': '54', 'Content-Type': 'text/xml; charset=utf-8'})
|
||||
self.assertEqual(response.statusCode(), 500)
|
||||
|
||||
def test_api(self):
|
||||
"""Using an empty query string (returns an XML exception)
|
||||
we are going to test if headers and body are returned correctly"""
|
||||
|
@ -32,6 +32,7 @@ from qgis.PyQt.QtCore import QSize
|
||||
import osgeo.gdal # NOQA
|
||||
|
||||
from test_qgsserver import QgsServerTestBase
|
||||
from qgis.core import QgsProject
|
||||
|
||||
# Strip path and content length because path may vary
|
||||
RE_STRIP_UNCHECKABLE = b'MAP=[^"]+|Content-Length: \d+'
|
||||
@ -196,6 +197,31 @@ class TestQgsServerWMS(QgsServerTestBase):
|
||||
'',
|
||||
'getschemaextension')
|
||||
|
||||
def wms_request_compare_project(self, request, extra=None, reference_file=None):
|
||||
projectPath = self.testdata_path + "test_project.qgs"
|
||||
assert os.path.exists(projectPath), "Project file not found: " + projectPath
|
||||
|
||||
project = QgsProject()
|
||||
project.read(projectPath)
|
||||
|
||||
query_string = 'https://www.qgis.org/?SERVICE=WMS&VERSION=1.3&REQUEST=%s' % (request)
|
||||
if extra is not None:
|
||||
query_string += extra
|
||||
header, body = self._execute_request_project(query_string, project)
|
||||
response = header + body
|
||||
reference_path = self.testdata_path + (request.lower() if not reference_file else reference_file) + '.txt'
|
||||
self.store_reference(reference_path, response)
|
||||
f = open(reference_path, 'rb')
|
||||
expected = f.read()
|
||||
f.close()
|
||||
response = re.sub(RE_STRIP_UNCHECKABLE, b'*****', response)
|
||||
expected = re.sub(RE_STRIP_UNCHECKABLE, b'*****', expected)
|
||||
|
||||
self.assertXMLEqual(response, expected, msg="request %s failed.\nQuery: %s\nExpected file: %s\nResponse:\n%s" % (query_string, request, reference_path, response.decode('utf-8')))
|
||||
|
||||
def test_wms_getcapabilities_project(self):
|
||||
self.wms_request_compare_project('GetCapabilities')
|
||||
|
||||
def wms_inspire_request_compare(self, request):
|
||||
"""WMS INSPIRE tests"""
|
||||
project = self.testdata_path + "test_project_inspire.qgs"
|
||||
|
Loading…
x
Reference in New Issue
Block a user