C++ APISession methods

stop_file_transfer

Requests termination of an active file transfer stream in the current session.

stop_file_transfer(std::string filename) requests termination of an active file transfer and returns blaze::status.

Function variants

blaze::status stop_file_transfer(std::string filename);
blaze::status stop_file_transfer(std::string filename, std::error_code& ec) noexcept;
void async_stop_file_transfer(std::string filename, std::function<void(std::error_code, blaze::status)> callback);
blaze::coro::awaitable_result<blaze::status> co_stop_file_transfer(std::string filename);

Status vs error

The returned blaze::status is the API result. std::error_code and std::system_error are used for transport/runtime failures only.

Parameters

Prop

Type

Result

blaze::status

Use direct comparison, for example:

if (status == blaze::status::ok) {
  // success
}

Behavior notes

  • Call stop_file_transfer only after successful connect and initialize.
  • This affects only the active transfer tracked by the current session.
  • blaze::status::ok means the stop request was accepted for an active transfer.
  • After blaze::status::ok, the related transfer eventually finishes with blaze::status::file_transfer_stopped.
  • A few already queued chunks can still arrive before the terminal stop status, so keep reading the transfer callback until the final status arrives.
  • If there is no active transfer for this filename, the operation returns blaze::status::file_not_being_transferred.
  • If your transfer logic is callback-based, use async_stop_file_transfer inside that async flow. Do not call the synchronous overload from a library callback thread.

Example

Example note

Use a reasonably large file in these examples so the transfer stays active long enough for the stop request to be sent.

Compilation note

Synchronous and Asynchronous examples compile in the same form from C++14 to C++26.

#include "blazeauth/api/api.hpp"

#include <atomic>
#include <future>
#include <iostream>
#include <string>
#include <system_error>

void print_error_code(const std::string& context, const std::error_code& ec) {
  std::cout << context << ": " << ec.message() << " ("
            << ec.value() << " : " << ec.category().name() << ")\n";
}

std::string read_line(const std::string& label) {
  std::string value;
  std::cout << label << ": ";
  std::getline(std::cin, value);
  return value;
}

void print_status(const std::string& context, blaze::status status) {
  std::cout << context << ": "
            << static_cast<unsigned int>(status)
            << " (" << blaze::to_string(status) << ")\n";
}

struct transfer_outcome {
  std::error_code ec;
  blaze::status status{blaze::status::none};
};

int main() {
  const std::string websocket_api_key = read_line("Websocket API key");
  const std::string client_id = read_line("Client ID");
  const std::string filename = read_line("Large filename to transfer");

  blaze::session session;

  try {
    const blaze::api_server server = session.connect();
    std::cout << "Connected to server location: " << server.location << '\n';

    const blaze::application app = session.initialize(websocket_api_key, client_id);
    if (!app.good()) {
      print_status("Initialize returned status", app.status);
      return 1;
    }

    std::promise<bool> started_promise;
    std::future<bool> started = started_promise.get_future();

    std::promise<transfer_outcome> finished_promise;
    std::future<transfer_outcome> finished = finished_promise.get_future();

    std::atomic<bool> started_signaled{false};
    std::atomic<bool> finished_signaled{false};

    session.async_transfer_file(
      filename,
      [&](std::error_code transfer_ec, blaze::filestream_data packet) {
        if (transfer_ec) {
          if (!started_signaled.exchange(true)) {
            started_promise.set_value(false);
          }
          if (!finished_signaled.exchange(true)) {
            finished_promise.set_value({transfer_ec, blaze::status::none});
          }
          return;
        }

        if (!packet.transfer_finished() && !started_signaled.exchange(true)) {
          started_promise.set_value(true);
        }

        if (packet.transfer_finished() && !finished_signaled.exchange(true)) {
          if (!started_signaled.exchange(true)) {
            started_promise.set_value(false);
          }
          finished_promise.set_value({{}, packet.status});
        }
      });

    if (!started.get()) {
      const transfer_outcome outcome = finished.get();
      if (outcome.ec) {
        print_error_code("Transfer failed before stop request", outcome.ec);
      } else {
        print_status("Transfer finished before stop request", outcome.status);
      }
      session.shutdown();
      return 1;
    }

    const blaze::status stop_status = session.stop_file_transfer(filename);
    if (stop_status != blaze::status::ok) {
      print_status("Stop-file-transfer returned status", stop_status);
      session.shutdown();
      return 1;
    }

    const transfer_outcome outcome = finished.get();
    if (outcome.ec) {
      print_error_code("Transfer finished with transport error", outcome.ec);
      session.shutdown();
      return 1;
    }

    if (outcome.status != blaze::status::file_transfer_stopped) {
      print_status("Transfer finished with unexpected status", outcome.status);
      session.shutdown();
      return 1;
    }

    std::cout << "Transfer stopped successfully\n";
    session.shutdown();
  } catch (const std::system_error& e) {
    print_error_code("Stop-file-transfer failed", e.code());
    return 1;
  }

  return 0;
}
#include "blazeauth/api/api.hpp"

