aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/reference_exported_symbols.txt1
-rw-r--r--src/filemanager.cpp58
-rw-r--r--src/proj.h3
-rw-r--r--src/proj_internal.h4
-rw-r--r--test/unit/test_network.cpp49
5 files changed, 108 insertions, 7 deletions
diff --git a/scripts/reference_exported_symbols.txt b/scripts/reference_exported_symbols.txt
index 6e4e5302..9d7d400a 100644
--- a/scripts/reference_exported_symbols.txt
+++ b/scripts/reference_exported_symbols.txt
@@ -794,6 +794,7 @@ proj_context_get_use_proj4_init_rules
proj_context_guess_wkt_dialect
proj_context_set_autoclose_database
proj_context_set_database_path
+proj_context_set_enable_network
proj_context_set_file_finder
proj_context_set_network_callbacks
proj_context_set(PJconsts*, projCtx_t*)
diff --git a/src/filemanager.cpp b/src/filemanager.cpp
index ea0a63ea..cd738d5e 100644
--- a/src/filemanager.cpp
+++ b/src/filemanager.cpp
@@ -63,9 +63,9 @@ class MyMutex {
//! @cond Doxygen_Suppress
-NS_PROJ_START
+using namespace NS_PROJ::internal;
-using namespace internal;
+NS_PROJ_START
// ---------------------------------------------------------------------------
@@ -488,6 +488,14 @@ std::unique_ptr<File> FileManager::open(PJ_CONTEXT *ctx, const char *filename) {
}
#endif
if (starts_with(filename, "http://") || starts_with(filename, "https://")) {
+ if (!pj_context_is_network_enabled(ctx)) {
+ pj_log(
+ ctx, PJ_LOG_ERROR,
+ "Attempt at accessing remote resource not authorized. Either "
+ "set PROJ_NETWORK=ON or "
+ "proj_context_set_enable_network(ctx, TRUE)");
+ return nullptr;
+ }
return NetworkFile::open(ctx, filename);
}
return FileStdio::open(ctx, filename);
@@ -756,3 +764,49 @@ int proj_context_set_network_callbacks(
ctx->networking.user_data = user_data;
return true;
}
+
+// ---------------------------------------------------------------------------
+
+/** Enable or disable network access.
+*
+* @param ctx PROJ context, or NULL
+* @param enable TRUE if network access is allowed.
+* @return TRUE if network access is possible. That is either libcurl is
+* available, or an alternate interface has been set.
+*/
+int proj_context_set_enable_network(PJ_CONTEXT *ctx, int enable) {
+ if (ctx == nullptr) {
+ ctx = pj_get_default_ctx();
+ }
+ ctx->networking.enabled_env_variable_checked = true;
+ ctx->networking.enabled = enable != FALSE;
+#ifdef CURL_ENABLED
+ return ctx->networking.enabled;
+#else
+ return ctx->networking.enabled &&
+ ctx->networking.open != NS_PROJ::no_op_network_open;
+#endif
+}
+
+// ---------------------------------------------------------------------------
+
+//! @cond Doxygen_Suppress
+
+bool pj_context_is_network_enabled(PJ_CONTEXT *ctx) {
+ if (ctx == nullptr) {
+ ctx = pj_get_default_ctx();
+ }
+ if (ctx->networking.enabled_env_variable_checked) {
+ return ctx->networking.enabled;
+ }
+ const char *enabled = getenv("PROJ_NETWORK");
+ if (enabled && enabled[0] != '\0') {
+ ctx->networking.enabled = ci_equal(enabled, "ON") ||
+ ci_equal(enabled, "YES") ||
+ ci_equal(enabled, "TRUE");
+ }
+ ctx->networking.enabled_env_variable_checked = true;
+ return ctx->networking.enabled;
+}
+
+//! @endcond
diff --git a/src/proj.h b/src/proj.h
index 95bbacd1..4f7878a4 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -421,6 +421,9 @@ int PROJ_DLL proj_context_set_network_callbacks(
proj_network_get_last_error_type get_last_error_cbk,
void* user_data);
+int PROJ_DLL proj_context_set_enable_network(PJ_CONTEXT* ctx,
+ int enabled);
+
/*! @cond Doxygen_Suppress */
/* Manage the transformation definition object PJ */
diff --git a/src/proj_internal.h b/src/proj_internal.h
index 0c148d02..d54d8fb9 100644
--- a/src/proj_internal.h
+++ b/src/proj_internal.h
@@ -668,6 +668,8 @@ struct projCppContext;
struct projNetworkCallbacksAndData
{
+ bool enabled = false;
+ bool enabled_env_variable_checked = false; // whereas we have checked PROJ_NETWORK env variable
proj_network_open_cbk_type open = nullptr;
proj_network_close_cbk_type close = nullptr;
proj_network_get_header_value_cbk_type get_header_value = nullptr;
@@ -824,6 +826,8 @@ PJ *pj_create_argv_internal (PJ_CONTEXT *ctx, int argc, char **argv);
void pj_pipeline_assign_context_to_steps( PJ* P, PJ_CONTEXT* ctx );
+bool pj_context_is_network_enabled(PJ_CONTEXT* ctx);
+
/* classic public API */
#include "proj_api.h"
diff --git a/test/unit/test_network.cpp b/test/unit/test_network.cpp
index 5940814b..ba592da4 100644
--- a/test/unit/test_network.cpp
+++ b/test/unit/test_network.cpp
@@ -30,6 +30,7 @@
#include <memory>
#include <stdio.h>
+#include <stdlib.h>
#include "proj_internal.h"
#include <proj.h>
@@ -77,18 +78,54 @@ TEST(networking, initial_check) {
// ---------------------------------------------------------------------------
+static void silent_logger(void *, int, const char *) {}
+
+// ---------------------------------------------------------------------------
+
TEST(networking, basic) {
- auto P = proj_create(
- PJ_DEFAULT_CTX,
+ const char *pipeline =
"+proj=pipeline "
"+step +proj=unitconvert +xy_in=deg +xy_out=rad "
"+step +proj=hgridshift +grids=https://cdn.proj.org/ntf_r93.tif "
- "+step +proj=unitconvert +xy_in=rad +xy_out=deg ");
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg";
+
+ // network access disabled by default
+ auto ctx = proj_context_create();
+ proj_log_func(ctx, nullptr, silent_logger);
+ auto P = proj_create(ctx, pipeline);
+ ASSERT_EQ(P, nullptr);
+ proj_context_destroy(ctx);
+
+#ifdef CURL_ENABLED
+ // enable through env variable
+ ctx = proj_context_create();
+ putenv(const_cast<char *>("PROJ_NETWORK=ON"));
+ P = proj_create(ctx, pipeline);
+ if (networkAccessOK) {
+ ASSERT_NE(P, nullptr);
+ }
+ proj_destroy(P);
+ proj_context_destroy(ctx);
+ putenv(const_cast<char *>("PROJ_NETWORK="));
+#endif
+
+ // still disabled
+ ctx = proj_context_create();
+ proj_log_func(ctx, nullptr, silent_logger);
+ P = proj_create(ctx, pipeline);
+ ASSERT_EQ(P, nullptr);
+ proj_context_destroy(ctx);
+
+ // enable through API
+ ctx = proj_context_create();
+ proj_context_set_enable_network(ctx, true);
+ P = proj_create(ctx, pipeline);
#ifdef CURL_ENABLED
if (networkAccessOK) {
ASSERT_NE(P, nullptr);
} else {
ASSERT_EQ(P, nullptr);
+ proj_context_destroy(ctx);
return;
}
double lon = 2;
@@ -102,16 +139,16 @@ TEST(networking, basic) {
#else
ASSERT_EQ(P, nullptr);
#endif
+ proj_context_destroy(ctx);
}
// ---------------------------------------------------------------------------
#ifdef CURL_ENABLED
-static void silent_logger(void *, int, const char *) {}
-
TEST(networking, curl_invalid_resource) {
auto ctx = proj_context_create();
+ proj_context_set_enable_network(ctx, true);
proj_log_func(ctx, nullptr, silent_logger);
auto P = proj_create(
ctx, "+proj=hgridshift +grids=https://i_do_not.exist/my.tif");
@@ -364,6 +401,7 @@ static const char *get_last_error_cbk(PJ_CONTEXT * /*ctx*/,
TEST(networking, custom) {
auto ctx = proj_context_create();
+ proj_context_set_enable_network(ctx, true);
ExchangeWithCallback exchange;
ASSERT_TRUE(proj_context_set_network_callbacks(
ctx, open_cbk, close_cbk, get_header_value_cbk, read_range_cbk,
@@ -499,6 +537,7 @@ TEST(networking, custom) {
TEST(networking, getfilesize) {
auto ctx = proj_context_create();
+ proj_context_set_enable_network(ctx, true);
ExchangeWithCallback exchange;
ASSERT_TRUE(proj_context_set_network_callbacks(
ctx, open_cbk, close_cbk, get_header_value_cbk, read_range_cbk,