diff --git a/test/src/unit-capi-config.cc b/test/src/unit-capi-config.cc
index 5f8abc0260d..b7835cb4e02 100644
--- a/test/src/unit-capi-config.cc
+++ b/test/src/unit-capi-config.cc
@@ -615,6 +615,7 @@ TEST_CASE("C API: Test config iter", "[capi][config]") {
all_param_values["rest.load_enumerations_on_array_open"] = "false";
all_param_values["rest.use_refactored_array_open"] = "true";
all_param_values["rest.use_refactored_array_open_and_query_submit"] = "true";
+ all_param_values["rest.payer_namespace"] = "";
all_param_values["sm.allow_separate_attribute_writes"] = "false";
all_param_values["sm.allow_updates_experimental"] = "false";
all_param_values["sm.encryption_key"] = "";
diff --git a/test/src/unit-curl.cc b/test/src/unit-curl.cc
index 7f40e8b31ec..e3e79017bc7 100644
--- a/test/src/unit-curl.cc
+++ b/test/src/unit-curl.cc
@@ -138,9 +138,19 @@ TEST_CASE(
ContextResources resources(
cfg, tiledb::test::g_helper_logger(), 1, 1, "test");
- // We copy because the [] operator is not const-qualified.
- auto extra_headers = resources.rest_client()->extra_headers();
- CHECK(extra_headers.size() == 2);
- CHECK(extra_headers["abc"] == "def");
- CHECK(extra_headers["ghi"] == "jkl");
+ const auto& extra_headers = resources.rest_client()->extra_headers();
+ CHECK(extra_headers.at("abc") == "def");
+ CHECK(extra_headers.at("ghi") == "jkl");
+}
+
+TEST_CASE(
+ "RestClient: Ensure payer namespace is set",
+ "[rest-client][payer-namespace]") {
+ tiledb::sm::Config cfg;
+ REQUIRE(cfg.set("rest.payer_namespace", "foo").ok());
+
+ ContextResources resources(
+ cfg, tiledb::test::g_helper_logger(), 1, 1, "test");
+ const auto& extra_headers = resources.rest_client()->extra_headers();
+ CHECK(extra_headers.at("X-Payer") == "foo");
}
diff --git a/tiledb/api/c_api/config/config_api_external.h b/tiledb/api/c_api/config/config_api_external.h
index 19d96f180ff..8cb17bdf53e 100644
--- a/tiledb/api/c_api/config/config_api_external.h
+++ b/tiledb/api/c_api/config/config_api_external.h
@@ -713,6 +713,9 @@ TILEDB_EXPORT void tiledb_config_free(tiledb_config_t** config) TILEDB_NOEXCEPT;
* (Optional) Prefix for custom headers on REST requests. For each custom
* header, use "rest.custom_headers.header_key" = "header_value"
* **Optional. No Default**
+ * - `rest.payer_namespace`
+ * The namespace that should be charged for the request.
+ * **Default**: no default set
* - `filestore.buffer_size`
* Specifies the size in bytes of the internal buffers used in the filestore
* API. The size should be bigger than the minimum tile size filestore
diff --git a/tiledb/sm/config/config.cc b/tiledb/sm/config/config.cc
index 4a5e677295c..325140d2125 100644
--- a/tiledb/sm/config/config.cc
+++ b/tiledb/sm/config/config.cc
@@ -96,6 +96,7 @@ const std::string Config::REST_LOAD_METADATA_ON_ARRAY_OPEN = "true";
const std::string Config::REST_LOAD_NON_EMPTY_DOMAIN_ON_ARRAY_OPEN = "true";
const std::string Config::REST_USE_REFACTORED_ARRAY_OPEN = "false";
const std::string Config::REST_USE_REFACTORED_QUERY_SUBMIT = "false";
+const std::string Config::REST_PAYER_NAMESPACE = "";
const std::string Config::SM_ALLOW_SEPARATE_ATTRIBUTE_WRITES = "false";
const std::string Config::SM_ALLOW_UPDATES_EXPERIMENTAL = "false";
const std::string Config::SM_ENCRYPTION_KEY = "";
@@ -270,6 +271,7 @@ const std::map default_config_values = {
std::make_pair(
"rest.use_refactored_array_open_and_query_submit",
Config::REST_USE_REFACTORED_QUERY_SUBMIT),
+ std::make_pair("rest.payer_namespace", Config::REST_PAYER_NAMESPACE),
std::make_pair(
"config.env_var_prefix", Config::CONFIG_ENVIRONMENT_VARIABLE_PREFIX),
std::make_pair("config.logging_level", Config::CONFIG_LOGGING_LEVEL),
diff --git a/tiledb/sm/config/config.h b/tiledb/sm/config/config.h
index 3dd6fa760f1..0ed2e5e050d 100644
--- a/tiledb/sm/config/config.h
+++ b/tiledb/sm/config/config.h
@@ -125,6 +125,9 @@ class Config {
/** Refactored query submit is disabled by default */
static const std::string REST_USE_REFACTORED_QUERY_SUBMIT;
+ /** The namespace that should be charged for the request. */
+ static const std::string REST_PAYER_NAMESPACE;
+
/** The prefix to use for checking for parameter environmental variables. */
static const std::string CONFIG_ENVIRONMENT_VARIABLE_PREFIX;
diff --git a/tiledb/sm/cpp_api/config.h b/tiledb/sm/cpp_api/config.h
index e7460807078..e447683267b 100644
--- a/tiledb/sm/cpp_api/config.h
+++ b/tiledb/sm/cpp_api/config.h
@@ -893,6 +893,9 @@ class Config {
* (Optional) Prefix for custom headers on REST requests. For each custom
* header, use "rest.custom_headers.header_key" = "header_value"
* **Optional. No Default**
+ * - `rest.payer_namespace`
+ * The namespace that should be charged for the request.
+ * **Default**: no default set
* - `filestore.buffer_size`
* Specifies the size in bytes of the internal buffers used in the
* filestore API. The size should be bigger than the minimum tile size
diff --git a/tiledb/sm/rest/rest_client.cc b/tiledb/sm/rest/rest_client.cc
index ae7575317e5..b7408fd6ffd 100644
--- a/tiledb/sm/rest/rest_client.cc
+++ b/tiledb/sm/rest/rest_client.cc
@@ -151,6 +151,12 @@ Status RestClient::init(
load_headers(*config_);
+ if (auto payer =
+ config_->get("rest.payer_namespace", Config::must_find);
+ !payer.empty()) {
+ extra_headers_["X-Payer"] = std::move(payer);
+ }
+
return Status::Ok();
}
diff --git a/tiledb/sm/rest/rest_client.h b/tiledb/sm/rest/rest_client.h
index d572cff96c3..84b2535a820 100644
--- a/tiledb/sm/rest/rest_client.h
+++ b/tiledb/sm/rest/rest_client.h
@@ -574,7 +574,7 @@ class RestClient {
*/
Status ensure_json_null_delimited_string(Buffer* buffer);
- /** Load all custom headers from the given config. */
+ /** Load all custom headers from the given config. */
void load_headers(const Config& cfg);
};