123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639 |
- /**
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0.
- */
- #include <aws/common/json.h>
- #include <aws/common/string.h>
- #include <aws/common/uri.h>
- #include <aws/sdkutils/private/endpoints_types_impl.h>
- #include <aws/sdkutils/private/endpoints_util.h>
- #include <aws/sdkutils/resource_name.h>
- static struct aws_byte_cursor s_scheme_http = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("http");
- static struct aws_byte_cursor s_scheme_https = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("https");
- static int s_resolve_fn_is_set(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_endpoints_value argv_value = {0};
- if (aws_array_list_length(argv) != 1 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_ANY, &argv_value)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve args for isSet.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- out_value->type = AWS_ENDPOINTS_VALUE_BOOLEAN;
- out_value->v.boolean = argv_value.type != AWS_ENDPOINTS_VALUE_NONE;
- on_done:
- aws_endpoints_value_clean_up(&argv_value);
- return result;
- }
- static int s_resolve_fn_not(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_endpoints_value argv_value = {0};
- if (aws_array_list_length(argv) != 1 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_BOOLEAN, &argv_value)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve args for not.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- out_value->type = AWS_ENDPOINTS_VALUE_BOOLEAN;
- out_value->v.boolean = !argv_value.v.boolean;
- on_done:
- aws_endpoints_value_clean_up(&argv_value);
- return result;
- }
- static int s_resolve_fn_get_attr(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_endpoints_value argv_value = {0};
- struct aws_endpoints_value argv_path = {0};
- if (aws_array_list_length(argv) != 2 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_ANY, &argv_value) ||
- aws_endpoints_argv_expect(allocator, scope, argv, 1, AWS_ENDPOINTS_VALUE_STRING, &argv_path)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve args for get attr.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- struct aws_byte_cursor path_cur = argv_path.v.owning_cursor_string.cur;
- if (argv_value.type == AWS_ENDPOINTS_VALUE_OBJECT) {
- if (aws_endpoints_path_through_object(allocator, &argv_value, path_cur, out_value)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to path through object.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- } else if (argv_value.type == AWS_ENDPOINTS_VALUE_ARRAY) {
- if (aws_endpoints_path_through_array(allocator, scope, &argv_value, path_cur, out_value)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to path through array.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- } else {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Invalid value type for pathing through.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- on_done:
- aws_endpoints_value_clean_up(&argv_value);
- aws_endpoints_value_clean_up(&argv_path);
- return result;
- }
- static int s_resolve_fn_substring(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_endpoints_value input_value = {0};
- struct aws_endpoints_value start_value = {0};
- struct aws_endpoints_value stop_value = {0};
- struct aws_endpoints_value reverse_value = {0};
- if (aws_array_list_length(argv) != 4 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_STRING, &input_value) ||
- aws_endpoints_argv_expect(allocator, scope, argv, 1, AWS_ENDPOINTS_VALUE_NUMBER, &start_value) ||
- aws_endpoints_argv_expect(allocator, scope, argv, 2, AWS_ENDPOINTS_VALUE_NUMBER, &stop_value) ||
- aws_endpoints_argv_expect(allocator, scope, argv, 3, AWS_ENDPOINTS_VALUE_BOOLEAN, &reverse_value)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve args for substring.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- if (start_value.v.number >= stop_value.v.number ||
- input_value.v.owning_cursor_string.cur.len < stop_value.v.number) {
- out_value->type = AWS_ENDPOINTS_VALUE_NONE;
- goto on_done;
- }
- for (size_t idx = 0; idx < input_value.v.owning_cursor_string.cur.len; ++idx) {
- if (input_value.v.owning_cursor_string.cur.ptr[idx] > 127) {
- out_value->type = AWS_ENDPOINTS_VALUE_NONE;
- goto on_done;
- }
- }
- if (!reverse_value.v.boolean) {
- size_t start = (size_t)start_value.v.number;
- size_t end = (size_t)stop_value.v.number;
- struct aws_byte_cursor substring = {
- .ptr = input_value.v.owning_cursor_string.cur.ptr + start,
- .len = end - start,
- };
- out_value->type = AWS_ENDPOINTS_VALUE_STRING;
- out_value->v.owning_cursor_string = aws_endpoints_owning_cursor_from_cursor(allocator, substring);
- } else {
- size_t r_start = input_value.v.owning_cursor_string.cur.len - (size_t)stop_value.v.number;
- size_t r_stop = input_value.v.owning_cursor_string.cur.len - (size_t)start_value.v.number;
- struct aws_byte_cursor substring = {
- .ptr = input_value.v.owning_cursor_string.cur.ptr + r_start,
- .len = r_stop - r_start,
- };
- out_value->type = AWS_ENDPOINTS_VALUE_STRING;
- out_value->v.owning_cursor_string = aws_endpoints_owning_cursor_from_cursor(allocator, substring);
- }
- on_done:
- aws_endpoints_value_clean_up(&input_value);
- aws_endpoints_value_clean_up(&start_value);
- aws_endpoints_value_clean_up(&stop_value);
- aws_endpoints_value_clean_up(&reverse_value);
- return result;
- }
- static int s_resolve_fn_string_equals(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_endpoints_value argv_value_1 = {0};
- struct aws_endpoints_value argv_value_2 = {0};
- if (aws_array_list_length(argv) != 2 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_STRING, &argv_value_1) ||
- aws_endpoints_argv_expect(allocator, scope, argv, 1, AWS_ENDPOINTS_VALUE_STRING, &argv_value_2)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve stringEquals.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- out_value->type = AWS_ENDPOINTS_VALUE_BOOLEAN;
- out_value->v.boolean =
- aws_byte_cursor_eq(&argv_value_1.v.owning_cursor_string.cur, &argv_value_2.v.owning_cursor_string.cur);
- on_done:
- aws_endpoints_value_clean_up(&argv_value_1);
- aws_endpoints_value_clean_up(&argv_value_2);
- return result;
- }
- static int s_resolve_fn_boolean_equals(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_endpoints_value argv_value_1 = {0};
- struct aws_endpoints_value argv_value_2 = {0};
- if (aws_array_list_length(argv) != 2 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_BOOLEAN, &argv_value_1) ||
- aws_endpoints_argv_expect(allocator, scope, argv, 1, AWS_ENDPOINTS_VALUE_BOOLEAN, &argv_value_2)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve booleanEquals.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- out_value->type = AWS_ENDPOINTS_VALUE_BOOLEAN;
- out_value->v.boolean = argv_value_1.v.boolean == argv_value_2.v.boolean;
- on_done:
- aws_endpoints_value_clean_up(&argv_value_1);
- aws_endpoints_value_clean_up(&argv_value_2);
- return result;
- }
- static int s_resolve_fn_uri_encode(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_byte_buf buf = {0};
- struct aws_endpoints_value argv_value = {0};
- if (aws_array_list_length(argv) != 1 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_STRING, &argv_value)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve parameter to uri encode.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- if (aws_byte_buf_init(&buf, allocator, 10)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve parameter to uri encode.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- if (aws_byte_buf_append_encoding_uri_param(&buf, &argv_value.v.owning_cursor_string.cur)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to uri encode value.");
- aws_byte_buf_clean_up(&buf);
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- out_value->type = AWS_ENDPOINTS_VALUE_STRING;
- out_value->v.owning_cursor_string =
- aws_endpoints_owning_cursor_from_string(aws_string_new_from_buf(allocator, &buf));
- on_done:
- aws_endpoints_value_clean_up(&argv_value);
- aws_byte_buf_clean_up(&buf);
- return result;
- }
- static bool s_is_uri_ip(struct aws_byte_cursor host, bool is_uri_encoded) {
- return aws_is_ipv4(host) || aws_is_ipv6(host, is_uri_encoded);
- }
- static int s_resolve_fn_parse_url(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_uri uri;
- struct aws_json_value *root = NULL;
- struct aws_endpoints_value argv_url = {0};
- if (aws_array_list_length(argv) != 1 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_STRING, &argv_url)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve args for parse url.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- if (aws_uri_init_parse(&uri, allocator, &argv_url.v.owning_cursor_string.cur)) {
- out_value->type = AWS_ENDPOINTS_VALUE_NONE;
- /* reset error from parser, since non-uri strings should successfully resolve to none. */
- aws_reset_error();
- goto on_done;
- }
- if (aws_uri_query_string(&uri)->len > 0) {
- out_value->type = AWS_ENDPOINTS_VALUE_NONE;
- goto on_done;
- }
- const struct aws_byte_cursor *scheme = aws_uri_scheme(&uri);
- AWS_ASSERT(scheme != NULL);
- root = aws_json_value_new_object(allocator);
- if (scheme->len == 0) {
- out_value->type = AWS_ENDPOINTS_VALUE_NONE;
- goto on_done;
- }
- if (!(aws_byte_cursor_eq(scheme, &s_scheme_http) || aws_byte_cursor_eq(scheme, &s_scheme_https))) {
- out_value->type = AWS_ENDPOINTS_VALUE_NONE;
- goto on_done;
- }
- if (aws_json_value_add_to_object(
- root, aws_byte_cursor_from_c_str("scheme"), aws_json_value_new_string(allocator, *scheme))) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to add scheme to object.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- const struct aws_byte_cursor *authority = aws_uri_authority(&uri);
- AWS_ASSERT(authority != NULL);
- if (authority->len == 0) {
- out_value->type = AWS_ENDPOINTS_VALUE_NONE;
- goto on_done;
- }
- if (aws_json_value_add_to_object(
- root, aws_byte_cursor_from_c_str("authority"), aws_json_value_new_string(allocator, *authority))) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to add authority to object.");
- goto on_done;
- }
- const struct aws_byte_cursor *path = aws_uri_path(&uri);
- if (aws_json_value_add_to_object(
- root, aws_byte_cursor_from_c_str("path"), aws_json_value_new_string(allocator, *path))) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to add path to object.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- struct aws_byte_cursor normalized_path_cur = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("normalizedPath");
- struct aws_byte_buf normalized_path_buf;
- if (aws_byte_buf_init_from_normalized_uri_path(allocator, *path, &normalized_path_buf) ||
- aws_json_value_add_to_object(
- root,
- normalized_path_cur,
- aws_json_value_new_string(allocator, aws_byte_cursor_from_buf(&normalized_path_buf)))) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to normalize path.");
- aws_byte_buf_clean_up(&normalized_path_buf);
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- aws_byte_buf_clean_up(&normalized_path_buf);
- const struct aws_byte_cursor *host_name = aws_uri_host_name(&uri);
- bool is_ip = s_is_uri_ip(*host_name, true);
- if (aws_json_value_add_to_object(
- root, aws_byte_cursor_from_c_str("isIp"), aws_json_value_new_boolean(allocator, is_ip))) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to add isIp to object.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- struct aws_byte_buf buf;
- if (aws_byte_buf_init(&buf, allocator, 0)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed init buffer for parseUrl return.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- if (aws_byte_buf_append_json_string(root, &buf)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to create JSON object.");
- aws_byte_buf_clean_up(&buf);
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- out_value->type = AWS_ENDPOINTS_VALUE_OBJECT;
- out_value->v.owning_cursor_object =
- aws_endpoints_owning_cursor_from_string(aws_string_new_from_buf(allocator, &buf));
- aws_byte_buf_clean_up(&buf);
- on_done:
- aws_uri_clean_up(&uri);
- aws_endpoints_value_clean_up(&argv_url);
- aws_json_value_destroy(root);
- return result;
- }
- static int s_resolve_is_valid_host_label(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- struct aws_endpoints_value argv_value = {0};
- struct aws_endpoints_value argv_allow_subdomains = {0};
- if (aws_array_list_length(argv) != 2 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_STRING, &argv_value) ||
- aws_endpoints_argv_expect(allocator, scope, argv, 1, AWS_ENDPOINTS_VALUE_BOOLEAN, &argv_allow_subdomains)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve not.");
- goto on_error;
- }
- out_value->type = AWS_ENDPOINTS_VALUE_BOOLEAN;
- out_value->v.boolean =
- aws_is_valid_host_label(argv_value.v.owning_cursor_string.cur, argv_allow_subdomains.v.boolean);
- aws_endpoints_value_clean_up(&argv_value);
- aws_endpoints_value_clean_up(&argv_allow_subdomains);
- return AWS_OP_SUCCESS;
- on_error:
- aws_endpoints_value_clean_up(&argv_value);
- aws_endpoints_value_clean_up(&argv_allow_subdomains);
- return aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- }
- static int s_resolve_fn_aws_partition(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_endpoints_value argv_region = {0};
- if (aws_array_list_length(argv) != 1 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_STRING, &argv_region)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve arguments for partitions.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- struct aws_hash_element *element = NULL;
- struct aws_byte_cursor key = argv_region.v.owning_cursor_string.cur;
- if (aws_hash_table_find(&scope->partitions->region_to_partition_info, &key, &element)) {
- AWS_LOGF_ERROR(
- AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to find partition info. " PRInSTR, AWS_BYTE_CURSOR_PRI(key));
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- if (element != NULL) {
- out_value->type = AWS_ENDPOINTS_VALUE_OBJECT;
- out_value->v.owning_cursor_object =
- aws_endpoints_owning_cursor_create(allocator, ((struct aws_partition_info *)element->value)->info);
- goto on_done;
- }
- key = aws_map_region_to_partition(key);
- if (key.len == 0) {
- key = aws_byte_cursor_from_c_str("aws");
- }
- if (aws_hash_table_find(&scope->partitions->region_to_partition_info, &key, &element) || element == NULL) {
- AWS_LOGF_ERROR(
- AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to find partition info. " PRInSTR, AWS_BYTE_CURSOR_PRI(key));
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- out_value->type = AWS_ENDPOINTS_VALUE_OBJECT;
- out_value->v.owning_cursor_object =
- aws_endpoints_owning_cursor_create(allocator, ((struct aws_partition_info *)element->value)->info);
- on_done:
- aws_endpoints_value_clean_up(&argv_region);
- return result;
- }
- static int s_resolve_fn_aws_parse_arn(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_json_value *object = NULL;
- struct aws_endpoints_value argv_value = {0};
- if (aws_array_list_length(argv) != 1 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_STRING, &argv_value)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve parseArn.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- struct aws_resource_name arn;
- if (aws_resource_name_init_from_cur(&arn, &argv_value.v.owning_cursor_string.cur)) {
- out_value->type = AWS_ENDPOINTS_VALUE_NONE;
- goto on_done;
- }
- object = aws_json_value_new_object(allocator);
- if (object == NULL) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to init object for parseArn.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- if (arn.partition.len == 0 || arn.resource_id.len == 0 || arn.service.len == 0) {
- out_value->type = AWS_ENDPOINTS_VALUE_NONE;
- goto on_done;
- }
- /* Split resource id into components, either on : or / */
- /* TODO: support multiple delims in existing split helper? */
- struct aws_json_value *resource_id_node = aws_json_value_new_array(allocator);
- size_t start = 0;
- for (size_t i = 0; i < arn.resource_id.len; ++i) {
- if (arn.resource_id.ptr[i] == '/' || arn.resource_id.ptr[i] == ':') {
- struct aws_byte_cursor cur = {
- .ptr = arn.resource_id.ptr + start,
- .len = i - start,
- };
- struct aws_json_value *element = aws_json_value_new_string(allocator, cur);
- if (element == NULL || aws_json_value_add_array_element(resource_id_node, element)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to add resource id element");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- start = i + 1;
- }
- }
- if (start <= arn.resource_id.len) {
- struct aws_byte_cursor cur = {
- .ptr = arn.resource_id.ptr + start,
- .len = arn.resource_id.len - start,
- };
- struct aws_json_value *element = aws_json_value_new_string(allocator, cur);
- if (element == NULL || aws_json_value_add_array_element(resource_id_node, element)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to add resource id element");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- }
- if (aws_json_value_add_to_object(
- object, aws_byte_cursor_from_c_str("partition"), aws_json_value_new_string(allocator, arn.partition)) ||
- aws_json_value_add_to_object(
- object, aws_byte_cursor_from_c_str("service"), aws_json_value_new_string(allocator, arn.service)) ||
- aws_json_value_add_to_object(
- object, aws_byte_cursor_from_c_str("region"), aws_json_value_new_string(allocator, arn.region)) ||
- aws_json_value_add_to_object(
- object, aws_byte_cursor_from_c_str("accountId"), aws_json_value_new_string(allocator, arn.account_id)) ||
- aws_json_value_add_to_object(object, aws_byte_cursor_from_c_str("resourceId"), resource_id_node)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to add elements to object for parseArn.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- out_value->type = AWS_ENDPOINTS_VALUE_OBJECT;
- out_value->v.owning_cursor_object =
- aws_endpoints_owning_cursor_from_string(aws_string_new_from_json(allocator, object));
- if (out_value->v.owning_cursor_object.cur.len == 0) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to create string from json.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- on_done:
- aws_json_value_destroy(object);
- aws_endpoints_value_clean_up(&argv_value);
- return result;
- }
- static int s_resolve_is_virtual_hostable_s3_bucket(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- int result = AWS_OP_SUCCESS;
- struct aws_endpoints_value argv_value = {0};
- struct aws_endpoints_value argv_allow_subdomains = {0};
- if (aws_array_list_length(argv) != 2 ||
- aws_endpoints_argv_expect(allocator, scope, argv, 0, AWS_ENDPOINTS_VALUE_STRING, &argv_value) ||
- aws_endpoints_argv_expect(allocator, scope, argv, 1, AWS_ENDPOINTS_VALUE_BOOLEAN, &argv_allow_subdomains)) {
- AWS_LOGF_ERROR(AWS_LS_SDKUTILS_ENDPOINTS_RESOLVE, "Failed to resolve args for isVirtualHostableS3Bucket.");
- result = aws_raise_error(AWS_ERROR_SDKUTILS_ENDPOINTS_RESOLVE_FAILED);
- goto on_done;
- }
- struct aws_byte_cursor label_cur = argv_value.v.owning_cursor_string.cur;
- bool has_uppercase_chars = false;
- for (size_t i = 0; i < label_cur.len; ++i) {
- if (label_cur.ptr[i] >= 'A' && label_cur.ptr[i] <= 'Z') {
- has_uppercase_chars = true;
- break;
- }
- }
- out_value->type = AWS_ENDPOINTS_VALUE_BOOLEAN;
- out_value->v.boolean = (label_cur.len >= 3 && label_cur.len <= 63) && !has_uppercase_chars &&
- aws_is_valid_host_label(label_cur, argv_allow_subdomains.v.boolean) &&
- !aws_is_ipv4(label_cur);
- on_done:
- aws_endpoints_value_clean_up(&argv_value);
- aws_endpoints_value_clean_up(&argv_allow_subdomains);
- return result;
- }
- typedef int(standard_lib_function_fn)(
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value);
- static standard_lib_function_fn *s_resolve_fn_vt[AWS_ENDPOINTS_FN_LAST] = {
- [AWS_ENDPOINTS_FN_IS_SET] = s_resolve_fn_is_set,
- [AWS_ENDPOINTS_FN_NOT] = s_resolve_fn_not,
- [AWS_ENDPOINTS_FN_GET_ATTR] = s_resolve_fn_get_attr,
- [AWS_ENDPOINTS_FN_SUBSTRING] = s_resolve_fn_substring,
- [AWS_ENDPOINTS_FN_STRING_EQUALS] = s_resolve_fn_string_equals,
- [AWS_ENDPOINTS_FN_BOOLEAN_EQUALS] = s_resolve_fn_boolean_equals,
- [AWS_ENDPOINTS_FN_URI_ENCODE] = s_resolve_fn_uri_encode,
- [AWS_ENDPOINTS_FN_PARSE_URL] = s_resolve_fn_parse_url,
- [AWS_ENDPOINTS_FN_IS_VALID_HOST_LABEL] = s_resolve_is_valid_host_label,
- [AWS_ENDPOINTS_FN_AWS_PARTITION] = s_resolve_fn_aws_partition,
- [AWS_ENDPOINTS_FN_AWS_PARSE_ARN] = s_resolve_fn_aws_parse_arn,
- [AWS_ENDPOINTS_FN_AWS_IS_VIRTUAL_HOSTABLE_S3_BUCKET] = s_resolve_is_virtual_hostable_s3_bucket,
- };
- int aws_endpoints_dispatch_standard_lib_fn_resolve(
- enum aws_endpoints_fn_type type,
- struct aws_allocator *allocator,
- struct aws_array_list *argv,
- struct aws_endpoints_resolution_scope *scope,
- struct aws_endpoints_value *out_value) {
- return s_resolve_fn_vt[type](allocator, argv, scope, out_value);
- }
|