Fix landing page after d61df93315e

Handle the messy initial / by making sure the
paths matches are evaluated against a sanitized
URL that always starts with a /
This commit is contained in:
Alessandro Pasotti 2021-10-08 12:57:59 +02:00
parent 2b1a1c1986
commit 8ba18051e4
9 changed files with 42 additions and 35 deletions

View File

@ -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
};

View File

@ -108,7 +108,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 );

View File

@ -263,14 +263,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
};
/************************************************************************

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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
const auto path { sanitizeUrl( context.request()->url() ).path() };
const auto path { sanitizeUrl( context.handlerPath( ) ).path() };
// Find matching handler
auto hasMatch { false };
for ( const auto &handler : mHandlers )

View File

@ -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 );

View File

@ -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() )
{
@ -141,7 +141,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 ) );
@ -601,17 +601,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();
}
}

View File

@ -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