static void parse_query_parts(grpc_uri *uri) { static const char *QUERY_PARTS_SEPARATOR = "&"; static const char *QUERY_PARTS_VALUE_SEPARATOR = "="; GPR_ASSERT(uri->query != NULL); if (uri->query[0] == '\0') { uri->query_parts = NULL; uri->query_parts_values = NULL; uri->num_query_parts = 0; return; } grpc_slice query_slice = grpc_slice_new(uri->query, strlen(uri->query), do_nothing); grpc_slice_buffer query_parts; /* the &-separated elements of the query */ grpc_slice_buffer query_param_parts; /* the =-separated subelements */ grpc_slice_buffer_init(&query_parts); grpc_slice_buffer_init(&query_param_parts); grpc_slice_split(query_slice, QUERY_PARTS_SEPARATOR, &query_parts); uri->query_parts = gpr_malloc(query_parts.count * sizeof(char *)); uri->query_parts_values = gpr_malloc(query_parts.count * sizeof(char *)); uri->num_query_parts = query_parts.count; for (size_t i = 0; i < query_parts.count; i++) { grpc_slice_split(query_parts.slices[i], QUERY_PARTS_VALUE_SEPARATOR, &query_param_parts); GPR_ASSERT(query_param_parts.count > 0); uri->query_parts[i] = grpc_dump_slice(query_param_parts.slices[0], GPR_DUMP_ASCII); if (query_param_parts.count > 1) { /* TODO(dgq): only the first value after the separator is considered. * Perhaps all chars after the first separator for the query part should * be included, even if they include the separator. */ uri->query_parts_values[i] = grpc_dump_slice(query_param_parts.slices[1], GPR_DUMP_ASCII); } else { uri->query_parts_values[i] = NULL; } grpc_slice_buffer_reset_and_unref(&query_param_parts); } grpc_slice_buffer_destroy(&query_parts); grpc_slice_buffer_destroy(&query_param_parts); grpc_slice_unref(query_slice); }
static grpc_resolver *sockaddr_create(grpc_exec_ctx *exec_ctx, grpc_resolver_args *args, bool parse(const grpc_uri *uri, grpc_resolved_address *dst)) { if (0 != strcmp(args->uri->authority, "")) { gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme", args->uri->scheme); return NULL; } /* Construct addresses. */ grpc_slice path_slice = grpc_slice_new(args->uri->path, strlen(args->uri->path), do_nothing); grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); grpc_lb_addresses *addresses = grpc_lb_addresses_create(path_parts.count, NULL /* user_data_vtable */); bool errors_found = false; for (size_t i = 0; i < addresses->num_addresses; i++) { grpc_uri ith_uri = *args->uri; char *part_str = grpc_slice_to_c_string(path_parts.slices[i]); ith_uri.path = part_str; if (!parse(&ith_uri, &addresses->addresses[i].address)) { errors_found = true; /* GPR_TRUE */ } gpr_free(part_str); if (errors_found) break; } grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts); grpc_slice_unref_internal(exec_ctx, path_slice); if (errors_found) { grpc_lb_addresses_destroy(exec_ctx, addresses); return NULL; } /* Instantiate resolver. */ sockaddr_resolver *r = gpr_zalloc(sizeof(sockaddr_resolver)); r->addresses = addresses; r->channel_args = grpc_channel_args_copy(args->args); grpc_resolver_init(&r->base, &sockaddr_resolver_vtable, args->combiner); return &r->base; }
static grpc_resolver* fake_resolver_create(grpc_exec_ctx* exec_ctx, grpc_resolver_factory* factory, grpc_resolver_args* args) { if (0 != strcmp(args->uri->authority, "")) { gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme", args->uri->scheme); return NULL; } // Get lb_enabled arg. Anything other than "0" is interpreted as true. const char* lb_enabled_qpart = grpc_uri_get_query_arg(args->uri, "lb_enabled"); const bool lb_enabled = lb_enabled_qpart != NULL && strcmp("0", lb_enabled_qpart) != 0; // Get the balancer's names. const char* balancer_names = grpc_uri_get_query_arg(args->uri, "balancer_names"); grpc_slice_buffer balancer_names_parts; grpc_slice_buffer_init(&balancer_names_parts); if (balancer_names != NULL) { const grpc_slice balancer_names_slice = grpc_slice_from_copied_string(balancer_names); grpc_slice_split(balancer_names_slice, ",", &balancer_names_parts); grpc_slice_unref(balancer_names_slice); } // Construct addresses. grpc_slice path_slice = grpc_slice_new(args->uri->path, strlen(args->uri->path), do_nothing); grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); if (balancer_names_parts.count > 0 && path_parts.count != balancer_names_parts.count) { gpr_log(GPR_ERROR, "Balancer names present but mismatched with number of addresses: " "%lu balancer names != %lu addresses", (unsigned long)balancer_names_parts.count, (unsigned long)path_parts.count); return NULL; } grpc_lb_addresses* addresses = grpc_lb_addresses_create(path_parts.count, NULL /* user_data_vtable */); bool errors_found = false; for (size_t i = 0; i < addresses->num_addresses; i++) { grpc_uri ith_uri = *args->uri; char* part_str = grpc_slice_to_c_string(path_parts.slices[i]); ith_uri.path = part_str; if (!parse_ipv4(&ith_uri, &addresses->addresses[i].address)) { errors_found = true; } gpr_free(part_str); if (errors_found) break; addresses->addresses[i].is_balancer = lb_enabled; addresses->addresses[i].balancer_name = balancer_names_parts.count > 0 ? grpc_dump_slice(balancer_names_parts.slices[i], GPR_DUMP_ASCII) : NULL; } grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts); grpc_slice_buffer_destroy_internal(exec_ctx, &balancer_names_parts); grpc_slice_unref(path_slice); if (errors_found) { grpc_lb_addresses_destroy(exec_ctx, addresses); return NULL; } // Instantiate resolver. fake_resolver* r = gpr_malloc(sizeof(fake_resolver)); memset(r, 0, sizeof(*r)); r->channel_args = grpc_channel_args_copy(args->args); r->addresses = addresses; gpr_mu_init(&r->mu); grpc_resolver_init(&r->base, &fake_resolver_vtable); return &r->base; }
static void test_strsplit(void) { grpc_slice_buffer *parts; grpc_slice str; LOG_TEST_NAME("test_strsplit"); parts = gpr_malloc(sizeof(grpc_slice_buffer)); grpc_slice_buffer_init(parts); str = grpc_slice_from_copied_string("one, two, three, four"); grpc_slice_split(str, ", ", parts); GPR_ASSERT(4 == parts->count); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "one")); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "two")); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[2], "three")); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[3], "four")); grpc_slice_buffer_reset_and_unref(parts); grpc_slice_unref(str); /* separator not present in string */ str = grpc_slice_from_copied_string("one two three four"); grpc_slice_split(str, ", ", parts); GPR_ASSERT(1 == parts->count); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "one two three four")); grpc_slice_buffer_reset_and_unref(parts); grpc_slice_unref(str); /* separator at the end */ str = grpc_slice_from_copied_string("foo,"); grpc_slice_split(str, ",", parts); GPR_ASSERT(2 == parts->count); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "foo")); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "")); grpc_slice_buffer_reset_and_unref(parts); grpc_slice_unref(str); /* separator at the beginning */ str = grpc_slice_from_copied_string(",foo"); grpc_slice_split(str, ",", parts); GPR_ASSERT(2 == parts->count); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "")); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "foo")); grpc_slice_buffer_reset_and_unref(parts); grpc_slice_unref(str); /* standalone separator */ str = grpc_slice_from_copied_string(","); grpc_slice_split(str, ",", parts); GPR_ASSERT(2 == parts->count); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "")); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[1], "")); grpc_slice_buffer_reset_and_unref(parts); grpc_slice_unref(str); /* empty input */ str = grpc_slice_from_copied_string(""); grpc_slice_split(str, ", ", parts); GPR_ASSERT(1 == parts->count); GPR_ASSERT(0 == grpc_slice_str_cmp(parts->slices[0], "")); grpc_slice_buffer_reset_and_unref(parts); grpc_slice_unref(str); grpc_slice_buffer_destroy(parts); gpr_free(parts); }