#include <atomic>
#include <future>
#include <iostream>
#include <memory>
#include <string>
#include <system_error>

void print_error_code(const std::string& context, const std::error_code& ec) {
  std::cout << context << ": " << ec.message() << " ("
            << ec.value() << " : " << ec.category().name() << ")\n";
}

std::string read_line(const std::string& label) {
  std::string value;
  std::cout << label << ": ";
  std::getline(std::cin, value);
  return value;
}

void print_status(const std::string& context, blaze::status status) {
  std::cout << context << ": "
            << static_cast<unsigned int>(status)
            << " (" << blaze::to_string(status) << ")\n";
}

int main() {
  const std::string websocket_api_key = read_line("Websocket API key");
  const std::string client_id = read_line("Client ID");
  const std::string filename = read_line("Large filename to transfer");

  blaze::session session;

  std::promise<int> completion;
  std::future<int> result = completion.get_future();

  auto completion_set = std::make_shared<std::atomic<bool>>(false);
  auto stop_requested = std::make_shared<std::atomic<bool>>(false);

  auto finish_with = [&completion, completion_set](int code) {
    if (!completion_set->exchange(true)) {
      completion.set_value(code);
    }
  };

  session.async_connect(
    [&session, &finish_with, websocket_api_key, client_id, filename, stop_requested](std::error_code connect_ec, blaze::api_server server) {
      if (connect_ec) {
        print_error_code("Connect failed", connect_ec);
        finish_with(1);
        return;
      }

      std::cout << "Connected to server location: " << server.location << '\n';

      session.async_initialize(websocket_api_key, client_id,
        [&session, &finish_with, filename, stop_requested](std::error_code init_ec, blaze::application app) {
          if (init_ec) {
            print_error_code("Initialize failed", init_ec);
            finish_with(1);
            return;
          }

          if (!app.good()) {
            print_status("Initialize returned status", app.status);
            finish_with(1);
            return;
          }

          session.async_transfer_file(
            filename,
            [&session, &finish_with, filename, stop_requested](std::error_code transfer_ec, blaze::filestream_data packet) {
              if (transfer_ec) {
                print_error_code("Transfer failed", transfer_ec);
                finish_with(1);
                return;
              }

              if (!packet.transfer_finished() && !stop_requested->exchange(true)) {
                session.async_stop_file_transfer(
                  filename,
                  [&finish_with](std::error_code stop_ec, blaze::status stop_status) {
                    if (stop_ec) {
                      print_error_code("Stop-file-transfer failed", stop_ec);
                      finish_with(1);
                      return;
                    }

                    if (stop_status != blaze::status::ok) {
                      print_status("Stop-file-transfer returned status", stop_status);
                      finish_with(1);
                    }
                  });
              }

              if (packet.transfer_finished()) {
                if (!stop_requested->load()) {
                  print_status("Transfer finished before stop request", packet.status);
                  finish_with(1);
                  return;
                }

                if (packet.status != blaze::status::file_transfer_stopped) {
                  print_status("Transfer finished with unexpected status", packet.status);
                  finish_with(1);
                  return;
                }

                std::cout << "Transfer stopped successfully\n";

                session.async_shutdown([&finish_with](std::error_code shutdown_ec) {
                  if (shutdown_ec) {
                    print_error_code("Shutdown failed", shutdown_ec);
                    finish_with(1);
                    return;
                  }

                  finish_with(0);
                });
              }
            });
        });
    });

  return result.get();
}

Project must be built with C++20 support and with coroutine support available both in the language mode and in the standard library implementation for this example to compile correctly.

#include "blazeauth/api/api.hpp"

#include <atomic>
#include <future>
#include <iostream>
#include <string>
#include <system_error>

void print_error_code(const std::string& context, const std::error_code& ec) {
  std::cout << context << ": " << ec.message() << " ("
            << ec.value() << " : " << ec.category().name() << ")\n";
}

