aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/include/net
diff options
context:
space:
mode:
authorLee Clagett <code@leeclagett.com>2017-01-25 00:16:05 -0500
committerLee Clagett <code@leeclagett.com>2017-01-25 15:39:32 -0500
commitc02e1cb943903d34becfaf1c6d9cd71e4424d748 (patch)
treea363ce155ba8f6b14a924c84380ec2886894f22d /contrib/epee/include/net
parentMerge pull request #1622 (diff)
downloadmonero-c02e1cb943903d34becfaf1c6d9cd71e4424d748.tar.xz
Updates to epee HTTP client code
- http_simple_client now uses std::chrono for timeouts - http_simple_client accepts timeouts per connect / invoke call - shortened names of epee http invoke functions - invoke command functions only take relative path, connection is not automatically performed
Diffstat (limited to 'contrib/epee/include/net')
-rw-r--r--contrib/epee/include/net/http_client.h94
-rw-r--r--contrib/epee/include/net/http_client_abstract_invoke.h101
-rw-r--r--contrib/epee/include/net/net_helper.h51
3 files changed, 63 insertions, 183 deletions
diff --git a/contrib/epee/include/net/http_client.h b/contrib/epee/include/net/http_client.h
index a54318ebb..c5aeb9251 100644
--- a/contrib/epee/include/net/http_client.h
+++ b/contrib/epee/include/net/http_client.h
@@ -263,7 +263,6 @@ using namespace std;
blocked_mode_client m_net_client;
std::string m_host_buff;
std::string m_port;
- unsigned int m_timeout;
std::string m_header_cache;
http_response_info m_response_info;
size_t m_len_in_summary;
@@ -276,23 +275,43 @@ using namespace std;
critical_section m_lock;
public:
- void set_host_name(const std::string& name)
+ explicit http_simple_client()
+ : i_target_handler()
+ , m_net_client()
+ , m_host_buff()
+ , m_port()
+ , m_header_cache()
+ , m_response_info()
+ , m_len_in_summary(0)
+ , m_len_in_remain(0)
+ , m_pcontent_encoding_handler(nullptr)
+ , m_state()
+ , m_chunked_state()
+ , m_chunked_cache()
+ , m_lock()
+ {}
+
+ bool set_server(const std::string& address)
+ {
+ http::url_content parsed{};
+ const bool r = parse_url(address, parsed);
+ CHECK_AND_ASSERT_MES(r, false, "failed to parse url: " << address);
+ set_server(std::move(parsed.host), std::to_string(parsed.port));
+ return true;
+ }
+
+ void set_server(std::string host, std::string port)
{
CRITICAL_REGION_LOCAL(m_lock);
- m_host_buff = name;
+ disconnect();
+ m_host_buff = std::move(host);
+ m_port = std::move(port);
}
- bool connect(const std::string& host, int port, unsigned int timeout)
- {
- return connect(host, std::to_string(port), timeout);
- }
- bool connect(const std::string& host, const std::string& port, unsigned int timeout)
+
+ bool connect(std::chrono::milliseconds timeout)
{
CRITICAL_REGION_LOCAL(m_lock);
- m_host_buff = host;
- m_port = port;
- m_timeout = timeout;
-
- return m_net_client.connect(host, port, timeout, timeout);
+ return m_net_client.connect(m_host_buff, m_port, timeout);
}
//---------------------------------------------------------------------------
bool disconnect()
@@ -316,20 +335,20 @@ using namespace std;
}
//---------------------------------------------------------------------------
inline
- bool invoke_get(const std::string& uri, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
+ bool invoke_get(const std::string& uri, std::chrono::milliseconds timeout, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
{
CRITICAL_REGION_LOCAL(m_lock);
- return invoke(uri, "GET", body, ppresponse_info, additional_params);
+ return invoke(uri, "GET", body, timeout, ppresponse_info, additional_params);
}
//---------------------------------------------------------------------------
- inline bool invoke(const std::string& uri, const std::string& method, const std::string& body, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
+ inline bool invoke(const std::string& uri, const std::string& method, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
{
CRITICAL_REGION_LOCAL(m_lock);
if(!is_connected())
{
MDEBUG("Reconnecting...");
- if(!connect(m_host_buff, m_port, m_timeout))
+ if(!connect(timeout))
{
MDEBUG("Failed to connect to " << m_host_buff << ":" << m_port);
return false;
@@ -347,27 +366,27 @@ using namespace std;
req_buff += "\r\n";
//--
- bool res = m_net_client.send(req_buff);
+ bool res = m_net_client.send(req_buff, timeout);
CHECK_AND_ASSERT_MES(res, false, "HTTP_CLIENT: Failed to SEND");
if(body.size())
- res = m_net_client.send(body);
+ res = m_net_client.send(body, timeout);
CHECK_AND_ASSERT_MES(res, false, "HTTP_CLIENT: Failed to SEND");
if(ppresponse_info)
*ppresponse_info = &m_response_info;
m_state = reciev_machine_state_header;
- return handle_reciev();
+ return handle_reciev(timeout);
}
//---------------------------------------------------------------------------
- inline bool invoke_post(const std::string& uri, const std::string& body, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
+ inline bool invoke_post(const std::string& uri, const std::string& body, std::chrono::milliseconds timeout, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list())
{
CRITICAL_REGION_LOCAL(m_lock);
- return invoke(uri, "POST", body, ppresponse_info, additional_params);
+ return invoke(uri, "POST", body, timeout, ppresponse_info, additional_params);
}
private:
//---------------------------------------------------------------------------
- inline bool handle_reciev()
+ inline bool handle_reciev(std::chrono::milliseconds timeout)
{
CRITICAL_REGION_LOCAL(m_lock);
bool keep_handling = true;
@@ -377,7 +396,7 @@ using namespace std;
{
if(need_more_data)
{
- if(!m_net_client.recv(recv_buffer))
+ if(!m_net_client.recv(recv_buffer, timeout))
{
MERROR("Unexpected recv fail");
m_state = reciev_machine_state_error;
@@ -878,33 +897,6 @@ using namespace std;
return true;
}
};
-
-
-
- /************************************************************************/
- /* */
- /************************************************************************/
- //inline
- template<class t_transport>
- bool invoke_request(const std::string& url, t_transport& tr, unsigned int timeout, const http_response_info** ppresponse_info, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list())
- {
- http::url_content u_c;
- bool res = parse_url(url, u_c);
-
- if(!tr.is_connected() && !u_c.host.empty())
- {
- CHECK_AND_ASSERT_MES(res, false, "failed to parse url: " << url);
-
- if(!u_c.port)
- u_c.port = 80;//default for http
-
- res = tr.connect(u_c.host, static_cast<int>(u_c.port), timeout);
- CHECK_AND_ASSERT_MES(res, false, "failed to connect " << u_c.host << ":" << u_c.port);
- }
-
- return tr.invoke(u_c.uri, method, body, ppresponse_info, additional_params);
- }
-
}
}
}
diff --git a/contrib/epee/include/net/http_client_abstract_invoke.h b/contrib/epee/include/net/http_client_abstract_invoke.h
deleted file mode 100644
index 9b6ab4db8..000000000
--- a/contrib/epee/include/net/http_client_abstract_invoke.h
+++ /dev/null
@@ -1,101 +0,0 @@
-
-// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// * Neither the name of the Andrey N. Sabelnikov nor the
-// names of its contributors may be used to endorse or promote products
-// derived from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-
-#pragma once
-#include "storages/serializeble_struct_helper.h"
-
-#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net.http"
-
-namespace epee
-{
- namespace net_utils
- {
- namespace http
- {
- template<class TArg, class TResult, class TTransport>
- bool invoke_http_json_remote_command(const std::string& url, TArg& out_struct, TResult& result_struct, TTransport& transport, unsigned int timeout = 5000, const std::string& method = "GET")
- {
- std::string req_param;
- StorageNamed::InMemStorageSpace::json::store_t_to_json(out_struct, req_param);
-
- const http_response_info* pri = NULL;
- if(!invoke_request(url, transport, timeout, &pri, method, req_param))
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url);
- return false;
- }
-
- if(!pri->m_response_code)
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", internal error (null response ptr)");
- return false;
- }
-
- if(pri->m_response_code != 200)
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", wrong response code: " << pri->m_response_code);
- return false;
- }
-
- return StorageNamed::InMemStorageSpace::json::load_t_from_json(result_struct, pri->m_body);
- }
-
-
-
- template<class TArg, class TResult, class TTransport>
- bool invoke_http_bin_remote_command(const std::string& url, TArg& out_struct, TResult& result_struct, TTransport& transport, unsigned int timeout = 5000, const std::string& method = "GET")
- {
- std::string req_param;
- epee::StorageNamed::save_struct_as_storage_to_buff(out_struct, req_param);
-
- const http_response_info* pri = NULL;
- if(!invoke_request(url, transport, timeout, &pri, method, req_param))
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url);
- return false;
- }
-
- if(!pri->m_response_code)
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", internal error (null response ptr)");
- return false;
- }
-
- if(pri->m_response_code != 200)
- {
- LOG_PRINT_L1("Failed to invoke http request to " << url << ", wrong response code: " << pri->m_response_code);
- return false;
- }
-
- return epee::StorageNamed::load_struct_from_storage_buff(result_struct, pri->m_body);
- }
-
-
- }
- }
-}
diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h
index 22cea122f..432169990 100644
--- a/contrib/epee/include/net/net_helper.h
+++ b/contrib/epee/include/net/net_helper.h
@@ -37,6 +37,7 @@
#include <ostream>
#include <string>
#include <boost/asio.hpp>
+#include <boost/asio/steady_timer.hpp>
#include <boost/preprocessor/selection/min.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
@@ -98,7 +99,7 @@ namespace net_utils
// No deadline is required until the first socket operation is started. We
// set the deadline to positive infinity so that the actor takes no action
// until a specific deadline is set.
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
// Start the persistent actor that checks for deadline expiry.
check_deadline();
@@ -111,26 +112,16 @@ namespace net_utils
shutdown();
}
- inline void set_recv_timeout(int reciev_timeout)
- {
- m_reciev_timeout = reciev_timeout;
- }
-
inline
- bool connect(const std::string& addr, int port, unsigned int connect_timeout, unsigned int reciev_timeout, const std::string& bind_ip = "0.0.0.0")
+ bool connect(const std::string& addr, int port, std::chrono::milliseconds timeout, const std::string& bind_ip = "0.0.0.0")
{
- return connect(addr, std::to_string(port), connect_timeout, reciev_timeout, bind_ip);
+ return connect(addr, std::to_string(port), timeout, bind_ip);
}
inline
- bool connect(const std::string& addr, const std::string& port, unsigned int connect_timeout, unsigned int reciev_timeout, const std::string& bind_ip = "0.0.0.0")
+ bool connect(const std::string& addr, const std::string& port, std::chrono::milliseconds timeout, const std::string& bind_ip = "0.0.0.0")
{
- m_connect_timeout = connect_timeout;
- m_reciev_timeout = reciev_timeout;
m_connected = false;
- if(!m_reciev_timeout)
- m_reciev_timeout = m_connect_timeout;
-
try
{
m_socket.close();
@@ -164,7 +155,7 @@ namespace net_utils
}
- m_deadline.expires_from_now(boost::posix_time::milliseconds(m_connect_timeout));
+ m_deadline.expires_from_now(timeout);
boost::system::error_code ec = boost::asio::error::would_block;
@@ -179,7 +170,7 @@ namespace net_utils
if (!ec && m_socket.is_open())
{
m_connected = true;
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
return true;
}else
{
@@ -231,12 +222,12 @@ namespace net_utils
inline
- bool send(const std::string& buff)
+ bool send(const std::string& buff, std::chrono::milliseconds timeout)
{
try
{
- m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
+ m_deadline.expires_from_now(timeout);
// Set up the variable that receives the result of the asynchronous
// operation. The error code is set to would_block to signal that the
@@ -264,7 +255,7 @@ namespace net_utils
return false;
}else
{
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
}
}
@@ -322,7 +313,7 @@ namespace net_utils
return false;
}else
{
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
}
}
@@ -350,7 +341,7 @@ namespace net_utils
}
inline
- bool recv(std::string& buff)
+ bool recv(std::string& buff, std::chrono::milliseconds timeout)
{
try
@@ -358,7 +349,7 @@ namespace net_utils
// Set a deadline for the asynchronous operation. Since this function uses
// a composed operation (async_read_until), the deadline applies to the
// entire operation, rather than individual reads from the socket.
- m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
+ m_deadline.expires_from_now(timeout);
// Set up the variable that receives the result of the asynchronous
// operation. The error code is set to would_block to signal that the
@@ -404,7 +395,7 @@ namespace net_utils
}else
{
MTRACE("READ ENDS: Success. bytes_tr: " << bytes_transfered);
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
}
/*if(!bytes_transfered)
@@ -432,7 +423,7 @@ namespace net_utils
}
- inline bool recv_n(std::string& buff, int64_t sz)
+ inline bool recv_n(std::string& buff, int64_t sz, std::chrono::milliseconds timeout)
{
try
@@ -440,7 +431,7 @@ namespace net_utils
// Set a deadline for the asynchronous operation. Since this function uses
// a composed operation (async_read_until), the deadline applies to the
// entire operation, rather than individual reads from the socket.
- m_deadline.expires_from_now(boost::posix_time::milliseconds(m_reciev_timeout));
+ m_deadline.expires_from_now(timeout);
// Set up the variable that receives the result of the asynchronous
// operation. The error code is set to would_block to signal that the
@@ -477,7 +468,7 @@ namespace net_utils
return false;
}else
{
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
}
if(bytes_transfered != buff.size())
@@ -539,7 +530,7 @@ namespace net_utils
// Check whether the deadline has passed. We compare the deadline against
// the current time since a new asynchronous operation may have moved the
// deadline before this actor had a chance to run.
- if (m_deadline.expires_at() <= boost::asio::deadline_timer::traits_type::now())
+ if (m_deadline.expires_at() <= std::chrono::steady_clock::now())
{
// The deadline has passed. The socket is closed so that any outstanding
// asynchronous operations are cancelled. This allows the blocked
@@ -550,7 +541,7 @@ namespace net_utils
// There is no longer an active deadline. The expiry is set to positive
// infinity so that the actor takes no action until a new deadline is set.
- m_deadline.expires_at(boost::posix_time::pos_infin);
+ m_deadline.expires_at(std::chrono::steady_clock::time_point::max());
}
// Put the actor back to sleep.
@@ -562,11 +553,9 @@ namespace net_utils
protected:
boost::asio::io_service m_io_service;
boost::asio::ip::tcp::socket m_socket;
- int m_connect_timeout;
- int m_reciev_timeout;
bool m_initialized;
bool m_connected;
- boost::asio::deadline_timer m_deadline;
+ boost::asio::steady_timer m_deadline;
volatile uint32_t m_shutdowned;
};