Skip to content

Commit

Permalink
Use notion of selected Protocol
Browse files Browse the repository at this point in the history
- use Protocol value instead of flags isSsl, isHttp, isHttps in the server/client implementation

Re ECFLOW-1957
  • Loading branch information
marcosbento committed Oct 21, 2024
1 parent 3eb760f commit 6a27b3e
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 51 deletions.
17 changes: 17 additions & 0 deletions libs/base/src/ecflow/base/ServerProtocol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,23 @@ static inline Protocol from_configuration_encoding(const std::string& encoding)
throw std::runtime_error("Invalid encoding");
}

static inline std::string scheme_for(Protocol protocol) {
switch (protocol) {
case Protocol::Http:
return "http";
case Protocol::Https:
return "https";
case Protocol::Plain:
case Protocol::Ssl:
default:
return "";
}
}

static inline bool is_any_variation_of_http(Protocol protocol) {
return protocol == Protocol::Http || protocol == Protocol::Https;
}

} // namespace ecf

#endif /* ecflow_base_ServerProtocol_HPP */
8 changes: 4 additions & 4 deletions libs/client/src/ecflow/client/ClientEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "ecflow/core/Converter.hpp"
#include "ecflow/core/Ecf.hpp"
#include "ecflow/core/Enumerate.hpp"
#include "ecflow/core/Environment.hpp"
#include "ecflow/core/File.hpp"
#include "ecflow/core/Host.hpp"
Expand Down Expand Up @@ -245,10 +246,9 @@ void ClientEnvironment::read_environment_variables() {

ecf::environment::get(ecf::environment::ECF_TRYNO, task_try_num_);

std::string host_protocol;
ecf::environment::get(ecf::environment::ECF_HOST_PROTOCOL, host_protocol);
if (host_protocol == "HTTP" || host_protocol == "HTTPS") {
http_ = true;
if (auto protocol = ecf::environment::fetch(ecf::environment::ECF_HOST_PROTOCOL); protocol) {
auto found = ecf::Enumerate<ecf::Protocol>::to_enum(protocol.value());
protocol_ = found ? found.value() : ecf::Protocol::Plain;
}

ecf::environment::get("ECF_HOSTFILE", host_file_);
Expand Down
29 changes: 15 additions & 14 deletions libs/client/src/ecflow/client/ClientEnvironment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#ifdef ECF_OPENSSL
#include "ecflow/base/Openssl.hpp"
#endif
#include "ecflow/base/ServerProtocol.hpp"

class ClientEnvironment final : public AbstractClientEnv {
public:
Expand Down Expand Up @@ -90,29 +91,30 @@ class ClientEnvironment final : public AbstractClientEnv {
// Used by python to enable debug of client api
void set_debug(bool flag);

bool http() const { return http_; }
void enable_http() {
http_ = true;
scheme_ = "http";
}
void enable_https() {
http_ = true;
scheme_ = "https";
}
std::string scheme() const { return scheme_; }
ecf::Protocol protocol() const { return protocol_; }
void enable_http() { protocol_ = ecf::Protocol::Http; }
void enable_https() { protocol_ = ecf::Protocol::Https; }

#ifdef ECF_OPENSSL
/// return true if this is a ssl enabled server
ecf::Openssl& openssl() { return ssl_; }
bool ssl() const { return ssl_.enabled(); }
void enable_ssl_if_defined() {
protocol_ = ecf::Protocol::Ssl;
ssl_.enable_if_defined(host(), port());
} // IF ECF_SSL=1,search server.crt, ELSE search <host>.<port>.crt
void enable_ssl() { ssl_.enable(host(), port()); } // search server.crt first, then <host>.<port>.crt
void enable_ssl() {
protocol_ = ecf::Protocol::Ssl;
ssl_.enable(host(), port());
} // search server.crt first, then <host>.<port>.crt
bool enable_ssl_no_throw() {
protocol_ = ecf::Protocol::Ssl;
return ssl_.enable_no_throw(host(), port());
} // search server.crt first, then <host>.<port>.crt
void disable_ssl() { ssl_.disable(); } // override environment setting for ECF_SSL
void disable_ssl() {
protocol_ = ecf::Protocol::Plain;
ssl_.disable();
} // override environment setting for ECF_SSL
#endif

// AbstractClientEnv functions:
Expand Down Expand Up @@ -179,8 +181,7 @@ class ClientEnvironment final : public AbstractClientEnv {
bool denied_{false}; // ECF_DENIED.If the server denies the communication, then the child command can be set to fail
// immediately
bool no_ecf_{false}; // NO_ECF. if defined then abort cmd immediately. useful when test jobs stand-alone
bool http_{false};
std::string scheme_{"http"}; // default is https
ecf::Protocol protocol_{ecf::Protocol::Plain};
bool debug_{false}; // For live debug, enabled by env variable ECF_CLIENT_DEBUG or set by option -d|--debug
bool under_test_{false}; // Used in testing client interface
bool host_file_read_{false}; // to ensure we read host file only once
Expand Down
6 changes: 3 additions & 3 deletions libs/client/src/ecflow/client/ClientInvoker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,12 +444,13 @@ int ClientInvoker::do_invoke_cmd(Cmd_ptr cts_cmd) const {
}
else
#endif
if (clientEnv_.http()) {
if (ecf::is_any_variation_of_http(clientEnv_.protocol())) {
if (clientEnv_.debug()) {
cout << TimeStamp::now() << "ClientInvoker: >>> Using HTTP client <<<" << endl;
}

HttpClient theClient(cts_cmd, clientEnv_.scheme(), clientEnv_.host(), clientEnv_.port());
const std::string scheme = ecf::scheme_for(clientEnv_.protocol());
HttpClient theClient(cts_cmd, scheme, clientEnv_.host(), clientEnv_.port());
theClient.run();

if (clientEnv_.debug()) {
Expand All @@ -470,7 +471,6 @@ int ClientInvoker::do_invoke_cmd(Cmd_ptr cts_cmd) const {
}
}
else {

if (clientEnv_.debug()) {
cout << TimeStamp::now() << "ClientInvoker: >>> Using TCP/IP client (without SSL) <<<"
<< endl;
Expand Down
18 changes: 8 additions & 10 deletions libs/rest/src/ecflow/http/HttpServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ void read_environment() {
ecf::environment::get("ECF_RESTAPI_NOSSL", opts.no_ssl);
ecf::environment::get("ECF_RESTAPI_POLLING_INTERVAL", opts.polling_interval);
ecf::environment::get("ECF_RESTAPI_PORT", opts.port);
ecf::environment::get("ECF_HOST", opts.ecflow_host);
ecf::environment::get("ECF_PORT", opts.ecflow_port);
ecf::environment::get(ecf::environment::ECF_HOST, opts.ecflow_host);
ecf::environment::get(ecf::environment::ECF_PORT, opts.ecflow_port);
ecf::environment::get("ECF_RESTAPI_TOKENS_FILE", opts.tokens_file);
ecf::environment::get("ECF_RESTAPI_CERT_DIRECTORY", opts.cert_directory);
ecf::environment::get("ECF_RESTAPI_MAX_UPDATE_INTERVAL", opts.max_polling_interval);
ecf::environment::get("ECF_HOST_PROTOCOL", opts.host_protocol);
ecf::environment::get(ecf::environment::ECF_HOST_PROTOCOL, opts.host_protocol);
}

void HttpServer::parse_args(int argc, char** argv) const {
Expand Down Expand Up @@ -87,19 +87,17 @@ void HttpServer::parse_args(int argc, char** argv) const {
opts.host_protocol = "HTTPS";
}

setenv("ECF_HOST", opts.ecflow_host.c_str(), 1);
setenv("ECF_PORT", ecf::convert_to<std::string>(opts.ecflow_port).c_str(), 1);
setenv("ECF_HOST_PROTOCOL", opts.host_protocol.c_str(), 1);
setenv(ecf::environment::ECF_HOST, opts.ecflow_host.c_str(), 1);
setenv(ecf::environment::ECF_PORT, ecf::convert_to<std::string>(opts.ecflow_port).c_str(), 1);
setenv(ecf::environment::ECF_HOST_PROTOCOL, opts.host_protocol.c_str(), 1);
// Unset these, otherwise ClientInvoker will automatically
// try to use them
unsetenv("ECF_PASSWD");
unsetenv("ECF_CUSTOM_PASSWD");
unsetenv(ecf::environment::ECF_PASSWD);
unsetenv(ecf::environment::ECF_CUSTOM_PASSWD);
}

void apply_listeners(httplib::Server& http_server) {

// TODO[MB]: Needs to be further refactored

const auto dump_headers = [](const httplib::Headers& headers, std::stringstream& ss) {
for (const auto& [key, value] : headers) {
ss << key << ": " << value << "\n";
Expand Down
20 changes: 10 additions & 10 deletions libs/server/src/ecflow/server/ServerEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ ServerEnvironment::ServerEnvironment(int argc, char* argv[])
submitJobsInterval_(defaultSubmitJobsInterval),
ecf_prune_node_log_(0),
jobGeneration_(true),
http_(false),
protocol_{ecf::Protocol::Plain},
debug_(false),
help_option_(false),
version_option_(false),
Expand All @@ -89,7 +89,7 @@ ServerEnvironment::ServerEnvironment(int argc, char* argv[], const std::string&
submitJobsInterval_(defaultSubmitJobsInterval),
ecf_prune_node_log_(0),
jobGeneration_(true),
http_(false),
protocol_{ecf::Protocol::Plain},
debug_(false),
help_option_(false),
version_option_(false),
Expand Down Expand Up @@ -788,7 +788,7 @@ std::string ServerEnvironment::dump() const {

std::vector<std::string> ServerEnvironment::expected_variables() {
std::vector<std::string> expected_variables;
expected_variables.push_back(ecf::environment::ECF_HOME);
expected_variables.emplace_back(ecf::environment::ECF_HOME);
expected_variables.emplace_back("ECF_LOG");
expected_variables.emplace_back("ECF_CHECK");
expected_variables.emplace_back("ECF_CHECKOLD");
Expand All @@ -799,18 +799,18 @@ std::vector<std::string> ServerEnvironment::expected_variables() {
expected_variables.emplace_back("ECF_URL_CMD");
expected_variables.emplace_back("ECF_URL_BASE");
expected_variables.emplace_back("ECF_URL");
expected_variables.emplace_back("ECF_MICRO");
expected_variables.emplace_back(ecf::environment::ECF_MICRO);
expected_variables.emplace_back("ECF_PID");
expected_variables.emplace_back("ECF_VERSION");
expected_variables.emplace_back("ECF_LISTS");
expected_variables.push_back(ecf::environment::ECF_PORT);
expected_variables.push_back(ecf::environment::ECF_HOST);
expected_variables.emplace_back(ecf::environment::ECF_PORT);
expected_variables.emplace_back(ecf::environment::ECF_HOST);
expected_variables.emplace_back("ECF_INTERVAL");
expected_variables.emplace_back("ECF_PASSWD");
expected_variables.emplace_back("ECF_CUSTOM_PASSWD");
expected_variables.emplace_back(ecf::environment::ECF_PASSWD);
expected_variables.emplace_back(ecf::environment::ECF_CUSTOM_PASSWD);
#ifdef ECF_OPENSSL
if (ecf::environment::has("ECF_SSL")) {
expected_variables.emplace_back("ECF_SSL");
if (ecf::environment::has(ecf::environment::ECF_SSL)) {
expected_variables.emplace_back(ecf::environment::ECF_SSL);
}
#endif
return expected_variables;
Expand Down
10 changes: 7 additions & 3 deletions libs/server/src/ecflow/server/ServerEnvironment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <boost/asio.hpp>

#include "ecflow/base/ServerProtocol.hpp"
#include "ecflow/core/CheckPt.hpp"
#include "ecflow/core/Host.hpp"
#include "ecflow/core/PasswdFile.hpp"
Expand Down Expand Up @@ -66,10 +67,13 @@ class ServerEnvironment {
/// return true if ssl enable via command line, AND SSL libraries are found
ecf::Openssl& openssl() { return ssl_; }
bool ssl() const { return ssl_.enabled(); }
void enable_ssl() { ssl_.enable(serverHost_, the_port()); } // search server.crt first, then <host>.<port>.crt
void enable_ssl() {
protocol_ = ecf::Protocol::Ssl;
ssl_.enable(serverHost_, the_port());
} // search server.crt first, then <host>.<port>.crt
#endif

bool http() const { return http_; }
ecf::Protocol protocol() const { return protocol_; }

/// returns the server port. This has a default value defined in server_environment.cfg
/// but can be overridden by the environment variable ECF_PORT
Expand Down Expand Up @@ -210,7 +214,7 @@ class ServerEnvironment {
int submitJobsInterval_;
int ecf_prune_node_log_;
bool jobGeneration_; // used in debug/test mode only
bool http_;
ecf::Protocol protocol_;
bool debug_;
bool help_option_;
bool version_option_;
Expand Down
3 changes: 2 additions & 1 deletion libs/server/src/ecflow/server/ServerMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ int main(int argc, char* argv[]) {
boost::asio::io_context io;

// Launching Http server
if (server_environment.http()) {
if (ecf::is_any_variation_of_http(server_environment.protocol())) {
// On the server side, we actually only support HTTP
HttpServer theServer(io, server_environment);
return run(theServer);
}
Expand Down
2 changes: 1 addition & 1 deletion libs/server/src/ecflow/server/ServerOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ ServerOptions::ServerOptions(int argc, char* argv[], ServerEnvironment* env) {
if (env->debug_) {
cout << "ServerOptions:: Deploying HTTP Server\n";
}
env->http_ = true;
env->protocol_ = ecf::Protocol::Http;
}

if (vm_.count("port")) {
Expand Down
11 changes: 6 additions & 5 deletions libs/udp/src/ecflow/udp/UDPServerMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <iostream>
#include <string>

#include "ecflow/core/Environment.hpp"
#include "ecflow/core/ecflow_version.h"
#include "ecflow/udp/RequestHandler.hpp"
#include "ecflow/udp/Trace.hpp"
Expand Down Expand Up @@ -76,18 +77,18 @@ int main(int argc, char* argv[]) try {
auto ecflow_host = options.get_optional_option<std::string>(ecf::UDPServerOptions::OPTION_ECFLOW_HOST);
auto ecflow_port = options.get_optional_option<size_t>(ecf::UDPServerOptions::OPTION_ECFLOW_PORT);
if (ecflow_host) {
setenv("ECF_HOST", ecflow_host.value().c_str(), 1);
setenv(ecf::environment::ECF_HOST, ecflow_host.value().c_str(), 1);
}
if (ecflow_port) {
setenv("ECF_PORT", std::to_string(ecflow_port.value()).c_str(), 1);
setenv(ecf::environment::ECF_PORT, std::to_string(ecflow_port.value()).c_str(), 1);
}
auto ecflow_http = options.has_http();
if (ecflow_http) {
setenv("ECF_HOST_PROTOCOL", "HTTPS", 1);
setenv(ecf::environment::ECF_HOST_PROTOCOL, "HTTP", 1);
}
// Avoid that the Client automatically uses environment passwords
unsetenv("ECF_PASSWD");
unsetenv("ECF_CUSTOM_PASSWD");
unsetenv(ecf::environment::ECF_PASSWD);
unsetenv(ecf::environment::ECF_CUSTOM_PASSWD);

launch_server(options);
}
Expand Down

0 comments on commit 6a27b3e

Please sign in to comment.