Skip to content

feat(config): add support for config store buffers longer than 8k #1181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions runtime/fastly/host-api/fastly.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ typedef fastly_host_http_response fastly_world_tuple2_handle_handle;
#define HEADER_MAX_LEN 69000
#define METHOD_MAX_LEN 1024
#define URI_MAX_LEN 8192
#define CONFIG_STORE_ENTRY_MAX_LEN 8000
#define DICTIONARY_ENTRY_MAX_LEN CONFIG_STORE_ENTRY_MAX_LEN
#define CONFIG_STORE_INITIAL_BUF_LEN 512
#define DICTIONARY_ENTRY_MAX_LEN 8000

// Ensure that all the things we want to use the hostcall buffer for actually
// fit into the buffer.
Expand Down
80 changes: 67 additions & 13 deletions runtime/fastly/host-api/host_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,8 @@ Result<std::optional<HostString>> HttpReq::http_req_downstream_tls_cipher_openss
auto status = fastly::req_downstream_tls_cipher_openssl_name(reinterpret_cast<char *>(ret.ptr),
default_size, &ret.len);
if (status == FASTLY_HOST_ERROR_BUFFER_LEN) {
// NB(@zkat): ERROR_BUFFER_LEN sets the expected length of the buffer to
// &ret.len, so we use that to inform our resize.
ret.ptr = static_cast<uint8_t *>(cabi_realloc(ret.ptr, default_size, 4, ret.len));
status = fastly::req_downstream_tls_cipher_openssl_name(reinterpret_cast<char *>(ret.ptr),
ret.len, &ret.len);
Expand Down Expand Up @@ -1650,6 +1652,8 @@ Result<std::optional<HostString>> HttpReq::http_req_downstream_tls_protocol() {
auto status = fastly::req_downstream_tls_protocol(reinterpret_cast<char *>(ret.ptr), default_size,
&ret.len);
if (status == FASTLY_HOST_ERROR_BUFFER_LEN) {
// NB(@zkat): ERROR_BUFFER_LEN sets the expected length of the buffer to
// &ret.len, so we use that to inform our resize.
ret.ptr = static_cast<uint8_t *>(cabi_realloc(ret.ptr, default_size, 4, ret.len));
status =
fastly::req_downstream_tls_protocol(reinterpret_cast<char *>(ret.ptr), ret.len, &ret.len);
Expand Down Expand Up @@ -1679,6 +1683,8 @@ Result<std::optional<HostBytes>> HttpReq::http_req_downstream_tls_client_hello()
ret.ptr = static_cast<uint8_t *>(cabi_malloc(default_size, 4));
auto status = fastly::req_downstream_tls_client_hello(ret.ptr, default_size, &ret.len);
if (status == FASTLY_HOST_ERROR_BUFFER_LEN) {
// NB(@zkat): ERROR_BUFFER_LEN sets the expected length of the buffer to
// &ret.len, so we use that to inform our resize.
ret.ptr = static_cast<uint8_t *>(cabi_realloc(ret.ptr, default_size, 4, ret.len));
status = fastly::req_downstream_tls_client_hello(ret.ptr, ret.len, &ret.len);
}
Expand Down Expand Up @@ -1708,6 +1714,8 @@ Result<std::optional<HostBytes>> HttpReq::http_req_downstream_tls_raw_client_cer
ret.ptr = static_cast<uint8_t *>(cabi_malloc(default_size, 4));
auto status = fastly::req_downstream_tls_raw_client_certificate(ret.ptr, default_size, &ret.len);
if (status == FASTLY_HOST_ERROR_BUFFER_LEN) {
// NB(@zkat): ERROR_BUFFER_LEN sets the expected length of the buffer to
// &ret.len, so we use that to inform our resize.
ret.ptr = static_cast<uint8_t *>(cabi_realloc(ret.ptr, default_size, 4, ret.len));
status = fastly::req_downstream_tls_raw_client_certificate(ret.ptr, ret.len, &ret.len);
}
Expand Down Expand Up @@ -1736,6 +1744,8 @@ Result<std::optional<HostBytes>> HttpReq::http_req_downstream_tls_ja3_md5() {
ret.ptr = static_cast<uint8_t *>(cabi_malloc(default_size, 4));
auto status = fastly::req_downstream_tls_ja3_md5(ret.ptr, &ret.len);
if (status == FASTLY_HOST_ERROR_BUFFER_LEN) {
// NB(@zkat): ERROR_BUFFER_LEN sets the expected length of the buffer to
// &ret.len, so we use that to inform our resize.
ret.ptr = static_cast<uint8_t *>(cabi_realloc(ret.ptr, default_size, 4, ret.len));
status = fastly::req_downstream_tls_ja3_md5(ret.ptr, &ret.len);
}
Expand Down Expand Up @@ -2686,25 +2696,47 @@ Result<ConfigStore> ConfigStore::open(std::string_view name) {
}

Result<std::optional<HostString>> ConfigStore::get(std::string_view name) {
return this->get(name, CONFIG_STORE_INITIAL_BUF_LEN);
}

Result<std::optional<HostString>> ConfigStore::get(std::string_view name,
uint32_t initial_buf_len) {
TRACE_CALL()
Result<std::optional<HostString>> res;

uint32_t buf_len{initial_buf_len};
auto name_str = string_view_to_world_string(name);
fastly::fastly_world_string ret;
fastly::fastly_host_error err;
ret.ptr = static_cast<uint8_t *>(cabi_malloc(CONFIG_STORE_ENTRY_MAX_LEN, 1));
if (!convert_result(fastly::config_store_get(this->handle, reinterpret_cast<char *>(name_str.ptr),
name_str.len, reinterpret_cast<char *>(ret.ptr),
CONFIG_STORE_ENTRY_MAX_LEN, &ret.len),
&err)) {

ret.ptr = static_cast<uint8_t *>(cabi_malloc(buf_len, 1));

bool succeeded{convert_result(
fastly::config_store_get(this->handle, reinterpret_cast<char *>(name_str.ptr), name_str.len,
reinterpret_cast<char *>(ret.ptr), buf_len, &ret.len),
&err)};

if (!succeeded && err == FASTLY_HOST_ERROR_BUFFER_LEN) {
// NB(@zkat): ERROR_BUFFER_LEN sets the expected length of the buffer to
// &ret.len, so we use that to inform our resize.
buf_len = ret.len;
ret.len = 0;
ret.ptr = static_cast<uint8_t *>(cabi_realloc(ret.ptr, initial_buf_len, 1, buf_len));
succeeded = convert_result(
fastly::config_store_get(this->handle, reinterpret_cast<char *>(name_str.ptr), name_str.len,
reinterpret_cast<char *>(ret.ptr), buf_len, &ret.len),
&err);
}

if (!succeeded) {
cabi_free(ret.ptr);
if (error_is_optional_none(err)) {
res.emplace(std::nullopt);
} else {
res.emplace_err(err);
}
} else {
ret.ptr = static_cast<uint8_t *>(cabi_realloc(ret.ptr, CONFIG_STORE_ENTRY_MAX_LEN, 1, ret.len));
ret.ptr = static_cast<uint8_t *>(cabi_realloc(ret.ptr, buf_len, 1, ret.len));
res.emplace(make_host_string(ret));
}

Expand Down Expand Up @@ -2842,25 +2874,43 @@ FastlyAsyncTask::Handle ObjectStorePendingDelete::async_handle() const {
}

Result<std::optional<HostBytes>> Secret::plaintext() const {
return this->plaintext(CONFIG_STORE_INITIAL_BUF_LEN);
}

Result<std::optional<HostBytes>> Secret::plaintext(uint32_t initial_buf_len) const {
TRACE_CALL()
Result<std::optional<HostBytes>> res;

uint32_t buf_len{initial_buf_len};
fastly::fastly_world_list_u8 ret;
fastly::fastly_host_error err;
ret.ptr = static_cast<uint8_t *>(JS_malloc(CONTEXT, DICTIONARY_ENTRY_MAX_LEN));
if (!convert_result(fastly::secret_store_plaintext(this->handle,
reinterpret_cast<char *>(ret.ptr),
DICTIONARY_ENTRY_MAX_LEN, &ret.len),
&err)) {
ret.ptr = static_cast<uint8_t *>(JS_malloc(CONTEXT, buf_len));
bool succeeded{
convert_result(fastly::secret_store_plaintext(this->handle, reinterpret_cast<char *>(ret.ptr),
buf_len, &ret.len),
&err)};

if (!succeeded && err == FASTLY_HOST_ERROR_BUFFER_LEN) {
// NB(@zkat): ERROR_BUFFER_LEN sets the expected length of the buffer to
// &ret.len, so we use that to inform our resize.
buf_len = ret.len;
ret.len = 0;
ret.ptr = static_cast<uint8_t *>(JS_realloc(CONTEXT, ret.ptr, initial_buf_len, buf_len));
succeeded =
convert_result(fastly::secret_store_plaintext(
this->handle, reinterpret_cast<char *>(ret.ptr), buf_len, &ret.len),
&err);
}

if (!succeeded) {
if (error_is_optional_none(err)) {
res.emplace(std::nullopt);
} else {
JS_free(CONTEXT, ret.ptr);
res.emplace_err(err);
}
} else {
ret.ptr =
static_cast<uint8_t *>(JS_realloc(CONTEXT, ret.ptr, DICTIONARY_ENTRY_MAX_LEN, ret.len));
ret.ptr = static_cast<uint8_t *>(JS_realloc(CONTEXT, ret.ptr, buf_len, ret.len));
res.emplace(make_host_bytes(ret.ptr, ret.len));
}

Expand Down Expand Up @@ -3363,6 +3413,8 @@ Result<HostBytes> CacheHandle::get_user_metadata() {
auto status = fastly::cache_get_user_metadata(handle, reinterpret_cast<char *>(ret.ptr),
default_size, &ret.len);
if (status == FASTLY_HOST_ERROR_BUFFER_LEN) {
// NB(@zkat): ERROR_BUFFER_LEN sets the expected length of the buffer to
// &ret.len, so we use that to inform our resize.
ret.ptr = static_cast<uint8_t *>(cabi_realloc(ret.ptr, default_size, 4, ret.len));
status = fastly::cache_get_user_metadata(handle, reinterpret_cast<char *>(ret.ptr), ret.len,
&ret.len);
Expand Down Expand Up @@ -4102,6 +4154,8 @@ Result<HostString> DeviceDetection::lookup(std::string_view user_agent) {
reinterpret_cast<char *>(user_agent_str.ptr), user_agent_str.len,
reinterpret_cast<char *>(ret.ptr), default_size, &ret.len);
if (status == FASTLY_HOST_ERROR_BUFFER_LEN) {
// NB(@zkat): ERROR_BUFFER_LEN sets the expected length of the buffer to
// &ret.len, so we use that to inform our resize.
ret.ptr = static_cast<uint8_t *>(cabi_realloc(ret.ptr, default_size, 4, ret.len));
status = fastly::device_detection_lookup(reinterpret_cast<char *>(user_agent_str.ptr),
user_agent_str.len, reinterpret_cast<char *>(ret.ptr),
Expand Down
2 changes: 2 additions & 0 deletions runtime/fastly/host-api/host_api_fastly.h
Original file line number Diff line number Diff line change
Expand Up @@ -846,6 +846,7 @@ class ConfigStore final {
static Result<ConfigStore> open(std::string_view name);

Result<std::optional<HostString>> get(std::string_view name);
Result<std::optional<HostString>> get(std::string_view name, uint32_t initial_buf_len);
};

class ObjectStorePendingLookup final {
Expand Down Expand Up @@ -918,6 +919,7 @@ class Secret final {
explicit Secret(Handle handle) : handle{handle} {}

Result<std::optional<HostBytes>> plaintext() const;
Result<std::optional<HostBytes>> plaintext(uint32_t initial_buf_len) const;
};

class SecretStore final {
Expand Down
Loading