Skip to content
Permalink
Browse files
Server OGC API handler: make it more robust in path matching
  • Loading branch information
elpaso authored and nyalldawson committed Nov 1, 2021
1 parent 8bc90ce commit 9990ad2c92b75baedfe64d986e5558bdcad6c2b4
@@ -259,6 +259,14 @@ Set the content types to ``contentTypes``
%End


QString handlerPath( const QgsServerApiContext &context ) const;
%Docstring
Returns the handler component of the URL path, i.e. the part of the path that comes
after the API path.

.. versionadded:: 3.22
%End

};

/************************************************************************
@@ -46,7 +46,7 @@ QVariantMap QgsServerOgcApiHandler::values( const QgsServerApiContext &context )
// value() calls the validators and throws an exception if validation fails
result[p.name()] = p.value( context );
}
const auto sanitizedPath { QgsServerOgcApi::sanitizeUrl( context.request()->url() ).path() };
const auto sanitizedPath { QgsServerOgcApi::sanitizeUrl( handlerPath( context ) ).path() };
const auto match { path().match( sanitizedPath ) };
if ( match.hasMatch() )
{
@@ -139,7 +139,7 @@ std::string QgsServerOgcApiHandler::href( const QgsServerApiContext &context, co
{
QUrl url { context.request()->url() };
QString urlBasePath { context.matchedPath() };
const auto match { path().match( url.path() ) };
const auto match { path().match( handlerPath( context ) ) };
if ( match.captured().count() > 0 )
{
url.setPath( urlBasePath + match.captured( 0 ) );
@@ -598,3 +598,17 @@ void QgsServerOgcApiHandler::setContentTypes( const QList<QgsServerOgcApi::Conte
{
mContentTypes = contentTypes;
}

QString QgsServerOgcApiHandler::handlerPath( const QgsServerApiContext &context ) const
{
const QUrl url { context.request()->url() };
const QString urlBasePath { context.matchedPath() };
if ( ! urlBasePath.isEmpty() )
{
return url.path().mid( urlBasePath.length() );
}
else
{
return url.path();
}
}
@@ -387,6 +387,14 @@ class SERVER_EXPORT QgsServerOgcApiHandler
*/
void setContentTypes( const QList<QgsServerOgcApi::ContentType> &contentTypes ) SIP_SKIP;

/**
* Returns the handler component of the URL path, i.e. the part of the path that comes
* after the API path.
*
* \since QGIS 3.22
*/
QString handlerPath( const QgsServerApiContext &context ) const;

private:

//! List of content types this handler can serve, first is the default
@@ -1751,7 +1751,7 @@ def templatePath(self, context):
class Handler4(QgsServerOgcApiHandler):

def path(self):
return QtCore.QRegularExpression("/tms/(?P<tilemapid>[^/]+)")
return QtCore.QRegularExpression("/(?P<tilemapid>[^/]+)")

def operationId(self):
return "handler4"
@@ -2031,16 +2031,15 @@ def testOgcApiHandlerException(self):

def test_path_capture(self):
"""Test issue GH #45439"""
project = QgsProject()

api = QgsServerOgcApi(self.server.serverInterface(),
'/services/api4', 'apifour', 'a fourth api', '1.2')
'/api4', 'apifour', 'a fourth api', '1.2')

h4 = Handler4()
api.registerHandler(h4)

request = QgsBufferServerRequest(
'http://localhost:19876/services/api4/tms/france_parts.json?MAP=france_parts')
'http://localhost:19876/api4/france_parts.json?MAP=france_parts')
response = QgsBufferServerResponse()

server = QgsServer()
@@ -2051,8 +2050,8 @@ def test_path_capture(self):

self.assertEqual(h4.params, {'tilemapid': 'france_parts.json'})

ctx = QgsServerApiContext(api.rootPath(), request, response, project, iface)
self.assertEqual(h4.href(ctx), 'http://localhost:19876/services/api4/tms/france_parts?MAP=france_parts')
ctx = QgsServerApiContext(api.rootPath(), request, response, None, iface)
self.assertEqual(h4.href(ctx), 'http://localhost:19876/api4/france_parts?MAP=france_parts')


if __name__ == '__main__':

0 comments on commit 9990ad2

Please sign in to comment.