Skip to content

Commit

Permalink
DatabaseContext::lookForGridInfo(): do not trigger network activity i…
Browse files Browse the repository at this point in the history
…n PROJ_GRID_AVAILABILITY_KNOWN_AVAILABLE mode when all grids are known (fixes OSGeo#4075)
  • Loading branch information
rouault committed Mar 14, 2024
1 parent e6a0514 commit 3925116
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 19 deletions.
39 changes: 29 additions & 10 deletions src/iso19111/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3324,14 +3324,18 @@ bool DatabaseContext::lookForGridInfo(
url.clear();
openLicense = false;
directDownload = false;

fullFilename.resize(2048);
int errno_before = proj_context_errno(ctxt);
gridAvailable = NS_PROJ::FileManager::open_resource_file(
ctxt, projFilename.c_str(), &fullFilename[0],
fullFilename.size() - 1) != nullptr;
proj_context_errno_set(ctxt, errno_before);
fullFilename.resize(strlen(fullFilename.c_str()));
gridAvailable = false;

const auto resolveFullFilename = [ctxt, &fullFilename, &projFilename]() {
fullFilename.resize(2048);
const int errno_before = proj_context_errno(ctxt);
bool lGridAvailable = NS_PROJ::FileManager::open_resource_file(
ctxt, projFilename.c_str(), &fullFilename[0],
fullFilename.size() - 1) != nullptr;
proj_context_errno_set(ctxt, errno_before);
fullFilename.resize(strlen(fullFilename.c_str()));
return lGridAvailable;
};

auto res =
d->run("SELECT "
Expand Down Expand Up @@ -3363,7 +3367,7 @@ bool DatabaseContext::lookForGridInfo(
old_proj_grid_name == projFilename) {
std::string fullFilenameNewName;
fullFilenameNewName.resize(2048);
errno_before = proj_context_errno(ctxt);
const int errno_before = proj_context_errno(ctxt);
bool gridAvailableWithNewName =
pj_find_file(ctxt, proj_grid_name.c_str(),
&fullFilenameNewName[0],
Expand All @@ -3376,8 +3380,17 @@ bool DatabaseContext::lookForGridInfo(
}
}

if (considerKnownGridsAsAvailable &&
if (!gridAvailable && considerKnownGridsAsAvailable &&
(!packageName.empty() || (!url.empty() && openLicense))) {

// In considerKnownGridsAsAvailable mode, try to fetch the local
// file name if it exists, but do not attempt network access.
const auto network_was_enabled =
proj_context_is_network_enabled(ctxt);
proj_context_set_enable_network(ctxt, false);
(void)resolveFullFilename();
proj_context_set_enable_network(ctxt, network_was_enabled);

gridAvailable = true;
}

Expand All @@ -3391,7 +3404,13 @@ bool DatabaseContext::lookForGridInfo(
}
info.directDownload = directDownload;
info.openLicense = openLicense;

if (!gridAvailable) {
gridAvailable = resolveFullFilename();
}
} else {
gridAvailable = resolveFullFilename();

if (starts_with(fullFilename, "http://") ||
starts_with(fullFilename, "https://")) {
url = fullFilename;
Expand Down
68 changes: 59 additions & 9 deletions test/unit/test_network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1264,26 +1264,28 @@ TEST(networking, network_endpoint_api) {

static PROJ_NETWORK_HANDLE *dummy_open_cbk(PJ_CONTEXT *, const char *,
unsigned long long, size_t, void *,
size_t *, size_t, char *, void *) {
assert(false);
size_t *, size_t, char *,
void *pUserData) {
*static_cast<bool *>(pUserData) = true;
return nullptr;
}

static void dummy_close_cbk(PJ_CONTEXT *, PROJ_NETWORK_HANDLE *, void *) {
assert(false);
static void dummy_close_cbk(PJ_CONTEXT *, PROJ_NETWORK_HANDLE *,
void *pUserData) {
*static_cast<bool *>(pUserData) = true;
}

static const char *dummy_get_header_value_cbk(PJ_CONTEXT *,
PROJ_NETWORK_HANDLE *,
const char *, void *) {
assert(false);
const char *, void *pUserData) {
*static_cast<bool *>(pUserData) = true;
return nullptr;
}

static size_t dummy_read_range_cbk(PJ_CONTEXT *, PROJ_NETWORK_HANDLE *,
unsigned long long, size_t, void *, size_t,
char *, void *) {
assert(false);
char *, void *pUserData) {
*static_cast<bool *>(pUserData) = true;
return 0;
}

Expand Down Expand Up @@ -1332,12 +1334,14 @@ TEST(networking, cache_basic) {
proj_cleanup();

// Check that a second access doesn't trigger any network activity
bool networkActivity = false;
ASSERT_TRUE(proj_context_set_network_callbacks(
ctx, dummy_open_cbk, dummy_close_cbk, dummy_get_header_value_cbk,
dummy_read_range_cbk, nullptr));
dummy_read_range_cbk, &networkActivity));
P = proj_create(ctx, pipeline);
ASSERT_NE(P, nullptr);
proj_destroy(P);
EXPECT_FALSE(networkActivity);

proj_context_destroy(ctx);
}
Expand Down Expand Up @@ -2020,4 +2024,50 @@ TEST(networking, pyproj_issue_1192) {

#endif

// ---------------------------------------------------------------------------

#ifdef CURL_ENABLED

TEST(networking, do_not_attempt_network_access_known_available_network_on) {

// Check that proj_create_operations() itself does not trigger network
// activity in enable_network == true and
// PROJ_GRID_AVAILABILITY_KNOWN_AVAILABLE mode when all grids are known.

const auto doTest = [](PJ_CONTEXT *ctxt) {
auto factory_context =
proj_create_operation_factory_context(ctxt, nullptr);
proj_operation_factory_context_set_grid_availability_use(
ctxt, factory_context, PROJ_GRID_AVAILABILITY_KNOWN_AVAILABLE);
proj_operation_factory_context_set_spatial_criterion(
ctxt, factory_context, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
auto from = proj_create(ctxt, "EPSG:4326");
auto to = proj_create(ctxt, "EPSG:4267");
auto pj_operations =
proj_create_operations(ctxt, from, to, factory_context);
proj_destroy(from);
proj_destroy(to);
auto num_operations = proj_list_get_count(pj_operations);
EXPECT_GE(num_operations, 10);
proj_operation_factory_context_destroy(factory_context);
proj_list_destroy(pj_operations);
};

auto ctx = proj_context_create();
proj_context_set_enable_network(ctx, true);

// Check that we don't trigger any network activity
bool networkActivity = false;
ASSERT_TRUE(proj_context_set_network_callbacks(
ctx, dummy_open_cbk, dummy_close_cbk, dummy_get_header_value_cbk,
dummy_read_range_cbk, &networkActivity));

doTest(ctx);
EXPECT_FALSE(networkActivity);

proj_context_destroy(ctx);
}

#endif

} // namespace

0 comments on commit 3925116

Please sign in to comment.