Skip to content
Permalink
Browse files
Fix landing page after d61df93
Handle the messy initial / by making sure the
paths matches are evaluated against a sanitized
URL that always starts with a /

Cherry-picked from master
  • Loading branch information
elpaso authored and nyalldawson committed Nov 1, 2021
1 parent 9990ad2 commit 53e4b22eef097600177aeaa5d8d14b163ee0d59e
@@ -87,6 +87,14 @@ Returns the API root path
void setRequest( const QgsServerRequest *request );
%Docstring
Sets context request to ``request``
%End

QString handlerPath( ) 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

};
@@ -105,7 +105,8 @@ Registers an OGC API ``handler``, ownership of the handler is transferred to the

static QUrl sanitizeUrl( const QUrl &url );
%Docstring
Returns a sanitized ``url`` with extra slashes removed
Returns a sanitized ``url`` with extra slashes removed and the path URL component that
always starts with a slash.
%End

static std::string relToString( const QgsServerOgcApi::Rel &rel );
@@ -259,14 +259,6 @@ 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

};

/************************************************************************
@@ -81,3 +81,17 @@ void QgsServerApiContext::setRequest( const QgsServerRequest *request )
{
mRequest = request;
}

QString QgsServerApiContext::handlerPath() const
{
const QUrl url { request()->url() };
const QString urlBasePath { matchedPath() };
if ( ! urlBasePath.isEmpty() )
{
return url.path().mid( urlBasePath.length() );
}
else
{
return url.path();
}
}
@@ -101,6 +101,14 @@ class SERVER_EXPORT QgsServerApiContext
*/
void setRequest( const QgsServerRequest *request );

/**
* 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;

private:

QString mApiRootPath;
@@ -75,13 +75,18 @@ QUrl QgsServerOgcApi::sanitizeUrl( const QUrl &url )
{
u.setPath( u.path().replace( QLatin1String( "//" ), QChar( '/' ) ) );
}
// Make sure the path starts with '/'
if ( !u.path().startsWith( '/' ) )
{
u.setPath( u.path().prepend( '/' ) );
}
return u;
}

void QgsServerOgcApi::executeRequest( const QgsServerApiContext &context ) const
{
// Get url
auto path { sanitizeUrl( context.request()->url() ).path() };
const auto path { sanitizeUrl( context.handlerPath( ) ).path() };
// Find matching handler
auto hasMatch { false };
for ( const auto &h : mHandlers )
@@ -145,7 +145,8 @@ class SERVER_EXPORT QgsServerOgcApi : public QgsServerApi
void registerHandler( QgsServerOgcApiHandler *handler SIP_TRANSFER );

/**
* Returns a sanitized \a url with extra slashes removed
* Returns a sanitized \a url with extra slashes removed and the path URL component that
* always starts with a slash.
*/
static QUrl sanitizeUrl( const QUrl &url );

@@ -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( handlerPath( context ) ).path() };
const auto sanitizedPath { QgsServerOgcApi::sanitizeUrl( context.handlerPath( ) ).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( handlerPath( context ) ) };
const auto match { path().match( QgsServerOgcApi::sanitizeUrl( context.handlerPath( ) ).path( ) ) };
if ( match.captured().count() > 0 )
{
url.setPath( urlBasePath + match.captured( 0 ) );
@@ -598,17 +598,3 @@ 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,14 +387,6 @@ 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

0 comments on commit 53e4b22

Please sign in to comment.