From bc1792dc98cd7490cbea22614a23a08970a46e8d Mon Sep 17 00:00:00 2001 From: valzav Date: Fri, 2 May 2014 14:46:15 -0700 Subject: [PATCH 1/9] commented out http header printed to stdout --- src/network/http/http_server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/http/http_server.cpp b/src/network/http/http_server.cpp index 28a12cd..095ba0c 100644 --- a/src/network/http/http_server.cpp +++ b/src/network/http/http_server.cpp @@ -32,7 +32,7 @@ namespace fc { namespace http { } ss << "Content-Length: "<get_socket().write( s.c_str(), s.size() ); } @@ -76,7 +76,7 @@ namespace fc { namespace http { http::server::response rep( fc::shared_ptr( new response::impl(c) ) ); auto req = c->read_request(); if( do_on_req ) do_on_req( req, rep ); - c->get_socket().close(); + c->get_socket().close(); } catch ( fc::exception& e ) { wlog( "unable to read request ${1}", ("1", e.to_detail_string() ) );//fc::except_str().c_str()); } From 3a34299199bf56aec4077392d7e10d1189ae3a0f Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 7 May 2014 21:27:37 -0400 Subject: [PATCH 2/9] update json validation and varint hashing --- include/fc/io/enum_type.hpp | 2 +- include/fc/io/json.hpp | 2 ++ include/fc/io/varint.hpp | 18 ++++++++++++++++-- include/fc/reflect/typename.hpp | 5 +++++ src/io/json.cpp | 10 ++++++++++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/fc/io/enum_type.hpp b/include/fc/io/enum_type.hpp index 2127ac2..0406976 100644 --- a/include/fc/io/enum_type.hpp +++ b/include/fc/io/enum_type.hpp @@ -50,7 +50,7 @@ namespace fc template void to_variant( const enum_type& var, variant& vo ) { - vo = var.value; + vo = (EnumType)var.value; } template void from_variant( const variant& var, enum_type& vo ) diff --git a/include/fc/io/json.hpp b/include/fc/io/json.hpp index eada29a..4931f9b 100644 --- a/include/fc/io/json.hpp +++ b/include/fc/io/json.hpp @@ -26,6 +26,8 @@ namespace fc static string to_string( const variant& v ); static string to_pretty_string( const variant& v ); + static bool is_valid( const std::string& json_str ); + template static void save_to_file( const T& v, const fc::path& fi, bool pretty = true ) { diff --git a/include/fc/io/varint.hpp b/include/fc/io/varint.hpp index c292bcc..ad4ac21 100644 --- a/include/fc/io/varint.hpp +++ b/include/fc/io/varint.hpp @@ -33,10 +33,12 @@ struct unsigned_int { * Uses the google protobuf algorithm for seralizing signed numbers */ 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; } template 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; }; @@ -50,4 +52,16 @@ void from_variant( const variant& var, unsigned_int& vo ); } // namespace fc - +#include +namespace std +{ + template<> + struct hash + { + public: + size_t operator()(const fc::signed_int &a) const + { + return std::hash()(a.value); + } + }; +} diff --git a/include/fc/reflect/typename.hpp b/include/fc/reflect/typename.hpp index 20cd1f6..9329023 100644 --- a/include/fc/reflect/typename.hpp +++ b/include/fc/reflect/typename.hpp @@ -21,4 +21,9 @@ namespace fc { template<> struct get_typename { static const char* name() { return "value"; } }; template<> struct get_typename> { static const char* name() { return "std::vector"; } }; + struct signed_int; + struct unsigned_int; + template<> struct get_typename { static const char* name() { return "signed_int"; } }; + template<> struct get_typename { static const char* name() { return "unsigned_int"; } }; + } diff --git a/src/io/json.cpp b/src/io/json.cpp index a746ddf..54b63f3 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -640,4 +640,14 @@ namespace fc 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 From 102e0c4ab81f50a3484fd9d5526a5e2a763dc4b8 Mon Sep 17 00:00:00 2001 From: valzav Date: Wed, 7 May 2014 20:58:54 -0700 Subject: [PATCH 3/9] fixed a bug in configure_logging that made adding more than one logger impossible --- src/log/logger_config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log/logger_config.cpp b/src/log/logger_config.cpp index a8fa079..22465de 100644 --- a/src/log/logger_config.cpp +++ b/src/log/logger_config.cpp @@ -47,8 +47,8 @@ namespace fc { auto ap = appender::get( *a ); if( ap ) { lgr.add_appender(ap); } } - return reg_console_appender || reg_file_appender; } + return reg_console_appender || reg_file_appender; } catch ( exception& e ) { fc::cerr< Date: Fri, 9 May 2014 11:50:18 -0400 Subject: [PATCH 4/9] change the naming of invalidOperation exception to the more fc-friendly invalid_operation, and add an implementation so it can be used. --- include/fc/exception/exception.hpp | 2 +- src/exception.cpp | 38 +++++++++++++++++++----------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/fc/exception/exception.hpp b/include/fc/exception/exception.hpp index 2db45d2..5b02e24 100644 --- a/include/fc/exception/exception.hpp +++ b/include/fc/exception/exception.hpp @@ -171,7 +171,7 @@ namespace fc FC_DECLARE_EXCEPTION( out_of_range_exception, "Out of Range" ); /** @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 diff --git a/src/exception.cpp b/src/exception.cpp index 8a73ab3..e6f7c0f 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -24,6 +24,7 @@ namespace fc eof_exception_code = 11, db_in_use_exception_code = 12, std_exception_code = 14, + invalid_operation_exception_code = 15 }; void to_variant( detail::exception_code e, variant& v ) @@ -69,6 +70,9 @@ namespace fc case db_in_use_exception_code: v = "db_in_use"; break; + case invalid_operation_exception_code: + v = "invalid_operation"; + break; case unspecified_exception_code: default: v = "unspecified"; @@ -79,20 +83,21 @@ namespace fc void from_variant( const variant& e, detail::exception_code& ll ) { string v = e.as_string(); - if( v == "unspecified" ) ll = unspecified_exception_code; - else if( v == "unhandled" ) ll = unhandled_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 == "bad_cast" ) ll = bad_cast_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 == "invalid_arg" ) ll = invalid_arg_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 == "assert" ) ll = assert_exception_code; - else if( v == "std" ) ll = std_exception_code; - else if( v == "eof" ) ll = eof_exception_code; - else if( v == "db_in_use") ll = db_in_use_exception_code; + if( v == "unspecified" ) ll = unspecified_exception_code; + else if( v == "unhandled" ) ll = unhandled_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 == "bad_cast" ) ll = bad_cast_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 == "invalid_arg" ) ll = invalid_arg_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 == "assert" ) ll = assert_exception_code; + else if( v == "std" ) ll = std_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 == "invalid_operation") ll = invalid_operation_exception_code; else FC_THROW_EXCEPTION( bad_cast_exception, "Invalid Error Report _code '${code}'", ("code", v) ); @@ -178,6 +183,7 @@ namespace fc FC_EXCEPTION_IMPL(key_not_found_exception) FC_EXCEPTION_IMPL(bad_cast_exception) FC_EXCEPTION_IMPL(out_of_range_exception) + FC_EXCEPTION_IMPL(invalid_operation_exception); FC_EXCEPTION_IMPL(canceled_exception) FC_EXCEPTION_IMPL(assert_exception) FC_EXCEPTION_IMPL(eof_exception) @@ -295,6 +301,8 @@ namespace fc throw eof_exception( my->_elog ); case detail::db_in_use_exception_code: throw db_in_use_exception( my->_elog ); + case detail::invalid_operation_exception_code: + throw invalid_operation_exception( my->_elog ); case detail::std_exception_code: throw std_exception( *this ); case detail::unspecified_exception_code: @@ -330,6 +338,8 @@ namespace fc return std::make_shared( my->_elog ); case detail::db_in_use_exception_code: return std::make_shared( my->_elog ); + case detail::invalid_operation_exception_code: + return std::make_shared( my->_elog ); case detail::std_exception_code: return std::make_shared( *this ); case detail::unspecified_exception_code: From 8d4fccba5fe5e48e01344022c416c7d091ab6f2a Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 11 May 2014 20:33:08 -0400 Subject: [PATCH 5/9] update pretty print save to file --- src/io/json.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/io/json.cpp b/src/io/json.cpp index 54b63f3..7fa05e8 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -608,8 +608,17 @@ namespace fc 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::to_stream( o, v ); + } } variant json::from_file( const fc::path& p ) { From 0a11b299846b48f0d04c51e4d32c9edc84a6e93e Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 13 May 2014 16:41:27 -0400 Subject: [PATCH 6/9] update error reporting --- include/fc/reflect/reflect.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fc/reflect/reflect.hpp b/include/fc/reflect/reflect.hpp index da62732..361a646 100644 --- a/include/fc/reflect/reflect.hpp +++ b/include/fc/reflect/reflect.hpp @@ -136,7 +136,7 @@ template<> struct reflector { \ switch( elem ) { \ BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_TO_STRING, ENUM, FIELDS ) \ 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; \ } \ From eb501387e8e81947eb4b6df611a897d246e2db4a Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Tue, 13 May 2014 21:14:40 -0700 Subject: [PATCH 7/9] Set the SO_REUSEPORT flag on OS X whenever we set the SO_REUSEADDR --- src/network/tcp_socket.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/network/tcp_socket.cpp b/src/network/tcp_socket.cpp index b9fdab7..b1a6dbe 100644 --- a/src/network/tcp_socket.cpp +++ b/src/network/tcp_socket.cpp @@ -136,6 +136,14 @@ namespace fc { FC_ASSERT(my->_sock.is_open()); boost::asio::socket_base::reuse_address option(enable); my->_sock.set_option(option); +#if defined(__APPLE__) + // 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__ } @@ -187,6 +195,14 @@ namespace fc { my = new impl; boost::asio::ip::tcp::acceptor::reuse_address option(enable); my->_accept.set_option(option); +#if defined(__APPLE__) + // 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 ) { From db7b1bdd69a46ab099cab95eee4c12fe49d6eb1c Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Wed, 14 May 2014 08:51:30 -0400 Subject: [PATCH 8/9] Add an optional timeout parameter when waiting for a local process to exit --- include/fc/interprocess/iprocess.hpp | 12 ++++++------ include/fc/interprocess/process.hpp | 3 ++- src/interprocess/process.cpp | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/fc/interprocess/iprocess.hpp b/include/fc/interprocess/iprocess.hpp index 3dcbfed..0f8671e 100644 --- a/include/fc/interprocess/iprocess.hpp +++ b/include/fc/interprocess/iprocess.hpp @@ -31,13 +31,13 @@ namespace fc * * @return *this */ - virtual iprocess& exec( const fc::path& exe, std::vector args, - const fc::path& work_dir = fc::path(), exec_opts opts = open_all ) = 0; + virtual iprocess& exec( const path& exe, std::vector args, + const path& work_dir = path(), exec_opts opts = open_all ) = 0; /** * @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 */ - 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 */ - 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 */ - virtual fc::buffered_istream_ptr err_stream() = 0; + virtual buffered_istream_ptr err_stream() = 0; }; diff --git a/include/fc/interprocess/process.hpp b/include/fc/interprocess/process.hpp index eb13a4a..28333ef 100644 --- a/include/fc/interprocess/process.hpp +++ b/include/fc/interprocess/process.hpp @@ -20,7 +20,8 @@ namespace fc { const fc::path& work_dir = fc::path(), exec_opts opts = open_all ); - virtual int result(); + + virtual int result(const microseconds& timeout = microseconds::maximum()); virtual void kill(); virtual fc::buffered_ostream_ptr in_stream(); virtual fc::buffered_istream_ptr out_stream(); diff --git a/src/interprocess/process.cpp b/src/interprocess/process.cpp index 5cb46d6..5504138 100644 --- a/src/interprocess/process.cpp +++ b/src/interprocess/process.cpp @@ -179,9 +179,9 @@ fc::buffered_istream_ptr process::err_stream() { return my->_err; } -int process::result() +int process::result(const microseconds& timeout /* = microseconds::maximum() */) { - return my->_exited.wait(); + return my->_exited.wait(timeout); } } From 50ac462471feddd82dd395c284b469fd2e44c06b Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Wed, 14 May 2014 16:02:41 -0400 Subject: [PATCH 9/9] Enable SO_REUSEPORT on Linux as well as OS X --- src/network/tcp_socket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/tcp_socket.cpp b/src/network/tcp_socket.cpp index b1a6dbe..c4b0e11 100644 --- a/src/network/tcp_socket.cpp +++ b/src/network/tcp_socket.cpp @@ -136,7 +136,7 @@ namespace fc { FC_ASSERT(my->_sock.is_open()); boost::asio::socket_base::reuse_address option(enable); my->_sock.set_option(option); -#if defined(__APPLE__) +#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; @@ -195,7 +195,7 @@ namespace fc { my = new impl; boost::asio::ip::tcp::acceptor::reuse_address option(enable); my->_accept.set_option(option); -#if defined(__APPLE__) +#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;