static grpc_resolver_factory *resolve_factory(const char *target, grpc_uri **uri) { char *tmp; grpc_resolver_factory *factory = NULL; GPR_ASSERT(uri != NULL); *uri = grpc_uri_parse(target, 1); factory = lookup_factory_by_uri(*uri); if (factory == NULL) { if (g_default_resolver_prefix != NULL) { grpc_uri_destroy(*uri); gpr_asprintf(&tmp, "%s%s", g_default_resolver_prefix, target); *uri = grpc_uri_parse(tmp, 1); factory = lookup_factory_by_uri(*uri); if (factory == NULL) { grpc_uri_destroy(grpc_uri_parse(target, 0)); grpc_uri_destroy(grpc_uri_parse(tmp, 0)); gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target, tmp); } gpr_free(tmp); } else { grpc_uri_destroy(grpc_uri_parse(target, 0)); gpr_log(GPR_ERROR, "don't know how to resolve '%s'", target); } } return factory; }
static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper, const char* server_uri, const grpc_channel_args* args, char** name_to_resolve, grpc_channel_args** new_args) { *name_to_resolve = grpc_get_http_proxy_server(); if (*name_to_resolve == NULL) return false; grpc_uri* uri = grpc_uri_parse(server_uri, false /* suppress_errors */); if (uri == NULL || uri->path[0] == '\0') { gpr_log(GPR_ERROR, "'http_proxy' environment variable set, but cannot " "parse server URI '%s' -- not using proxy", server_uri); if (uri != NULL) grpc_uri_destroy(uri); return false; } if (strcmp(uri->scheme, "unix") == 0) { gpr_log(GPR_INFO, "not using proxy for Unix domain socket '%s'", server_uri); grpc_uri_destroy(uri); return false; } grpc_arg new_arg; new_arg.key = GRPC_ARG_HTTP_CONNECT_SERVER; new_arg.type = GRPC_ARG_STRING; new_arg.value.string = uri->path[0] == '/' ? uri->path + 1 : uri->path; *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); grpc_uri_destroy(uri); return true; }
char *grpc_get_default_authority(const char *target) { grpc_uri *uri = NULL; grpc_resolver_factory *factory = resolve_factory(target, &uri); char *authority = grpc_resolver_factory_get_default_authority(factory, uri); grpc_uri_destroy(uri); return authority; }
static void test_succeeds(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_uri *uri = grpc_uri_parse(string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, factory->vtable->scheme); GPR_ASSERT(uri); memset(&args, 0, sizeof(args)); args.uri = uri; resolver = grpc_resolver_factory_create_resolver(factory, &args); GPR_ASSERT(resolver != NULL); on_resolution_arg on_res_arg; memset(&on_res_arg, 0, sizeof(on_res_arg)); on_res_arg.expected_server_name = uri->path; grpc_closure *on_resolution = grpc_closure_create(on_resolution_cb, &on_res_arg); grpc_resolver_next(&exec_ctx, resolver, &on_res_arg.resolver_result, on_resolution); GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds"); grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); }
grpc_resolver *grpc_resolver_create(const char *target) { grpc_uri *uri = NULL; grpc_resolver_factory *factory = resolve_factory(target, &uri); grpc_resolver *resolver; grpc_resolver_args args; memset(&args, 0, sizeof(args)); args.uri = uri; resolver = grpc_resolver_factory_create_resolver(factory, &args); grpc_uri_destroy(uri); return resolver; }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { char *s = gpr_malloc(size + 1); memcpy(s, data, size); s[size] = 0; grpc_uri *x; if ((x = grpc_uri_parse(s, 1))) { grpc_uri_destroy(x); } gpr_free(s); return 0; }
static void test_succeeds(const char *uri_text, const char *scheme, const char *authority, const char *path, const char *query, const char *fragment) { grpc_uri *uri = grpc_uri_parse(uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp(scheme, uri->scheme)); GPR_ASSERT(0 == strcmp(authority, uri->authority)); GPR_ASSERT(0 == strcmp(path, uri->path)); GPR_ASSERT(0 == strcmp(query, uri->query)); GPR_ASSERT(0 == strcmp(fragment, uri->fragment)); grpc_uri_destroy(uri); }
static void test_parse_unix(const char *uri_text, const char *pathname) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); grpc_resolved_address addr; GPR_ASSERT(1 == parse_unix(uri, &addr)); struct sockaddr_un *addr_un = (struct sockaddr_un *)addr.addr; GPR_ASSERT(AF_UNIX == addr_un->sun_family); GPR_ASSERT(0 == strcmp(addr_un->sun_path, pathname)); grpc_uri_destroy(uri); grpc_exec_ctx_finish(&exec_ctx); }
static grpc_resolver *create_resolver(const char *name) { grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns"); grpc_uri *uri = grpc_uri_parse(name, 0); GPR_ASSERT(uri); grpc_resolver_args args; memset(&args, 0, sizeof(args)); args.uri = uri; grpc_resolver *resolver = grpc_resolver_factory_create_resolver(factory, &args); grpc_resolver_factory_unref(factory); grpc_uri_destroy(uri); return resolver; }
static void test_fails(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_uri *uri = grpc_uri_parse(string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, factory->vtable->scheme); GPR_ASSERT(uri); memset(&args, 0, sizeof(args)); args.uri = uri; resolver = grpc_resolver_factory_create_resolver(factory, &args); GPR_ASSERT(resolver == NULL); grpc_uri_destroy(uri); grpc_exec_ctx_finish(&exec_ctx); }
static void test_parse_ipv4(const char *uri_text, const char *host, unsigned short port) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); grpc_resolved_address addr; char ntop_buf[INET_ADDRSTRLEN]; GPR_ASSERT(1 == parse_ipv4(uri, &addr)); struct sockaddr_in *addr_in = (struct sockaddr_in *)addr.addr; GPR_ASSERT(AF_INET == addr_in->sin_family); GPR_ASSERT(NULL != grpc_inet_ntop(AF_INET, &addr_in->sin_addr, ntop_buf, sizeof(ntop_buf))); GPR_ASSERT(0 == strcmp(ntop_buf, host)); GPR_ASSERT(ntohs(addr_in->sin_port) == port); grpc_uri_destroy(uri); grpc_exec_ctx_finish(&exec_ctx); }
char* grpc_get_http_proxy_server() { char* uri_str = gpr_getenv("http_proxy"); if (uri_str == NULL) return NULL; grpc_uri* uri = grpc_uri_parse(uri_str, false /* suppress_errors */); char* proxy_name = NULL; if (uri == NULL || uri->authority == NULL) { gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var"); goto done; } if (strcmp(uri->scheme, "http") != 0) { gpr_log(GPR_ERROR, "'%s' scheme not supported in proxy URI", uri->scheme); goto done; } if (strchr(uri->authority, '@') != NULL) { gpr_log(GPR_ERROR, "userinfo not supported in proxy URI"); goto done; } proxy_name = gpr_strdup(uri->authority); done: gpr_free(uri_str); grpc_uri_destroy(uri); return proxy_name; }
static void test_fake_resolver() { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_combiner *combiner = grpc_combiner_create(NULL); // Create resolver. grpc_fake_resolver_response_generator *response_generator = grpc_fake_resolver_response_generator_create(); grpc_resolver *resolver = build_fake_resolver(&exec_ctx, combiner, response_generator); GPR_ASSERT(resolver != NULL); // Setup expectations. grpc_uri *uris[] = {grpc_uri_parse(&exec_ctx, "ipv4:10.2.1.1:1234", true), grpc_uri_parse(&exec_ctx, "ipv4:127.0.0.1:4321", true)}; char *balancer_names[] = {"name1", "name2"}; const bool is_balancer[] = {true, false}; grpc_lb_addresses *addresses = grpc_lb_addresses_create(3, NULL); for (size_t i = 0; i < GPR_ARRAY_SIZE(uris); ++i) { grpc_lb_addresses_set_address_from_uri( addresses, i, uris[i], is_balancer[i], balancer_names[i], NULL); grpc_uri_destroy(uris[i]); } const grpc_arg addresses_arg = grpc_lb_addresses_create_channel_arg(addresses); grpc_channel_args *results = grpc_channel_args_copy_and_add(NULL, &addresses_arg, 1); grpc_lb_addresses_destroy(&exec_ctx, addresses); on_resolution_arg on_res_arg; memset(&on_res_arg, 0, sizeof(on_res_arg)); on_res_arg.expected_resolver_result = results; grpc_closure *on_resolution = grpc_closure_create( on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner, false)); // Set resolver results and trigger first resolution. on_resolution_cb // performs the checks. grpc_fake_resolver_response_generator_set_response( &exec_ctx, response_generator, results); grpc_resolver_next_locked(&exec_ctx, resolver, &on_res_arg.resolver_result, on_resolution); grpc_exec_ctx_flush(&exec_ctx); GPR_ASSERT(on_res_arg.was_called); // Setup update. grpc_uri *uris_update[] = { grpc_uri_parse(&exec_ctx, "ipv4:192.168.1.0:31416", true)}; char *balancer_names_update[] = {"name3"}; const bool is_balancer_update[] = {false}; grpc_lb_addresses *addresses_update = grpc_lb_addresses_create(1, NULL); for (size_t i = 0; i < GPR_ARRAY_SIZE(uris_update); ++i) { grpc_lb_addresses_set_address_from_uri(addresses_update, i, uris_update[i], is_balancer_update[i], balancer_names_update[i], NULL); grpc_uri_destroy(uris_update[i]); } grpc_arg addresses_update_arg = grpc_lb_addresses_create_channel_arg(addresses_update); grpc_channel_args *results_update = grpc_channel_args_copy_and_add(NULL, &addresses_update_arg, 1); grpc_lb_addresses_destroy(&exec_ctx, addresses_update); // Setup expectations for the update. on_resolution_arg on_res_arg_update; memset(&on_res_arg_update, 0, sizeof(on_res_arg_update)); on_res_arg_update.expected_resolver_result = results_update; on_resolution = grpc_closure_create(on_resolution_cb, &on_res_arg_update, grpc_combiner_scheduler(combiner, false)); // Set updated resolver results and trigger a second resolution. grpc_fake_resolver_response_generator_set_response( &exec_ctx, response_generator, results_update); grpc_resolver_next_locked(&exec_ctx, resolver, &on_res_arg_update.resolver_result, on_resolution); grpc_exec_ctx_flush(&exec_ctx); GPR_ASSERT(on_res_arg.was_called); // Requesting a new resolution without re-senting the response shouldn't // trigger the resolution callback. memset(&on_res_arg, 0, sizeof(on_res_arg)); grpc_resolver_next_locked(&exec_ctx, resolver, &on_res_arg.resolver_result, on_resolution); grpc_exec_ctx_flush(&exec_ctx); GPR_ASSERT(!on_res_arg.was_called); GRPC_COMBINER_UNREF(&exec_ctx, combiner, "test_fake_resolver"); GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_fake_resolver"); grpc_exec_ctx_finish(&exec_ctx); grpc_fake_resolver_response_generator_unref(response_generator); }
static void test_query_parts() { { const char *uri_text = "http://foo/path?a&b=B&c=&#frag"; grpc_uri *uri = grpc_uri_parse(uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); GPR_ASSERT(0 == strcmp("foo", uri->authority)); GPR_ASSERT(0 == strcmp("/path", uri->path)); GPR_ASSERT(0 == strcmp("a&b=B&c=&", uri->query)); GPR_ASSERT(4 == uri->num_query_parts); GPR_ASSERT(0 == strcmp("a", uri->query_parts[0])); GPR_ASSERT(NULL == uri->query_parts_values[0]); GPR_ASSERT(0 == strcmp("b", uri->query_parts[1])); GPR_ASSERT(0 == strcmp("B", uri->query_parts_values[1])); GPR_ASSERT(0 == strcmp("c", uri->query_parts[2])); GPR_ASSERT(0 == strcmp("", uri->query_parts_values[2])); GPR_ASSERT(0 == strcmp("", uri->query_parts[3])); GPR_ASSERT(NULL == uri->query_parts_values[3]); GPR_ASSERT(NULL == grpc_uri_get_query_arg(uri, "a")); GPR_ASSERT(0 == strcmp("B", grpc_uri_get_query_arg(uri, "b"))); GPR_ASSERT(0 == strcmp("", grpc_uri_get_query_arg(uri, "c"))); GPR_ASSERT(NULL == grpc_uri_get_query_arg(uri, "")); GPR_ASSERT(0 == strcmp("frag", uri->fragment)); grpc_uri_destroy(uri); } { /* test the current behavior of multiple query part values */ const char *uri_text = "http://auth/path?foo=bar=baz&foobar=="; grpc_uri *uri = grpc_uri_parse(uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); GPR_ASSERT(0 == strcmp("auth", uri->authority)); GPR_ASSERT(0 == strcmp("/path", uri->path)); GPR_ASSERT(0 == strcmp("foo=bar=baz&foobar==", uri->query)); GPR_ASSERT(2 == uri->num_query_parts); GPR_ASSERT(0 == strcmp("bar", grpc_uri_get_query_arg(uri, "foo"))); GPR_ASSERT(0 == strcmp("", grpc_uri_get_query_arg(uri, "foobar"))); grpc_uri_destroy(uri); } { /* empty query */ const char *uri_text = "http://foo/path"; grpc_uri *uri = grpc_uri_parse(uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); GPR_ASSERT(0 == strcmp("foo", uri->authority)); GPR_ASSERT(0 == strcmp("/path", uri->path)); GPR_ASSERT(0 == strcmp("", uri->query)); GPR_ASSERT(0 == uri->num_query_parts); GPR_ASSERT(NULL == uri->query_parts); GPR_ASSERT(NULL == uri->query_parts_values); GPR_ASSERT(0 == strcmp("", uri->fragment)); grpc_uri_destroy(uri); } }