Merge branch 'phoenix' into tcp_rate_limiting
This commit is contained in:
commit
873a0ea70d
14 changed files with 98 additions and 31 deletions
|
|
@ -171,7 +171,7 @@ namespace fc
|
||||||
FC_DECLARE_EXCEPTION( out_of_range_exception, "Out of Range" );
|
FC_DECLARE_EXCEPTION( out_of_range_exception, "Out of Range" );
|
||||||
|
|
||||||
/** @brief if an operation is unsupported or not valid this may be thrown */
|
/** @brief if an operation is unsupported or not valid this may be thrown */
|
||||||
FC_DECLARE_EXCEPTION( invalidOperation_exception, "Invalid Operation" );
|
FC_DECLARE_EXCEPTION( invalid_operation_exception, "Invalid Operation" );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief used to report a canceled Operation
|
* @brief used to report a canceled Operation
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,13 @@ namespace fc
|
||||||
*
|
*
|
||||||
* @return *this
|
* @return *this
|
||||||
*/
|
*/
|
||||||
virtual iprocess& exec( const fc::path& exe, std::vector<std::string> args,
|
virtual iprocess& exec( const path& exe, std::vector<std::string> args,
|
||||||
const fc::path& work_dir = fc::path(), exec_opts opts = open_all ) = 0;
|
const path& work_dir = path(), exec_opts opts = open_all ) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return blocks until the process exits
|
* @return blocks until the process exits
|
||||||
*/
|
*/
|
||||||
virtual int result() = 0;
|
virtual int result(const microseconds& timeout = microseconds::maximum()) = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,16 +48,16 @@ namespace fc
|
||||||
/**
|
/**
|
||||||
* @brief returns a stream that writes to the process' stdin
|
* @brief returns a stream that writes to the process' stdin
|
||||||
*/
|
*/
|
||||||
virtual fc::buffered_ostream_ptr in_stream() = 0;
|
virtual buffered_ostream_ptr in_stream() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief returns a stream that reads from the process' stdout
|
* @brief returns a stream that reads from the process' stdout
|
||||||
*/
|
*/
|
||||||
virtual fc::buffered_istream_ptr out_stream() = 0;
|
virtual buffered_istream_ptr out_stream() = 0;
|
||||||
/**
|
/**
|
||||||
* @brief returns a stream that reads from the process' stderr
|
* @brief returns a stream that reads from the process' stderr
|
||||||
*/
|
*/
|
||||||
virtual fc::buffered_istream_ptr err_stream() = 0;
|
virtual buffered_istream_ptr err_stream() = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@ namespace fc {
|
||||||
const fc::path& work_dir = fc::path(),
|
const fc::path& work_dir = fc::path(),
|
||||||
exec_opts opts = open_all );
|
exec_opts opts = open_all );
|
||||||
|
|
||||||
virtual int result();
|
|
||||||
|
virtual int result(const microseconds& timeout = microseconds::maximum());
|
||||||
virtual void kill();
|
virtual void kill();
|
||||||
virtual fc::buffered_ostream_ptr in_stream();
|
virtual fc::buffered_ostream_ptr in_stream();
|
||||||
virtual fc::buffered_istream_ptr out_stream();
|
virtual fc::buffered_istream_ptr out_stream();
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ namespace fc
|
||||||
template<typename IntType, typename EnumType>
|
template<typename IntType, typename EnumType>
|
||||||
void to_variant( const enum_type<IntType,EnumType>& var, variant& vo )
|
void to_variant( const enum_type<IntType,EnumType>& var, variant& vo )
|
||||||
{
|
{
|
||||||
vo = var.value;
|
vo = (EnumType)var.value;
|
||||||
}
|
}
|
||||||
template<typename IntType, typename EnumType>
|
template<typename IntType, typename EnumType>
|
||||||
void from_variant( const variant& var, enum_type<IntType,EnumType>& vo )
|
void from_variant( const variant& var, enum_type<IntType,EnumType>& vo )
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@ namespace fc
|
||||||
static string to_string( const variant& v );
|
static string to_string( const variant& v );
|
||||||
static string to_pretty_string( const variant& v );
|
static string to_pretty_string( const variant& v );
|
||||||
|
|
||||||
|
static bool is_valid( const std::string& json_str );
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void save_to_file( const T& v, const fc::path& fi, bool pretty = true )
|
static void save_to_file( const T& v, const fc::path& fi, bool pretty = true )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,12 @@ struct unsigned_int {
|
||||||
* Uses the google protobuf algorithm for seralizing signed numbers
|
* Uses the google protobuf algorithm for seralizing signed numbers
|
||||||
*/
|
*/
|
||||||
struct signed_int {
|
struct signed_int {
|
||||||
signed_int( int32_t v = 0 ):value(v){}
|
signed_int( int64_t v = 0 ):value(v){}
|
||||||
operator int32_t()const { return value; }
|
operator int32_t()const { return value; }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
signed_int& operator=( const T& v ) { value = v; return *this; }
|
signed_int& operator=( const T& v ) { value = v; return *this; }
|
||||||
|
signed_int& operator++(int){ ++value; return *this; }
|
||||||
|
signed_int& operator++(){ ++value; return *this; }
|
||||||
|
|
||||||
int32_t value;
|
int32_t value;
|
||||||
};
|
};
|
||||||
|
|
@ -50,4 +52,16 @@ void from_variant( const variant& var, unsigned_int& vo );
|
||||||
|
|
||||||
} // namespace fc
|
} // namespace fc
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template<>
|
||||||
|
struct hash<fc::signed_int>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
size_t operator()(const fc::signed_int &a) const
|
||||||
|
{
|
||||||
|
return std::hash<int32_t>()(a.value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ template<> struct reflector<ENUM> { \
|
||||||
switch( elem ) { \
|
switch( elem ) { \
|
||||||
BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_TO_STRING, ENUM, FIELDS ) \
|
BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_TO_STRING, ENUM, FIELDS ) \
|
||||||
default: \
|
default: \
|
||||||
fc::throw_bad_enum_cast( BOOST_PP_STRINGIZE(elem), BOOST_PP_STRINGIZE(ENUM) ); \
|
fc::throw_bad_enum_cast( fc::to_string(int64_t(elem)).c_str(), BOOST_PP_STRINGIZE(ENUM) ); \
|
||||||
}\
|
}\
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
} \
|
} \
|
||||||
|
|
|
||||||
|
|
@ -21,4 +21,9 @@ namespace fc {
|
||||||
template<> struct get_typename<value> { static const char* name() { return "value"; } };
|
template<> struct get_typename<value> { static const char* name() { return "value"; } };
|
||||||
template<> struct get_typename<std::vector<char>> { static const char* name() { return "std::vector<char>"; } };
|
template<> struct get_typename<std::vector<char>> { static const char* name() { return "std::vector<char>"; } };
|
||||||
|
|
||||||
|
struct signed_int;
|
||||||
|
struct unsigned_int;
|
||||||
|
template<> struct get_typename<signed_int> { static const char* name() { return "signed_int"; } };
|
||||||
|
template<> struct get_typename<unsigned_int> { static const char* name() { return "unsigned_int"; } };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ namespace fc
|
||||||
eof_exception_code = 11,
|
eof_exception_code = 11,
|
||||||
db_in_use_exception_code = 12,
|
db_in_use_exception_code = 12,
|
||||||
std_exception_code = 14,
|
std_exception_code = 14,
|
||||||
|
invalid_operation_exception_code = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
void to_variant( detail::exception_code e, variant& v )
|
void to_variant( detail::exception_code e, variant& v )
|
||||||
|
|
@ -69,6 +70,9 @@ namespace fc
|
||||||
case db_in_use_exception_code:
|
case db_in_use_exception_code:
|
||||||
v = "db_in_use";
|
v = "db_in_use";
|
||||||
break;
|
break;
|
||||||
|
case invalid_operation_exception_code:
|
||||||
|
v = "invalid_operation";
|
||||||
|
break;
|
||||||
case unspecified_exception_code:
|
case unspecified_exception_code:
|
||||||
default:
|
default:
|
||||||
v = "unspecified";
|
v = "unspecified";
|
||||||
|
|
@ -79,20 +83,21 @@ namespace fc
|
||||||
void from_variant( const variant& e, detail::exception_code& ll )
|
void from_variant( const variant& e, detail::exception_code& ll )
|
||||||
{
|
{
|
||||||
string v = e.as_string();
|
string v = e.as_string();
|
||||||
if( v == "unspecified" ) ll = unspecified_exception_code;
|
if( v == "unspecified" ) ll = unspecified_exception_code;
|
||||||
else if( v == "unhandled" ) ll = unhandled_exception_code;
|
else if( v == "unhandled" ) ll = unhandled_exception_code;
|
||||||
else if( v == "timeout" ) ll = timeout_exception_code;
|
else if( v == "timeout" ) ll = timeout_exception_code;
|
||||||
else if( v == "key_not_found" ) ll = key_not_found_exception_code;
|
else if( v == "key_not_found" ) ll = key_not_found_exception_code;
|
||||||
else if( v == "bad_cast" ) ll = bad_cast_exception_code;
|
else if( v == "bad_cast" ) ll = bad_cast_exception_code;
|
||||||
else if( v == "file_not_found" ) ll = file_not_found_exception_code;
|
else if( v == "file_not_found" ) ll = file_not_found_exception_code;
|
||||||
else if( v == "parse_error" ) ll = parse_error_exception_code;
|
else if( v == "parse_error" ) ll = parse_error_exception_code;
|
||||||
else if( v == "invalid_arg" ) ll = invalid_arg_exception_code;
|
else if( v == "invalid_arg" ) ll = invalid_arg_exception_code;
|
||||||
else if( v == "out_of_range" ) ll = out_of_range_exception_code;
|
else if( v == "out_of_range" ) ll = out_of_range_exception_code;
|
||||||
else if( v == "canceled" ) ll = canceled_exception_code;
|
else if( v == "canceled" ) ll = canceled_exception_code;
|
||||||
else if( v == "assert" ) ll = assert_exception_code;
|
else if( v == "assert" ) ll = assert_exception_code;
|
||||||
else if( v == "std" ) ll = std_exception_code;
|
else if( v == "std" ) ll = std_exception_code;
|
||||||
else if( v == "eof" ) ll = eof_exception_code;
|
else if( v == "eof" ) ll = eof_exception_code;
|
||||||
else if( v == "db_in_use") ll = db_in_use_exception_code;
|
else if( v == "db_in_use") ll = db_in_use_exception_code;
|
||||||
|
else if( v == "invalid_operation") ll = invalid_operation_exception_code;
|
||||||
else FC_THROW_EXCEPTION( bad_cast_exception,
|
else FC_THROW_EXCEPTION( bad_cast_exception,
|
||||||
"Invalid Error Report _code '${code}'",
|
"Invalid Error Report _code '${code}'",
|
||||||
("code", v) );
|
("code", v) );
|
||||||
|
|
@ -178,6 +183,7 @@ namespace fc
|
||||||
FC_EXCEPTION_IMPL(key_not_found_exception)
|
FC_EXCEPTION_IMPL(key_not_found_exception)
|
||||||
FC_EXCEPTION_IMPL(bad_cast_exception)
|
FC_EXCEPTION_IMPL(bad_cast_exception)
|
||||||
FC_EXCEPTION_IMPL(out_of_range_exception)
|
FC_EXCEPTION_IMPL(out_of_range_exception)
|
||||||
|
FC_EXCEPTION_IMPL(invalid_operation_exception);
|
||||||
FC_EXCEPTION_IMPL(canceled_exception)
|
FC_EXCEPTION_IMPL(canceled_exception)
|
||||||
FC_EXCEPTION_IMPL(assert_exception)
|
FC_EXCEPTION_IMPL(assert_exception)
|
||||||
FC_EXCEPTION_IMPL(eof_exception)
|
FC_EXCEPTION_IMPL(eof_exception)
|
||||||
|
|
@ -295,6 +301,8 @@ namespace fc
|
||||||
throw eof_exception( my->_elog );
|
throw eof_exception( my->_elog );
|
||||||
case detail::db_in_use_exception_code:
|
case detail::db_in_use_exception_code:
|
||||||
throw db_in_use_exception( my->_elog );
|
throw db_in_use_exception( my->_elog );
|
||||||
|
case detail::invalid_operation_exception_code:
|
||||||
|
throw invalid_operation_exception( my->_elog );
|
||||||
case detail::std_exception_code:
|
case detail::std_exception_code:
|
||||||
throw std_exception( *this );
|
throw std_exception( *this );
|
||||||
case detail::unspecified_exception_code:
|
case detail::unspecified_exception_code:
|
||||||
|
|
@ -330,6 +338,8 @@ namespace fc
|
||||||
return std::make_shared<eof_exception>( my->_elog );
|
return std::make_shared<eof_exception>( my->_elog );
|
||||||
case detail::db_in_use_exception_code:
|
case detail::db_in_use_exception_code:
|
||||||
return std::make_shared<db_in_use_exception>( my->_elog );
|
return std::make_shared<db_in_use_exception>( my->_elog );
|
||||||
|
case detail::invalid_operation_exception_code:
|
||||||
|
return std::make_shared<invalid_operation_exception>( my->_elog );
|
||||||
case detail::std_exception_code:
|
case detail::std_exception_code:
|
||||||
return std::make_shared<std_exception>( *this );
|
return std::make_shared<std_exception>( *this );
|
||||||
case detail::unspecified_exception_code:
|
case detail::unspecified_exception_code:
|
||||||
|
|
|
||||||
|
|
@ -179,9 +179,9 @@ fc::buffered_istream_ptr process::err_stream() {
|
||||||
return my->_err;
|
return my->_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int process::result()
|
int process::result(const microseconds& timeout /* = microseconds::maximum() */)
|
||||||
{
|
{
|
||||||
return my->_exited.wait();
|
return my->_exited.wait(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -608,8 +608,17 @@ namespace fc
|
||||||
|
|
||||||
void json::save_to_file( const variant& v, const fc::path& fi, bool pretty )
|
void json::save_to_file( const variant& v, const fc::path& fi, bool pretty )
|
||||||
{
|
{
|
||||||
|
if( pretty )
|
||||||
|
{
|
||||||
|
auto str = json::to_pretty_string( v );
|
||||||
|
fc::ofstream o(fi);
|
||||||
|
o.write( str.c_str(), str.size() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fc::ofstream o(fi);
|
fc::ofstream o(fi);
|
||||||
fc::to_stream( o, v );
|
fc::to_stream( o, v );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
variant json::from_file( const fc::path& p )
|
variant json::from_file( const fc::path& p )
|
||||||
{
|
{
|
||||||
|
|
@ -640,4 +649,14 @@ namespace fc
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool json::is_valid( const std::string& utf8_str )
|
||||||
|
{
|
||||||
|
if( utf8_str.size() == 0 ) return false;
|
||||||
|
fc::stringstream in( utf8_str );
|
||||||
|
variant_from_stream( in );
|
||||||
|
try { in.peek(); } catch ( const eof_exception& e ) { return true; }
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // fc
|
} // fc
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,8 @@ namespace fc {
|
||||||
auto ap = appender::get( *a );
|
auto ap = appender::get( *a );
|
||||||
if( ap ) { lgr.add_appender(ap); }
|
if( ap ) { lgr.add_appender(ap); }
|
||||||
}
|
}
|
||||||
return reg_console_appender || reg_file_appender;
|
|
||||||
}
|
}
|
||||||
|
return reg_console_appender || reg_file_appender;
|
||||||
} catch ( exception& e )
|
} catch ( exception& e )
|
||||||
{
|
{
|
||||||
fc::cerr<<e.to_detail_string()<<"\n";
|
fc::cerr<<e.to_detail_string()<<"\n";
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ namespace fc { namespace http {
|
||||||
}
|
}
|
||||||
ss << "Content-Length: "<<body_length<<"\r\n\r\n";
|
ss << "Content-Length: "<<body_length<<"\r\n\r\n";
|
||||||
auto s = ss.str();
|
auto s = ss.str();
|
||||||
fc::cerr<<s<<"\n";
|
//fc::cerr<<s<<"\n";
|
||||||
con->get_socket().write( s.c_str(), s.size() );
|
con->get_socket().write( s.c_str(), s.size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ namespace fc { namespace http {
|
||||||
http::server::response rep( fc::shared_ptr<response::impl>( new response::impl(c) ) );
|
http::server::response rep( fc::shared_ptr<response::impl>( new response::impl(c) ) );
|
||||||
auto req = c->read_request();
|
auto req = c->read_request();
|
||||||
if( do_on_req ) do_on_req( req, rep );
|
if( do_on_req ) do_on_req( req, rep );
|
||||||
c->get_socket().close();
|
c->get_socket().close();
|
||||||
} catch ( fc::exception& e ) {
|
} catch ( fc::exception& e ) {
|
||||||
wlog( "unable to read request ${1}", ("1", e.to_detail_string() ) );//fc::except_str().c_str());
|
wlog( "unable to read request ${1}", ("1", e.to_detail_string() ) );//fc::except_str().c_str());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,14 @@ namespace fc {
|
||||||
FC_ASSERT(my->_sock.is_open());
|
FC_ASSERT(my->_sock.is_open());
|
||||||
boost::asio::socket_base::reuse_address option(enable);
|
boost::asio::socket_base::reuse_address option(enable);
|
||||||
my->_sock.set_option(option);
|
my->_sock.set_option(option);
|
||||||
|
#if defined(__APPLE__) || (defined(__linux__) && defined(SO_REUSEPORT))
|
||||||
|
// OSX needs SO_REUSEPORT in addition to SO_REUSEADDR.
|
||||||
|
// This probably needs to be set for any BSD
|
||||||
|
int reuseport_value = 1;
|
||||||
|
if (setsockopt(my->_sock.native(), SOL_SOCKET, SO_REUSEPORT,
|
||||||
|
(char*)&reuseport_value, sizeof(reuseport_value)) < 0)
|
||||||
|
wlog("Error setting SO_REUSEPORT");
|
||||||
|
#endif // __APPLE__
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -209,6 +217,14 @@ namespace fc {
|
||||||
my = new impl;
|
my = new impl;
|
||||||
boost::asio::ip::tcp::acceptor::reuse_address option(enable);
|
boost::asio::ip::tcp::acceptor::reuse_address option(enable);
|
||||||
my->_accept.set_option(option);
|
my->_accept.set_option(option);
|
||||||
|
#if defined(__APPLE__) || (defined(__linux__) && defined(SO_REUSEPORT))
|
||||||
|
// OSX needs SO_REUSEPORT in addition to SO_REUSEADDR.
|
||||||
|
// This probably needs to be set for any BSD
|
||||||
|
int reuseport_value = 1;
|
||||||
|
if (setsockopt(my->_accept.native(), SOL_SOCKET, SO_REUSEPORT,
|
||||||
|
(char*)&reuseport_value, sizeof(reuseport_value)) < 0)
|
||||||
|
wlog("Error setting SO_REUSEPORT");
|
||||||
|
#endif // __APPLE__
|
||||||
}
|
}
|
||||||
void tcp_server::listen( uint16_t port )
|
void tcp_server::listen( uint16_t port )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue