Merge branch 'master' of https://github.com/cryptonomex/fc
This commit is contained in:
commit
0dca15c395
7 changed files with 323 additions and 320 deletions
|
|
@ -142,6 +142,17 @@ find_package(OpenSSL REQUIRED)
|
|||
|
||||
set( CMAKE_FIND_LIBRARY_SUFFIXES ${ORIGINAL_LIB_SUFFIXES} )
|
||||
|
||||
# We are now building in support for deflate compression into our websockets layer by default,
|
||||
# which requires zlib. Aside from that, all of fc compiles without zlib, so this could be
|
||||
# made optional without much effort
|
||||
# (important exception, apple: as of 10.10 yosemite, the OpenSSL static libraries shipped with
|
||||
# os x have a dependency on zlib)
|
||||
# On a side note, fc's fc::zlib_compress() function uses a separate implementation of zlib
|
||||
# from the miniz library. If we're comfortable requiring an external zlib, we can
|
||||
# reimplement fc::zlib_compress() to call the real zlib, and remove miniz.c from our
|
||||
# repository.
|
||||
find_package( ZLIB REQUIRED )
|
||||
|
||||
option( UNITY_BUILD OFF )
|
||||
|
||||
set( fc_sources
|
||||
|
|
@ -473,14 +484,6 @@ if(WIN32)
|
|||
|
||||
endif(WIN32)
|
||||
|
||||
IF(APPLE)
|
||||
# As of 10.10 yosemite, the OpenSSL static libraries shipped with os x have a dependency
|
||||
# on zlib, so any time you link in openssl you also need to link zlib. . We really want to detect whether openssl was configured with the --no-zlib
|
||||
# option or not when it was built, but that's difficult to do in practice, so we
|
||||
# just always try to link it in on mac.
|
||||
find_package( ZLIB REQUIRED )
|
||||
ENDIF(APPLE)
|
||||
|
||||
SET(OPENSSL_CONF_TARGET )
|
||||
IF(DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
SET (OPENSSL_CONF_TARGET ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
namespace fc {
|
||||
namespace fc {
|
||||
namespace raw {
|
||||
template<typename Stream>
|
||||
inline void pack( Stream& s, const fc::exception& e )
|
||||
|
|
@ -76,7 +76,7 @@ namespace fc {
|
|||
|
||||
template<typename Stream>
|
||||
inline void unpack( Stream& s, fc::time_point_sec& tp )
|
||||
{ try {
|
||||
{ try {
|
||||
uint32_t sec;
|
||||
s.read( (char*)&sec, sizeof(sec) );
|
||||
tp = fc::time_point() + fc::seconds(sec);
|
||||
|
|
@ -112,7 +112,7 @@ namespace fc {
|
|||
usec = fc::microseconds(usec_as_int64);
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "" ) }
|
||||
|
||||
template<typename Stream, typename T, size_t N>
|
||||
template<typename Stream, typename T, size_t N>
|
||||
inline void pack( Stream& s, const fc::array<T,N>& v) {
|
||||
s.write((const char*)&v.data[0],N*sizeof(T));
|
||||
}
|
||||
|
|
@ -120,20 +120,20 @@ namespace fc {
|
|||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const std::shared_ptr<T>& v)
|
||||
{
|
||||
pack( s, *v );
|
||||
fc::raw::pack( s, *v );
|
||||
}
|
||||
|
||||
template<typename Stream, typename T, size_t N>
|
||||
inline void unpack( Stream& s, fc::array<T,N>& v)
|
||||
template<typename Stream, typename T, size_t N>
|
||||
inline void unpack( Stream& s, fc::array<T,N>& v)
|
||||
{ try {
|
||||
s.read((char*)&v.data[0],N*sizeof(T));
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<type,length>", ("type",fc::get_typename<T>::name())("length",N) ) }
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, std::shared_ptr<T>& v)
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, std::shared_ptr<T>& v)
|
||||
{ try {
|
||||
v = std::make_shared<T>();
|
||||
unpack( s, *v );
|
||||
fc::raw::unpack( s, *v );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<T>", ("type",fc::get_typename<T>::name()) ) }
|
||||
|
||||
template<typename Stream> inline void pack( Stream& s, const signed_int& v ) {
|
||||
|
|
@ -177,58 +177,58 @@ namespace fc {
|
|||
vi.value = static_cast<uint32_t>(v);
|
||||
}
|
||||
|
||||
template<typename Stream, typename T> inline void unpack( Stream& s, const T& vi )
|
||||
template<typename Stream, typename T> inline void unpack( Stream& s, const T& vi )
|
||||
{
|
||||
T tmp;
|
||||
unpack( s, tmp );
|
||||
fc::raw::unpack( s, tmp );
|
||||
FC_ASSERT( vi == tmp );
|
||||
}
|
||||
|
||||
template<typename Stream> inline void pack( Stream& s, const char* v ) { pack( s, fc::string(v) ); }
|
||||
|
||||
template<typename Stream, typename T>
|
||||
void pack( Stream& s, const safe<T>& v ) { pack( s, v.value ); }
|
||||
template<typename Stream> inline void pack( Stream& s, const char* v ) { fc::raw::pack( s, fc::string(v) ); }
|
||||
|
||||
template<typename Stream, typename T>
|
||||
void unpack( Stream& s, fc::safe<T>& v ) { unpack( s, v.value ); }
|
||||
void pack( Stream& s, const safe<T>& v ) { fc::raw::pack( s, v.value ); }
|
||||
|
||||
template<typename Stream, typename T, unsigned int S, typename Align>
|
||||
template<typename Stream, typename T>
|
||||
void unpack( Stream& s, fc::safe<T>& v ) { fc::raw::unpack( s, v.value ); }
|
||||
|
||||
template<typename Stream, typename T, unsigned int S, typename Align>
|
||||
void pack( Stream& s, const fc::fwd<T,S,Align>& v ) {
|
||||
pack( *v );
|
||||
fc::raw::pack( *v );
|
||||
}
|
||||
|
||||
template<typename Stream, typename T, unsigned int S, typename Align>
|
||||
template<typename Stream, typename T, unsigned int S, typename Align>
|
||||
void unpack( Stream& s, fc::fwd<T,S,Align>& v ) {
|
||||
unpack( *v );
|
||||
fc::raw::unpack( *v );
|
||||
}
|
||||
template<typename Stream, typename T>
|
||||
void pack( Stream& s, const fc::smart_ref<T>& v ) { pack( s, *v ); }
|
||||
template<typename Stream, typename T>
|
||||
void pack( Stream& s, const fc::smart_ref<T>& v ) { fc::raw::pack( s, *v ); }
|
||||
|
||||
template<typename Stream, typename T>
|
||||
void unpack( Stream& s, fc::smart_ref<T>& v ) { unpack( s, *v ); }
|
||||
template<typename Stream, typename T>
|
||||
void unpack( Stream& s, fc::smart_ref<T>& v ) { fc::raw::unpack( s, *v ); }
|
||||
|
||||
// optional
|
||||
template<typename Stream, typename T>
|
||||
template<typename Stream, typename T>
|
||||
void pack( Stream& s, const fc::optional<T>& v ) {
|
||||
pack( s, bool(!!v) );
|
||||
if( !!v ) pack( s, *v );
|
||||
fc::raw::pack( s, bool(!!v) );
|
||||
if( !!v ) fc::raw::pack( s, *v );
|
||||
}
|
||||
|
||||
template<typename Stream, typename T>
|
||||
void unpack( Stream& s, fc::optional<T>& v )
|
||||
void unpack( Stream& s, fc::optional<T>& v )
|
||||
{ try {
|
||||
bool b; unpack( s, b );
|
||||
if( b ) { v = T(); unpack( s, *v ); }
|
||||
bool b; fc::raw::unpack( s, b );
|
||||
if( b ) { v = T(); fc::raw::unpack( s, *v ); }
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "optional<${type}>", ("type",fc::get_typename<T>::name() ) ) }
|
||||
|
||||
// std::vector<char>
|
||||
template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value ) {
|
||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value ) {
|
||||
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
if( value.size() )
|
||||
s.write( &value.front(), (uint32_t)value.size() );
|
||||
}
|
||||
template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value ) {
|
||||
unsigned_int size; unpack( s, size );
|
||||
template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value ) {
|
||||
unsigned_int size; fc::raw::unpack( s, size );
|
||||
FC_ASSERT( size.value < MAX_ARRAY_ALLOC_SIZE );
|
||||
value.resize(size.value);
|
||||
if( value.size() )
|
||||
|
|
@ -237,29 +237,29 @@ namespace fc {
|
|||
|
||||
// fc::string
|
||||
template<typename Stream> inline void pack( Stream& s, const fc::string& v ) {
|
||||
pack( s, unsigned_int((uint32_t)v.size()));
|
||||
fc::raw::pack( s, unsigned_int((uint32_t)v.size()));
|
||||
if( v.size() ) s.write( v.c_str(), v.size() );
|
||||
}
|
||||
|
||||
template<typename Stream> inline void unpack( Stream& s, fc::string& v ) {
|
||||
std::vector<char> tmp; unpack(s,tmp);
|
||||
std::vector<char> tmp; fc::raw::unpack(s,tmp);
|
||||
if( tmp.size() )
|
||||
v = fc::string(tmp.data(),tmp.data()+tmp.size());
|
||||
else v = fc::string();
|
||||
}
|
||||
|
||||
// bool
|
||||
template<typename Stream> inline void pack( Stream& s, const bool& v ) { pack( s, uint8_t(v) ); }
|
||||
template<typename Stream> inline void pack( Stream& s, const bool& v ) { fc::raw::pack( s, uint8_t(v) ); }
|
||||
template<typename Stream> inline void unpack( Stream& s, bool& v )
|
||||
{
|
||||
uint8_t b;
|
||||
unpack( s, b );
|
||||
fc::raw::unpack( s, b );
|
||||
FC_ASSERT( (b & ~1) == 0 );
|
||||
v=(b!=0);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
||||
template<typename Stream, typename Class>
|
||||
struct pack_object_visitor {
|
||||
pack_object_visitor(const Class& _c, Stream& _s)
|
||||
|
|
@ -267,9 +267,9 @@ namespace fc {
|
|||
|
||||
template<typename T, typename C, T(C::*p)>
|
||||
void operator()( const char* name )const {
|
||||
raw::pack( s, c.*p );
|
||||
fc::raw::pack( s, c.*p );
|
||||
}
|
||||
private:
|
||||
private:
|
||||
const Class& c;
|
||||
Stream& s;
|
||||
};
|
||||
|
|
@ -280,11 +280,11 @@ namespace fc {
|
|||
:c(_c),s(_s){}
|
||||
|
||||
template<typename T, typename C, T(C::*p)>
|
||||
inline void operator()( const char* name )const
|
||||
inline void operator()( const char* name )const
|
||||
{ try {
|
||||
raw::unpack( s, c.*p );
|
||||
fc::raw::unpack( s, c.*p );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "Error unpacking field ${field}", ("field",name) ) }
|
||||
private:
|
||||
private:
|
||||
Class& c;
|
||||
Stream& s;
|
||||
};
|
||||
|
|
@ -300,23 +300,23 @@ namespace fc {
|
|||
template<>
|
||||
struct if_class<fc::false_type> {
|
||||
template<typename Stream, typename T>
|
||||
static inline void pack( Stream& s, const T& v ) {
|
||||
s.write( (char*)&v, sizeof(v) );
|
||||
static inline void pack( Stream& s, const T& v ) {
|
||||
s.write( (char*)&v, sizeof(v) );
|
||||
}
|
||||
template<typename Stream, typename T>
|
||||
static inline void unpack( Stream& s, T& v ) {
|
||||
s.read( (char*)&v, sizeof(v) );
|
||||
static inline void unpack( Stream& s, T& v ) {
|
||||
s.read( (char*)&v, sizeof(v) );
|
||||
}
|
||||
};
|
||||
|
||||
template<typename IsEnum=fc::false_type>
|
||||
struct if_enum {
|
||||
template<typename Stream, typename T>
|
||||
static inline void pack( Stream& s, const T& v ) {
|
||||
static inline void pack( Stream& s, const T& v ) {
|
||||
fc::reflector<T>::visit( pack_object_visitor<Stream,T>( v, s ) );
|
||||
}
|
||||
template<typename Stream, typename T>
|
||||
static inline void unpack( Stream& s, T& v ) {
|
||||
static inline void unpack( Stream& s, T& v ) {
|
||||
fc::reflector<T>::visit( unpack_object_visitor<Stream,T>( v, s ) );
|
||||
}
|
||||
};
|
||||
|
|
@ -327,32 +327,32 @@ namespace fc {
|
|||
fc::raw::pack(s, (int64_t)v);
|
||||
}
|
||||
template<typename Stream, typename T>
|
||||
static inline void unpack( Stream& s, T& v ) {
|
||||
static inline void unpack( Stream& s, T& v ) {
|
||||
int64_t temp;
|
||||
fc::raw::unpack(s, temp);
|
||||
v = (T)temp;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<typename IsReflected=fc::false_type>
|
||||
struct if_reflected {
|
||||
template<typename Stream, typename T>
|
||||
static inline void pack( Stream& s, const T& v ) {
|
||||
static inline void pack( Stream& s, const T& v ) {
|
||||
if_class<typename fc::is_class<T>::type>::pack(s,v);
|
||||
}
|
||||
template<typename Stream, typename T>
|
||||
static inline void unpack( Stream& s, T& v ) {
|
||||
static inline void unpack( Stream& s, T& v ) {
|
||||
if_class<typename fc::is_class<T>::type>::unpack(s,v);
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct if_reflected<fc::true_type> {
|
||||
template<typename Stream, typename T>
|
||||
static inline void pack( Stream& s, const T& v ) {
|
||||
static inline void pack( Stream& s, const T& v ) {
|
||||
if_enum< typename fc::reflector<T>::is_enum >::pack(s,v);
|
||||
}
|
||||
template<typename Stream, typename T>
|
||||
static inline void unpack( Stream& s, T& v ) {
|
||||
static inline void unpack( Stream& s, T& v ) {
|
||||
if_enum< typename fc::reflector<T>::is_enum >::unpack(s,v);
|
||||
}
|
||||
};
|
||||
|
|
@ -361,7 +361,7 @@ namespace fc {
|
|||
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const std::unordered_set<T>& value ) {
|
||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
auto itr = value.begin();
|
||||
auto end = value.end();
|
||||
while( itr != end ) {
|
||||
|
|
@ -371,7 +371,7 @@ namespace fc {
|
|||
}
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, std::unordered_set<T>& value ) {
|
||||
unsigned_int size; unpack( s, size );
|
||||
unsigned_int size; fc::raw::unpack( s, size );
|
||||
value.clear();
|
||||
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
|
||||
value.reserve(size.value);
|
||||
|
|
@ -386,19 +386,19 @@ namespace fc {
|
|||
|
||||
template<typename Stream, typename K, typename V>
|
||||
inline void pack( Stream& s, const std::pair<K,V>& value ) {
|
||||
pack( s, value.first );
|
||||
pack( s, value.second );
|
||||
fc::raw::pack( s, value.first );
|
||||
fc::raw::pack( s, value.second );
|
||||
}
|
||||
template<typename Stream, typename K, typename V>
|
||||
inline void unpack( Stream& s, std::pair<K,V>& value )
|
||||
inline void unpack( Stream& s, std::pair<K,V>& value )
|
||||
{
|
||||
unpack( s, value.first );
|
||||
unpack( s, value.second );
|
||||
fc::raw::unpack( s, value.first );
|
||||
fc::raw::unpack( s, value.second );
|
||||
}
|
||||
|
||||
template<typename Stream, typename K, typename V>
|
||||
template<typename Stream, typename K, typename V>
|
||||
inline void pack( Stream& s, const std::unordered_map<K,V>& value ) {
|
||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
auto itr = value.begin();
|
||||
auto end = value.end();
|
||||
while( itr != end ) {
|
||||
|
|
@ -407,9 +407,9 @@ namespace fc {
|
|||
}
|
||||
}
|
||||
template<typename Stream, typename K, typename V>
|
||||
inline void unpack( Stream& s, std::unordered_map<K,V>& value )
|
||||
inline void unpack( Stream& s, std::unordered_map<K,V>& value )
|
||||
{
|
||||
unsigned_int size; unpack( s, size );
|
||||
unsigned_int size; fc::raw::unpack( s, size );
|
||||
value.clear();
|
||||
FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE );
|
||||
value.reserve(size.value);
|
||||
|
|
@ -422,7 +422,7 @@ namespace fc {
|
|||
}
|
||||
template<typename Stream, typename K, typename V>
|
||||
inline void pack( Stream& s, const std::map<K,V>& value ) {
|
||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
auto itr = value.begin();
|
||||
auto end = value.end();
|
||||
while( itr != end ) {
|
||||
|
|
@ -431,9 +431,9 @@ namespace fc {
|
|||
}
|
||||
}
|
||||
template<typename Stream, typename K, typename V>
|
||||
inline void unpack( Stream& s, std::map<K,V>& value )
|
||||
inline void unpack( Stream& s, std::map<K,V>& value )
|
||||
{
|
||||
unsigned_int size; unpack( s, size );
|
||||
unsigned_int size; fc::raw::unpack( s, size );
|
||||
value.clear();
|
||||
FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE );
|
||||
for( uint32_t i = 0; i < size.value; ++i )
|
||||
|
|
@ -446,7 +446,7 @@ namespace fc {
|
|||
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const std::deque<T>& value ) {
|
||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
auto itr = value.begin();
|
||||
auto end = value.end();
|
||||
while( itr != end ) {
|
||||
|
|
@ -457,7 +457,7 @@ namespace fc {
|
|||
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, std::deque<T>& value ) {
|
||||
unsigned_int size; unpack( s, size );
|
||||
unsigned_int size; fc::raw::unpack( s, size );
|
||||
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
|
||||
value.resize(size.value);
|
||||
auto itr = value.begin();
|
||||
|
|
@ -470,7 +470,7 @@ namespace fc {
|
|||
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const std::vector<T>& value ) {
|
||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
auto itr = value.begin();
|
||||
auto end = value.end();
|
||||
while( itr != end ) {
|
||||
|
|
@ -481,7 +481,7 @@ namespace fc {
|
|||
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, std::vector<T>& value ) {
|
||||
unsigned_int size; unpack( s, size );
|
||||
unsigned_int size; fc::raw::unpack( s, size );
|
||||
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
|
||||
value.resize(size.value);
|
||||
auto itr = value.begin();
|
||||
|
|
@ -494,7 +494,7 @@ namespace fc {
|
|||
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const std::set<T>& value ) {
|
||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||
auto itr = value.begin();
|
||||
auto end = value.end();
|
||||
while( itr != end ) {
|
||||
|
|
@ -505,93 +505,93 @@ namespace fc {
|
|||
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, std::set<T>& value ) {
|
||||
unsigned_int size; unpack( s, size );
|
||||
unsigned_int size; fc::raw::unpack( s, size );
|
||||
for( uint64_t i = 0; i < size.value; ++i )
|
||||
{
|
||||
T tmp;
|
||||
unpack( s, tmp );
|
||||
fc::raw::unpack( s, tmp );
|
||||
value.insert( std::move(tmp) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename Stream, typename T>
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const T& v ) {
|
||||
fc::raw::detail::if_reflected< typename fc::reflector<T>::is_defined >::pack(s,v);
|
||||
}
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, T& v )
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, T& v )
|
||||
{ try {
|
||||
fc::raw::detail::if_reflected< typename fc::reflector<T>::is_defined >::unpack(s,v);
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
||||
|
||||
template<typename T>
|
||||
inline size_t pack_size( const T& v )
|
||||
inline size_t pack_size( const T& v )
|
||||
{
|
||||
datastream<size_t> ps;
|
||||
raw::pack(ps,v );
|
||||
datastream<size_t> ps;
|
||||
fc::raw::pack(ps,v );
|
||||
return ps.tellp();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::vector<char> pack( const T& v ) {
|
||||
datastream<size_t> ps;
|
||||
raw::pack(ps,v );
|
||||
datastream<size_t> ps;
|
||||
fc::raw::pack(ps,v );
|
||||
std::vector<char> vec(ps.tellp());
|
||||
|
||||
if( vec.size() ) {
|
||||
datastream<char*> ds( vec.data(), size_t(vec.size()) );
|
||||
raw::pack(ds,v);
|
||||
datastream<char*> ds( vec.data(), size_t(vec.size()) );
|
||||
fc::raw::pack(ds,v);
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T unpack( const std::vector<char>& s )
|
||||
inline T unpack( const std::vector<char>& s )
|
||||
{ try {
|
||||
T tmp;
|
||||
if( s.size() ) {
|
||||
datastream<const char*> ds( s.data(), size_t(s.size()) );
|
||||
raw::unpack(ds,tmp);
|
||||
datastream<const char*> ds( s.data(), size_t(s.size()) );
|
||||
fc::raw::unpack(ds,tmp);
|
||||
}
|
||||
return tmp;
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
||||
|
||||
template<typename T>
|
||||
inline void unpack( const std::vector<char>& s, T& tmp )
|
||||
inline void unpack( const std::vector<char>& s, T& tmp )
|
||||
{ try {
|
||||
if( s.size() ) {
|
||||
datastream<const char*> ds( s.data(), size_t(s.size()) );
|
||||
raw::unpack(ds,tmp);
|
||||
datastream<const char*> ds( s.data(), size_t(s.size()) );
|
||||
fc::raw::unpack(ds,tmp);
|
||||
}
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
||||
|
||||
template<typename T>
|
||||
inline void pack( char* d, uint32_t s, const T& v ) {
|
||||
datastream<char*> ds(d,s);
|
||||
raw::pack(ds,v );
|
||||
datastream<char*> ds(d,s);
|
||||
fc::raw::pack(ds,v );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T unpack( const char* d, uint32_t s )
|
||||
inline T unpack( const char* d, uint32_t s )
|
||||
{ try {
|
||||
T v;
|
||||
datastream<const char*> ds( d, s );
|
||||
raw::unpack(ds,v);
|
||||
fc::raw::unpack(ds,v);
|
||||
return v;
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
||||
|
||||
template<typename T>
|
||||
inline void unpack( const char* d, uint32_t s, T& v )
|
||||
inline void unpack( const char* d, uint32_t s, T& v )
|
||||
{ try {
|
||||
datastream<const char*> ds( d, s );
|
||||
raw::unpack(ds,v);
|
||||
fc::raw::unpack(ds,v);
|
||||
return v;
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
||||
|
||||
template<typename Stream>
|
||||
struct pack_static_variant
|
||||
struct pack_static_variant
|
||||
{
|
||||
Stream& stream;
|
||||
pack_static_variant( Stream& s ):stream(s){}
|
||||
|
|
@ -599,7 +599,7 @@ namespace fc {
|
|||
typedef void result_type;
|
||||
template<typename T> void operator()( const T& v )const
|
||||
{
|
||||
pack( stream, v );
|
||||
fc::raw::pack( stream, v );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -612,25 +612,25 @@ namespace fc {
|
|||
typedef void result_type;
|
||||
template<typename T> void operator()( T& v )const
|
||||
{
|
||||
unpack( stream, v );
|
||||
fc::raw::unpack( stream, v );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Stream, typename... T>
|
||||
template<typename Stream, typename... T>
|
||||
void pack( Stream& s, const static_variant<T...>& sv )
|
||||
{
|
||||
pack( s, unsigned_int(sv.which()) );
|
||||
fc::raw::pack( s, unsigned_int(sv.which()) );
|
||||
sv.visit( pack_static_variant<Stream>(s) );
|
||||
}
|
||||
|
||||
template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv )
|
||||
{
|
||||
unsigned_int w;
|
||||
unpack( s, w );
|
||||
fc::raw::unpack( s, w );
|
||||
sv.set_which(w.value);
|
||||
sv.visit( unpack_static_variant<Stream>(s) );
|
||||
}
|
||||
|
||||
|
||||
} } // namespace fc::raw
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@
|
|||
|
||||
namespace fc { namespace http {
|
||||
namespace detail {
|
||||
class websocket_server_impl;
|
||||
class websocket_tls_server_impl;
|
||||
class abstract_websocket_server;
|
||||
class websocket_client_impl;
|
||||
class websocket_tls_client_impl;
|
||||
} // namespace detail;
|
||||
|
|
@ -42,7 +41,7 @@ namespace fc { namespace http {
|
|||
class websocket_server
|
||||
{
|
||||
public:
|
||||
websocket_server();
|
||||
websocket_server(bool enable_permessage_deflate = true);
|
||||
~websocket_server();
|
||||
|
||||
void on_connection( const on_connection_handler& handler);
|
||||
|
|
@ -51,16 +50,16 @@ namespace fc { namespace http {
|
|||
void start_accept();
|
||||
|
||||
private:
|
||||
friend class detail::websocket_server_impl;
|
||||
std::unique_ptr<detail::websocket_server_impl> my;
|
||||
std::unique_ptr<detail::abstract_websocket_server> my;
|
||||
};
|
||||
|
||||
|
||||
class websocket_tls_server
|
||||
{
|
||||
public:
|
||||
websocket_tls_server( const std::string& server_pem = std::string(),
|
||||
const std::string& ssl_password = std::string());
|
||||
websocket_tls_server(const std::string& server_pem = std::string(),
|
||||
const std::string& ssl_password = std::string(),
|
||||
bool enable_permessage_deflate = true);
|
||||
~websocket_tls_server();
|
||||
|
||||
void on_connection( const on_connection_handler& handler);
|
||||
|
|
@ -69,8 +68,7 @@ namespace fc { namespace http {
|
|||
void start_accept();
|
||||
|
||||
private:
|
||||
friend class detail::websocket_tls_server_impl;
|
||||
std::unique_ptr<detail::websocket_tls_server_impl> my;
|
||||
std::unique_ptr<detail::abstract_websocket_server> my;
|
||||
};
|
||||
|
||||
class websocket_client
|
||||
|
|
|
|||
|
|
@ -18,9 +18,11 @@ namespace fc {
|
|||
* fc::optional adds less than 400.
|
||||
*/
|
||||
template<typename T>
|
||||
class optional
|
||||
class optional
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
optional():_valid(false){}
|
||||
~optional(){ reset(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <websocketpp/config/asio.hpp>
|
||||
#include <websocketpp/server.hpp>
|
||||
#include <websocketpp/config/asio_client.hpp>
|
||||
#include <websocketpp/extensions/permessage_deflate/enabled.hpp>
|
||||
#include <websocketpp/client.hpp>
|
||||
#include <websocketpp/logger/stub.hpp>
|
||||
|
||||
|
|
@ -19,12 +20,11 @@
|
|||
namespace fc { namespace http {
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct asio_with_stub_log : public websocketpp::config::asio {
|
||||
|
||||
typedef asio_with_stub_log type;
|
||||
typedef asio base;
|
||||
|
||||
//// All boilerplate copying the base class's config, except as noted
|
||||
typedef base::concurrency_type concurrency_type;
|
||||
|
||||
typedef base::request_type request_type;
|
||||
|
|
@ -33,15 +33,8 @@ namespace fc { namespace http {
|
|||
typedef base::message_type message_type;
|
||||
typedef base::con_msg_manager_type con_msg_manager_type;
|
||||
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
/// Custom Logging policies
|
||||
/*typedef websocketpp::log::syslog<concurrency_type,
|
||||
websocketpp::log::elevel> elog_type;
|
||||
typedef websocketpp::log::syslog<concurrency_type,
|
||||
websocketpp::log::alevel> alog_type;
|
||||
*/
|
||||
//typedef base::alog_type alog_type;
|
||||
//typedef base::elog_type elog_type;
|
||||
|
||||
/// Custom Logging policies, use do-nothing log::stub instead of log::basic
|
||||
typedef websocketpp::log::stub elog_type;
|
||||
typedef websocketpp::log::stub alog_type;
|
||||
|
||||
|
|
@ -60,13 +53,15 @@ namespace fc { namespace http {
|
|||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
|
||||
// override default value of 5 sec timeout
|
||||
static const long timeout_open_handshake = 0;
|
||||
};
|
||||
struct asio_tls_with_stub_log : public websocketpp::config::asio_tls {
|
||||
|
||||
typedef asio_with_stub_log type;
|
||||
typedef asio_tls base;
|
||||
|
||||
struct asio_with_stub_log_and_deflate : public websocketpp::config::asio {
|
||||
typedef asio_with_stub_log_and_deflate type;
|
||||
typedef asio base;
|
||||
|
||||
//// All boilerplate copying the base class's config, except as noted
|
||||
typedef base::concurrency_type concurrency_type;
|
||||
|
||||
typedef base::request_type request_type;
|
||||
|
|
@ -76,14 +71,82 @@ namespace fc { namespace http {
|
|||
typedef base::con_msg_manager_type con_msg_manager_type;
|
||||
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
/// Custom Logging policies
|
||||
/*typedef websocketpp::log::syslog<concurrency_type,
|
||||
websocketpp::log::elevel> elog_type;
|
||||
typedef websocketpp::log::syslog<concurrency_type,
|
||||
websocketpp::log::alevel> alog_type;
|
||||
*/
|
||||
//typedef base::alog_type alog_type;
|
||||
//typedef base::elog_type elog_type;
|
||||
/// Custom Logging policies, use do-nothing log::stub instead of log::basic
|
||||
typedef websocketpp::log::stub elog_type;
|
||||
typedef websocketpp::log::stub alog_type;
|
||||
|
||||
typedef base::rng_type rng_type;
|
||||
|
||||
struct transport_config : public base::transport_config {
|
||||
typedef type::concurrency_type concurrency_type;
|
||||
typedef type::alog_type alog_type;
|
||||
typedef type::elog_type elog_type;
|
||||
typedef type::request_type request_type;
|
||||
typedef type::response_type response_type;
|
||||
typedef websocketpp::transport::asio::basic_socket::endpoint
|
||||
socket_type;
|
||||
};
|
||||
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
|
||||
/// enable the permessage_compress extension
|
||||
struct permessage_deflate_config {};
|
||||
typedef websocketpp::extensions::permessage_deflate::enabled
|
||||
<permessage_deflate_config> permessage_deflate_type;
|
||||
|
||||
// override default value of 5 sec timeout
|
||||
static const long timeout_open_handshake = 0;
|
||||
};
|
||||
|
||||
struct asio_tls_stub_log : public websocketpp::config::asio_tls {
|
||||
typedef asio_tls_stub_log type;
|
||||
typedef asio_tls base;
|
||||
|
||||
//// All boilerplate copying the base class's config, except as noted
|
||||
typedef base::concurrency_type concurrency_type;
|
||||
|
||||
typedef base::request_type request_type;
|
||||
typedef base::response_type response_type;
|
||||
|
||||
typedef base::message_type message_type;
|
||||
typedef base::con_msg_manager_type con_msg_manager_type;
|
||||
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
/// Custom Logging policies, use do-nothing log::stub instead of log::basic
|
||||
typedef websocketpp::log::stub elog_type;
|
||||
typedef websocketpp::log::stub alog_type;
|
||||
|
||||
typedef base::rng_type rng_type;
|
||||
|
||||
struct transport_config : public base::transport_config {
|
||||
typedef type::concurrency_type concurrency_type;
|
||||
typedef type::alog_type alog_type;
|
||||
typedef type::elog_type elog_type;
|
||||
typedef type::request_type request_type;
|
||||
typedef type::response_type response_type;
|
||||
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
|
||||
};
|
||||
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
};
|
||||
|
||||
struct asio_tls_stub_log_and_deflate : public websocketpp::config::asio_tls {
|
||||
typedef asio_tls_stub_log_and_deflate type;
|
||||
typedef asio_tls base;
|
||||
|
||||
//// All boilerplate copying the base class's config, except as noted
|
||||
typedef base::concurrency_type concurrency_type;
|
||||
|
||||
typedef base::request_type request_type;
|
||||
typedef base::response_type response_type;
|
||||
|
||||
typedef base::message_type message_type;
|
||||
typedef base::con_msg_manager_type con_msg_manager_type;
|
||||
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
/// Custom Logging policies, use do-nothing log::stub instead of log::basic
|
||||
typedef websocketpp::log::stub elog_type;
|
||||
typedef websocketpp::log::stub alog_type;
|
||||
|
||||
|
|
@ -101,48 +164,13 @@ namespace fc { namespace http {
|
|||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
|
||||
static const long timeout_open_handshake = 0;
|
||||
/// enable the permessage_compress extension
|
||||
struct permessage_deflate_config {};
|
||||
typedef websocketpp::extensions::permessage_deflate::enabled
|
||||
<permessage_deflate_config> permessage_deflate_type;
|
||||
};
|
||||
struct asio_tls_stub_log : public websocketpp::config::asio_tls {
|
||||
typedef asio_tls_stub_log type;
|
||||
typedef asio_tls base;
|
||||
|
||||
typedef base::concurrency_type concurrency_type;
|
||||
|
||||
typedef base::request_type request_type;
|
||||
typedef base::response_type response_type;
|
||||
|
||||
typedef base::message_type message_type;
|
||||
typedef base::con_msg_manager_type con_msg_manager_type;
|
||||
typedef base::endpoint_msg_manager_type endpoint_msg_manager_type;
|
||||
|
||||
//typedef base::alog_type alog_type;
|
||||
//typedef base::elog_type elog_type;
|
||||
typedef websocketpp::log::stub elog_type;
|
||||
typedef websocketpp::log::stub alog_type;
|
||||
|
||||
typedef base::rng_type rng_type;
|
||||
|
||||
struct transport_config : public base::transport_config {
|
||||
typedef type::concurrency_type concurrency_type;
|
||||
typedef type::alog_type alog_type;
|
||||
typedef type::elog_type elog_type;
|
||||
typedef type::request_type request_type;
|
||||
typedef type::response_type response_type;
|
||||
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
|
||||
};
|
||||
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using websocketpp::connection_hdl;
|
||||
typedef websocketpp::server<asio_with_stub_log> websocket_server_type;
|
||||
typedef websocketpp::server<asio_tls_stub_log> websocket_tls_server_type;
|
||||
|
||||
template<typename T>
|
||||
class websocket_connection_impl : public websocket_connection
|
||||
|
|
@ -173,7 +201,19 @@ namespace fc { namespace http {
|
|||
|
||||
typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;
|
||||
|
||||
class websocket_server_impl
|
||||
class abstract_websocket_server
|
||||
{
|
||||
public:
|
||||
virtual ~abstract_websocket_server() {}
|
||||
|
||||
virtual void on_connection( const on_connection_handler& handler) = 0;
|
||||
virtual void listen( uint16_t port ) = 0;
|
||||
virtual void listen( const fc::ip::endpoint& ep ) = 0;
|
||||
virtual void start_accept() = 0;
|
||||
};
|
||||
|
||||
template <typename config>
|
||||
class websocket_server_impl : public abstract_websocket_server
|
||||
{
|
||||
public:
|
||||
websocket_server_impl()
|
||||
|
|
@ -185,15 +225,15 @@ namespace fc { namespace http {
|
|||
_server.set_reuse_addr(true);
|
||||
_server.set_open_handler( [&]( connection_hdl hdl ){
|
||||
_server_thread.async( [&](){
|
||||
auto new_con = std::make_shared<websocket_connection_impl<websocket_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
|
||||
websocket_connection_ptr new_con = std::make_shared<websocket_connection_impl<typename websocketpp::server<config>::connection_ptr>>( _server.get_con_from_hdl(hdl) );
|
||||
_on_connection( _connections[hdl] = new_con );
|
||||
}).wait();
|
||||
});
|
||||
_server.set_message_handler( [&]( connection_hdl hdl, websocket_server_type::message_ptr msg ){
|
||||
_server.set_message_handler( [&]( connection_hdl hdl, typename websocketpp::server<config>::message_ptr msg ){
|
||||
_server_thread.async( [&](){
|
||||
auto current_con = _connections.find(hdl);
|
||||
assert( current_con != _connections.end() );
|
||||
wdump(("server")(msg->get_payload()));
|
||||
//wdump(("server")(msg->get_payload()));
|
||||
//std::cerr<<"recv: "<<msg->get_payload()<<"\n";
|
||||
auto payload = msg->get_payload();
|
||||
std::shared_ptr<websocket_connection> con = current_con->second;
|
||||
|
|
@ -206,13 +246,13 @@ namespace fc { namespace http {
|
|||
|
||||
_server.set_http_handler( [&]( connection_hdl hdl ){
|
||||
_server_thread.async( [&](){
|
||||
auto current_con = std::make_shared<websocket_connection_impl<websocket_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
|
||||
auto current_con = std::make_shared<websocket_connection_impl<typename websocketpp::server<config>::connection_ptr>>( _server.get_con_from_hdl(hdl) );
|
||||
_on_connection( current_con );
|
||||
|
||||
auto con = _server.get_con_from_hdl(hdl);
|
||||
con->defer_http_response();
|
||||
std::string request_body = con->get_request_body();
|
||||
wdump(("server")(request_body));
|
||||
//wdump(("server")(request_body));
|
||||
|
||||
fc::async([current_con, request_body, con] {
|
||||
std::string response = current_con->on_http(request_body);
|
||||
|
|
@ -274,132 +314,62 @@ namespace fc { namespace http {
|
|||
if( _closed ) _closed->wait();
|
||||
}
|
||||
|
||||
void on_connection( const on_connection_handler& handler ) override
|
||||
{
|
||||
_on_connection = handler;
|
||||
}
|
||||
|
||||
void listen( uint16_t port ) override
|
||||
{
|
||||
_server.listen(port);
|
||||
}
|
||||
|
||||
void listen( const fc::ip::endpoint& ep ) override
|
||||
{
|
||||
_server.listen( boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4(uint32_t(ep.get_address())),ep.port()) );
|
||||
}
|
||||
|
||||
void start_accept() override
|
||||
{
|
||||
_server.start_accept();
|
||||
}
|
||||
|
||||
typedef std::map<connection_hdl, websocket_connection_ptr,std::owner_less<connection_hdl> > con_map;
|
||||
|
||||
con_map _connections;
|
||||
fc::thread& _server_thread;
|
||||
websocket_server_type _server;
|
||||
websocketpp::server<config> _server;
|
||||
on_connection_handler _on_connection;
|
||||
fc::promise<void>::ptr _closed;
|
||||
uint32_t _pending_messages = 0;
|
||||
};
|
||||
|
||||
class websocket_tls_server_impl
|
||||
template <typename config>
|
||||
class websocket_tls_server_impl : public websocket_server_impl<config>
|
||||
{
|
||||
public:
|
||||
websocket_tls_server_impl( const string& server_pem, const string& ssl_password )
|
||||
:_server_thread( fc::thread::current() )
|
||||
{
|
||||
//if( server_pem.size() )
|
||||
{
|
||||
_server.set_tls_init_handler( [=]( websocketpp::connection_hdl hdl ) -> context_ptr {
|
||||
context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
|
||||
try {
|
||||
ctx->set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::no_sslv3 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
ctx->set_password_callback([=](std::size_t max_length, boost::asio::ssl::context::password_purpose){ return ssl_password;});
|
||||
ctx->use_certificate_chain_file(server_pem);
|
||||
ctx->use_private_key_file(server_pem, boost::asio::ssl::context::pem);
|
||||
} catch (std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
return ctx;
|
||||
});
|
||||
}
|
||||
|
||||
_server.clear_access_channels( websocketpp::log::alevel::all );
|
||||
_server.init_asio(&fc::asio::default_io_service());
|
||||
_server.set_reuse_addr(true);
|
||||
_server.set_open_handler( [&]( connection_hdl hdl ){
|
||||
_server_thread.async( [&](){
|
||||
auto new_con = std::make_shared<websocket_connection_impl<websocket_tls_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
|
||||
_on_connection( _connections[hdl] = new_con );
|
||||
}).wait();
|
||||
});
|
||||
_server.set_message_handler( [&]( connection_hdl hdl, websocket_server_type::message_ptr msg ){
|
||||
_server_thread.async( [&](){
|
||||
auto current_con = _connections.find(hdl);
|
||||
assert( current_con != _connections.end() );
|
||||
auto received = msg->get_payload();
|
||||
std::shared_ptr<websocket_connection> con = current_con->second;
|
||||
fc::async([con,received](){ con->on_message( received ); });
|
||||
}).wait();
|
||||
});
|
||||
|
||||
_server.set_http_handler( [&]( connection_hdl hdl ){
|
||||
_server_thread.async( [&](){
|
||||
|
||||
auto current_con = std::make_shared<websocket_connection_impl<websocket_tls_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
|
||||
try{
|
||||
_on_connection( current_con );
|
||||
|
||||
auto con = _server.get_con_from_hdl(hdl);
|
||||
wdump(("server")(con->get_request_body()));
|
||||
auto response = current_con->on_http( con->get_request_body() );
|
||||
|
||||
con->set_body( response );
|
||||
con->set_status( websocketpp::http::status_code::ok );
|
||||
} catch ( const fc::exception& e )
|
||||
{
|
||||
edump((e.to_detail_string()));
|
||||
}
|
||||
current_con->closed();
|
||||
|
||||
}).wait();
|
||||
});
|
||||
|
||||
_server.set_close_handler( [&]( connection_hdl hdl ){
|
||||
_server_thread.async( [&](){
|
||||
_connections[hdl]->closed();
|
||||
_connections.erase( hdl );
|
||||
}).wait();
|
||||
});
|
||||
|
||||
_server.set_fail_handler( [&]( connection_hdl hdl ){
|
||||
if( _server.is_listening() )
|
||||
{
|
||||
_server_thread.async( [&](){
|
||||
if( _connections.find(hdl) != _connections.end() )
|
||||
{
|
||||
_connections[hdl]->closed();
|
||||
_connections.erase( hdl );
|
||||
}
|
||||
}).wait();
|
||||
}
|
||||
this->_server.set_tls_init_handler( [=]( websocketpp::connection_hdl hdl ) -> context_ptr {
|
||||
context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
|
||||
try {
|
||||
ctx->set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
boost::asio::ssl::context::no_sslv3 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
ctx->set_password_callback([=](std::size_t max_length, boost::asio::ssl::context::password_purpose){ return ssl_password;});
|
||||
ctx->use_certificate_chain_file(server_pem);
|
||||
ctx->use_private_key_file(server_pem, boost::asio::ssl::context::pem);
|
||||
} catch (std::exception& e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
return ctx;
|
||||
});
|
||||
}
|
||||
~websocket_tls_server_impl()
|
||||
{
|
||||
if( _server.is_listening() )
|
||||
_server.stop_listening();
|
||||
auto cpy_con = _connections;
|
||||
for( auto item : cpy_con )
|
||||
_server.close( item.first, 0, "server exit" );
|
||||
}
|
||||
|
||||
typedef std::map<connection_hdl, websocket_connection_ptr,std::owner_less<connection_hdl> > con_map;
|
||||
|
||||
con_map _connections;
|
||||
fc::thread& _server_thread;
|
||||
websocket_tls_server_type _server;
|
||||
on_connection_handler _on_connection;
|
||||
fc::promise<void>::ptr _closed;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef websocketpp::client<asio_with_stub_log> websocket_client_type;
|
||||
typedef websocketpp::client<asio_tls_stub_log> websocket_tls_client_type;
|
||||
|
||||
|
|
@ -542,57 +512,63 @@ namespace fc { namespace http {
|
|||
|
||||
} // namespace detail
|
||||
|
||||
websocket_server::websocket_server():my( new detail::websocket_server_impl() ) {}
|
||||
websocket_server::websocket_server(bool enable_permessage_deflate /* = true */) :
|
||||
my( enable_permessage_deflate ?
|
||||
(detail::abstract_websocket_server*)new detail::websocket_server_impl<detail::asio_with_stub_log_and_deflate> :
|
||||
(detail::abstract_websocket_server*)new detail::websocket_server_impl<detail::asio_with_stub_log> )
|
||||
{}
|
||||
websocket_server::~websocket_server(){}
|
||||
|
||||
void websocket_server::on_connection( const on_connection_handler& handler )
|
||||
{
|
||||
my->_on_connection = handler;
|
||||
my->on_connection(handler);
|
||||
}
|
||||
|
||||
void websocket_server::listen( uint16_t port )
|
||||
{
|
||||
my->_server.listen(port);
|
||||
my->listen(port);
|
||||
}
|
||||
void websocket_server::listen( const fc::ip::endpoint& ep )
|
||||
{
|
||||
my->_server.listen( boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4(uint32_t(ep.get_address())),ep.port()) );
|
||||
my->listen(ep);
|
||||
}
|
||||
|
||||
void websocket_server::start_accept() {
|
||||
my->_server.start_accept();
|
||||
my->start_accept();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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(const string& server_pem,
|
||||
const string& ssl_password,
|
||||
bool enable_permessage_deflate /* = true */) :
|
||||
my( enable_permessage_deflate ?
|
||||
(detail::abstract_websocket_server*)new detail::websocket_tls_server_impl<detail::asio_tls_stub_log_and_deflate>(server_pem, ssl_password) :
|
||||
(detail::abstract_websocket_server*)new detail::websocket_tls_server_impl<detail::asio_tls_stub_log>(server_pem, ssl_password) )
|
||||
{}
|
||||
websocket_tls_server::~websocket_tls_server(){}
|
||||
|
||||
void websocket_tls_server::on_connection( const on_connection_handler& handler )
|
||||
{
|
||||
my->_on_connection = handler;
|
||||
my->on_connection(handler);
|
||||
}
|
||||
|
||||
void websocket_tls_server::listen( uint16_t port )
|
||||
{
|
||||
my->_server.listen(port);
|
||||
my->listen(port);
|
||||
}
|
||||
void websocket_tls_server::listen( const fc::ip::endpoint& ep )
|
||||
{
|
||||
my->_server.listen( boost::asio::ip::tcp::endpoint( boost::asio::ip::address_v4(uint32_t(ep.get_address())),ep.port()) );
|
||||
my->listen(ep);
|
||||
}
|
||||
|
||||
void websocket_tls_server::start_accept() {
|
||||
my->_server.start_accept();
|
||||
void websocket_tls_server::start_accept()
|
||||
{
|
||||
my->start_accept();
|
||||
}
|
||||
|
||||
|
||||
websocket_tls_client::websocket_tls_client():my( new detail::websocket_tls_client_impl() ) {}
|
||||
websocket_tls_client::~websocket_tls_client(){ }
|
||||
|
||||
|
||||
|
||||
websocket_client::websocket_client():my( new detail::websocket_client_impl() ),smy(new detail::websocket_tls_client_impl()) {}
|
||||
websocket_client::~websocket_client(){ }
|
||||
|
||||
|
|
|
|||
|
|
@ -63,18 +63,42 @@ namespace fc {
|
|||
_enqueue_thread();
|
||||
}
|
||||
std::exception_ptr e;
|
||||
try { thread::current().wait_until( ptr(this,true), timeout_us ); }
|
||||
|
||||
//
|
||||
// Create shared_ptr to take ownership of this; i.e. this will
|
||||
// be deleted when p_this goes out of scope. Consequently,
|
||||
// it would be Very Bad to let p_this go out of scope
|
||||
// before we're done reading/writing instance variables!
|
||||
// See https://github.com/cryptonomex/graphene/issues/597
|
||||
//
|
||||
|
||||
ptr p_this = ptr( this, true );
|
||||
|
||||
try
|
||||
{
|
||||
//
|
||||
// We clone p_this here because the wait_until() API requires us
|
||||
// to use std::move(). I.e. wait_until() takes ownership of any
|
||||
// pointer passed to it. Since we want to keep ownership ourselves,
|
||||
// we need to have two shared_ptr's to this:
|
||||
//
|
||||
// - p_this to keep this alive until the end of the current function
|
||||
// - p_this2 to be owned by wait_until() as the wait_until() API requires
|
||||
//
|
||||
ptr p_this2 = p_this;
|
||||
thread::current().wait_until( std::move( p_this2 ), timeout_us );
|
||||
}
|
||||
catch (...) { e = std::current_exception(); }
|
||||
|
||||
_dequeue_thread();
|
||||
|
||||
if( e ) std::rethrow_exception(e);
|
||||
|
||||
if( _ready )
|
||||
if( _ready )
|
||||
{
|
||||
if( _exceptp )
|
||||
if( _exceptp )
|
||||
_exceptp->dynamic_rethrow_exception();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
FC_THROW_EXCEPTION( timeout_exception, "" );
|
||||
}
|
||||
|
|
|
|||
2
vendor/websocketpp
vendored
2
vendor/websocketpp
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit c5510d6de04917812b910a8dd44735c1f17061d9
|
||||
Subproject commit 378437aecdcb1dfe62096ffd5d944bf1f640ccc3
|
||||
Loading…
Reference in a new issue