Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 9.4] DatabaseContext::lookForGridInfo(): do not trigger network activity … #4090

Merged
merged 1 commit into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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