void http_api_connection::on_request( const fc::http::request& req, const fc::http::server::response& resp ) { // this must be called by outside HTTP server's on_request method std::string resp_body; http::reply::status_code resp_status; try { resp.add_header( "Content-Type", "application/json" ); std::string req_body( req.body.begin(), req.body.end() ); auto var = fc::json::from_string( req_body ); const auto& var_obj = var.get_object(); if( var_obj.contains( "method" ) ) { auto call = var.as<fc::rpc::request>(); try { auto result = _rpc_state.local_call( call.method, call.params ); resp_body = fc::json::to_string( fc::rpc::response( *call.id, result ) ); resp_status = http::reply::OK; } catch ( const fc::exception& e ) { resp_body = fc::json::to_string( fc::rpc::response( *call.id, error_object{ 1, e.to_detail_string(), fc::variant(e)} ) ); resp_status = http::reply::InternalServerError; } } else { resp_status = http::reply::BadRequest; resp_body = ""; } } catch ( const fc::exception& e ) { resp_status = http::reply::InternalServerError; resp_body = ""; wdump((e.to_detail_string())); } try { resp.set_status( resp_status ); resp.set_length( resp_body.length() ); resp.write( resp_body.c_str(), resp_body.length() ); } catch( const fc::exception& e ) { wdump((e.to_detail_string())); } return; }
void handle_request( const fc::http::request& r, const fc::http::server::response& s ) { //ilog( "handle request ${r}", ("r",r.path) ); s.add_header( "Connection", "close" ); try { auto pos = r.path.find( "/", 1 ); auto first_dir = r.path.substr(1,pos); //ilog( "command: ${command}", ("command",first_dir) ); if( first_dir == "pending" ) { s.set_status( fc::http::reply::OK ); auto pending_json = fc::json::to_string( _pending ); s.set_length( pending_json.size() ); s.write( pending_json.c_str(), pending_json.size() ); } else if( first_dir == "update_record" ) { FC_ASSERT( r.body.size() ); std::string str(r.body.data(),r.body.size()); auto rec = fc::json::from_string( str ).as<signed_name_record>(); _self->update_record( rec ); s.set_status( fc::http::reply::RecordCreated ); s.set_length( 12 ); s.write( "Record Created", 12 ); } else if( first_dir == "fetch_by_name/" ) { auto name = r.path.substr( pos+1, std::string::npos ); auto record = _self->fetch_record( name ); s.set_status( fc::http::reply::Found ); auto blkjson = fc::json::to_string( record ); s.set_length( blkjson.size() ); s.write( blkjson.c_str(), blkjson.size() ); } else if( first_dir == "fetch_by_key/" ) { auto key = r.path.substr( pos+1, std::string::npos ); auto record = _self->fetch_record_by_key( key ); s.set_status( fc::http::reply::Found ); auto blkjson = fc::json::to_string( record ); s.set_length( blkjson.size() ); s.write( blkjson.c_str(), blkjson.size() ); } else if( first_dir == "store_key/" ) { auto name = r.path.substr( pos+1, std::string::npos ); std::string str(r.body.data(),r.body.size()); auto rec = fc::json::from_string( str ).as<stored_key>(); _self->store_key( name, rec ); s.set_status( fc::http::reply::RecordCreated ); s.set_length( 12 ); s.write( "Record Created", 12 ); } else if( first_dir == "fetch_key/" ) { auto user_name = r.path.substr( pos+1, std::string::npos ); auto key_data = _self->fetch_key( user_name ); s.set_status( fc::http::reply::Found ); auto blkjson = fc::json::to_string( key_data ); s.set_length( blkjson.size() ); s.write( blkjson.c_str(), blkjson.size() ); } else if( first_dir == "fetch_block/" ) { auto block_num = r.path.substr( pos+1, std::string::npos ); auto blk = _self->fetch_block( fc::to_uint64( block_num ) ); s.set_status( fc::http::reply::Found ); auto blkjson = fc::json::to_string( blk ); s.set_length( blkjson.size() ); s.write( blkjson.c_str(), blkjson.size() ); } else { auto dotpos = r.path.find( ".." ); FC_ASSERT( dotpos == std::string::npos ); auto filename = _data_dir / r.path.substr(1,std::string::npos); if( fc::exists( filename ) ) { FC_ASSERT( !fc::is_directory( filename ) ); auto file_size = fc::file_size( filename ); FC_ASSERT( file_size != 0 ); fc::file_mapping fm( filename.generic_string().c_str(), fc::read_only ); fc::mapped_region mr( fm, fc::read_only, 0, fc::file_size( filename ) ); s.set_status( fc::http::reply::OK ); s.set_length( file_size ); s.write( (const char*)mr.get_address(), mr.get_size() ); return; } s.set_status( fc::http::reply::NotFound ); s.set_length( 9 ); s.write( "Not Found", 9 ); } } catch ( const fc::exception& e ) { s.set_status( fc::http::reply::BadRequest ); auto msg = e.to_detail_string(); s.set_length( msg.size() ); if( msg.size() ) { s.write( msg.c_str(), msg.size() ); } } }