std::string read_line(const std::string& label) {
  std::string value;
  std::cout << label << ": ";
  std::getline(std::cin, value);
  return value;
}

void print_status(const std::string& context, blaze::status status) {
  std::cout << context << ": "
            << static_cast<unsigned int>(status)
            << " (" << blaze::to_string(status) << ")\n";
}

struct transfer_outcome {
  std::error_code ec;
  blaze::status status{blaze::status::none};
};

#if BLAZEAUTH_HAS_COROUTINES

blaze::coro::task<std::error_code> run_stop_request(
  blaze::session& session,
  const std::string& filename
) {
  const auto [stop_ec, stop_status] = co_await session.co_stop_file_transfer(filename);
  if (stop_ec) {
    co_return stop_ec;
  }

  if (stop_status != blaze::status::ok) {
    co_return blaze::make_error_code(stop_status);
  }

  co_return {};
}

int main() {
  const std::string websocket_api_key = read_line("Websocket API key");
  const std::string client_id = read_line("Client ID");
  const std::string filename = read_line("Large filename to transfer");

  blaze::session session;

  try {
    const blaze::api_server server = session.connect();
    std::cout << "Connected to server location: " << server.location << '\n';

    const blaze::application app = session.initialize(websocket_api_key, client_id);
    if (!app.good()) {
      print_status("Initialize returned status", app.status);
      return 1;
    }

    std::promise<bool> started_promise;
    std::future<bool> started = started_promise.get_future();

    std::promise<transfer_outcome> finished_promise;
    std::future<transfer_outcome> finished = finished_promise.get_future();

    std::atomic<bool> started_signaled{false};
    std::atomic<bool> finished_signaled{false};

    session.async_transfer_file(
      filename,
      [&](std::error_code transfer_ec, blaze::filestream_data packet) {
        if (transfer_ec) {
          if (!started_signaled.exchange(true)) {
            started_promise.set_value(false);
          }
          if (!finished_signaled.exchange(true)) {
            finished_promise.set_value({transfer_ec, blaze::status::none});
          }
          return;
        }

        if (!packet.transfer_finished() && !started_signaled.exchange(true)) {
          started_promise.set_value(true);
        }

        if (packet.transfer_finished() && !finished_signaled.exchange(true)) {
          if (!started_signaled.exchange(true)) {
            started_promise.set_value(false);
          }
          finished_promise.set_value({{}, packet.status});
        }
      });

    if (!started.get()) {
      const transfer_outcome outcome = finished.get();
      if (outcome.ec) {
        print_error_code("Transfer failed before stop request", outcome.ec);
      } else {
        print_status("Transfer finished before stop request", outcome.status);
      }
      session.shutdown();
      return 1;
    }

    std::promise<std::error_code> completion;
    std::future<std::error_code> stop_result = completion.get_future();

    blaze::coro::co_spawn([&session, &completion, filename]() -> blaze::coro::task<void> {
      const std::error_code ec = co_await run_stop_request(session, filename);
      completion.set_value(ec);
      co_return;
    }());

    const std::error_code stop_ec = stop_result.get();
    if (stop_ec) {
      print_error_code("Stop-file-transfer failed", stop_ec);
      session.shutdown();
      return 1;
    }

    const transfer_outcome outcome = finished.get();
    if (outcome.ec) {
      print_error_code("Transfer finished with transport error", outcome.ec);
      session.shutdown();
      return 1;
    }

    if (outcome.status != blaze::status::file_transfer_stopped) {
      print_status("Transfer finished with unexpected status", outcome.status);
      session.shutdown();
      return 1;
    }

    std::cout << "Transfer stopped successfully\n";
    session.shutdown();
  } catch (const std::system_error& e) {
    print_error_code("Stop-file-transfer failed", e.code());
    return 1;
  }

  return 0;
}

#else

int main() {
  std::cout << "This example requires coroutine support in the Blazeauth library build.\n";
  return 0;
}

#endif

Stop-file-transfer statuses

ValueStatusReturned when
1okStop request was accepted for an active transfer.
305file_not_being_transferredNo active transfer exists for the provided filename in the current session.

Connection-level shutdowns

Normal stop-file-transfer results are returned as blaze::status. The websocket may still be closed by session-level guards:

Close codeMeaningWhen it can happen
4200not_initializedstop_file_transfer was called before a successful initialize.
4201rate_limitedSession or IP rate limiting closed the websocket around this operation.

On this page