Response::Response(const char *stream, std::size_t size) : status_code_(0), status_code_type_(0), http_version_(0), reason_phrase_(), content_buffer_() { try { assert(stream); StatusLine status_line(stream, stream + size); status_code_ = status_line.GetStatusCode(); status_code_type_ = status_line.GetStatusCodeType(); http_version_ = status_line.GetHttpVersion(); reason_phrase_ = status_line.GetReasonPhrase(); ContentLocator locator(stream, size); const char *content_begin_pos = locator.GetContentBeginPos(); std::size_t content_length = locator.GetContentLength(); content_buffer_.assign(content_begin_pos, content_begin_pos + content_length); } catch (...) { throw ResponseException(std::string(stream, size)); } }
void Daemon::run( InputMessage &message, Channel channel ) { NOTE(); { OutputMessage response( MessageType::Control ); if ( _state != State::Grouped ) { Logger::log( "command Run came at bad moment" ); response.tag( Code::Refuse ); channel->send( response ); return; } response.tag( Code::OK ); channel->send( response ); channel->receive( message, [&,this] ( size_t length ) { char *arg = new char[ length + 1 ](); _arguments.emplace_back( arg ); return arg; } ); message.clear(); channel->receiveHeader( message ); if ( message.tag< Code >() != Code::Start ) { throw ResponseException( { Code::Start }, message.tag< Code >() ); } } _runMain = true; }
Channel Daemon::connectLine( Address &address, LineType type, int channelId ) { OutputMessage request( MessageType::Control ); std::string name = this->name(); int r = rank(); switch( type ){ case LineType::Master: request.tag( Code::Join ); request << r << name; break; case LineType::Data: request.tag( Code::DataLine ); request << r << channelId; break; } Channel channel = connect( address ); channel->send( request ); InputMessage response; channel->receive( response ); if ( response.tag< Code >() == Code::OK ) return channel; if ( response.tag< Code >() == Code::Refuse ) return Channel(); throw ResponseException( { Code::OK, Code::Refuse }, response.tag< Code >() ); }
void RPCHandlerIntermediary::down(MessageContext * context) throw (IntermediaryException,ResponseException) { // Get Qualifier //-------------------- string qualifier = context->getMessage()->getQualifier(); // No Qualifier -> fail //----------------- if (qualifier.length()==0) { stringstream ss; ss << "The input message did not have a qualifier. This is required to find a handler factory"; Logging::getLogger("wsb.libremote.intermediary.rpchandler")->errorStream() << ss.str(); throw ss.str(); } // No Matching Factory -> fail //----------------- else if (this->handlerFactories.count(qualifier)==0) { stringstream ss; ss << "The input qualifier has no registered Factory. This is required to handle the message"; Logging::getLogger("wsb.libremote.intermediary.rpchandler")->errorStream() << ss.str(); throw ss.str(); } // There is a Factory -> Proceed //-------------------- RPCHandlerFactory * factory = this->handlerFactories[qualifier]; //-- Instanciate handler RPCHandler * handler = factory->newInstance(context); Message * response = handler->handle(context); // If there is a response -> trigger //----------------- if (response != NULL) { throw ResponseException(response); } }
bool Daemon::processControl( Channel channel ) { InputMessage message; channel->peek( message ); auto cleanup = [&] { channel->receiveHeader( message ); }; Code code = message.tag< Code >(); switch ( code ) { case Code::Enslave: enslave( message, std::move( channel ) ); break; case Code::Disconnect: cleanup(); release( std::move( channel ) ); return false; case Code::Peers: startGrouping( message, std::move( channel ) ); break; case Code::ConnectTo: connecting( message, std::move( channel ) ); break; case Code::Join: join( message, std::move( channel ) ); break; case Code::DataLine: addDataLine( message, std::move( channel ) ); break; case Code::Grouped: cleanup(); grouped( std::move( channel ) ); break; case Code::InitialData: initData( message, std::move( channel ) ); break; case Code::Run: run( message, std::move( channel ) ); break; case Code::PrepareToLeave: cleanup(); prepare( std::move( channel ) ); break; case Code::CutRope: cleanup(); cutRope( std::move( channel ) ); break; case Code::Leave: cleanup(); leave( std::move( channel ) ); break; case Code::Error: cleanup(); error( std::move( channel ) ); break; case Code::Renegade: renegade( message, std::move( channel ) ); break; case Code::Status: cleanup(); status( std::move( channel ) ); break; case Code::Shutdown: cleanup(); shutdown( std::move( channel ) ); break; case Code::ForceShutdown: cleanup(); forceShutdown(); break; case Code::ForceReset: cleanup(); forceReset(); return false; default: cleanup(); throw ResponseException( { Code::Enslave, Code::Disconnect, Code::Peers, Code::ConnectTo, Code::Join, Code::DataLine, Code::Grouped, Code::InitialData, Code::Run, Code::PrepareToLeave, Code::Leave, Code::CutRope, Code::Error, Code::Renegade, Code::Shutdown, Code::ForceShutdown, Code::ForceReset, }, code ); break; } return true; }