From 28e1770f27bb335d29bfa44a5c963904007b5e73 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 27 Dec 2019 17:42:04 +0100 Subject: CurlFileHandle: set UserAgent --- src/filemanager.cpp | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'src/filemanager.cpp') diff --git a/src/filemanager.cpp b/src/filemanager.cpp index a279a6cf..625dca03 100644 --- a/src/filemanager.cpp +++ b/src/filemanager.cpp @@ -61,8 +61,22 @@ class MyMutex { #include // for sqlite3_snprintf #endif +#if defined(__linux) +#include +#elif defined(_WIN32) +#include +#elif defined(__MACH__) && defined(__APPLE__) +#include +#elif defined(__FreeBSD__) +#include +#include +#endif + //! @cond Doxygen_Suppress +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) + using namespace NS_PROJ::internal; NS_PROJ_START @@ -546,6 +560,7 @@ struct CurlFileHandle { CURL *m_handle; std::string m_headers{}; std::string m_lastval{}; + std::string m_useragent{}; char m_szCurlErrBuf[CURL_ERROR_SIZE + 1] = {}; CurlFileHandle(const CurlFileHandle &) = delete; @@ -562,6 +577,67 @@ struct CurlFileHandle { // --------------------------------------------------------------------------- +static std::string GetExecutableName() { +#if defined(__linux) + std::string path; + path.resize(1024); + const auto ret = readlink("/proc/self/exe", &path[0], path.size()); + if (ret > 0) { + path.resize(ret); + const auto pos = path.rfind('/'); + if (pos != std::string::npos) { + path = path.substr(pos + 1); + } + return path; + } +#elif defined(_WIN32) + std::string path; + path.resize(1024); + if (GetModuleFileNameA(nullptr, &path[0], + static_cast(path.size()))) { + path.resize(strlen(path.c_str())); + const auto pos = path.rfind('\\'); + if (pos != std::string::npos) { + path = path.substr(pos + 1); + } + return path; + } +#elif defined(__MACH__) && defined(__APPLE__) + std::string path; + path.resize(1024); + uint32_t size = static_cast(path.size()); + if (_NSGetExecutablePath(&path[0], &size) == 0) { + path.resize(strlen(path.c_str())); + const auto pos = path.rfind('/'); + if (pos != std::string::npos) { + path = path.substr(pos + 1); + } + return path; + } +#elif defined(__FreeBSD__) + int mib[4]; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + std::string path; + path.resize(1024); + size_t size = path.size(); + if (sysctl(mib, 4, &path[0], &size, nullptr, 0) == 0) { + path.resize(strlen(path.c_str())); + const auto pos = path.rfind('/'); + if (pos != std::string::npos) { + path = path.substr(pos + 1); + } + return path; + } +#endif + + return std::string(); +} + +// --------------------------------------------------------------------------- + CurlFileHandle::CurlFileHandle(const char *url, CURL *handle) : m_url(url), m_handle(handle) { curl_easy_setopt(handle, CURLOPT_URL, m_url.c_str()); @@ -584,6 +660,16 @@ CurlFileHandle::CurlFileHandle(const char *url, CURL *handle) } curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, m_szCurlErrBuf); + + if (getenv("PROJ_NO_USERAGENT") == nullptr) { + m_useragent = "PROJ " STR(PROJ_VERSION_MAJOR) "." STR( + PROJ_VERSION_MINOR) "." STR(PROJ_VERSION_PATCH); + const auto exeName = GetExecutableName(); + if (!exeName.empty()) { + m_useragent = exeName + " using " + m_useragent; + } + curl_easy_setopt(handle, CURLOPT_USERAGENT, m_useragent.data()); + } } // --------------------------------------------------------------------------- -- cgit v1.2.3