Fix wxXmlResource::Load() with HTTP URLs
Make the code in this function work even with wxFileSystemHandlers that don't implement FindFirst() at all: we can, and should, still try loading the passed in path with them, rather than not doing anything at all. This makes Load() works with HTTP URLs again, as it apparently used to do a long time ago, but didn't do any more. Add a unit test, even if only a semi-manual one, to try to help with this not getting broken again (ideal would be to launch our own HTTP server inside the test, but this is a bit more complicated). Closes #19109.
This commit is contained in:
@@ -343,7 +343,8 @@ bool wxXmlResource::Load(const wxString& filemask_)
|
|||||||
{
|
{
|
||||||
wxString filemask = ConvertFileNameToURL(filemask_);
|
wxString filemask = ConvertFileNameToURL(filemask_);
|
||||||
|
|
||||||
bool allOK = true;
|
bool allOK = true,
|
||||||
|
anyOK = false;
|
||||||
|
|
||||||
#if wxUSE_FILESYSTEM
|
#if wxUSE_FILESYSTEM
|
||||||
wxFileSystem fsys;
|
wxFileSystem fsys;
|
||||||
@@ -356,33 +357,47 @@ bool wxXmlResource::Load(const wxString& filemask_)
|
|||||||
wxString fnd = wxXmlFindFirst;
|
wxString fnd = wxXmlFindFirst;
|
||||||
if ( fnd.empty() )
|
if ( fnd.empty() )
|
||||||
{
|
{
|
||||||
wxLogError(_("Cannot load resources from '%s'."), filemask);
|
// Some file system handlers (e.g. wxInternetFSHandler) just don't
|
||||||
return false;
|
// implement FindFirst() at all, try using the original path as is.
|
||||||
|
fnd = filemask;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!fnd.empty())
|
while (!fnd.empty())
|
||||||
{
|
{
|
||||||
|
bool thisOK = true;
|
||||||
|
|
||||||
#if wxUSE_FILESYSTEM
|
#if wxUSE_FILESYSTEM
|
||||||
if ( IsArchive(fnd) )
|
if ( IsArchive(fnd) )
|
||||||
{
|
{
|
||||||
if ( !Load(fnd + wxT("#zip:*.xrc")) )
|
if ( !Load(fnd + wxT("#zip:*.xrc")) )
|
||||||
allOK = false;
|
thisOK = false;
|
||||||
}
|
}
|
||||||
else // a single resource URL
|
else // a single resource URL
|
||||||
#endif // wxUSE_FILESYSTEM
|
#endif // wxUSE_FILESYSTEM
|
||||||
{
|
{
|
||||||
wxXmlDocument * const doc = DoLoadFile(fnd);
|
wxXmlDocument * const doc = DoLoadFile(fnd);
|
||||||
if ( !doc )
|
if ( !doc )
|
||||||
allOK = false;
|
thisOK = false;
|
||||||
else
|
else
|
||||||
Data().push_back(new wxXmlResourceDataRecord(fnd, doc));
|
Data().push_back(new wxXmlResourceDataRecord(fnd, doc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( thisOK )
|
||||||
|
anyOK = true;
|
||||||
|
else
|
||||||
|
allOK = false;
|
||||||
|
|
||||||
fnd = wxXmlFindNext;
|
fnd = wxXmlFindNext;
|
||||||
}
|
}
|
||||||
# undef wxXmlFindFirst
|
# undef wxXmlFindFirst
|
||||||
# undef wxXmlFindNext
|
# undef wxXmlFindNext
|
||||||
|
|
||||||
|
if ( !anyOK )
|
||||||
|
{
|
||||||
|
wxLogError(_("Cannot load resources from '%s'."), filemask);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return allOK;
|
return allOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#if wxUSE_XRC
|
#if wxUSE_XRC
|
||||||
|
|
||||||
|
#include "wx/fs_inet.h"
|
||||||
#include "wx/xml/xml.h"
|
#include "wx/xml/xml.h"
|
||||||
#include "wx/sstream.h"
|
#include "wx/sstream.h"
|
||||||
#include "wx/wfstream.h"
|
#include "wx/wfstream.h"
|
||||||
@@ -204,4 +205,31 @@ TEST_CASE_METHOD(XrcTestCase, "XRC::IDRanges", "[xrc]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test is disabled by default as it requires the environment variable
|
||||||
|
// below to be defined to point to a HTTP URL with the file to load.
|
||||||
|
//
|
||||||
|
// Use something like "python3 -m http.server samples/xrc/rc" and set
|
||||||
|
// WX_TEST_XRC_URL to http://localhost/menu.xrc to run this test.
|
||||||
|
TEST_CASE_METHOD(XrcTestCase, "XRC::LoadURL", "[xrc][.]")
|
||||||
|
{
|
||||||
|
wxString url;
|
||||||
|
REQUIRE( wxGetEnv("WX_TEST_XRC_URL", &url) );
|
||||||
|
|
||||||
|
// Ensure that loading from HTTP URLs is supported.
|
||||||
|
struct InetHandler : wxInternetFSHandler
|
||||||
|
{
|
||||||
|
InetHandler()
|
||||||
|
{
|
||||||
|
wxFileSystem::AddHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~InetHandler()
|
||||||
|
{
|
||||||
|
wxFileSystem::RemoveHandler(this);
|
||||||
|
}
|
||||||
|
} inetHandler;
|
||||||
|
|
||||||
|
CHECK( wxXmlResource::Get()->Load(url) );
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_XRC
|
#endif // wxUSE_XRC
|
||||||
|
Reference in New Issue
Block a user