Skip to content

Commit

Permalink
fix explicit vsicurl prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
notguiltyspark committed Jan 19, 2025
1 parent b601cc7 commit f4c58c3
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 12 deletions.
43 changes: 31 additions & 12 deletions src/gui/ogr/qgsgdalguiutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,16 +222,20 @@ QString QgsGdalGuiUtils::createDatabaseURI( const QString &connectionType, const

QString QgsGdalGuiUtils::createProtocolURI( const QString &type, const QString &url, const QString &configId, const QString &username, const QString &password, bool expandAuthConfig )
{
QString uri;
QString uri = url;
QString prefix;
if ( type == QLatin1String( "vsicurl" ) )
{
uri = url;
// If no protocol is provided in the URL, default to HTTP
if ( !uri.startsWith( "http://" ) && !uri.startsWith( "https://" ) && !uri.startsWith( "ftp://" ) )
prefix = QStringLiteral( "/vsicurl/" );
if ( !uri.startsWith( prefix ) )
{
uri.prepend( QStringLiteral( "http://" ) );
// If no protocol is provided in the URL, default to HTTP
if ( !uri.startsWith( QLatin1String( "http://" ) ) && !uri.startsWith( QLatin1String( "https://" ) ) && !uri.startsWith( QLatin1String( "ftp://" ) ) )
{
uri.prepend( QStringLiteral( "http://" ) );
}
uri.prepend( prefix );
}
uri.prepend( QStringLiteral( "/vsicurl/" ) );
}
else if ( type == QLatin1String( "vsis3" )
|| type == QLatin1String( "vsigs" )
Expand All @@ -241,25 +245,40 @@ QString QgsGdalGuiUtils::createProtocolURI( const QString &type, const QString &
|| type == QLatin1String( "vsiswift" )
|| type == QLatin1String( "vsihdfs" ) )
{
uri = url;
uri.prepend( QStringLiteral( "/%1/" ).arg( type ) );
prefix = QStringLiteral( "/%1/" ).arg( type );
if ( !uri.startsWith( prefix ) )
{
uri.prepend( prefix );
}
}
// catching both GeoJSON and GeoJSONSeq
else if ( type.startsWith( QLatin1String( "GeoJSON" ) ) )
{
uri = url;
// no change needed for now
}
else if ( type == QLatin1String( "CouchDB" ) )
{
uri = QStringLiteral( "couchdb:%1" ).arg( url );
prefix = QStringLiteral( "couchdb:" );
if ( !uri.startsWith( prefix ) )
{
uri.prepend( prefix );
}
}
else if ( type == QLatin1String( "DODS/OPeNDAP" ) )
{
uri = QStringLiteral( "DODS:%1" ).arg( url );
prefix = QStringLiteral( "DODS:" );
if ( !uri.startsWith( prefix ) )
{
uri.prepend( prefix );
}
}
else if ( type == QLatin1String( "WFS3" ) )
{
uri = QStringLiteral( "WFS3:%1" ).arg( url );
prefix = QStringLiteral( "WFS3:" );
if ( !uri.startsWith( prefix ) )
{
uri.prepend( prefix );
}
}
QgsDebugMsgLevel( "Connection type is=" + type + " and uri=" + uri, 2 );
// Update URI with authentication information
Expand Down
1 change: 1 addition & 0 deletions tests/src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ set(TESTS
testqgsmessagebar.cpp
testprojectionissues.cpp
testqgsgui.cpp
testqgsgdalguiutils.cpp
testprocessinggui.cpp
testqgsprocessingmodel.cpp
testqgsrubberband.cpp
Expand Down
232 changes: 232 additions & 0 deletions tests/src/gui/testqgsgdalguiutils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/***************************************************************************
testqgsgdalguiutils.cpp
--------------------------------------
Date : 12.11.2024
Copyright : (C) 2024 Abdullaev Ruslan
Email : caboose7 at yandex dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgstest.h"
#include "qgsgdalguiutils.h"
#include "qgsauthconfig.h"
#include "qgsapplication.h"

class TestQgsGdalGuiUtils : public QObject
{
Q_OBJECT

public:
TestQgsGdalGuiUtils();

private slots:
void initTestCase();
void cleanupTestCase();

void checkUriBuilding();
};

TestQgsGdalGuiUtils::TestQgsGdalGuiUtils()
: QObject()
{
}

void TestQgsGdalGuiUtils::initTestCase()
{
QgsApplication::init();
QgsApplication::initQgis();
}

void TestQgsGdalGuiUtils::checkUriBuilding()
{
// Test vsicurl: no protocol -> should default to http
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "www.test.com" ), QString(), QString(), QString(), false );
QString expected( "/vsicurl/http://www.test.com" );
QCOMPARE( actual, expected );
}

// Test vsicurl: with http already specified
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "http://www.test.com" ), QString(), QString(), QString(), false );
// Already has protocol, just add prefix
QString expected( "/vsicurl/http://www.test.com" );
QCOMPARE( actual, expected );
}

// Test vsicurl: with https
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "https://data.test.com/path" ), QString(), QString(), QString(), false );
QString expected( "/vsicurl/https://data.test.com/path" );
QCOMPARE( actual, expected );
}

// Test vsicurl: with ftp
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "ftp://files.test.com" ), QString(), QString(), QString(), false );
QString expected( "/vsicurl/ftp://files.test.com" );
QCOMPARE( actual, expected );
}

// Test vsicurl: prefix already included
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "/vsicurl/http://already.prefixed.com" ), QString(), QString(), QString(), false );
// No change expected
QString expected( "/vsicurl/http://already.prefixed.com" );
QCOMPARE( actual, expected );
}

// Test vsis3: no prefix yet
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsis3" ), QLatin1String( "bucket/key" ), QString(), QString(), QString(), false );
QString expected( "/vsis3/bucket/key" );
QCOMPARE( actual, expected );
}

// Test vsis3: prefix already included
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsis3" ), QLatin1String( "/vsis3/mydata" ), QString(), QString(), QString(), false );
QString expected( "/vsis3/mydata" );
QCOMPARE( actual, expected );
}

// Test vsigs
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsigs" ), QLatin1String( "gs://mybucket/data" ), QString(), QString(), QString(), false );
// Even if gs:// is specified, code only prepends /vsigs/ if not present
QString expected( "/vsigs/gs://mybucket/data" );
QCOMPARE( actual, expected );
}

// Test vsiaz
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsiaz" ), QLatin1String( "mycontainer/myfile" ), QString(), QString(), QString(), false );
QString expected( "/vsiaz/mycontainer/myfile" );
QCOMPARE( actual, expected );
}

// Test vsiadls
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsiadls" ), QLatin1String( "adls_path" ), QString(), QString(), QString(), false );
QString expected( "/vsiadls/adls_path" );
QCOMPARE( actual, expected );
}

// Test vsioss
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsioss" ), QLatin1String( "my_oss_bucket/file" ), QString(), QString(), QString(), false );
QString expected( "/vsioss/my_oss_bucket/file" );
QCOMPARE( actual, expected );
}

// Test vsiswift
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsiswift" ), QLatin1String( "swift_container/object" ), QString(), QString(), QString(), false );
QString expected( "/vsiswift/swift_container/object" );
QCOMPARE( actual, expected );
}

// Test vsihdfs
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsihdfs" ), QLatin1String( "hdfs_path" ), QString(), QString(), QString(), false );
QString expected( "/vsihdfs/hdfs_path" );
QCOMPARE( actual, expected );
}

// Test GeoJSON
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "GeoJSON" ), QLatin1String( "file.json" ), QString(), QString(), QString(), false );
// No prefix changes for GeoJSON
QString expected( "file.json" );
QCOMPARE( actual, expected );
}

// Test GeoJSONSeq
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "GeoJSONSeq" ), QLatin1String( "seq_file.json" ), QString(), QString(), QString(), false );
// No prefix changes for GeoJSONSeq
QString expected( "seq_file.json" );
QCOMPARE( actual, expected );
}

// Test CouchDB: no prefix yet
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "CouchDB" ), QLatin1String( "localhost:5984/db" ), QString(), QString(), QString(), false );
QString expected( "couchdb:localhost:5984/db" );
QCOMPARE( actual, expected );
}

// Test CouchDB: prefix already included
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "CouchDB" ), QLatin1String( "couchdb:localhost:5984/db" ), QString(), QString(), QString(), false );
QString expected( "couchdb:localhost:5984/db" );
QCOMPARE( actual, expected );
}

// Test DODS/OPeNDAP: no prefix
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "DODS/OPeNDAP" ), QLatin1String( "http://opendap.data" ), QString(), QString(), QString(), false );
QString expected( "DODS:http://opendap.data" );
QCOMPARE( actual, expected );
}

// Test DODS/OPeNDAP: prefix already included
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "DODS/OPeNDAP" ), QLatin1String( "DODS:http://opendap.data" ), QString(), QString(), QString(), false );
QString expected( "DODS:http://opendap.data" );
QCOMPARE( actual, expected );
}

// Test WFS3: no prefix
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "WFS3" ), QLatin1String( "https://mywfs3.org" ), QString(), QString(), QString(), false );
QString expected( "WFS3:https://mywfs3.org" );
QCOMPARE( actual, expected );
}

// Test WFS3: prefix already
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "WFS3" ), QLatin1String( "WFS3:https://mywfs3.org" ), QString(), QString(), QString(), false );
QString expected( "WFS3:https://mywfs3.org" );
QCOMPARE( actual, expected );
}

// Test with configId and expandAuthConfig = false
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "mydata.com" ), QLatin1String( "myconfig" ), QString(), QString(), false );
// Should prepend prefix and protocol
QString expected( "/vsicurl/http://mydata.com authcfg='myconfig'" );
QCOMPARE( actual, expected );
}

// Test with configId and no username/password, expandAuthConfig = true
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "CouchDB" ), QLatin1String( "mydb" ), QLatin1String( "ab34567" ), QString(), QString(), true );
// Prefix is added, then authcfg updated. If no real auth expansion, it remains as is.
// Actual code tries to expand, if fails, it returns with authcfg.
QString expected( "couchdb:mydb" );
QCOMPARE( actual, expected );
}

// Test with username/password and no configId
{
QString actual = QgsGdalGuiUtils::createProtocolURI( QLatin1String( "vsicurl" ), QLatin1String( "https://securedata.com" ), QString(), QLatin1String( "user" ), QLatin1String( "pass" ), false );
// Insert credentials into the URI after "://"
QString expected( "/vsicurl/https://user:pass@securedata.com" );
QCOMPARE( actual, expected );
}
}

void TestQgsGdalGuiUtils::cleanupTestCase()
{
QgsApplication::exitQgis();
}

QGSTEST_MAIN( TestQgsGdalGuiUtils )
#include "testqgsgdalguiutils.moc"

0 comments on commit f4c58c3

Please sign in to comment.