From: Bjoern Sikora Date: Tue, 1 Sep 2009 09:38:21 +0000 (+0200) Subject: Introduced HTTPHelper class to easily perform HTTP operations within services. X-Git-Tag: v1.1~211 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=efbde53630234481ebcacebbd74ae22fad277cc7;p=bpdyndnsd Introduced HTTPHelper class to easily perform HTTP operations within services. Ensured that config reload will re-init all helper classes. --- diff --git a/src/config.cpp b/src/config.cpp index bcb5130..4d334af 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -118,7 +118,7 @@ Config::~Config() * @param argv[] Pointer to command line argument array given to main. * @return 0 if all is fine, -1 if not. */ -int Config::parse_cmd_line(int argc, char *argv[]) +int Config::parse_cmd_line(int argc, char *argv[], HTTPHelper::Ptr http_help) { try { @@ -159,7 +159,7 @@ int Config::parse_cmd_line(int argc, char *argv[]) if ( VariablesMap.count("dns_cache_ttl") ) dns_cache_ttl = VariablesMap["dns_cache_ttl"].as(); - Service::Ptr service = create_service(protocol,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl); + Service::Ptr service = create_service(protocol,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl,http_help); if ( service ) { ServiceHolder->add_service(service); @@ -248,11 +248,11 @@ int Config::parse_cmd_line(int argc, char *argv[]) * @param password Password. * @return A pointer to the created Service object. */ -Service::Ptr Config::create_service(const string &protocol,const string &hostname, const string &login, const string &password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl) +Service::Ptr Config::create_service(const string &protocol,const string &hostname, const string &login, const string &password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl, const HTTPHelper::Ptr http_help) { if(protocol == "dhs") { - Service::Ptr service_dhs(new DHS(protocol,hostname,login,password,Log,update_interval,max_updates_within_interval,dns_cache_ttl)); + Service::Ptr service_dhs(new DHS(protocol,hostname,login,password,Log,http_help,update_interval,max_updates_within_interval,dns_cache_ttl)); return service_dhs; } else if(protocol == "ods") @@ -274,7 +274,7 @@ Service::Ptr Config::create_service(const string &protocol,const string &hostnam * @param full_filename Filename of the service config file to load. * @return 0 if all is fine, -1 otherwise. */ -int Config::load_service_config_file(const string& full_filename) +int Config::load_service_config_file(const string& full_filename, const HTTPHelper::Ptr http_help) { Log->print_load_service_conf(full_filename); @@ -310,7 +310,7 @@ int Config::load_service_config_file(const string& full_filename) if ( vm.count("dns_cache_ttl") ) dns_cache_ttl = VariablesMap["dns_cache_ttl"].as(); - Service::Ptr service = create_service(protocol,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl); + Service::Ptr service = create_service(protocol,host,login,password,update_interval,max_updates_within_interval,dns_cache_ttl,http_help); if ( service ) { ServiceHolder->add_service(service); @@ -436,7 +436,7 @@ int Config::load_main_config_file(const string& full_filename) * @param config_path The path to the config directory. * @return 0 if all is fine, -1 otherwise */ -int Config::load_config_from_files() +int Config::load_config_from_files(const HTTPHelper::Ptr http_help) { fs::path full_config_path = fs::path(ConfigPath); @@ -459,7 +459,7 @@ int Config::load_config_from_files() else if ( boost::regex_search( actual_file,expr ) ) { string full_filename = dir_itr->path().string(); - if ( load_service_config_file(full_filename) != 0 ) + if ( load_service_config_file(full_filename,http_help) != 0 ) return -1; } } diff --git a/src/config.h b/src/config.h index 5fdac70..12f6e27 100644 --- a/src/config.h +++ b/src/config.h @@ -14,6 +14,7 @@ #include "logger.h" #include "serviceholder.h" +#include "httphelper.h" #include #include @@ -45,9 +46,9 @@ private: std::string ExternalWarningLog; int ExternalWarningLevel; - Service::Ptr create_service(const std::string &protocol,const std::string &hostname, const std::string &login, const std::string &password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl); + Service::Ptr create_service(const std::string &protocol,const std::string &hostname, const std::string &login, const std::string &password, const int update_interval, const int max_updates_within_interval, const int dns_cache_ttl, const HTTPHelper::Ptr http_help); int load_main_config_file(const std::string& full_filename); - int load_service_config_file(const std::string& full_filename); + int load_service_config_file(const std::string& full_filename, const HTTPHelper::Ptr http_help); public: @@ -57,9 +58,9 @@ public: ~Config(); - int parse_cmd_line(int argc, char *argv[]); + int parse_cmd_line(int argc, char *argv[], const HTTPHelper::Ptr http_help); - int load_config_from_files(); + int load_config_from_files(const HTTPHelper::Ptr http_help); Options_descriptionPtr get_opt_desc_cmd() const; diff --git a/src/dhs.cpp b/src/dhs.cpp index 9027a3a..9229a72 100644 --- a/src/dhs.cpp +++ b/src/dhs.cpp @@ -28,7 +28,7 @@ DHS::DHS() * @param _login The login name. * @param _password The corresponding password. */ -DHS::DHS(const string& _protocol, const string& _hostname, const string& _login, const string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval, const int _dns_cache_ttl) +DHS::DHS(const string& _protocol, const string& _hostname, const string& _login, const string& _password, const Logger::Ptr& _logger, const HTTPHelper::Ptr& _http_help, const int _update_interval, const int _max_updates_within_interval, const int _dns_cache_ttl) { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) set_update_interval(0); // use default protocol value @@ -50,6 +50,8 @@ DHS::DHS(const string& _protocol, const string& _hostname, const string& _login, set_login(_login); set_password(_password); set_logger(_logger); + + HTTPHelp = _http_help; } @@ -68,6 +70,8 @@ DHS::~DHS() */ int DHS::perform_update(const std::string& ip) { + + return 0; } diff --git a/src/dhs.h b/src/dhs.h index 9f95ca9..0196ae9 100644 --- a/src/dhs.h +++ b/src/dhs.h @@ -28,13 +28,15 @@ private: template void serialize(Archive & ar, const unsigned int version); + HTTPHelper::Ptr HTTPHelp; + public: typedef boost::shared_ptr Ptr; DHS(); - DHS(const std::string& _protocol, const std::string& _hostname, const std::string& _login, const std::string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval, const int dns_cache_ttl); + DHS(const std::string& _protocol, const std::string& _hostname, const std::string& _login, const std::string& _password, const Logger::Ptr& _logger, const HTTPHelper::Ptr& _http_help, const int _update_interval, const int _max_updates_within_interval, const int dns_cache_ttl); ~DHS(); diff --git a/src/httphelper.cpp b/src/httphelper.cpp new file mode 100644 index 0000000..927f2b3 --- /dev/null +++ b/src/httphelper.cpp @@ -0,0 +1,106 @@ +/** @file + * @brief HTTPHelper class implementation. This class represents a Helper to perform HTTP operations easily. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#include "httphelper.h" + +HTTPHelper::HTTPHelper() + : Proxy("") + , ProxyPort(0) + , Log(new Logger) +{ +} + +HTTPHelper::HTTPHelper(Logger::Ptr _log, string _proxy, int _proxy_port) +{ + Log = _log; + Proxy = _proxy; + ProxyPort = _proxy_port; + CurlEasyHandle = init_curl(CurlWritedataBuff, CurlErrBuff); +} + + +HTTPHelper::~HTTPHelper() +{ +} + + + +/** + * Perform a HTTP GET operation + * @param url URL for HTTP GET operation + * @return The data GET from the URL + */ +string HTTPHelper::http_get(const string& url) +{ + int curl_err_code; + + set_curl_url(url); + + if ( (curl_err_code = curl_easy_perform(CurlEasyHandle) ) != 0 ) + { + // TODO: Logging errors + return ""; + } + // Operation performed without any problems so we can return the CurlWritedataBuff + return CurlWritedataBuff; +} + + +/** + * Initialized curl easy handle with a few options. + * @param curl_writedata_buff Reference to a string wich will be filled with the curl result + * @param curl_err_buff A pointer to an char array which will be filled with error message. + * @return A pointer to the easy curl handle. + */ +CURL* HTTPHelper::init_curl(string& curl_writedata_buff,char* curl_err_buff) const +{ + CURL *curl_easy_handle = curl_easy_init(); + + curl_easy_setopt(curl_easy_handle,CURLOPT_NOPROGRESS,1); + curl_easy_setopt(curl_easy_handle,CURLOPT_CONNECTTIMEOUT,5); + curl_easy_setopt(curl_easy_handle,CURLOPT_TIMEOUT,10); + curl_easy_setopt(curl_easy_handle,CURLOPT_BUFFERSIZE,1024); + curl_easy_setopt(curl_easy_handle,CURLOPT_ERRORBUFFER,curl_err_buff); + curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEFUNCTION,http_receive); + curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEDATA,&curl_writedata_buff); + + if ( !Proxy.empty() ) + { + curl_easy_setopt(curl_easy_handle,CURLOPT_PROXY,Proxy.c_str()); + curl_easy_setopt(curl_easy_handle,CURLOPT_PROXYPORT,ProxyPort); + } + + return curl_easy_handle; +} + + +/** + * Sets a url to the easy curl handle + * @param url The url to set. + */ +void HTTPHelper::set_curl_url(const string& url) +{ + curl_easy_setopt(CurlEasyHandle,CURLOPT_URL,url.c_str()); +} + + +/** + * Callback Function is called every time CURL is receiving data from HTTPS-Server and will copy all received Data to the given stream pointer + * @param inBuffer Pointer to input. + * @param size How many mem blocks are received + * @param nmemb size of each memblock + * @param outBuffer Pointer to output stream. + * @return The size received. + */ +int HTTPHelper::http_receive( char *inBuffer, size_t size, size_t nmemb, string *outBuffer ) +{ + outBuffer->append(inBuffer); + return (size*nmemb); +} + diff --git a/src/httphelper.h b/src/httphelper.h new file mode 100644 index 0000000..67c894f --- /dev/null +++ b/src/httphelper.h @@ -0,0 +1,53 @@ +/** @file + * @brief HTTPHelper class header. This class represents a Helper to perform HTTP operations easily. + * + * + * + * @copyright Intra2net AG + * @license GPLv2 +*/ + +#ifndef HTTPHELPER_H +#define HTTPHELPER_H + +#include "logger.h" + +#include +#include + + +class HTTPHelper +{ +private: + + std::string Proxy; + int ProxyPort; + CURL* CurlEasyHandle; + std::string CurlWritedataBuff; + char* CurlErrBuff; + + Logger::Ptr Log; + +public: + + typedef boost::shared_ptr Ptr; + + HTTPHelper(); + + HTTPHelper(Logger::Ptr _log, std::string _proxy, int _proxy_port); + + ~HTTPHelper(); + + CURL* init_curl(std::string& curl_writedata_buff, char* curl_err_buff) const; + + + std::string http_get(const std::string& url); + + void set_curl_url(const std::string& url); + + // libcurl is a C library, so we have to make the callback member function static :-( + static int http_receive(char *inBuffer, size_t size, size_t nmemb, std::string *outBuffer); + +}; + +#endif diff --git a/src/iphelper.h b/src/iphelper.h index 95e2170..9cc74fa 100644 --- a/src/iphelper.h +++ b/src/iphelper.h @@ -15,9 +15,7 @@ #include #include -/** - @author Bjoern Sikora -*/ + class IPHelper { private: diff --git a/src/logger.cpp b/src/logger.cpp index 293c397..61d0cb0 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -68,7 +68,9 @@ void Logger::log_warning(const string& msg, int level) const { string external = ExternalWarningLog; external.append(" "); + external.append("\""); external.append(msg); + external.append("\""); int ret_val = system(external.c_str()); } } @@ -863,7 +865,7 @@ void Logger::print_webcheck_no_ip() const if ( (level <= Loglevel) || ((level <= ExternalWarningLevel) && (!ExternalWarningLog.empty())) ) { ostringstream msg; - msg << "This hosts' IP could not be determined through any configured webcheck url." << endl; + msg << "IP-Address of this host could not be determined through any configured webcheck url." << endl; log_warning(msg.str(),level); } } @@ -941,7 +943,7 @@ void Logger::print_regex_found_ip(const string& ip) const */ void Logger::print_regex_ip_not_found(const string& data) const { - int level = 0; + int level = 1; if ( (level <= Loglevel) || ((level <= ExternalWarningLevel) && (!ExternalWarningLog.empty())) ) { ostringstream msg; @@ -976,7 +978,7 @@ void Logger::print_multiple_cmd_option(const string& message) const */ void Logger::print_update_not_allowed(const int current_time, const int old_time, const int MaxUpdatesWithinInterval, const string& service) const { - int level = 0; + int level = 1; if ( (level <= Loglevel) || ((level <= ExternalWarningLevel) && (!ExternalWarningLog.empty())) ) { ostringstream msg; diff --git a/src/main.cpp b/src/main.cpp index 992bd22..ed86fd2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,7 @@ #include "serviceholder.cpp" #include "updater.cpp" #include "iphelper.cpp" +#include "httphelper.cpp" #include "serializeservicecontainer.cpp" @@ -274,12 +275,8 @@ int main(int argc, char *argv[]) updater = _updater; _updater.reset(); - // load the cmd options - if ( updater->init_config_from_cmd(argc,argv) != 0 ) - return -1; - - // load the config and service files - if ( updater->init_config_from_files() != 0 ) + // load config and initialize helper classes + if ( updater->load_config(argc,argv) != 0 ) return -1; // open pidfile and check for running process @@ -290,10 +287,6 @@ int main(int argc, char *argv[]) if ( init_signals() != 0) return -1; - // init the ip_helper - if ( updater->init_ip_helper() != 0 ) - return -1; - // init daemon_mode if enabled if ( init_daemon_mode(updater->get_config()->get_daemon_mode()) != 0 ) return -1; @@ -318,7 +311,6 @@ int main(int argc, char *argv[]) }while ( updater->get_config()->get_daemon_mode() == 1 ); - // Serialize services to save their actual state. if ( shutdown() != 0 ) return -1; diff --git a/src/updater.cpp b/src/updater.cpp index 0f35a65..bcb11ca 100644 --- a/src/updater.cpp +++ b/src/updater.cpp @@ -55,6 +55,57 @@ Updater::~Updater() } + +/** + * Load config and initialize helper classes. + * @param argc Number of arguments in array + * @param argv Array with cmd options + */ +int Updater::load_config(int argc, char *argv[]) +{ + // load the cmd options + if ( init_config_from_cmd(argc,argv) != 0 ) + return -1; + + // load the config and service files + if ( init_config_from_files() != 0 ) + return -1; + + // init all helper classes + if ( init_helper_classes() != 0 ) + return -1; + + return 0; +} + + +/** + * Reloading the config. Delete all Service objects and then init new Service objects from config files. + */ +int Updater::reload_config() +{ + // serialize all service objects + if ( ServiceHolder->serialize_services() != 0 ) + return -1; + + // delete all service objects + ServiceHolder->delete_services(); + + // delete the actual Variables_map, perhaps with old cmd options which would overwrite new config file options. + Conf->delete_variables_map(); + + // load only config files + if ( init_config_from_files() != 0 ) + return -1; + + // init all helper classes + if ( init_helper_classes() != 0 ) + return -1; + + return 0; +} + + /** * Parse the command line arguments and initialize corresponding options. * @param argc Number command line arguments. @@ -64,7 +115,7 @@ Updater::~Updater() int Updater::init_config_from_cmd(int argc, char *argv[]) { // Load the command line parameters - if( Conf->parse_cmd_line( argc, argv) != 0) + if( Conf->parse_cmd_line( argc, argv, HTTPHelp) != 0) return -1; // If we have loaded the cmd options we need to init the log facility immediately in case debugging is enabled from cmd. @@ -83,7 +134,7 @@ int Updater::init_config_from_cmd(int argc, char *argv[]) int Updater::init_config_from_files() { // Load the main and service config files in config path - if ( Conf->load_config_from_files() != 0 ) + if ( Conf->load_config_from_files(HTTPHelp) != 0 ) return -1; // Re-init log facility, perhaps new config file options for logger are set. @@ -101,22 +152,20 @@ int Updater::init_config_from_files() /** - * Getter for member Config. - * @return Member Config. + * Init all Helper classes + * @return */ -Config::Ptr Updater::get_config() const +int Updater::init_helper_classes() { - return Conf; -} + // Initialize IPHelper + if ( init_ip_helper() != 0 ) + return -1; + // Initialize HTTPHelper + if ( init_http_helper() != 0 ) + return -1; -/** - * Getter for member Logger. - * @return Member Logger. - */ -Logger::Ptr Updater::get_logger() const -{ - return Log; + return 0; } @@ -136,25 +185,37 @@ int Updater::init_ip_helper() /** - * Reloading the config. Delete all Service objects and then init new Service objects from config files. + * Init the IPHelp member with needed values. + * @return 0 if all is fine, -1 otherwise. */ -int Updater::reload_config() +int Updater::init_http_helper() { - // serialize all service objects - if ( ServiceHolder->serialize_services() != 0 ) - return -1; + // initialize IPHelper + HTTPHelper::Ptr _httphelp(new HTTPHelper(Log,Conf->get_proxy(),Conf->get_proxy_port())); + HTTPHelp = _httphelp; + _httphelp.reset(); - // delete all service objects - ServiceHolder->delete_services(); + return 0; +} - // delete the actual Variables_map, perhaps with old cmd options which would overwrite new config file options. - Conf->delete_variables_map(); - // load only config files - if ( init_config_from_files() != 0 ) - return -1; +/** + * Getter for member Config. + * @return Member Config. + */ +Config::Ptr Updater::get_config() const +{ + return Conf; +} - return 0; + +/** + * Getter for member Logger. + * @return Member Logger. + */ +Logger::Ptr Updater::get_logger() const +{ + return Log; } diff --git a/src/updater.h b/src/updater.h index d7cea0e..cc9bf13 100644 --- a/src/updater.h +++ b/src/updater.h @@ -12,6 +12,7 @@ #include "config.h" #include "iphelper.h" +#include "httphelper.h" #include "logger.h" #include "serviceholder.h" @@ -25,6 +26,7 @@ private: Config::Ptr Conf; IPHelper::Ptr IPHelp; + HTTPHelper::Ptr HTTPHelp; Logger::Ptr Log; Serviceholder::Ptr ServiceHolder; @@ -48,11 +50,17 @@ public: Serviceholder::Ptr get_service_holder() const; + int load_config(int argc, char *argv[]); + int reload_config(); + int init_helper_classes(); + void init_log_facility(); int init_ip_helper(); + + int init_http_helper(); }; #endif