Skip to content

Commit

Permalink
proj_coordoperation_get_grid_used(): make it work more reliably when …
Browse files Browse the repository at this point in the history
…networking is enabled (fixes #3176)
  • Loading branch information
rouault committed May 4, 2022
1 parent d542418 commit 7e6d08d
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 55 deletions.
59 changes: 25 additions & 34 deletions src/filemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1633,15 +1633,18 @@ static NS_PROJ::io::DatabaseContextPtr getDBcontext(PJ_CONTEXT *ctx) {
/************************************************************************/

std::unique_ptr<NS_PROJ::File>
NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) {
NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name,
char *out_full_filename,
size_t out_full_filename_size) {

if (ctx == nullptr) {
ctx = pj_get_default_ctx();
}

auto file = std::unique_ptr<NS_PROJ::File>(
reinterpret_cast<NS_PROJ::File *>(pj_open_lib_internal(
ctx, name, "rb", pj_open_file_with_manager, nullptr, 0)));
auto file =
std::unique_ptr<NS_PROJ::File>(reinterpret_cast<NS_PROJ::File *>(
pj_open_lib_internal(ctx, name, "rb", pj_open_file_with_manager,
out_full_filename, out_full_filename_size)));

// Retry with the new proj grid name if the file name doesn't end with .tif
std::string tmpString; // keep it in this upper scope !
Expand All @@ -1657,8 +1660,9 @@ NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) {
if (!filename.empty()) {
file.reset(reinterpret_cast<NS_PROJ::File *>(
pj_open_lib_internal(ctx, filename.c_str(), "rb",
pj_open_file_with_manager, nullptr,
0)));
pj_open_file_with_manager,
out_full_filename,
out_full_filename_size)));
if (file) {
proj_context_errno_set(ctx, 0);
} else {
Expand Down Expand Up @@ -1687,8 +1691,9 @@ NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) {
if (!filename.empty()) {
file.reset(reinterpret_cast<NS_PROJ::File *>(
pj_open_lib_internal(ctx, filename.c_str(), "rb",
pj_open_file_with_manager, nullptr,
0)));
pj_open_file_with_manager,
out_full_filename,
out_full_filename_size)));
if (file) {
proj_context_errno_set(ctx, 0);
}
Expand All @@ -1713,6 +1718,11 @@ NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) {
file =
open(ctx, remote_file.c_str(), NS_PROJ::FileAccess::READ_ONLY);
if (file) {
if (out_full_filename) {
strncpy(out_full_filename, remote_file.c_str(),
out_full_filename_size);
out_full_filename[out_full_filename_size - 1] = '\0';
}
pj_log(ctx, PJ_LOG_DEBUG, "Using %s", remote_file.c_str());
proj_context_errno_set(ctx, 0);
}
Expand All @@ -1739,32 +1749,13 @@ NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name) {
*/
int pj_find_file(PJ_CONTEXT *ctx, const char *short_filename,
char *out_full_filename, size_t out_full_filename_size) {
auto file = std::unique_ptr<NS_PROJ::File>(
reinterpret_cast<NS_PROJ::File *>(pj_open_lib_internal(
ctx, short_filename, "rb", pj_open_file_with_manager,
out_full_filename, out_full_filename_size)));

// Retry with the old proj grid name if the file name ends with .tif
if (file == nullptr && strstr(short_filename, ".tif") != nullptr) {

auto dbContext = getDBcontext(ctx);
if (dbContext) {
try {
auto filename = dbContext->getOldProjGridName(short_filename);
if (!filename.empty()) {
file.reset(reinterpret_cast<NS_PROJ::File *>(
pj_open_lib_internal(ctx, filename.c_str(), "rb",
pj_open_file_with_manager,
out_full_filename,
out_full_filename_size)));
}
} catch (const std::exception &e) {
pj_log(ctx, PJ_LOG_DEBUG, "%s", e.what());
return false;
}
}
}

const bool old_network_enabled = proj_context_is_network_enabled(ctx);
if (old_network_enabled)
proj_context_set_enable_network(ctx, false);
auto file = NS_PROJ::FileManager::open_resource_file(
ctx, short_filename, out_full_filename, out_full_filename_size);
if (old_network_enabled)
proj_context_set_enable_network(ctx, true);
return file != nullptr;
}

Expand Down
6 changes: 4 additions & 2 deletions src/filemanager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ class FileManager {
static std::string getProjLibEnvVar(PJ_CONTEXT *ctx);

// "High-level" interface, honoring PROJ_LIB and the like.
static std::unique_ptr<File> open_resource_file(PJ_CONTEXT *ctx,
const char *name);
static std::unique_ptr<File>
open_resource_file(PJ_CONTEXT *ctx, const char *name,
char *out_full_filename = nullptr,
size_t out_full_filename_size = 0);

static void fillDefaultNetworkInterface(PJ_CONTEXT *ctx);

Expand Down
34 changes: 17 additions & 17 deletions src/iso19111/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3260,20 +3260,16 @@ bool DatabaseContext::lookForGridInfo(
openLicense = false;
directDownload = false;

if (considerKnownGridsAsAvailable) {
fullFilename = projFilename;
} else {
fullFilename.resize(2048);
if (d->pjCtxt() == nullptr) {
d->setPjCtxt(pj_get_default_ctx());
}
int errno_before = proj_context_errno(d->pjCtxt());
gridAvailable =
pj_find_file(d->pjCtxt(), projFilename.c_str(), &fullFilename[0],
fullFilename.size() - 1) != 0;
proj_context_errno_set(d->pjCtxt(), errno_before);
fullFilename.resize(strlen(fullFilename.c_str()));
fullFilename.resize(2048);
if (d->pjCtxt() == nullptr) {
d->setPjCtxt(pj_get_default_ctx());
}
int errno_before = proj_context_errno(d->pjCtxt());
gridAvailable =
pj_find_file(d->pjCtxt(), projFilename.c_str(), &fullFilename[0],
fullFilename.size() - 1) != 0;
proj_context_errno_set(d->pjCtxt(), errno_before);
fullFilename.resize(strlen(fullFilename.c_str()));

auto res =
d->run("SELECT "
Expand Down Expand Up @@ -3305,10 +3301,7 @@ bool DatabaseContext::lookForGridInfo(
old_proj_grid_name == projFilename) {
std::string fullFilenameNewName;
fullFilenameNewName.resize(2048);
if (d->pjCtxt() == nullptr) {
d->setPjCtxt(pj_get_default_ctx());
}
int errno_before = proj_context_errno(d->pjCtxt());
errno_before = proj_context_errno(d->pjCtxt());
bool gridAvailableWithNewName =
pj_find_file(d->pjCtxt(), proj_grid_name.c_str(),
&fullFilenameNewName[0],
Expand All @@ -3328,6 +3321,13 @@ bool DatabaseContext::lookForGridInfo(

info.fullFilename = fullFilename;
info.packageName = packageName;
std::string endpoint(proj_context_get_url_endpoint(d->pjCtxt()));
if (!endpoint.empty() && starts_with(url, "https://cdn.proj.org/")) {
if (endpoint.back() != '/') {
endpoint += '/';
}
url = endpoint + url.substr(strlen("https://cdn.proj.org/"));
}
info.url = url;
info.directDownload = directDownload;
info.openLicense = openLicense;
Expand Down
10 changes: 8 additions & 2 deletions test/unit/test_c_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,9 @@ TEST_F(CApi, proj_coordoperation_get_grid_used) {
ASSERT_NE(op, nullptr);
ObjectKeeper keeper(op);

const std::string old_endpoint = proj_context_get_url_endpoint(m_ctxt);
proj_context_set_url_endpoint(m_ctxt, "https://example.com");

EXPECT_EQ(proj_coordoperation_get_grid_used_count(m_ctxt, op), 1);
const char *shortName = nullptr;
const char *fullName = nullptr;
Expand Down Expand Up @@ -1569,9 +1572,11 @@ TEST_F(CApi, proj_coordoperation_get_grid_used) {
EXPECT_EQ(shortName, std::string("ca_nrc_ntv1_can.tif"));
// EXPECT_EQ(fullName, std::string(""));
EXPECT_EQ(packageName, std::string(""));
EXPECT_EQ(std::string(url), "https://cdn.proj.org/ca_nrc_ntv1_can.tif");
EXPECT_EQ(std::string(url), "https://example.com/ca_nrc_ntv1_can.tif");
EXPECT_EQ(directDownload, 1);
EXPECT_EQ(openLicense, 1);

proj_context_set_url_endpoint(m_ctxt, old_endpoint.c_str());
}

// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -2440,7 +2445,8 @@ TEST_F(CApi, check_coord_op_obj_can_be_used_with_proj_trans) {

{
PJ *pj_used = proj_trans_get_last_used_operation(projCRS);
ASSERT_TRUE(proj_is_equivalent_to(pj_used, projCRS, PJ_COMP_STRICT));
ASSERT_TRUE(
proj_is_equivalent_to(pj_used, projCRS, PJ_COMP_STRICT));
proj_destroy(pj_used);
}
}
Expand Down

0 comments on commit 7e6d08d

Please sign in to comment.