diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..ccc5446 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,10 @@ +include: + - template: Jobs/Code-Quality.gitlab-ci.yml + +stages: + - test + +trigger_build_peerplays: + stage: test + script: + - "curl -X POST -F token=$CI_JOB_TOKEN -F ref=$REF_NAME https://gitlab.com/api/v4/projects/10735589/trigger/pipeline" diff --git a/.gitmodules b/.gitmodules index 0e539dc..b4e43d2 100755 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "vendor/secp256k1-zkp"] path = vendor/secp256k1-zkp url = https://github.com/bitshares/secp256k1-zkp.git +[submodule "vendor/editline"] + path = vendor/editline + url = https://github.com/troglobit/editline.git diff --git a/CMakeLists.txt b/CMakeLists.txt index bd52180..436af6c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,54 @@ else ( MSVC ) endif ( MSVC ) # End configure secp256k1-zkp +# Configure editline +if ( MSVC ) + # autoconf won't work here, hard code the defines + set( EDITLINE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline" ) + + file( GLOB EDITLINE_SOURCES "${EDITLINE_DIR}/src/editline.c" ) + add_library( editline ${EDITLINE_SOURCES} ) + + target_include_directories( editline PRIVATE "${EDITLINE_DIR}" PUBLIC "${EDITLINE_DIR}/include" ) + + set_target_properties( editline PROPERTIES COMPILE_DEFINITIONS LINKER_LANGUAGE C ) +else ( MSVC ) + include(ExternalProject) + if ( MINGW ) + ExternalProject_Add( project_editline + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/editline --host=x86_64-w64-mingw32 + BUILD_COMMAND make + INSTALL_COMMAND true + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline/src/project_editline-build/.libs/libeditline.a + ) + else ( MINGW ) + ExternalProject_Add( project_editline + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/editline + BUILD_COMMAND make + INSTALL_COMMAND true + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline/src/project_editline-build/.libs/libeditline.a + ) + endif ( MINGW ) + ExternalProject_Add_Step(project_editline autogen + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/autogen.sh + DEPENDERS configure + ) + + ExternalProject_Get_Property(project_editline binary_dir) + + add_library(editline STATIC IMPORTED) + set_property(TARGET editline PROPERTY IMPORTED_LOCATION ${binary_dir}/src/.libs/libeditline${CMAKE_STATIC_LIBRARY_SUFFIX}) + set_property(TARGET editline PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/include) + add_dependencies(editline project_editline) + install( FILES ${binary_dir}/src/.libs/libeditline${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION lib/cryptonomex ) +endif ( MSVC ) +# End configure editline + IF( WIN32 ) MESSAGE(STATUS "Configuring fc to build on Win32") @@ -168,6 +216,7 @@ set( fc_sources src/variant.cpp src/exception.cpp src/variant_object.cpp + src/static_variant.cpp src/thread/thread.cpp src/thread/thread_specific.cpp src/thread/future.cpp @@ -258,27 +307,17 @@ add_subdirectory( vendor/websocketpp EXCLUDE_FROM_ALL ) setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC ) install( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" DESTINATION include ) -# begin readline stuff -find_package(Curses) -find_package(Readline) - -file(GLOB HEADERS "include/bts/cli/*.hpp") - -if (READLINE_FOUND) - target_compile_definitions (fc PRIVATE HAVE_READLINE) - set(readline_libraries ${Readline_LIBRARY}) - if (CURSES_FOUND) - list(APPEND readline_libraries ${CURSES_LIBRARY}) - endif() - set(readline_includes ${Readline_INCLUDE_DIR}) -endif() +# begin editline stuff if(WIN32) target_compile_definitions( fc PRIVATE _CRT_NONSTDC_NO_DEPRECATE ) +else(WIN32) + target_compile_definitions( fc PRIVATE HAVE_EDITLINE ) + set( editline_libraries editline ) endif(WIN32) -# end readline stuff +# end editline stuff if( NOT CPP_STANDARD ) - set( CPP_STANDARD, "-std=c++11" ) + set( CPP_STANDARD "-std=c++11" ) endif() IF(WIN32) @@ -360,7 +399,6 @@ target_include_directories(fc ${OPENSSL_INCLUDE_DIR} "vendor/diff-match-patch-cpp-stl" ${CMAKE_CURRENT_SOURCE_DIR}/vendor/websocketpp - "${readline_includes}" PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp @@ -370,7 +408,7 @@ target_include_directories(fc IF(NOT WIN32) set(LINK_USR_LOCAL_LIB -L/usr/local/lib) ENDIF() -target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${readline_libraries} ${ECC_LIB} ) +target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${editline_libraries} ${ECC_LIB} ) if(MSVC) set_source_files_properties( src/network/http/websocket.cpp PROPERTIES COMPILE_FLAGS "/bigobj" ) @@ -495,3 +533,4 @@ ADD_CUSTOM_COMMAND(TARGET fc POST_BUILD ${POST_BUILD_STEP_COMMANDS} ) MESSAGE(STATUS "Finished fc module configuration...") + diff --git a/CMakeModules/FindReadline.cmake b/CMakeModules/FindReadline.cmake deleted file mode 100755 index 745cfe5..0000000 --- a/CMakeModules/FindReadline.cmake +++ /dev/null @@ -1,47 +0,0 @@ -# - Try to find readline include dirs and libraries -# -# Usage of this module as follows: -# -# find_package(Readline) -# -# Variables used by this module, they can change the default behaviour and need -# to be set before calling find_package: -# -# Readline_ROOT_DIR Set this variable to the root installation of -# readline if the module has problems finding the -# proper installation path. -# -# Variables defined by this module: -# -# READLINE_FOUND System has readline, include and lib dirs found -# Readline_INCLUDE_DIR The readline include directories. -# Readline_LIBRARY The readline library. - -find_path(Readline_ROOT_DIR - NAMES include/readline/readline.h -) - -find_path(Readline_INCLUDE_DIR - NAMES readline/readline.h - HINTS ${Readline_ROOT_DIR}/include -) - -find_library(Readline_LIBRARY - NAMES readline - HINTS ${Readline_ROOT_DIR}/lib -) - -if(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY) - set(READLINE_FOUND TRUE) -else(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY) - FIND_LIBRARY(Readline_LIBRARY NAMES readline) - include(FindPackageHandleStandardArgs) - FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG Readline_INCLUDE_DIR Readline_LIBRARY ) - MARK_AS_ADVANCED(Readline_INCLUDE_DIR Readline_LIBRARY) -endif(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY) - -mark_as_advanced( - Readline_ROOT_DIR - Readline_INCLUDE_DIR - Readline_LIBRARY -) diff --git a/include/fc/array.hpp b/include/fc/array.hpp index 541cd69..d11a3bb 100755 --- a/include/fc/array.hpp +++ b/include/fc/array.hpp @@ -115,7 +115,9 @@ namespace fc { memcpy(&bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); } else - memset( &bi, char(0), sizeof(bi) ); + for (size_t i = 0; i < bi.size(); i++) { + bi.data[i] = 0; + } } diff --git a/include/fc/crypto/openssl.hpp b/include/fc/crypto/openssl.hpp index af883d6..fc0a98b 100755 --- a/include/fc/crypto/openssl.hpp +++ b/include/fc/crypto/openssl.hpp @@ -8,6 +8,7 @@ #include #include #include +#include /** * @file openssl.hpp diff --git a/include/fc/crypto/rand.hpp b/include/fc/crypto/rand.hpp index 749547f..8979ba7 100755 --- a/include/fc/crypto/rand.hpp +++ b/include/fc/crypto/rand.hpp @@ -4,5 +4,5 @@ namespace fc { /* provides access to the OpenSSL random number generator */ void rand_bytes(char* buf, int count); - void rand_pseudo_bytes(char* buf, int count); + //void rand_pseudo_bytes(char* buf, int count); } // namespace fc diff --git a/include/fc/network/http/websocket.hpp b/include/fc/network/http/websocket.hpp index a42c1f8..6cfd66c 100755 --- a/include/fc/network/http/websocket.hpp +++ b/include/fc/network/http/websocket.hpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include @@ -26,14 +26,14 @@ namespace fc { namespace http { void on_message_handler( const std::function& h ) { _on_message = h; } void on_http_handler( const std::function& h ) { _on_http = h; } - void set_session_data( fc::any d ){ _session_data = std::move(d); } - fc::any& get_session_data() { return _session_data; } + void set_session_data( boost::any d ){ _session_data = std::move(d); } + boost::any& get_session_data() { return _session_data; } virtual std::string get_request_header(const std::string& key) = 0; fc::signal closed; private: - fc::any _session_data; + boost::any _session_data; std::function _on_message; std::function _on_http; }; @@ -53,6 +53,8 @@ namespace fc { namespace http { uint16_t get_listening_port(); void start_accept(); + void stop_listening(); + void close(); private: friend class detail::websocket_server_impl; std::unique_ptr my; @@ -84,6 +86,10 @@ namespace fc { namespace http { websocket_connection_ptr connect( const std::string& uri ); websocket_connection_ptr secure_connect( const std::string& uri ); + + void close(); + void synchronous_close(); + private: std::unique_ptr my; std::unique_ptr smy; diff --git a/include/fc/optional.hpp b/include/fc/optional.hpp index bb760a5..4737b06 100755 --- a/include/fc/optional.hpp +++ b/include/fc/optional.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace fc { @@ -23,12 +24,13 @@ namespace fc { public: typedef T value_type; - optional():_valid(false){} + optional():_valid(false){ memset(_value, 0, sizeof(_value)); } ~optional(){ reset(); } optional( optional& o ) :_valid(false) { + memset(_value, 0, sizeof(_value)); if( o._valid ) new (ptr()) T( *o ); _valid = o._valid; } @@ -36,6 +38,7 @@ namespace fc { optional( const optional& o ) :_valid(false) { + memset(_value, 0, sizeof(_value)); if( o._valid ) new (ptr()) T( *o ); _valid = o._valid; } @@ -43,6 +46,7 @@ namespace fc { optional( optional&& o ) :_valid(false) { + memset(_value, 0, sizeof(_value)); if( o._valid ) new (ptr()) T( fc::move(*o) ); _valid = o._valid; o.reset(); @@ -52,6 +56,7 @@ namespace fc { optional( const optional& o ) :_valid(false) { + memset(_value, 0, sizeof(_value)); if( o._valid ) new (ptr()) T( *o ); _valid = o._valid; } @@ -60,6 +65,7 @@ namespace fc { optional( optional& o ) :_valid(false) { + memset(_value, 0, sizeof(_value)); if( o._valid ) { new (ptr()) T( *o ); @@ -71,6 +77,7 @@ namespace fc { optional( optional&& o ) :_valid(false) { + memset(_value, 0, sizeof(_value)); if( o._valid ) new (ptr()) T( fc::move(*o) ); _valid = o._valid; o.reset(); @@ -80,6 +87,7 @@ namespace fc { optional( U&& u ) :_valid(true) { + memset(_value, 0, sizeof(_value)); new ((char*)ptr()) T( fc::forward(u) ); } diff --git a/include/fc/rpc/websocket_api.hpp b/include/fc/rpc/websocket_api.hpp index ebb6fe7..2b228aa 100755 --- a/include/fc/rpc/websocket_api.hpp +++ b/include/fc/rpc/websocket_api.hpp @@ -10,7 +10,7 @@ namespace fc { namespace rpc { class websocket_api_connection : public api_connection { public: - websocket_api_connection( fc::http::websocket_connection& c, uint32_t max_conversion_depth ); + websocket_api_connection(const std::shared_ptr &c, uint32_t max_conversion_depth ); ~websocket_api_connection(); virtual variant send_call( @@ -29,7 +29,7 @@ namespace fc { namespace rpc { const std::string& message, bool send_message = true ); - fc::http::websocket_connection& _connection; + std::shared_ptr _connection; fc::rpc::state _rpc_state; }; diff --git a/include/fc/static_variant.hpp b/include/fc/static_variant.hpp index ed8c66f..aa753a3 100755 --- a/include/fc/static_variant.hpp +++ b/include/fc/static_variant.hpp @@ -1,4 +1,5 @@ -/** This source adapted from https://github.com/kmicklas/variadic-static_variant + +/** This source adapted from https://github.com/kmicklas/variadic-static_variant Now available at https://github.com/kmicklas/variadic-variant. * * Copyright (C) 2013 Kenneth Micklas * @@ -13,21 +14,15 @@ #include #include #include - namespace fc { - // Implementation details, the user should not import this: namespace impl { - template struct storage_ops; - template struct position; - template struct type_info; - template struct copy_construct { @@ -40,7 +35,6 @@ struct copy_construct sv.init(v); } }; - template struct move_construct { @@ -53,25 +47,19 @@ struct move_construct sv.init( std::move(v) ); } }; - template struct storage_ops { static void del(int n, void *data) {} static void con(int n, void *data) {} - template static typename visitor::result_type apply(int n, void *data, visitor& v) {} - template static typename visitor::result_type apply(int n, void *data, const visitor& v) {} - template static typename visitor::result_type apply(int n, const void *data, visitor& v) {} - template static typename visitor::result_type apply(int n, const void *data, const visitor& v) {} }; - template struct storage_ops { static void del(int n, void *data) { @@ -82,32 +70,27 @@ struct storage_ops { if(n == N) new(reinterpret_cast(data)) T(); else storage_ops::con(n, data); } - template static typename visitor::result_type apply(int n, void *data, visitor& v) { if(n == N) return v(*reinterpret_cast(data)); else return storage_ops::apply(n, data, v); } - template static typename visitor::result_type apply(int n, void *data, const visitor& v) { if(n == N) return v(*reinterpret_cast(data)); else return storage_ops::apply(n, data, v); } - template static typename visitor::result_type apply(int n, const void *data, visitor& v) { if(n == N) return v(*reinterpret_cast(data)); else return storage_ops::apply(n, data, v); } - template static typename visitor::result_type apply(int n, const void *data, const visitor& v) { if(n == N) return v(*reinterpret_cast(data)); else return storage_ops::apply(n, data, v); } }; - template struct storage_ops { static void del(int n, void *data) { @@ -116,7 +99,6 @@ struct storage_ops { static void con(int n, void *data) { FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." ); } - template static typename visitor::result_type apply(int n, void *data, visitor& v) { FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." ); @@ -134,22 +116,18 @@ struct storage_ops { FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." ); } }; - template struct position { static const int pos = -1; }; - template struct position { static const int pos = 0; }; - template struct position { static const int pos = position::pos != -1 ? position::pos + 1 : -1; }; - template struct type_info { static const bool no_reference_types = false; @@ -157,7 +135,6 @@ struct type_info { static const size_t size = type_info::size > sizeof(T&) ? type_info::size : sizeof(T&); static const size_t count = 1 + type_info::count; }; - template struct type_info { static const bool no_reference_types = type_info::no_reference_types; @@ -165,7 +142,6 @@ struct type_info { static const size_t size = type_info::size > sizeof(T) ? type_info::size : sizeof(T&); static const size_t count = 1 + type_info::count; }; - template<> struct type_info<> { static const bool no_reference_types = true; @@ -174,48 +150,94 @@ struct type_info<> { static const size_t size = 0; }; -} // namespace impl +template +size_t size( TTag ) +{ + return 0; +} +template +size_t size( TTag tag ) +{ + if (tag <= 0) + { + return sizeof(A); + } + + return size( --tag ); +} + + +class dynamic_storage +{ + char* storage; +public: + dynamic_storage(); + + ~dynamic_storage(); + + void* data() const; + + void alloc( size_t size ); + + void release(); +}; + +} // namespace impl template class static_variant { + using tag_type = int64_t; + static_assert(impl::type_info::no_reference_types, "Reference types are not permitted in static_variant."); static_assert(impl::type_info::no_duplicates, "static_variant type arguments contain duplicate types."); - int _tag; - char storage[impl::type_info::size]; - template + using type_in_typelist = typename std::enable_if::pos != -1, X>::type; // type is in typelist of static_variant. + + + int _tag; + impl::dynamic_storage storage; + template> void init(const X& x) { _tag = impl::position::pos; - new(storage) X(x); + storage.alloc( sizeof(X) ); + new(storage.data()) X(x); } - - template + template> void init(X&& x) { _tag = impl::position::pos; - new(storage) X( std::move(x) ); + storage.alloc( sizeof(X) ); + new(storage.data()) X( std::move(x) ); } + void init(tag_type tag) + { + FC_ASSERT( tag >= 0 ); + FC_ASSERT( tag < count() ); + _tag = tag; + storage.alloc( impl::size( tag ) ); + impl::storage_ops<0, Types...>::con(_tag, storage.data()); + } + + void clean() + { + impl::storage_ops<0, Types...>::del(_tag, storage.data() ); + storage.release(); + } template friend struct impl::copy_construct; template friend struct impl::move_construct; public: - template + template> struct tag { - static_assert( - impl::position::pos != -1, - "Type not in static_variant." - ); static const int value = impl::position::pos; }; static_variant() { - _tag = 0; - impl::storage_ops<0, Types...>::con(0, storage); - } - + init(0); + } template static_variant( const static_variant& cpy ) { @@ -225,46 +247,34 @@ public: { cpy.visit( impl::copy_construct(*this) ); } - static_variant( static_variant&& mv ) { mv.visit( impl::move_construct(*this) ); } - - template + template> static_variant(const X& v) { - static_assert( - impl::position::pos != -1, - "Type not in static_variant." - ); init(v); } ~static_variant() { - impl::storage_ops<0, Types...>::del(_tag, storage); + clean(); } - - - template + template> static_variant& operator=(const X& v) { - static_assert( - impl::position::pos != -1, - "Type not in static_variant." - ); - this->~static_variant(); + clean(); init(v); return *this; } static_variant& operator=( const static_variant& v ) { if( this == &v ) return *this; - this->~static_variant(); + clean(); v.visit( impl::copy_construct(*this) ); return *this; } static_variant& operator=( static_variant&& v ) { if( this == &v ) return *this; - this->~static_variant(); + clean(); v.visit( impl::move_construct(*this) ); return *this; } @@ -276,98 +286,73 @@ public: { return a.which() < b.which(); } - - template + template> X& get() { - static_assert( - impl::position::pos != -1, - "Type not in static_variant." - ); if(_tag == impl::position::pos) { - void* tmp(storage); - return *reinterpret_cast(tmp); + return *reinterpret_cast(storage.data()); } else { FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename::name()) ); - // std::string("static_variant does not contain value of type ") + typeid(X).name() - // ); } } - template + template> const X& get() const { - static_assert( - impl::position::pos != -1, - "Type not in static_variant." - ); if(_tag == impl::position::pos) { - const void* tmp(storage); - return *reinterpret_cast(tmp); + return *reinterpret_cast(storage.data()); } else { FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename::name()) ); } } template typename visitor::result_type visit(visitor& v) { - return impl::storage_ops<0, Types...>::apply(_tag, storage, v); + return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v); } - template typename visitor::result_type visit(const visitor& v) { - return impl::storage_ops<0, Types...>::apply(_tag, storage, v); + return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v); } - template typename visitor::result_type visit(visitor& v)const { - return impl::storage_ops<0, Types...>::apply(_tag, storage, v); + return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v); } - template typename visitor::result_type visit(const visitor& v)const { - return impl::storage_ops<0, Types...>::apply(_tag, storage, v); + return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v); } - static int count() { return impl::type_info::count; } void set_which( int w ) { + FC_ASSERT( w >= 0 ); FC_ASSERT( w < count() ); - this->~static_variant(); - _tag = w; - impl::storage_ops<0, Types...>::con(_tag, storage); + clean(); + init(w); } - int which() const {return _tag;} }; - template struct visitor { typedef Result result_type; }; - struct from_static_variant { variant& var; const uint32_t _max_depth; from_static_variant( variant& dv, uint32_t max_depth ):var(dv),_max_depth(max_depth){} - typedef void result_type; template void operator()( const T& v )const { to_variant( v, var, _max_depth ); } }; - struct to_static_variant { const variant& var; const uint32_t _max_depth; to_static_variant( const variant& dv, uint32_t max_depth ):var(dv),_max_depth(max_depth){} - typedef void result_type; template void operator()( T& v )const { from_variant( var, v, _max_depth ); } }; - - template void to_variant( const fc::static_variant& s, fc::variant& v, uint32_t max_depth ) { FC_ASSERT( max_depth > 0 ); @@ -384,6 +369,5 @@ struct visitor { s.set_which( ar[0].as_uint64() ); s.visit( to_static_variant(ar[1], max_depth - 1) ); } - template struct get_typename { static const char* name() { return typeid(static_variant).name(); } }; -} // namespace fc +} // namespace fc \ No newline at end of file diff --git a/src/compress/miniz.c b/src/compress/miniz.c index 7123d62..f794c93 100755 --- a/src/compress/miniz.c +++ b/src/compress/miniz.c @@ -1497,7 +1497,10 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex { mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i; r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); - for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8; + for ( i = 0; i <= 143; ++i) *p++ = 8; + for ( ; i <= 255; ++i) *p++ = 9; + for ( ; i <= 279; ++i) *p++ = 7; + for ( ; i <= 287; ++i) *p++ = 8; } else { @@ -2281,7 +2284,11 @@ static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahe if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break; TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; } - if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32; + if (!dist) break; + q = (const mz_uint16*)(d->m_dict + probe_pos); + if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; + p = s; + probe_len = 32; do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); if (!probe_len) @@ -2848,7 +2855,7 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, #include #include - #if defined(_MSC_VER) + #if defined(_MSC_VER) static FILE *mz_fopen(const char *pFilename, const char *pMode) { FILE* pFile = NULL; diff --git a/src/crypto/aes.cpp b/src/crypto/aes.cpp index 7564816..44c4085 100755 --- a/src/crypto/aes.cpp +++ b/src/crypto/aes.cpp @@ -30,6 +30,7 @@ struct aes_encoder::impl aes_encoder::aes_encoder() { static int init = init_openssl(); + (void)init; } aes_encoder::~aes_encoder() @@ -70,7 +71,9 @@ uint32_t aes_encoder::encode( const char* plaintxt, uint32_t plaintext_len, char FC_THROW_EXCEPTION( aes_exception, "error during aes 256 cbc encryption update", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } - FC_ASSERT( ciphertext_len == plaintext_len, "", ("ciphertext_len",ciphertext_len)("plaintext_len",plaintext_len) ); + int64_t ciphertext_len_i64 = ciphertext_len; + int64_t plaintext_len_i64 = plaintext_len; + FC_ASSERT( ciphertext_len_i64 == plaintext_len_i64, "", ("ciphertext_len",ciphertext_len)("plaintext_len",plaintext_len) ); return ciphertext_len; } #if 0 @@ -98,6 +101,7 @@ struct aes_decoder::impl aes_decoder::aes_decoder() { static int init = init_openssl(); + (void)init; } void aes_decoder::init( const fc::sha256& key, const fc::uint128& init_value ) @@ -137,7 +141,9 @@ uint32_t aes_decoder::decode( const char* ciphertxt, uint32_t ciphertxt_len, cha FC_THROW_EXCEPTION( aes_exception, "error during aes 256 cbc decryption update", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } - FC_ASSERT( ciphertxt_len == plaintext_len, "", ("ciphertxt_len",ciphertxt_len)("plaintext_len",plaintext_len) ); + int64_t ciphertxt_len_i64 = ciphertxt_len; + int64_t plaintext_len_i64 = plaintext_len; + FC_ASSERT( ciphertxt_len_i64 == plaintext_len_i64, "", ("ciphertxt_len",ciphertxt_len)("plaintext_len",plaintext_len) ); return plaintext_len; } #if 0 @@ -377,63 +383,4 @@ std::vector aes_load( const fc::path& file, const fc::sha512& key ) return aes_decrypt( key, cipher ); } FC_RETHROW_EXCEPTIONS( warn, "", ("file",file) ) } -/* This stuff has to go somewhere, I guess this is as good a place as any... - OpenSSL isn't thread-safe unless you give it access to some mutexes, - so the CRYPTO_set_id_callback() function needs to be called before there's any - chance of OpenSSL being accessed from multiple threads. -*/ -struct openssl_thread_config -{ - static boost::mutex* openssl_mutexes; - static unsigned long get_thread_id(); - static void locking_callback(int mode, int type, const char *file, int line); - openssl_thread_config(); - ~openssl_thread_config(); -}; -openssl_thread_config openssl_thread_config_manager; - -boost::mutex* openssl_thread_config::openssl_mutexes = nullptr; - -unsigned long openssl_thread_config::get_thread_id() -{ -#ifdef _WIN32 - return (unsigned long)::GetCurrentThreadId(); -#else - return (unsigned long)(&fc::thread::current()); // TODO: should expose boost thread id -#endif -} - -void openssl_thread_config::locking_callback(int mode, int type, const char *file, int line) -{ - if (mode & CRYPTO_LOCK) - openssl_mutexes[type].lock(); - else - openssl_mutexes[type].unlock(); -} - -// Warning: Things get complicated if third-party libraries also try to install their their own -// OpenSSL thread functions. Right now, we don't install our own handlers if another library has -// installed them before us which is a partial solution, but you'd really need to evaluate -// each library that does this to make sure they will play nice. -openssl_thread_config::openssl_thread_config() -{ - if (CRYPTO_get_id_callback() == NULL && - CRYPTO_get_locking_callback() == NULL) - { - openssl_mutexes = new boost::mutex[CRYPTO_num_locks()]; - CRYPTO_set_id_callback(&get_thread_id); - CRYPTO_set_locking_callback(&locking_callback); - } -} -openssl_thread_config::~openssl_thread_config() -{ - if (CRYPTO_get_id_callback() == &get_thread_id) - { - CRYPTO_set_id_callback(NULL); - CRYPTO_set_locking_callback(NULL); - delete[] openssl_mutexes; - openssl_mutexes = nullptr; - } -} - } // namespace fc diff --git a/src/crypto/elliptic_common.cpp b/src/crypto/elliptic_common.cpp index 4eb95fb..6665297 100755 --- a/src/crypto/elliptic_common.cpp +++ b/src/crypto/elliptic_common.cpp @@ -85,8 +85,10 @@ namespace fc { namespace ecc { ssl_bignum order; FC_ASSERT( EC_GROUP_get_order( group, order, ctx ) ); private_key_secret bin; - FC_ASSERT( BN_num_bytes( order ) == bin.data_size() ); - FC_ASSERT( BN_bn2bin( order, (unsigned char*) bin.data() ) == bin.data_size() ); + size_t order_BN_num_bytes = BN_num_bytes( order ); + FC_ASSERT( order_BN_num_bytes == bin.data_size() ); + size_t order_BN_bn2bin = BN_bn2bin( order, (unsigned char*) bin.data() ); + FC_ASSERT( order_BN_bn2bin == bin.data_size() ); return bin; } @@ -104,8 +106,10 @@ namespace fc { namespace ecc { FC_ASSERT( EC_GROUP_get_order( group, order, ctx ) ); BN_rshift1( order, order ); private_key_secret bin; - FC_ASSERT( BN_num_bytes( order ) == bin.data_size() ); - FC_ASSERT( BN_bn2bin( order, (unsigned char*) bin.data() ) == bin.data_size() ); + size_t order_BN_num_bytes = BN_num_bytes( order ); + FC_ASSERT( order_BN_num_bytes == bin.data_size() ); + size_t order_BN_bn2bin = BN_bn2bin( order, (unsigned char*) bin.data() ); + FC_ASSERT( order_BN_bn2bin == bin.data_size() ); return bin; } diff --git a/src/crypto/elliptic_secp256k1.cpp b/src/crypto/elliptic_secp256k1.cpp index 515d086..5ffda21 100755 --- a/src/crypto/elliptic_secp256k1.cpp +++ b/src/crypto/elliptic_secp256k1.cpp @@ -32,6 +32,7 @@ namespace fc { namespace ecc { static const secp256k1_context_t* ctx = _get_context(); static int init_o = init_openssl(); (void)ctx; + (void)init_o; } class public_key_impl diff --git a/src/crypto/md5.cpp b/src/crypto/md5.cpp index b84796d..d17e417 100755 --- a/src/crypto/md5.cpp +++ b/src/crypto/md5.cpp @@ -91,6 +91,8 @@ namespace fc { if( ve.size() ) memcpy(&bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); else - memset( &bi, char(0), sizeof(bi) ); + for (size_t i = 0; i < bi.data_size(); i++) { + bi.data()[i] = 0; + } } } diff --git a/src/crypto/openssl.cpp b/src/crypto/openssl.cpp index e3044ac..5ccebf2 100755 --- a/src/crypto/openssl.cpp +++ b/src/crypto/openssl.cpp @@ -8,6 +8,8 @@ #include #include +#include + namespace fc { struct openssl_scope @@ -15,9 +17,6 @@ namespace fc static path _configurationFilePath; openssl_scope() { - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - const boost::filesystem::path& boostPath = _configurationFilePath; if(boostPath.empty() == false) { @@ -30,13 +29,16 @@ namespace fc #endif } - OPENSSL_config(nullptr); + if (CONF_modules_load_file(_configurationFilePath.string().c_str(), "fc", CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0) { + elog("FATAL: error loading configuration file\n"); + ERR_print_errors_fp(stderr); + exit(1); + } + } ~openssl_scope() { - EVP_cleanup(); - ERR_free_strings(); } }; diff --git a/src/crypto/rand.cpp b/src/crypto/rand.cpp index 7235ab6..ac0b9db 100755 --- a/src/crypto/rand.cpp +++ b/src/crypto/rand.cpp @@ -9,19 +9,21 @@ namespace fc { void rand_bytes(char* buf, int count) { static int init = init_openssl(); + (void)init; int result = RAND_bytes((unsigned char*)buf, count); if (result != 1) FC_THROW("Error calling OpenSSL's RAND_bytes(): ${code}", ("code", (uint32_t)ERR_get_error())); } -void rand_pseudo_bytes(char* buf, int count) -{ - static int init = init_openssl(); - - int result = RAND_pseudo_bytes((unsigned char*)buf, count); - if (result == -1) - FC_THROW("Error calling OpenSSL's RAND_pseudo_bytes(): ${code}", ("code", (uint32_t)ERR_get_error())); -} +//void rand_pseudo_bytes(char* buf, int count) +//{ +// static int init = init_openssl(); +// (void)init; +// +// int result = RAND_pseudo_bytes((unsigned char*)buf, count); +// if (result == -1) +// FC_THROW("Error calling OpenSSL's RAND_pseudo_bytes(): ${code}", ("code", (uint32_t)ERR_get_error())); +//} } // namespace fc diff --git a/src/crypto/ripemd160.cpp b/src/crypto/ripemd160.cpp index 3e96048..2d0ade7 100755 --- a/src/crypto/ripemd160.cpp +++ b/src/crypto/ripemd160.cpp @@ -106,7 +106,9 @@ bool operator == ( const ripemd160& h1, const ripemd160& h2 ) { void from_variant( const variant& v, ripemd160& bi, uint32_t max_depth ) { std::vector ve = v.as< std::vector >( max_depth ); - memset( &bi, char(0), sizeof(bi) ); + for (size_t i = 0; i < bi.data_size(); i++) { + bi.data()[i] = 0; + } if( ve.size() ) memcpy( &bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); } diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp index f509f00..a9b296b 100755 --- a/src/crypto/sha1.cpp +++ b/src/crypto/sha1.cpp @@ -90,7 +90,9 @@ bool operator == ( const sha1& h1, const sha1& h2 ) { void from_variant( const variant& v, sha1& bi, uint32_t max_depth ) { std::vector ve = v.as< std::vector >( max_depth ); - memset( &bi, char(0), sizeof(bi) ); + for (size_t i = 0; i < bi.data_size(); i++) { + bi.data()[i] = 0; + } if( ve.size() ) memcpy( &bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); } diff --git a/src/crypto/sha224.cpp b/src/crypto/sha224.cpp index 4015f90..d94679f 100755 --- a/src/crypto/sha224.cpp +++ b/src/crypto/sha224.cpp @@ -86,7 +86,9 @@ namespace fc { void from_variant( const variant& v, sha224& bi, uint32_t max_depth ) { std::vector ve = v.as< std::vector >( max_depth ); - memset( &bi, char(0), sizeof(bi) ); + for (size_t i = 0; i < bi.data_size(); i++) { + bi.data()[i] = 0; + } if( ve.size() ) memcpy( &bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); } diff --git a/src/crypto/sha256.cpp b/src/crypto/sha256.cpp index e27fd60..3f87ca0 100755 --- a/src/crypto/sha256.cpp +++ b/src/crypto/sha256.cpp @@ -200,7 +200,9 @@ namespace fc { void from_variant( const variant& v, sha256& bi, uint32_t max_depth ) { std::vector ve = v.as< std::vector >( max_depth ); - memset( &bi, char(0), sizeof(bi) ); + for (size_t i = 0; i < bi.data_size(); i++) { + bi.data()[i] = 0; + } if( ve.size() ) memcpy( &bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); } diff --git a/src/crypto/sha512.cpp b/src/crypto/sha512.cpp index 49bc8d9..d2511a8 100755 --- a/src/crypto/sha512.cpp +++ b/src/crypto/sha512.cpp @@ -92,7 +92,9 @@ namespace fc { void from_variant( const variant& v, sha512& bi, uint32_t max_depth ) { std::vector ve = v.as< std::vector >( max_depth ); - memset( &bi, char(0), sizeof(bi) ); + for (size_t i = 0; i < bi.data_size(); i++) { + bi.data()[i] = 0; + } if( ve.size() ) memcpy( &bi, ve.data(), fc::min(ve.size(),sizeof(bi)) ); } diff --git a/src/network/http/websocket.cpp b/src/network/http/websocket.cpp index 6440dd6..2d446e5 100755 --- a/src/network/http/websocket.cpp +++ b/src/network/http/websocket.cpp @@ -132,14 +132,10 @@ namespace fc { namespace http { typedef websocketpp::transport::asio::tls_socket::endpoint socket_type; }; - typedef websocketpp::transport::asio::endpoint - transport_type; + typedef websocketpp::transport::asio::endpoint transport_type; }; - - - using websocketpp::connection_hdl; typedef websocketpp::server websocket_server_type; typedef websocketpp::server websocket_tls_server_type; @@ -152,7 +148,7 @@ namespace fc { namespace http { :_ws_connection(con){ } - ~websocket_connection_impl() + virtual ~websocket_connection_impl() { } @@ -399,35 +395,26 @@ namespace fc { namespace http { }; - - - - - - - - - - - typedef websocketpp::client websocket_client_type; typedef websocketpp::client websocket_tls_client_type; typedef websocket_client_type::connection_ptr websocket_client_connection_type; typedef websocket_tls_client_type::connection_ptr websocket_tls_client_connection_type; - class websocket_client_impl + using websocketpp::connection_hdl; + + template + class generic_websocket_client_impl { public: - typedef websocket_client_type::message_ptr message_ptr; - - websocket_client_impl() + generic_websocket_client_impl() :_client_thread( fc::thread::current() ) { _client.clear_access_channels( websocketpp::log::alevel::all ); - _client.set_message_handler( [&]( connection_hdl hdl, message_ptr msg ){ + _client.set_message_handler( [&]( connection_hdl hdl, + typename websocketpp::client::message_ptr msg ){ _client_thread.async( [&](){ - idump((msg->get_payload())); + wdump((msg->get_payload())); //std::cerr<<"recv: "<get_payload()<<"\n"; auto received = msg->get_payload(); fc::async( [=](){ @@ -453,73 +440,40 @@ namespace fc { namespace http { _client.init_asio( &fc::asio::default_io_service() ); } - ~websocket_client_impl() + virtual ~generic_websocket_client_impl() { - if(_connection ) + if( _connection ) { _connection->close(0, "client closed"); _connection.reset(); - _closed->wait(); } + if( _closed ) + _closed->wait(); } + + fc::promise::ptr _connected; fc::promise::ptr _closed; fc::thread& _client_thread; - websocket_client_type _client; + websocketpp::client _client; websocket_connection_ptr _connection; std::string _uri; + fc::optional _hdl; }; + class websocket_client_impl : public generic_websocket_client_impl + {}; - - class websocket_tls_client_impl + class websocket_tls_client_impl : public generic_websocket_client_impl { public: - typedef websocket_tls_client_type::message_ptr message_ptr; - websocket_tls_client_impl( const std::string& ca_filename ) - :_client_thread( fc::thread::current() ) + : generic_websocket_client_impl() { // ca_filename has special values: // "_none" disables cert checking (potentially insecure!) // "_default" uses default CA's provided by OS - _client.clear_access_channels( websocketpp::log::alevel::all ); - _client.set_message_handler( [&]( connection_hdl hdl, message_ptr msg ){ - _client_thread.async( [&](){ - idump((msg->get_payload())); - _connection->on_message( msg->get_payload() ); - }).wait(); - }); - _client.set_close_handler( [=]( connection_hdl hdl ){ - if( _connection ) - { - try { - _client_thread.async( [&](){ - ilog(". ${p}", ("p",uint64_t(_connection.get()))); - if( !_shutting_down && !_closed && _connection ) - _connection->closed(); - _connection.reset(); - } ).wait(); - } catch ( const fc::exception& e ) - { - if( _closed ) _closed->set_exception( e.dynamic_copy_exception() ); - } - if( _closed ) _closed->set_value(); - } - }); - _client.set_fail_handler( [=]( connection_hdl hdl ){ - elog( "." ); - auto con = _client.get_con_from_hdl(hdl); - auto message = con->get_ec().message(); - if( _connection ) - _client_thread.async( [&](){ if( _connection ) _connection->closed(); _connection.reset(); } ).wait(); - if( _connected && !_connected->ready() ) - _connected->set_exception( exception_ptr( new FC_EXCEPTION( exception, "${message}", ("message",message)) ) ); - if( _closed ) - _closed->set_value(); - }); - // // We need ca_filename to be copied into the closure, as the referenced object might be destroyed by the caller by the time // tls_init_handler() is called. According to [1], capture-by-value results in the desired behavior (i.e. creation of @@ -552,18 +506,8 @@ namespace fc { namespace http { return ctx; }); - _client.init_asio( &fc::asio::default_io_service() ); - } - ~websocket_tls_client_impl() - { - if(_connection ) - { - ilog("."); - _shutting_down = true; - _connection->close(0, "client closed"); - _closed->wait(); - } } + virtual ~websocket_tls_client_impl() {} std::string get_host()const { @@ -576,20 +520,19 @@ namespace fc { namespace http { return; ctx->set_verify_mode( boost::asio::ssl::verify_peer ); if( ca_filename == "_default" ) + { +#if WIN32 + add_windows_root_certs( *ctx ); +#else ctx->set_default_verify_paths(); +#endif + } else ctx->load_verify_file( ca_filename ); ctx->set_verify_depth(10); ctx->set_verify_callback( boost::asio::ssl::rfc2818_verification( get_host() ) ); } - bool _shutting_down = false; - fc::promise::ptr _connected; - fc::promise::ptr _closed; - fc::thread& _client_thread; - websocket_tls_client_type _client; - websocket_connection_ptr _connection; - std::string _uri; }; @@ -622,8 +565,16 @@ namespace fc { namespace http { my->_server.start_accept(); } + void websocket_server::stop_listening() + { + my->_server.stop_listening(); + } - + void websocket_server::close() + { + for (auto& connection : my->_connections) + my->_server.close(connection.first, websocketpp::close::status::normal, "Goodbye"); + } websocket_tls_server::websocket_tls_server( const string& server_pem, const string& ssl_password ):my( new detail::websocket_tls_server_impl(server_pem, ssl_password) ) {} websocket_tls_server::~websocket_tls_server(){} @@ -646,7 +597,6 @@ namespace fc { namespace http { my->_server.start_accept(); } - websocket_tls_client::websocket_tls_client( const std::string& ca_filename ):my( new detail::websocket_tls_client_impl( ca_filename ) ) {} websocket_tls_client::~websocket_tls_client(){ } @@ -659,7 +609,7 @@ namespace fc { namespace http { { try { if( uri.substr(0,4) == "wss:" ) return secure_connect(uri); - FC_ASSERT( uri.substr(0,3) == "ws:" ); + FC_ASSERT( uri.substr(0,4) == "wss:" || uri.substr(0,3) == "ws:", "Unsupported protocol" ); // wlog( "connecting to ${uri}", ("uri",uri)); websocketpp::lib::error_code ec; @@ -687,7 +637,8 @@ namespace fc { namespace http { { try { if( uri.substr(0,3) == "ws:" ) return connect(uri); - FC_ASSERT( uri.substr(0,4) == "wss:" ); + FC_ASSERT( uri.substr(0,4) == "wss:" || uri.substr(0,3) == "ws:", "Unsupported protocol" ); + // wlog( "connecting to ${uri}", ("uri",uri)); websocketpp::lib::error_code ec; @@ -709,6 +660,19 @@ namespace fc { namespace http { return smy->_connection; } FC_CAPTURE_AND_RETHROW( (uri) ) } + void websocket_client::close() + { + if (my->_hdl) + my->_client.close(*my->_hdl, websocketpp::close::status::normal, "Goodbye"); + } + + void websocket_client::synchronous_close() + { + close(); + if (my->_closed) + my->_closed->wait(); + } + websocket_connection_ptr websocket_tls_client::connect( const std::string& uri ) { try { // wlog( "connecting to ${uri}", ("uri",uri)); diff --git a/src/network/ntp.cpp b/src/network/ntp.cpp index 5c0a085..02c0033 100755 --- a/src/network/ntp.cpp +++ b/src/network/ntp.cpp @@ -182,7 +182,7 @@ namespace fc } } } // try - catch (fc::canceled_exception) + catch (fc::canceled_exception&) { throw; } diff --git a/src/rpc/cli.cpp b/src/rpc/cli.cpp index 4957fc3..6aef4e9 100755 --- a/src/rpc/cli.cpp +++ b/src/rpc/cli.cpp @@ -7,22 +7,8 @@ #include #endif -#ifdef HAVE_READLINE -# include -# include -// I don't know exactly what version of readline we need. I know the 4.2 version that ships on some macs is -// missing some functions we require. We're developing against 6.3, but probably anything in the 6.x -// series is fine -# if RL_VERSION_MAJOR < 6 -# ifdef _MSC_VER -# pragma message("You have an old version of readline installed that might not support some of the features we need") -# pragma message("Readline support will not be compiled in") -# else -# warning "You have an old version of readline installed that might not support some of the features we need" -# warning "Readline support will not be compiled in" -# endif -# undef HAVE_READLINE -# endif +#ifdef HAVE_EDITLINE +# include "editline.h" # ifdef WIN32 # include # endif @@ -131,61 +117,107 @@ void cli::run() } -char * dupstr (const char* s) { - char *r; - - r = (char*) malloc ((strlen (s) + 1)); - strcpy (r, s); - return (r); -} - -char* my_generator(const char* text, int state) +/**** + * @brief loop through list of commands, attempting to find a match + * @param token what the user typed + * @param match sets to 1 if only 1 match was found + * @returns the remaining letters of the name of the command or NULL if 1 match not found + */ +static char *my_rl_complete(char *token, int *match) { - static int list_index, len; - const char *name; - if (!state) { - list_index = 0; - len = strlen (text); - } + const auto& cmds = cli_commands(); + const size_t partlen = strlen (token); /* Part of token */ - auto& cmd = cli_commands(); - - while( list_index < cmd.size() ) + std::vector> matched_cmds; + for( const std::string& it : cmds ) { - name = cmd[list_index].c_str(); - list_index++; - - if (strncmp (name, text, len) == 0) - return (dupstr(name)); + if( it.compare(0, partlen, token) == 0 ) + { + matched_cmds.push_back( it ); + } } - /* If no names matched, then return NULL. */ - return ((char *)NULL); + if( matched_cmds.size() == 0 ) + return NULL; + + const std::string& first_matched_cmd = matched_cmds[0]; + if( matched_cmds.size() == 1 ) + { + *match = 1; + std::string matched_cmd = first_matched_cmd + " "; + return strdup( matched_cmd.c_str() + partlen ); + } + + size_t first_cmd_len = first_matched_cmd.size(); + size_t matched_len = partlen; + for( ; matched_len < first_cmd_len; ++matched_len ) + { + char next_char = first_matched_cmd[matched_len]; + bool end = false; + for( const std::string& s : matched_cmds ) + { + if( s.size() <= matched_len || s[matched_len] != next_char ) + { + end = true; + break; + } + } + if( end ) + break; + } + + if( matched_len == partlen ) + return NULL; + + std::string matched_cmd_part = first_matched_cmd.substr( partlen, matched_len - partlen ); + return strdup( matched_cmd_part.c_str() ); } - -static char** cli_completion( const char * text , int start, int end) +/*** + * @brief return an array of matching commands + * @param token the incoming text + * @param array the resultant array of possible matches + * @returns the number of matches + */ +static int cli_completion(char *token, char ***array) { - char **matches; - matches = (char **)NULL; + auto& cmd = cli_commands(); + int num_commands = cmd.size(); -#ifdef HAVE_READLINE - if (start == 0) - matches = rl_completion_matches ((char*)text, &my_generator); - else - rl_bind_key('\t',rl_abort); -#endif + char **copy = (char **) malloc (num_commands * sizeof(char *)); + if (copy == NULL) + { + // possible out of memory + return 0; + } + int total_matches = 0; - return (matches); + int partlen = strlen(token); + + for (const std::string& it : cmd) + { + if ( it.compare(0, partlen, token) == 0) + { + copy[total_matches] = strdup ( it.c_str() ); + ++total_matches; + } + } + *array = copy; + + return total_matches; } - +/*** + * @brief Read input from the user + * @param prompt the prompt to display + * @param line what the user typed + */ void cli::getline( const fc::string& prompt, fc::string& line) { // getting file descriptor for C++ streams is near impossible // so we just assume it's the same as the C stream... -#ifdef HAVE_READLINE +#ifdef HAVE_EDITLINE #ifndef WIN32 if( isatty( fileno( stdin ) ) ) #else @@ -197,8 +229,9 @@ void cli::getline( const fc::string& prompt, fc::string& line) if( _isatty( _fileno( stdin ) ) ) #endif { - rl_attempted_completion_function = cli_completion; - + el_hist_size = 256; + rl_set_complete_func(my_rl_complete); + rl_set_list_possib_func(cli_completion); static fc::thread getline_thread("getline"); getline_thread.async( [&](){ char* line_read = nullptr; @@ -206,10 +239,17 @@ void cli::getline( const fc::string& prompt, fc::string& line) line_read = readline(prompt.c_str()); if( line_read == nullptr ) FC_THROW_EXCEPTION( fc::eof_exception, "" ); - rl_bind_key( '\t', rl_complete ); - if( *line_read ) - add_history(line_read); line = line_read; + try + { + if (*line_read) + add_history(line_read); + } + catch(...) + { + free(line_read); + throw; + } free(line_read); }).wait(); } diff --git a/src/rpc/websocket_api.cpp b/src/rpc/websocket_api.cpp index ae4e26e..1c4ee5a 100755 --- a/src/rpc/websocket_api.cpp +++ b/src/rpc/websocket_api.cpp @@ -7,7 +7,7 @@ websocket_api_connection::~websocket_api_connection() { } -websocket_api_connection::websocket_api_connection( fc::http::websocket_connection& c, uint32_t max_depth ) +websocket_api_connection::websocket_api_connection(const std::shared_ptr& c, uint32_t max_depth ) : api_connection(max_depth),_connection(c) { _rpc_state.add_method( "call", [this]( const variants& args ) -> variant @@ -47,9 +47,12 @@ websocket_api_connection::websocket_api_connection( fc::http::websocket_connecti return this->receive_call( 0, method_name, args ); } ); - _connection.on_message_handler( [&]( const std::string& msg ){ on_message(msg,true); } ); - _connection.on_http_handler( [&]( const std::string& msg ){ return on_message(msg,false); } ); - _connection.closed.connect( [this](){ closed(); } ); + _connection->on_message_handler( [&]( const std::string& msg ){ on_message(msg,true); } ); + _connection->on_http_handler( [&]( const std::string& msg ){ return on_message(msg,false); } ); + _connection->closed.connect( [this](){ + closed(); + _connection = nullptr; + } ); } variant websocket_api_connection::send_call( @@ -58,7 +61,7 @@ variant websocket_api_connection::send_call( variants args /* = variants() */ ) { auto request = _rpc_state.start_remote_call( "call", {api_id, std::move(method_name), std::move(args) } ); - _connection.send_message( fc::json::to_string(fc::variant(request, _max_conversion_depth), + _connection->send_message( fc::json::to_string(fc::variant(request, _max_conversion_depth), fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ) ); return _rpc_state.wait_for_response( *request.id ); } @@ -68,7 +71,7 @@ variant websocket_api_connection::send_callback( variants args /* = variants() */ ) { auto request = _rpc_state.start_remote_call( "callback", {callback_id, std::move(args) } ); - _connection.send_message( fc::json::to_string(fc::variant(request, _max_conversion_depth), + _connection->send_message( fc::json::to_string(fc::variant(request, _max_conversion_depth), fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ) ); return _rpc_state.wait_for_response( *request.id ); } @@ -78,7 +81,7 @@ void websocket_api_connection::send_notice( variants args /* = variants() */ ) { fc::rpc::request req{ optional(), "notice", {callback_id, std::move(args)}}; - _connection.send_message( fc::json::to_string(fc::variant(req, _max_conversion_depth), + _connection->send_message( fc::json::to_string(fc::variant(req, _max_conversion_depth), fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ) ); } @@ -118,7 +121,7 @@ std::string websocket_api_connection::on_message( { auto reply = fc::json::to_string( response( *call.id, result, "2.0" ), fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ); if( send_message ) - _connection.send_message( reply ); + _connection->send_message( reply ); return reply; } } @@ -136,7 +139,7 @@ std::string websocket_api_connection::on_message( auto reply = fc::json::to_string( variant(response( *call.id, error_object{ 1, optexcept->to_string(), fc::variant(*optexcept, _max_conversion_depth)}, "2.0" ), _max_conversion_depth ), fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ); if( send_message ) - _connection.send_message( reply ); + _connection->send_message( reply ); return reply; } diff --git a/src/static_variant.cpp b/src/static_variant.cpp new file mode 100644 index 0000000..63cbb8f --- /dev/null +++ b/src/static_variant.cpp @@ -0,0 +1,31 @@ +#include + + +namespace fc { namespace impl { + +dynamic_storage::dynamic_storage() : storage(nullptr) {}; + +dynamic_storage::~dynamic_storage() +{ + release(); +} + +void* dynamic_storage::data() const +{ + FC_ASSERT( storage != nullptr ); + return (void*)storage; +} + +void dynamic_storage::alloc( size_t size ) +{ + release(); + storage = new char[size]; +} + +void dynamic_storage::release() +{ + delete [] storage; + storage = nullptr; +} + +}} diff --git a/src/thread/mutex.cpp b/src/thread/mutex.cpp index 9f3f9ba..ed00b8d 100755 --- a/src/thread/mutex.cpp +++ b/src/thread/mutex.cpp @@ -13,18 +13,18 @@ namespace fc { {} mutex::~mutex() { - if( m_blist ) - { - context* c = m_blist; - fc::thread::current().debug("~mutex"); -#if 0 - while( c ) { - // elog( "still blocking on context %p (%s)", m_blist, (m_blist->cur_task ? m_blist->cur_task->get_desc() : "no current task") ); - c = c->next_blocked_mutex; - } -#endif - BOOST_ASSERT( false && "Attempt to free mutex while others are blocking on lock." ); - } +// if( m_blist ) +// { +// context* c = m_blist; +// fc::thread::current().debug("~mutex"); +//#if 0 +// while( c ) { +// // elog( "still blocking on context %p (%s)", m_blist, (m_blist->cur_task ? m_blist->cur_task->get_desc() : "no current task") ); +// c = c->next_blocked_mutex; +// } +//#endif +// BOOST_ASSERT( false && "Attempt to free mutex while others are blocking on lock." ); +// } } /** diff --git a/src/utf8.cpp b/src/utf8.cpp index 14551c4..e5e50f3 100755 --- a/src/utf8.cpp +++ b/src/utf8.cpp @@ -13,7 +13,7 @@ namespace fc { bool is_utf8( const std::string& str ) { - auto itr = utf8::find_invalid(str.begin(), str.end()); + //auto itr = utf8::find_invalid(str.begin(), str.end()); return utf8::is_valid( str.begin(), str.end() ); } diff --git a/tests/api.cpp b/tests/api.cpp index e0514c3..fbe42f2 100755 --- a/tests/api.cpp +++ b/tests/api.cpp @@ -61,7 +61,7 @@ int main( int argc, char** argv ) fc::http::websocket_server server; server.on_connection([&]( const websocket_connection_ptr& c ){ - auto wsc = std::make_shared(*c, MAX_DEPTH); + auto wsc = std::make_shared(c, MAX_DEPTH); auto login = std::make_shared(); login->calc = calc_api; wsc->register_api(fc::api(login)); @@ -76,7 +76,7 @@ int main( int argc, char** argv ) try { fc::http::websocket_client client; auto con = client.connect( "ws://localhost:8090" ); - auto apic = std::make_shared(*con, MAX_DEPTH); + auto apic = std::make_shared(con, MAX_DEPTH); auto remote_login_api = apic->get_remote_api(); auto remote_calc = remote_login_api->get_calc(); remote_calc->on_result( []( uint32_t r ) { elog( "callback result ${r}", ("r",r) ); } ); diff --git a/tests/crypto/base_n_tests.cpp b/tests/crypto/base_n_tests.cpp index 4ec3c1d..909d28b 100755 --- a/tests/crypto/base_n_tests.cpp +++ b/tests/crypto/base_n_tests.cpp @@ -86,7 +86,7 @@ static void test_58( const std::string& test, const std::string& expected ) try { len = fc::from_base58( enc1, buffer, 10 ); BOOST_CHECK( len <= 10 ); - } catch ( fc::exception expected ) {} + } catch ( fc::exception& expected ) {} } } diff --git a/tests/crypto/rand_test.cpp b/tests/crypto/rand_test.cpp index e0d1250..fb7826c 100755 --- a/tests/crypto/rand_test.cpp +++ b/tests/crypto/rand_test.cpp @@ -33,11 +33,11 @@ BOOST_AUTO_TEST_CASE(rand_test) check_randomness( buffer, sizeof(buffer) ); } -BOOST_AUTO_TEST_CASE(pseudo_rand_test) -{ - char buffer[10013]; - fc::rand_pseudo_bytes( buffer, sizeof(buffer) ); - check_randomness( buffer, sizeof(buffer) ); -} +//BOOST_AUTO_TEST_CASE(pseudo_rand_test) +//{ +// char buffer[10013]; +// fc::rand_pseudo_bytes( buffer, sizeof(buffer) ); +// check_randomness( buffer, sizeof(buffer) ); +//} BOOST_AUTO_TEST_SUITE_END() diff --git a/vendor/editline b/vendor/editline new file mode 160000 index 0000000..62bba78 --- /dev/null +++ b/vendor/editline @@ -0,0 +1 @@ +Subproject commit 62bba782585c6c18d7a2b27beeb60a45db9abb43 diff --git a/vendor/websocketpp/changelog.md b/vendor/websocketpp/changelog.md index 15846ce..a838e54 100644 --- a/vendor/websocketpp/changelog.md +++ b/vendor/websocketpp/changelog.md @@ -1,4 +1,7 @@ HEAD +- Bug: Change default listen backlog from 0 to socket_base::max_connections. + #549. Thank you derwassi and zwelab for reporting and na1pir for providing + access to hardware to debug the issue. 0.7.0 - 2016-02-22 - MINOR BREAKING SOCKET POLICY CHANGE: Asio transport socket policy method diff --git a/vendor/websocketpp/test/connection/connection.cpp b/vendor/websocketpp/test/connection/connection.cpp index 36b6d14..de79d93 100644 --- a/vendor/websocketpp/test/connection/connection.cpp +++ b/vendor/websocketpp/test/connection/connection.cpp @@ -30,6 +30,8 @@ #include "connection_tu2.hpp" +#include + // Include special debugging transport //#include #include @@ -172,6 +174,20 @@ void http_func(server* s, websocketpp::connection_hdl hdl) { BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok)); } +void http_func_with_move(server* s, websocketpp::connection_hdl hdl) { + using namespace websocketpp::http; + + server::connection_ptr con = s->get_con_from_hdl(hdl); + + std::string res = con->get_resource(); + + con->set_body( std::move(res) ); + con->set_status(status_code::ok); + + BOOST_CHECK_EQUAL(con->get_response_code(), status_code::ok); + BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok)); +} + void defer_http_func(server* s, bool * deferred, websocketpp::connection_hdl hdl) { *deferred = true; @@ -237,6 +253,18 @@ BOOST_AUTO_TEST_CASE( http_request ) { BOOST_CHECK_EQUAL(run_server_test(s,input), output); } +BOOST_AUTO_TEST_CASE( http_request_with_move ) { + std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n"; + std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: "; + output+=websocketpp::user_agent; + output+="\r\n\r\n/foo/bar"; + + server s; + s.set_http_handler(bind(&http_func_with_move,&s,::_1)); + + BOOST_CHECK_EQUAL(run_server_test(s,input), output); +} + BOOST_AUTO_TEST_CASE( deferred_http_request ) { std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n"; std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: "; diff --git a/vendor/websocketpp/websocketpp/connection.hpp b/vendor/websocketpp/websocketpp/connection.hpp index 3bbbbb3..b992b17 100644 --- a/vendor/websocketpp/websocketpp/connection.hpp +++ b/vendor/websocketpp/websocketpp/connection.hpp @@ -1041,6 +1041,7 @@ public: * @see websocketpp::http::response::set_body */ void set_body(std::string const & value); + void set_body( std::string&& value ); /// Append a header /** diff --git a/vendor/websocketpp/websocketpp/extensions/permessage_deflate/enabled.hpp b/vendor/websocketpp/websocketpp/extensions/permessage_deflate/enabled.hpp index 1581f14..cb48943 100644 --- a/vendor/websocketpp/websocketpp/extensions/permessage_deflate/enabled.hpp +++ b/vendor/websocketpp/websocketpp/extensions/permessage_deflate/enabled.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -46,7 +47,7 @@ namespace websocketpp { namespace extensions { -/// Implementation of the draft permessage-deflate WebSocket extension +/// Implementation of RFC 7692, the permessage-deflate WebSocket extension /** * ### permessage-deflate interface * @@ -174,18 +175,30 @@ namespace websocketpp { namespace extensions { namespace permessage_deflate { -/// Default value for server_max_window_bits as defined by draft 17 +/// Default value for server_max_window_bits as defined by RFC 7692 static uint8_t const default_server_max_window_bits = 15; -/// Minimum value for server_max_window_bits as defined by draft 17 +/// Minimum value for server_max_window_bits as defined by RFC 7692 +/** + * NOTE: A value of 8 is not actually supported by zlib, the deflate + * library that WebSocket++ uses. To preserve backwards compatibility + * with RFC 7692 and previous versions of the library a value of 8 + * is accepted by the library but will always be negotiated as 9. + */ static uint8_t const min_server_max_window_bits = 8; -/// Maximum value for server_max_window_bits as defined by draft 17 +/// Maximum value for server_max_window_bits as defined by RFC 7692 static uint8_t const max_server_max_window_bits = 15; -/// Default value for client_max_window_bits as defined by draft 17 +/// Default value for client_max_window_bits as defined by RFC 7692 static uint8_t const default_client_max_window_bits = 15; -/// Minimum value for client_max_window_bits as defined by draft 17 +/// Minimum value for client_max_window_bits as defined by RFC 7692 +/** + * NOTE: A value of 8 is not actually supported by zlib, the deflate + * library that WebSocket++ uses. To preserve backwards compatibility + * with RFC 7692 and previous versions of the library a value of 8 + * is accepted by the library but will always be negotiated as 9. + */ static uint8_t const min_client_max_window_bits = 8; -/// Maximum value for client_max_window_bits as defined by draft 17 +/// Maximum value for client_max_window_bits as defined by RFC 7692 static uint8_t const max_client_max_window_bits = 15; namespace mode { @@ -213,7 +226,7 @@ public: , m_server_max_window_bits_mode(mode::accept) , m_client_max_window_bits_mode(mode::accept) , m_initialized(false) - , m_compress_buffer_size(16384) + , m_compress_buffer_size(8192) { m_dstate.zalloc = Z_NULL; m_dstate.zfree = Z_NULL; @@ -292,6 +305,7 @@ public: } m_compress_buffer.reset(new unsigned char[m_compress_buffer_size]); + m_decompress_buffer.reset(new unsigned char[m_compress_buffer_size]); if ((m_server_no_context_takeover && is_server) || (m_client_no_context_takeover && !is_server)) { @@ -372,7 +386,7 @@ public: /** * The bits setting is the base 2 logarithm of the maximum window size that * the server must use to compress outgoing messages. The permitted range - * is 8 to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB + * is 9 to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB * window. The default setting is 15. * * Mode Options: @@ -386,6 +400,14 @@ public: * adjusted by the server. A server may unilaterally set this value without * client support. * + * NOTE: The permessage-deflate spec specifies that a value of 8 is allowed. + * Prior to version 0.8.0 a value of 8 was also allowed by this library. + * zlib, the deflate compression library that WebSocket++ uses has always + * silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9 + * and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0 + * continues to perform the 8->9 conversion for backwards compatibility + * purposes but this should be considered deprecated functionality. + * * @param bits The size to request for the outgoing window size * @param mode The mode to use for negotiating this parameter * @return A status code @@ -394,6 +416,12 @@ public: if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) { return error::make_error_code(error::invalid_max_window_bits); } + + // See note in doc comment above about what is happening here + if (bits == 8) { + bits = 9; + } + m_server_max_window_bits = bits; m_server_max_window_bits_mode = mode; @@ -403,8 +431,8 @@ public: /// Limit client LZ77 sliding window size /** * The bits setting is the base 2 logarithm of the window size that the - * client must use to compress outgoing messages. The permitted range is 8 - * to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB window. + * client must use to compress outgoing messages. The permitted range is 9 + * to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB window. * The default setting is 15. * * Mode Options: @@ -417,6 +445,14 @@ public: * outgoing window size unilaterally. A server may only limit the client's * window size if the remote client supports that feature. * + * NOTE: The permessage-deflate spec specifies that a value of 8 is allowed. + * Prior to version 0.8.0 a value of 8 was also allowed by this library. + * zlib, the deflate compression library that WebSocket++ uses has always + * silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9 + * and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0 + * continues to perform the 8->9 conversion for backwards compatibility + * purposes but this should be considered deprecated functionality. + * * @param bits The size to request for the outgoing window size * @param mode The mode to use for negotiating this parameter * @return A status code @@ -425,6 +461,12 @@ public: if (bits < min_client_max_window_bits || bits > max_client_max_window_bits) { return error::make_error_code(error::invalid_max_window_bits); } + + // See note in doc comment above about what is happening here + if (bits == 8) { + bits = 9; + } + m_client_max_window_bits = bits; m_client_max_window_bits_mode = mode; @@ -555,7 +597,7 @@ public: do { m_istate.avail_out = m_compress_buffer_size; - m_istate.next_out = m_compress_buffer.get(); + m_istate.next_out = m_decompress_buffer.get(); ret = inflate(&m_istate, Z_SYNC_FLUSH); @@ -564,7 +606,7 @@ public: } out.append( - reinterpret_cast(m_compress_buffer.get()), + reinterpret_cast(m_decompress_buffer.get()), m_compress_buffer_size - m_istate.avail_out ); } while (m_istate.avail_out == 0); @@ -642,11 +684,17 @@ private: * client requested that we use. * * options: - * - decline (refuse to use the attribute) - * - accept (use whatever the client says) - * - largest (use largest possible value) + * - decline (ignore value, offer our default instead) + * - accept (use the value requested by the client) + * - largest (use largest value acceptable to both) * - smallest (use smallest possible value) * + * NOTE: As a value of 8 is no longer explicitly supported by zlib but might + * be requested for negotiation by an older client/server, if the result of + * the negotiation would be to send a value of 8, a value of 9 is offered + * instead. This ensures that WebSocket++ will only ever negotiate connections + * with compression settings explicitly supported by zlib. + * * @param [in] value The value of the attribute from the offer * @param [out] ec A reference to the error code to return errors via */ @@ -678,6 +726,11 @@ private: ec = make_error_code(error::invalid_mode); m_server_max_window_bits = default_server_max_window_bits; } + + // See note in doc comment + if (m_server_max_window_bits == 8) { + m_server_max_window_bits = 9; + } } /// Negotiate client_max_window_bits attribute @@ -687,11 +740,17 @@ private: * negotiation mode. * * options: - * - decline (refuse to use the attribute) - * - accept (use whatever the client says) - * - largest (use largest possible value) + * - decline (ignore value, offer our default instead) + * - accept (use the value requested by the client) + * - largest (use largest value acceptable to both) * - smallest (use smallest possible value) * + * NOTE: As a value of 8 is no longer explicitly supported by zlib but might + * be requested for negotiation by an older client/server, if the result of + * the negotiation would be to send a value of 8, a value of 9 is offered + * instead. This ensures that WebSocket++ will only ever negotiate connections + * with compression settings explicitly supported by zlib. + * * @param [in] value The value of the attribute from the offer * @param [out] ec A reference to the error code to return errors via */ @@ -727,6 +786,11 @@ private: ec = make_error_code(error::invalid_mode); m_client_max_window_bits = default_client_max_window_bits; } + + // See note in doc comment + if (m_client_max_window_bits == 8) { + m_client_max_window_bits = 9; + } } bool m_enabled; @@ -741,6 +805,7 @@ private: int m_flush; size_t m_compress_buffer_size; lib::unique_ptr_uchar_array m_compress_buffer; + lib::unique_ptr_uchar_array m_decompress_buffer; z_stream m_dstate; z_stream m_istate; }; @@ -750,3 +815,4 @@ private: } // namespace websocketpp #endif // WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP + diff --git a/vendor/websocketpp/websocketpp/impl/connection_impl.hpp b/vendor/websocketpp/websocketpp/impl/connection_impl.hpp index d1f8dff..61f4e49 100644 --- a/vendor/websocketpp/websocketpp/impl/connection_impl.hpp +++ b/vendor/websocketpp/websocketpp/impl/connection_impl.hpp @@ -575,6 +575,17 @@ void connection::set_body(std::string const & value) { m_response.set_body(value); } +template +void connection::set_body( std::string&& value ) +{ + if (m_internal_state != istate::PROCESS_HTTP_REQUEST) { + throw exception("Call to set_status from invalid state", + error::make_error_code(error::invalid_state)); + } + + m_response.set_body(std::move(value)); +} + // TODO: EXCEPTION_FREE template void connection::append_header(std::string const & key, diff --git a/vendor/websocketpp/websocketpp/transport/asio/connection.hpp b/vendor/websocketpp/websocketpp/transport/asio/connection.hpp index 8eb8c75..ade6696 100644 --- a/vendor/websocketpp/websocketpp/transport/asio/connection.hpp +++ b/vendor/websocketpp/websocketpp/transport/asio/connection.hpp @@ -311,10 +311,10 @@ public: * needed. */ timer_ptr set_timer(long duration, timer_handler callback) { - timer_ptr new_timer = lib::make_shared( - lib::ref(*m_io_service), - lib::asio::milliseconds(duration) - ); + timer_ptr new_timer( + new lib::asio::steady_timer( + *m_io_service, + lib::asio::milliseconds(duration))); if (config::enable_multithreading) { new_timer->async_wait(m_strand->wrap(lib::bind( @@ -461,8 +461,7 @@ protected: m_io_service = io_service; if (config::enable_multithreading) { - m_strand = lib::make_shared( - lib::ref(*io_service)); + m_strand.reset(new lib::asio::io_service::strand(*io_service)); } lib::error_code ec = socket_con_type::init_asio(io_service, m_strand, diff --git a/vendor/websocketpp/websocketpp/transport/asio/endpoint.hpp b/vendor/websocketpp/websocketpp/transport/asio/endpoint.hpp index f64e847..a551a4d 100644 --- a/vendor/websocketpp/websocketpp/transport/asio/endpoint.hpp +++ b/vendor/websocketpp/websocketpp/transport/asio/endpoint.hpp @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -191,8 +192,7 @@ public: m_io_service = ptr; m_external_io_service = true; - m_acceptor = lib::make_shared( - lib::ref(*m_io_service)); + m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_service)); m_state = READY; ec = lib::error_code(); @@ -314,8 +314,10 @@ public: * * New values affect future calls to listen only. * - * A value of zero will use the operating system default. This is the - * default value. + * The default value is specified as *::asio::socket_base::max_connections + * which uses the operating system defined maximum queue length. Your OS + * may restrict or silently lower this value. A value of zero may cause + * all connections to be rejected. * * @since 0.3.0 * @@ -660,9 +662,7 @@ public: * @since 0.3.0 */ void start_perpetual() { - m_work = lib::make_shared( - lib::ref(*m_io_service) - ); + m_work.reset(new lib::asio::io_service::work(*m_io_service)); } /// Clears the endpoint's perpetual flag, allowing it to exit when empty @@ -826,8 +826,7 @@ protected: // Create a resolver if (!m_resolver) { - m_resolver = lib::make_shared( - lib::ref(*m_io_service)); + m_resolver.reset(new lib::asio::ip::tcp::resolver(*m_io_service)); } tcon->set_uri(u); diff --git a/vendor/websocketpp/websocketpp/transport/asio/security/none.hpp b/vendor/websocketpp/websocketpp/transport/asio/security/none.hpp index 0e68a65..c05758b 100644 --- a/vendor/websocketpp/websocketpp/transport/asio/security/none.hpp +++ b/vendor/websocketpp/websocketpp/transport/asio/security/none.hpp @@ -168,8 +168,7 @@ protected: return socket::make_error_code(socket::error::invalid_state); } - m_socket = lib::make_shared( - lib::ref(*service)); + m_socket.reset(new lib::asio::ip::tcp::socket(*service)); m_state = READY; diff --git a/vendor/websocketpp/websocketpp/transport/asio/security/tls.hpp b/vendor/websocketpp/websocketpp/transport/asio/security/tls.hpp index a8aafec..c06546c 100644 --- a/vendor/websocketpp/websocketpp/transport/asio/security/tls.hpp +++ b/vendor/websocketpp/websocketpp/transport/asio/security/tls.hpp @@ -193,8 +193,7 @@ protected: if (!m_context) { return socket::make_error_code(socket::error::invalid_tls_context); } - m_socket = lib::make_shared( - _WEBSOCKETPP_REF(*service),lib::ref(*m_context)); + m_socket.reset(new socket_type(*service, *m_context)); m_io_service = service; m_strand = strand;