aboutsummaryrefslogtreecommitdiff
path: root/src/open_lib.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-12-25 20:13:03 +0100
committerEven Rouault <even.rouault@spatialys.com>2019-12-27 11:14:16 +0100
commit2093aca0720949303410280912b61efd791d2f01 (patch)
treea69c5392ed6689a88d9d959ddb41107413efacc6 /src/open_lib.cpp
parentc4589fbe42e5fea07a03919d3484164f5fb70dd3 (diff)
downloadPROJ-2093aca0720949303410280912b61efd791d2f01.tar.gz
PROJ-2093aca0720949303410280912b61efd791d2f01.zip
Network: make CDN endpoint configurable either in proj.ini, PROJ_NETWORK_ENDPOINT or proj_context_set_url_endpoint()
Diffstat (limited to 'src/open_lib.cpp')
-rw-r--r--src/open_lib.cpp113
1 files changed, 103 insertions, 10 deletions
diff --git a/src/open_lib.cpp b/src/open_lib.cpp
index 926505ba..cde5be7b 100644
--- a/src/open_lib.cpp
+++ b/src/open_lib.cpp
@@ -366,16 +366,21 @@ std::unique_ptr<NS_PROJ::File> NS_PROJ::FileManager::open_resource_file(
!starts_with(name, "http://") &&
!starts_with(name, "https://") &&
pj_context_is_network_enabled(ctx) ) {
- std::string remote_file("https://cdn.proj.org/");
- remote_file += name;
- auto pos = remote_file.rfind('.');
- if( pos + 4 == remote_file.size() ) {
- remote_file = remote_file.substr(0, pos) + ".tif";
- file = open(ctx, remote_file.c_str());
- if( file ) {
- pj_log( ctx, PJ_LOG_DEBUG_MAJOR,
- "Using %s", remote_file.c_str() );
- pj_ctx_set_errno( ctx, 0 );
+ std::string remote_file(pj_context_get_url_endpoint(ctx));
+ if( !remote_file.empty() ) {
+ if( remote_file.back() != '/' ) {
+ remote_file += '/';
+ }
+ remote_file += name;
+ auto pos = remote_file.rfind('.');
+ if( pos + 4 == remote_file.size() ) {
+ remote_file = remote_file.substr(0, pos) + ".tif";
+ file = open(ctx, remote_file.c_str());
+ if( file ) {
+ pj_log( ctx, PJ_LOG_DEBUG_MAJOR,
+ "Using %s", remote_file.c_str() );
+ pj_ctx_set_errno( ctx, 0 );
+ }
}
}
}
@@ -433,3 +438,91 @@ int pj_find_file(projCtx ctx, const char *short_filename,
}
return 0;
}
+
+/************************************************************************/
+/* pj_context_get_url_endpoint() */
+/************************************************************************/
+
+std::string pj_context_get_url_endpoint(PJ_CONTEXT* ctx)
+{
+ if( !ctx->endpoint.empty() ) {
+ return ctx->endpoint;
+ }
+ pj_load_ini(ctx);
+ return ctx->endpoint;
+}
+
+/************************************************************************/
+/* trim() */
+/************************************************************************/
+
+static std::string trim(const std::string& s) {
+ const auto first = s.find_first_not_of(' ');
+ const auto last = s.find_last_not_of(' ');
+ if( first == std::string::npos || last == std::string::npos ) {
+ return std::string();
+ }
+ return s.substr(first, last - first + 1);
+}
+
+/************************************************************************/
+/* pj_load_ini() */
+/************************************************************************/
+
+void pj_load_ini(projCtx ctx)
+{
+ if( ctx->iniFileLoaded )
+ return;
+
+ const char* endpoint_from_env = getenv("PROJ_NETWORK_ENDPOINT");
+ if( endpoint_from_env && endpoint_from_env[0] != '\0' ) {
+ ctx->endpoint = endpoint_from_env;
+ }
+
+ ctx->iniFileLoaded = true;
+ auto file = std::unique_ptr<NS_PROJ::File>(
+ reinterpret_cast<NS_PROJ::File*>(
+ pj_open_lib_internal(ctx, "proj.ini", "rb",
+ pj_open_file_with_manager,
+ nullptr, 0)));
+ if( !file )
+ return;
+ file->seek(0, SEEK_END);
+ const auto filesize = file->tell();
+ if( filesize == 0 || filesize > 100 * 1024U )
+ return;
+ file->seek(0, SEEK_SET);
+ std::string content;
+ content.resize(static_cast<size_t>(filesize));
+ const auto nread = file->read(&content[0], content.size());
+ if( nread != content.size() )
+ return;
+ content += '\n';
+ size_t pos = 0;
+ while( pos != std::string::npos ) {
+ const auto eol = content.find_first_of("\r\n", pos);
+ if( eol == std::string::npos ) {
+ break;
+ }
+
+ const auto equal = content.find('=', pos);
+ if( equal < eol )
+ {
+ const auto key = trim(content.substr(pos, equal-pos));
+ const auto value = trim(content.substr(equal + 1,
+ eol - (equal+1)));
+ if( ctx->endpoint.empty() && key == "cdn_endpoint" ) {
+ ctx->endpoint = value;
+ } else if ( key == "network" ) {
+ const char *enabled = getenv("PROJ_NETWORK");
+ if (enabled == nullptr || enabled[0] == '\0') {
+ ctx->networking.enabled = ci_equal(value, "ON") ||
+ ci_equal(value, "YES") ||
+ ci_equal(value, "TRUE");
+ }
+ }
+ }
+
+ pos = content.find_first_not_of("\r\n", eol);
+ }
+}