39#include "BESInternalError.h"
48#include "RemoteResource.h"
49#include "TheBESKeys.h"
50#include "BESStopWatch.h"
53#define BES_CATALOG_ROOT_KEY "BES.Catalog.catalog.RootDirectory"
56#define MODULE HTTP_MODULE
57#define prolog string("RemoteResource::").append(__func__).append("() - ")
63string RemoteResource::d_temp_file_dir;
64std::mutex RemoteResource::d_temp_file_dir_mutex;
65std::mutex RemoteResource::d_mkstemp_mutex;
81 : d_url(std::move(target_url)), d_uid(std::move(uid)) {
83 if (d_url->protocol() == FILE_PROTOCOL) {
84 set_filename_for_file_url();
86 d_delete_file = false;
88 }
else if (d_url->protocol() == HTTPS_PROTOCOL || d_url->protocol() == HTTP_PROTOCOL) {
89 BESDEBUG(MODULE, prolog <<
"URL: " << d_url->str() << endl);
92 set_delete_temp_file();
95 string err = prolog +
"Unsupported protocol: " + d_url->protocol();
96 throw BESInternalError(err, __FILE__, __LINE__);
101 vector<string> path_elements;
103 if (!path_elements.empty()) {
104 d_basename = path_elements.back();
107 http::get_type_from_url(d_url->str(), d_type);
108 if (d_type.empty()) {
118 if (!d_filename.empty() && d_delete_file)
119 unlink(d_filename.c_str());
136void RemoteResource::set_temp_file_dir() {
137 lock_guard<mutex> lock(d_temp_file_dir_mutex);
140 if (!d_temp_file_dir.empty())
146 throw BESInternalError(
"Temporary file directory '" + d_temp_file_dir +
"' error: " + strerror(errno),
158void RemoteResource::set_delete_temp_file() {
169void RemoteResource::set_filename_for_file_url() {
170 BESDEBUG(MODULE, prolog <<
"Found FILE protocol." << endl);
171 d_filename = d_url->path();
174 d_filename = d_filename.substr(0, d_filename.size() - 1);
179 if (catalog_root.empty()) {
180 throw BESInternalError(prolog +
"ERROR - " + BES_CATALOG_ROOT_KEY +
"is not set", __FILE__, __LINE__);
183 if (d_filename.find(catalog_root) != 0) {
186 BESDEBUG(MODULE,
"d_filename: " << d_filename << endl);
204 lock_guard<mutex> lock(d_mkstemp_mutex);
213 string new_name = d_filename +
"_" + d_uid +
"#" + d_basename;
214 if (rename(d_filename.c_str(), new_name.c_str()) != 0) {
215 throw BESInternalError(
"Could not rename " + d_filename +
" to " + new_name +
" ("
216 + ::strerror(errno) +
")", __FILE__, __LINE__);
219 d_filename = new_name;
221 d_initialized =
true;
236void RemoteResource::get_url(
int fd) {
238 BESDEBUG(MODULE, prolog <<
"BEGIN" << endl);
239 BES_STOPWATCH_START(MODULE, prolog +
"Timing retrieval. Target url: " + d_url->str());
243 curl::http_get_and_write_resource(d_url, fd, &d_response_headers);
244 BESDEBUG(MODULE, prolog <<
"Resource " << d_url->str() <<
" saved to temporary file " << d_filename << endl);
247 string err_msg = prolog +
"Hyrax encountered a Service Chaining Error while "
248 "attempting to retrieve a RemoteResource.\n" + http_error.
get_message();
256 auto status = lseek(fd, 0, SEEK_SET);
258 throw BESInternalError(
"Could not seek within the response file.", __FILE__, __LINE__);
259 BESDEBUG(MODULE, prolog <<
"Reset file descriptor to start of file." << endl);
262 BESDEBUG(MODULE, prolog <<
"END" << endl);
std::string get_message() const
get the error message for this exception
void set_message(const std::string &msg)
set the error message for this exception
exception thrown if internal error encountered
static bool endsWith(std::string const &fullString, std::string const &ending)
static void tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters="/")
static int mkdir_p(const std::string &path, mode_t mode)
static std::string pathConcat(const std::string &firstPart, const std::string &secondPart, char separator='/')
Concatenate path fragments making sure that they are separated by a single '/' character.
static int make_temp_file(const std::string &temp_file_dir, std::string &temp_file_name)
Make and open a temporary file. The file is opened such that we know it is unique and not in use by a...
static TheBESKeys * TheKeys()
Access to the singleton.
static bool read_bool_key(const std::string &key, bool default_value)
Read a boolean-valued key from the bes.conf file.
static std::string read_string_key(const std::string &key, const std::string &default_value)
Read a string-valued key from the bes.conf file.
RemoteResource()=default
The default constructor is here to ease testing. Remove if not needed. jhrg 3/8/23.
virtual ~RemoteResource()
utility class for the HTTP catalog module