void HandlePollResponse(const std::string & upload_key, FSM & fsm, const mf::api::upload::poll_upload::Response & response) { if (!response.response_data) { auto timer = fsm.Timer(); timer->expires_from_now( std::chrono::seconds(poll_upload_retry_timeout_seconds)); timer->async_wait(boost::bind(&RetryPoll<FSM>, upload_key, fsm.AsFrontShared(), boost::asio::placeholders::error)); } else { const auto & response_data = *response.response_data; // if result is negative, it indicates a failure if (response_data.result < 0) { fsm.ProcessEvent( event::Error{std::error_code(response_data.result, poll_result_category()), "Poll upload bad response"}); } else if (response_data.fileerror != 0) { fsm.ProcessEvent(event::Error{ std::error_code(response_data.fileerror, poll_upload_file_error_category()), "Poll upload file error received"}); } else if (response_data.quickkey) { HandlePollCompleteResponse(fsm, response); } else { auto timer = fsm.Timer(); timer->expires_from_now( std::chrono::seconds(poll_upload_retry_timeout_seconds)); timer->async_wait(boost::bind(&RetryPoll<FSM>, upload_key, fsm.AsFrontShared(), boost::asio::placeholders::error)); } } }
void operator()( Event const &, FSM & fsm, SourceState&, TargetState& ) { namespace instant = mf::api::upload::instant; auto request = instant::Request( fsm.filename(), fsm.hash(), fsm.filesize()); switch (fsm.onDuplicateAction()) { case OnDuplicateAction::Fail: // This is the default, same as "skip" and doesn't need to be // set. break; case OnDuplicateAction::Replace: request.SetActionOnDuplicate(instant::ActionOnDuplicate::Replace); break; case OnDuplicateAction::AutoRename: request.SetActionOnDuplicate(instant::ActionOnDuplicate::Keep); break; default: assert(!"Invalid duplicate action."); break; } UploadTarget target_folder = fsm.targetFolder(); boost::apply_visitor(TargetSetter(&request), target_folder); auto fsmp = fsm.AsFrontShared(); fsm.GetSessionMaintainer()->Call( request, [fsmp](const instant::Response & response) { if (response.error_code) { fsmp->ProcessEvent(event::Error{response.error_code, "Failed to instant upload file."}); } else { fsmp->ProcessEvent(event::InstantSuccess{ response.quickkey, response.filename }); } }); }
void StartPoll(const std::string & upload_key, FSM & fsm) { if (upload_key.empty()) { assert(!"Reached poll upload without upload key"); fsm.ProcessEvent( event::Error{make_error_code(uploader::errc::LogicError), "Filsize unavailable."}); return; } auto fsmp = fsm.AsFrontShared(); fsm.GetSessionMaintainer()->Call( mf::api::upload::poll_upload::Request(upload_key), [fsmp, upload_key]( const mf::api::upload::poll_upload::Response & response) { HandlePollResponse(upload_key, *fsmp, response); }); }