diff --git a/CMakeLists.txt b/CMakeLists.txt index dfeb5e7..ddb0c91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ include_directories( include ) set( sources src/ssh.cpp + src/url.cpp src/process.cpp src/http_connection.cpp src/url.cpp diff --git a/include/fc/base58.hpp b/include/fc/base58.hpp index 4198bfb..e9dc90c 100644 --- a/include/fc/base58.hpp +++ b/include/fc/base58.hpp @@ -1,9 +1,8 @@ -#ifndef _FC_BASE58_HPP_ -#define _FC_BASE58_HPP_ +#pragma once #include namespace fc { -fc::string to_base58( const char* d, uint32_t s ); -size_t from_base58( const fc::string& base58_str, char* out_data, size_t out_data_len ); + fc::string to_base58( const char* d, uint32_t s ); + fc::vector from_base58( const fc::string& base58_str ); + size_t from_base58( const fc::string& base58_str, char* out_data, size_t out_data_len ); } -#endif // _FC_BASE58_HPP_ diff --git a/include/fc/datastream.hpp b/include/fc/datastream.hpp index c333935..54870d3 100644 --- a/include/fc/datastream.hpp +++ b/include/fc/datastream.hpp @@ -1,7 +1,6 @@ -#ifndef _FC_DATASTREAM_HPP_ -#define _FC_DATASTREAM_HPP_ +#pragma once #include -#include +#include #include #include @@ -40,8 +39,8 @@ struct datastream { m_pos += s; return true; } - FC_THROW_MSG( "Attempt to read %s bytes beyond end of buffer of size %s", - int64_t(-((m_end-m_pos) - s)), int64_t(m_end-m_start) ); + FC_THROW_REPORT( "Attempt to read ${bytes_past} bytes beyond end of buffer with size ${buffer_size} ", + fc::value().set("bytes_past",int64_t(-((m_end-m_pos) - s))).set("buffer_size", int64_t(m_end-m_start)) ); return false; } @@ -51,7 +50,8 @@ struct datastream { m_pos += s; return true; } - FC_THROW_MSG( "Attempt to write %s bytes beyond end of buffer of size %s", int64_t(-((m_end-m_pos) - s)),int64_t(m_end-m_start) ); + FC_THROW_REPORT( "Attempt to write ${bytes_past} bytes beyond end of buffer with size ${buffer_size} ", + fc::value().set("bytes_past",int64_t(-((m_end-m_pos) - s))).set("buffer_size", int64_t(m_end-m_start)) ); return false; } @@ -61,7 +61,8 @@ struct datastream { ++m_pos; return true; } - FC_THROW_MSG( "Attempt to write %s byte beyond end of buffer of size %s", int64_t(-((m_end-m_pos) - 1)), int64_t(m_end-m_start) ); + FC_THROW_REPORT( "Attempt to write ${bytes_past} bytes beyond end of buffer with size ${buffer_size} ", + fc::value().set("bytes_past",int64_t(-((m_end-m_pos) - 1))).set("buffer_size", int64_t(m_end-m_start)) ); return false; } @@ -72,7 +73,8 @@ struct datastream { ++m_pos; return true; } - FC_THROW_MSG( "Attempt to read %s byte beyond end of buffer of size %s", int64_t(-((m_end-m_pos) - 1)), int64_t(m_end-m_start) ); + FC_THROW_REPORT( "Attempt to read ${bytes_past} bytes beyond end of buffer of size ${buffer_size} ", + fc::value().set("bytes_past",int64_t(-((m_end-m_pos) - 1))).set("buffer_size", int64_t(m_end-m_start)) ); ++m_pos; return false; } @@ -111,4 +113,3 @@ private: } // namespace fc -#endif diff --git a/include/fc/filesystem.hpp b/include/fc/filesystem.hpp index fbd5276..28261c2 100644 --- a/include/fc/filesystem.hpp +++ b/include/fc/filesystem.hpp @@ -1,5 +1,4 @@ -#ifndef _FC_FILESYSTEM_HPP_ -#define _FC_FILESYSTEM_HPP_ +#pragma once #include #include @@ -70,6 +69,9 @@ namespace fc { path unique_path(); path temp_directory_path(); + + class value; + void pack( fc::value& , const fc::path& ); + void unpack( const fc::value& , fc::path& ); } -#endif // _FC_FILESYSTEM_HPP_ diff --git a/include/fc/http/connection.hpp b/include/fc/http/connection.hpp index 41e94e5..0f71530 100644 --- a/include/fc/http/connection.hpp +++ b/include/fc/http/connection.hpp @@ -32,6 +32,7 @@ namespace fc { }; struct request { + fc::string get_header( const fc::string& key )const; fc::string method; fc::string domain; fc::string path; @@ -39,6 +40,8 @@ namespace fc { fc::vector body; }; + fc::vector
parse_urlencoded_params( const fc::string& f ); + /** * Connections have reference semantics, all copies refer to the same * underlying socket. diff --git a/include/fc/ip.hpp b/include/fc/ip.hpp index a34ee6b..10e53dc 100644 --- a/include/fc/ip.hpp +++ b/include/fc/ip.hpp @@ -1,5 +1,4 @@ -#ifndef _FC_IP_HPP_ -#define _FC_IP_HPP_ +#pragma once #include namespace fc { @@ -47,5 +46,7 @@ namespace fc { uint32_t _port; }; } + class value; + void pack( fc::value& , const fc::ip::endpoint& ); + void unpack( const fc::value& , fc::ip::endpoint& ); } -#endif // _FC_ENDPOINT_HPP_ diff --git a/include/fc/pke.hpp b/include/fc/pke.hpp index 912f7fc..b0edba9 100644 --- a/include/fc/pke.hpp +++ b/include/fc/pke.hpp @@ -1,7 +1,7 @@ -#ifndef FC_PKE_HPP_ -#define FC_PKE_HPP_ +#pragma once #include #include +#include /** * Define common crypto methods and data types to abstract underlying implementation. @@ -143,7 +143,13 @@ namespace fc { typedef private_key<> private_key_t; typedef signature<> signature_t; + class value; + void pack( fc::value& , const fc::signature_t& ); + void unpack( const fc::value& , fc::signature_t& ); + void pack( fc::value& , const fc::public_key_t& ); + void unpack( const fc::value& , fc::private_key_t& ); + void pack( fc::value& , const fc::private_key_t& ); + void unpack( const fc::value& , fc::public_key_t& ); } // namespace fc -#endif diff --git a/include/fc/raw.hpp b/include/fc/raw.hpp index 0de79c6..e9428b8 100644 --- a/include/fc/raw.hpp +++ b/include/fc/raw.hpp @@ -1,5 +1,4 @@ -#ifndef _TORNET_RPC_RAW_HPP_ -#define _TORNET_RPC_RAW_HPP_ +#pragma once #include #include #include @@ -7,7 +6,6 @@ #include #include #include -//#include namespace fc { class value; @@ -280,4 +278,3 @@ namespace fc { } } // namespace fc::raw -#endif // BOOST_RPC_RAW_HPP diff --git a/include/fc/task.hpp b/include/fc/task.hpp index 6c3cdcb..9c36e6d 100644 --- a/include/fc/task.hpp +++ b/include/fc/task.hpp @@ -61,12 +61,13 @@ namespace fc { public: template task( Functor&& f ):task_base(&_functor) { + typedef typename fc::deduce::type FunctorType; static_assert( sizeof(f) <= sizeof(_functor), "sizeof(Functor) is larger than FunctorSize" ); - new ((char*)&_functor) Functor( fc::forward(f) ); - _destroy_functor = &detail::functor_destructor::destroy; + new ((char*)&_functor) FunctorType( fc::forward(f) ); + _destroy_functor = &detail::functor_destructor::destroy; _promise_impl = static_cast*>(this); - _run_functor = &detail::functor_run::run; + _run_functor = &detail::functor_run::run; } aligned _functor; private: @@ -77,12 +78,13 @@ namespace fc { public: template task( Functor&& f ):task_base(&_functor) { + typedef typename fc::deduce::type FunctorType; static_assert( sizeof(f) <= sizeof(_functor), "sizeof(Functor) is larger than FunctorSize" ); - new ((char*)&_functor) Functor( fc::forward(f) ); - _destroy_functor = &detail::functor_destructor::destroy; + new ((char*)&_functor) FunctorType( fc::forward(f) ); + _destroy_functor = &detail::functor_destructor::destroy; _promise_impl = static_cast*>(this); - _run_functor = &detail::void_functor_run::run; + _run_functor = &detail::void_functor_run::run; } aligned _functor; private: diff --git a/include/fc/thread.hpp b/include/fc/thread.hpp index 334b56f..3d8c960 100644 --- a/include/fc/thread.hpp +++ b/include/fc/thread.hpp @@ -52,8 +52,9 @@ namespace fc { template auto async( Functor&& f, const char* desc ="", priority prio = priority()) -> fc::future { typedef decltype(f()) Result; - fc::task* tsk = - new fc::task( fc::forward(f) ); + typedef typename fc::deduce::type FunctorType; + fc::task* tsk = + new fc::task( fc::forward(f) ); fc::future r(fc::shared_ptr< fc::promise >(tsk,true) ); async_task(tsk,prio,desc); return r; diff --git a/include/fc/time.hpp b/include/fc/time.hpp index 6771a37..7f9678d 100644 --- a/include/fc/time.hpp +++ b/include/fc/time.hpp @@ -1,7 +1,7 @@ -#ifndef _FC_TIME_HPP_ -#define _FC_TIME_HPP_ +#pragma once #include #include +#include namespace fc { class microseconds { @@ -41,5 +41,16 @@ namespace fc { private: microseconds elapsed; }; + + // forward declare io + class value; + void pack( fc::value& , const fc::time_point& ); + void unpack( const fc::value& , fc::time_point& ); + + namespace raw { + template + void unpack( Stream& s, fc::time_point& v ); + template + void pack( Stream& s, const fc::time_point& v ); + } } -#endif // _FC_TIME_HPP_ diff --git a/include/fc/time_io.hpp b/include/fc/time_io.hpp new file mode 100644 index 0000000..4fb284b --- /dev/null +++ b/include/fc/time_io.hpp @@ -0,0 +1,18 @@ +#pragma once +#include +#include + +namespace fc { + namespace raw { + template + void unpack( Stream& s, fc::time_point& v ) { + int64_t micro; + fc::raw::unpack(s, micro ); + v = fc::time_point( fc::microseconds(micro); + } + template + void pack( Stream& s, const fc::time_point& v ) { + fc::raw::pack( s, v.time_since_epoch().count() ); + } + } +} diff --git a/src/base58.cpp b/src/base58.cpp index 1fc5dc9..073a985 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -609,6 +610,13 @@ fc::string to_base58( const char* d, uint32_t s ) { return EncodeBase58( (const unsigned char*)d, (const unsigned char*)d+s ).c_str(); } +fc::vector from_base58( const fc::string& base58_str ) { + std::vector out; + if( !DecodeBase58( base58_str.c_str(), out ) ) { + FC_THROW_REPORT( "Unable to decode base58 string ${base58_str}", fc::value().set("base58_str",base58_str) ); + } + return fc::vector((const char*)out.data(), ((const char*)out.data())+out.size() ); +} /** * @return the number of bytes decoded */ @@ -616,7 +624,7 @@ size_t from_base58( const fc::string& base58_str, char* out_data, size_t out_dat //slog( "%s", base58_str.c_str() ); std::vector out; if( !DecodeBase58( base58_str.c_str(), out ) ) { - FC_THROW_MSG( "Unable to decode base58 string '%s'", base58_str ); + FC_THROW_REPORT( "Unable to decode base58 string ${base58_str}", fc::value().set("base58_str",base58_str) ); } memcpy( out_data, out.data(), out.size() ); diff --git a/src/error_report.cpp b/src/error_report.cpp index 4a817e9..c14e393 100644 --- a/src/error_report.cpp +++ b/src/error_report.cpp @@ -86,8 +86,9 @@ fc::string error_frame::to_string()const { int64_t prev = 0; auto next = desc.find( '$' ); while( prev != int64_t(fc::string::npos) && prev < int64_t(desc.size()) ) { + // slog( "prev: %d next %d %s", prev, next, desc.substr(prev,next).c_str() ); // print everything from the last pos until the first '$' - ss << desc.substr( prev, next ); + ss << desc.substr( prev, next-prev ); // if we got to the end, return it. if( next == string::npos ) { return ss.str(); } @@ -102,6 +103,7 @@ fc::string error_frame::to_string()const { if( next != fc::string::npos ) { // the key is between prev and next fc::string key = desc.substr( prev+1, (next-prev-1) ); + //slog( "key '%s'", key.c_str() ); if( meta ) { auto itr = meta->find( key.c_str() ); if( itr != meta->end() ) { diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 8cbfab9..feba102 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -4,8 +4,15 @@ #include #include #include +#include namespace fc { + void pack( fc::value& v, const fc::path& s ) { + v = s.generic_string(); + } + void unpack( const fc::value& v, fc::path& s ) { + s = path(fc::value_cast(v)); + } path::path(){} path::~path(){}; diff --git a/src/http_connection.cpp b/src/http_connection.cpp index 38b745e..b9cfb1b 100644 --- a/src/http_connection.cpp +++ b/src/http_connection.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include FC_START_SHARED_IMPL(fc::http::connection) @@ -154,4 +156,42 @@ http::request connection::read_request()const { return req; } +fc::string request::get_header( const fc::string& key )const { + for( auto itr = headers.begin(); itr != headers.end(); ++itr ) { + if( itr->key == key ) { return itr->val; } + } + return fc::string(); +} +fc::vector
parse_urlencoded_params( const fc::string& f ) { + int num_args = 0; + for( size_t i = 0; i < f.size(); ++i ) { + if( f[i] == '=' ) ++num_args; + } + fc::vector
h(num_args); + int arg = 0; + for( size_t i = 0; i < f.size(); ++i ) { + while( f[i] != '=' && i < f.size() ) { + if( f[i] == '%' ) { + h[arg].key += char((fc::from_hex(f[i+1]) << 4) | fc::from_hex(f[i+2])); + i += 3; + } else { + h[arg].key += f[i]; + ++i; + } + } + ++i; + while( i < f.size() && f[i] != '&' ) { + if( f[i] == '%' ) { + h[arg].val += char((fc::from_hex(f[i+1]) << 4) | fc::from_hex(f[i+2])); + i += 3; + } else { + h[arg].val += f[i] == '+' ? ' ' : f[i]; + ++i; + } + } + ++arg; + } + return h; +} + } } // fc::http diff --git a/src/http_server.cpp b/src/http_server.cpp index 09db676..6349f06 100644 --- a/src/http_server.cpp +++ b/src/http_server.cpp @@ -56,6 +56,7 @@ namespace fc { namespace http { try { http::connection con; while( tcp_serv.accept( con.get_socket() ) ) { + slog( "Accept Connection" ); fc::async( [=](){ handle_connection( con, on_req ); } ); con = http::connection(); } @@ -66,9 +67,14 @@ namespace fc { namespace http { void handle_connection( const http::connection& c, std::function do_on_req ) { - http::server::response rep( fc::shared_ptr( new response::impl(c, [=](){ this->handle_connection(c,do_on_req); } ) ) ); - auto req = c.read_request(); - if( do_on_req ) do_on_req( req, rep ); + wlog( "reading request.." ); + try { + http::server::response rep( fc::shared_ptr( new response::impl(c, [=](){ this->handle_connection(c,do_on_req); } ) ) ); + auto req = c.read_request(); + if( do_on_req ) do_on_req( req, rep ); + } catch ( ... ) { + wlog( "unable to read request %s", fc::except_str().c_str()); + } } std::function on_req; fc::tcp_server tcp_serv; @@ -126,6 +132,13 @@ namespace fc { namespace http { } my->body_bytes_sent += len; my->con.get_socket().write( data, len ); + if( my->body_bytes_sent == int64_t(my->body_length) ) { + if( my->handle_next_req ) { + slog( "handle next request..." ); + //fc::async( std::function(my->handle_next_req) ); + fc::async( my->handle_next_req ); + } + } } server::response::~response(){} diff --git a/src/ip.cpp b/src/ip.cpp index 48b22e0..f7f8840 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -53,4 +54,12 @@ namespace fc { namespace ip { return string(_ip) + ':' + fc::string(boost::lexical_cast(_port).c_str()); } -} } +} + void pack( fc::value& v, const fc::ip::endpoint& s ) { + v = fc::string(s); + } + void unpack( const fc::value& v, fc::ip::endpoint& s ) { + s = fc::ip::endpoint::from_string(fc::value_cast(v)); + } + +} diff --git a/src/pke.cpp b/src/pke.cpp index 9cc4460..2ed6fbf 100644 --- a/src/pke.cpp +++ b/src/pke.cpp @@ -1,6 +1,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -10,6 +14,44 @@ #include namespace fc { + void pack( fc::value& v, const fc::public_key_t& s ) { + fc::vector ve = fc::raw::pack( s ); + v = to_base58( ve.data(), ve.size() ); + } + void unpack( const fc::value& v, fc::public_key_t& s ) { + try { + auto ve = from_base58(fc::value_cast(v)); + s = fc::raw::unpack(ve); + } catch ( ... ) { + wlog( "error unpacking signature" ); + } + } + + void pack( fc::value& v, const fc::private_key_t& s ) { + fc::vector ve = fc::raw::pack( s ); + v = to_base58( ve.data(), ve.size() ); + } + void unpack( const fc::value& v, fc::private_key_t& s ) { + try { + auto ve = from_base58(fc::value_cast(v)); + s = fc::raw::unpack(ve); + } catch ( ... ) { + wlog( "error unpacking private_key" ); + } + } + void pack( fc::value& v, const fc::signature_t& s ) { + fc::vector ve = fc::raw::pack( s ); + v = to_base58( ve.data(), ve.size() ); + } + void unpack( const fc::value& v, fc::signature_t& s ) { + try { + auto ve = from_base58(fc::value_cast(v)); + s = fc::raw::unpack(ve); + } catch ( ... ) { + wlog( "error unpacking signature" ); + } + } + RSA* get_pub( const char* key, uint32_t key_size, uint32_t pe ) { RSA* rsa = RSA_new();