diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c index 4ab467329a6..06038bb5ba9 100644 --- a/src/core/ext/client_channel/client_channel.c +++ b/src/core/ext/client_channel/client_channel.c @@ -44,8 +44,8 @@ #include #include "src/core/ext/client_channel/http_connect_handshaker.h" -#include "src/core/ext/client_channel/http_proxy.h" #include "src/core/ext/client_channel/lb_policy_registry.h" +#include "src/core/ext/client_channel/proxy_mapper_registry.h" #include "src/core/ext/client_channel/resolver_registry.h" #include "src/core/ext/client_channel/subchannel.h" #include "src/core/lib/channel/channel_args.h" @@ -153,10 +153,6 @@ static void *method_parameters_create_from_json(const grpc_json *json) { */ typedef struct client_channel_channel_data { - /** server name */ - char *server_name; - /** HTTP CONNECT proxy to use, if any */ - char *proxy_name; /** resolver for this channel */ grpc_resolver *resolver; /** have we started resolving this channel */ @@ -317,17 +313,6 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, // Use pick_first if nothing was specified and we didn't select grpclb // above. if (lb_policy_name == NULL) lb_policy_name = "pick_first"; - // If using a proxy, add channel arg for server in HTTP CONNECT request. - if (chand->proxy_name != NULL) { - grpc_arg new_arg; - new_arg.key = GRPC_ARG_HTTP_CONNECT_SERVER; - new_arg.type = GRPC_ARG_STRING; - new_arg.value.string = chand->server_name; - grpc_channel_args *tmp_args = chand->resolver_result; - chand->resolver_result = - grpc_channel_args_copy_and_add(chand->resolver_result, &new_arg, 1); - grpc_channel_args_destroy(exec_ctx, tmp_args); - } // Instantiate LB policy. grpc_lb_policy_args lb_policy_args; lb_policy_args.args = chand->resolver_result; @@ -542,24 +527,21 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx, GPR_ASSERT(arg->type == GRPC_ARG_POINTER); grpc_client_channel_factory_ref(arg->value.pointer.p); chand->client_channel_factory = arg->value.pointer.p; - // Instantiate resolver. + // Get server name to resolve, using proxy mapper if needed. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI); GPR_ASSERT(arg != NULL); GPR_ASSERT(arg->type == GRPC_ARG_STRING); - grpc_uri *uri = grpc_uri_parse(arg->value.string, true); - if (uri == NULL) return GRPC_ERROR_CREATE("cannot parse server URI"); - if (uri->path[0] == '\0') { - grpc_uri_destroy(uri); - return GRPC_ERROR_CREATE("server URI is missing path"); - } - chand->server_name = - gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path); - grpc_uri_destroy(uri); - chand->proxy_name = grpc_get_http_proxy_server(); - char *name_to_resolve = - chand->proxy_name == NULL ? arg->value.string : chand->proxy_name; + char *proxy_name = NULL; + grpc_channel_args *new_args = NULL; + grpc_proxy_mappers_map_name(exec_ctx, arg->value.string, args->channel_args, + &proxy_name, &new_args); + // Instantiate resolver. chand->resolver = grpc_resolver_create( - exec_ctx, name_to_resolve, args->channel_args, chand->interested_parties); + exec_ctx, proxy_name != NULL ? proxy_name : arg->value.string, + new_args != NULL ? new_args : args->channel_args, + chand->interested_parties); + if (proxy_name != NULL) gpr_free(proxy_name); + if (new_args != NULL) grpc_channel_args_destroy(exec_ctx, new_args); if (chand->resolver == NULL) { return GRPC_ERROR_CREATE("resolver creation failed"); } @@ -570,8 +552,6 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx, static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) { channel_data *chand = elem->channel_data; - gpr_free(chand->server_name); - gpr_free(chand->proxy_name); if (chand->resolver != NULL) { grpc_resolver_shutdown(exec_ctx, chand->resolver); GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel"); diff --git a/src/core/ext/client_channel/client_channel_plugin.c b/src/core/ext/client_channel/client_channel_plugin.c index 7f75233727e..6f9df3e386e 100644 --- a/src/core/ext/client_channel/client_channel_plugin.c +++ b/src/core/ext/client_channel/client_channel_plugin.c @@ -39,6 +39,7 @@ #include "src/core/ext/client_channel/client_channel.h" #include "src/core/ext/client_channel/http_connect_handshaker.h" +#include "src/core/ext/client_channel/http_proxy.h" #include "src/core/ext/client_channel/lb_policy_registry.h" #include "src/core/ext/client_channel/proxy_mapper_registry.h" #include "src/core/ext/client_channel/resolver_registry.h" @@ -82,6 +83,7 @@ void grpc_client_channel_init(void) { grpc_lb_policy_registry_init(); grpc_resolver_registry_init(); grpc_proxy_mapper_registry_init(); + grpc_register_http_proxy_mapper(); grpc_subchannel_index_init(); grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MIN, set_default_host_if_unset, NULL); diff --git a/src/core/ext/client_channel/http_proxy.c b/src/core/ext/client_channel/http_proxy.c index 9a6c818c4ee..7daa0714951 100644 --- a/src/core/ext/client_channel/http_proxy.c +++ b/src/core/ext/client_channel/http_proxy.c @@ -40,10 +40,13 @@ #include #include +#include "src/core/ext/client_channel/http_connect_handshaker.h" +#include "src/core/ext/client_channel/proxy_mapper_registry.h" #include "src/core/ext/client_channel/uri_parser.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/support/env.h" -char* grpc_get_http_proxy_server() { +static 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 */); @@ -66,3 +69,49 @@ done: grpc_uri_destroy(uri); return proxy_name; } + +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; + } + 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; +} + +static bool proxy_mapper_map_address(grpc_exec_ctx* exec_ctx, + grpc_proxy_mapper* mapper, + const grpc_resolved_address* address, + const grpc_channel_args* args, + grpc_resolved_address** new_address, + grpc_channel_args** new_args) { + return false; +} + +static void proxy_mapper_destroy(grpc_proxy_mapper* mapper) {} + +static const grpc_proxy_mapper_vtable proxy_mapper_vtable = { + proxy_mapper_map_name, proxy_mapper_map_address, proxy_mapper_destroy}; + +static grpc_proxy_mapper proxy_mapper = {&proxy_mapper_vtable}; + +void grpc_register_http_proxy_mapper() { + grpc_proxy_mapper_register(true /* at_start */, &proxy_mapper); +} diff --git a/src/core/ext/client_channel/http_proxy.h b/src/core/ext/client_channel/http_proxy.h index 0d77ae253b0..c8882b1ef18 100644 --- a/src/core/ext/client_channel/http_proxy.h +++ b/src/core/ext/client_channel/http_proxy.h @@ -34,8 +34,6 @@ #ifndef GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H #define GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H -/// Returns the name of the proxy to use, or NULL if no proxy is configured. -/// Caller takes ownership of result. -char* grpc_get_http_proxy_server(); +void grpc_register_http_proxy_mapper(); #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_HTTP_PROXY_H */ diff --git a/src/core/ext/client_channel/proxy_mapper.c b/src/core/ext/client_channel/proxy_mapper.c index 6b6f328d3ce..f92afe847bf 100644 --- a/src/core/ext/client_channel/proxy_mapper.c +++ b/src/core/ext/client_channel/proxy_mapper.c @@ -38,13 +38,24 @@ void grpc_proxy_mapper_init(const grpc_proxy_mapper_vtable* vtable, mapper->vtable = vtable; } -bool grpc_proxy_mapper_map(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper, - const grpc_resolved_address* address, - const grpc_channel_args* args, - grpc_resolved_address** new_address, - grpc_channel_args** new_args) { - return mapper->vtable->map(exec_ctx, mapper, address, args, new_address, - new_args); +bool grpc_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) { + return mapper->vtable->map_name(exec_ctx, mapper, server_uri, args, + name_to_resolve, new_args); +} + +bool grpc_proxy_mapper_map_address(grpc_exec_ctx* exec_ctx, + grpc_proxy_mapper* mapper, + const grpc_resolved_address* address, + const grpc_channel_args* args, + grpc_resolved_address** new_address, + grpc_channel_args** new_args) { + return mapper->vtable->map_address(exec_ctx, mapper, address, args, + new_address, new_args); } void grpc_proxy_mapper_destroy(grpc_proxy_mapper* mapper) { diff --git a/src/core/ext/client_channel/proxy_mapper.h b/src/core/ext/client_channel/proxy_mapper.h index fa930379e70..6e4607fe4d9 100644 --- a/src/core/ext/client_channel/proxy_mapper.h +++ b/src/core/ext/client_channel/proxy_mapper.h @@ -43,15 +43,22 @@ typedef struct grpc_proxy_mapper grpc_proxy_mapper; typedef struct { + /// Determines the proxy name to resolve for \a server_uri. + /// If no proxy is needed, returns false. + /// Otherwise, sets \a name_to_resolve, optionally sets \a new_args, + /// and returns true. + bool (*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); /// Determines the proxy address to use to contact \a address. /// If no proxy is needed, returns false. /// Otherwise, sets \a new_address, optionally sets \a new_args, and /// returns true. - bool (*map)(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper, - const grpc_resolved_address* address, - const grpc_channel_args* args, - grpc_resolved_address** new_address, - grpc_channel_args** new_args); + bool (*map_address)(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper, + const grpc_resolved_address* address, + const grpc_channel_args* args, + grpc_resolved_address** new_address, + grpc_channel_args** new_args); /// Destroys \a mapper. void (*destroy)(grpc_proxy_mapper* mapper); } grpc_proxy_mapper_vtable; @@ -63,11 +70,20 @@ struct grpc_proxy_mapper { void grpc_proxy_mapper_init(const grpc_proxy_mapper_vtable* vtable, grpc_proxy_mapper* mapper); -bool grpc_proxy_mapper_map(grpc_exec_ctx* exec_ctx, grpc_proxy_mapper* mapper, - const grpc_resolved_address* address, - const grpc_channel_args* args, - grpc_resolved_address** new_address, - grpc_channel_args** new_args); +bool grpc_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); + +bool grpc_proxy_mapper_map_address(grpc_exec_ctx* exec_ctx, + grpc_proxy_mapper* mapper, + const grpc_resolved_address* address, + const grpc_channel_args* args, + grpc_resolved_address** new_address, + grpc_channel_args** new_args); + void grpc_proxy_mapper_destroy(grpc_proxy_mapper* mapper); #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_H */ diff --git a/src/core/ext/client_channel/proxy_mapper_registry.c b/src/core/ext/client_channel/proxy_mapper_registry.c index 0a156c8b1c1..2c44b9d4903 100644 --- a/src/core/ext/client_channel/proxy_mapper_registry.c +++ b/src/core/ext/client_channel/proxy_mapper_registry.c @@ -61,15 +61,28 @@ static void grpc_proxy_mapper_list_register(grpc_proxy_mapper_list* list, ++list->num_mappers; } -static bool grpc_proxy_mapper_list_map(grpc_exec_ctx* exec_ctx, - grpc_proxy_mapper_list* list, - const grpc_resolved_address* address, - const grpc_channel_args* args, - grpc_resolved_address** new_address, - grpc_channel_args** new_args) { +static bool grpc_proxy_mapper_list_map_name(grpc_exec_ctx* exec_ctx, + grpc_proxy_mapper_list* list, + const char* server_uri, + const grpc_channel_args* args, + char** name_to_resolve, + grpc_channel_args** new_args) { for (size_t i = 0; i < list->num_mappers; ++i) { - if (grpc_proxy_mapper_map(exec_ctx, list->list[i], address, args, - new_address, new_args)) { + if (grpc_proxy_mapper_map_name(exec_ctx, list->list[i], server_uri, args, + name_to_resolve, new_args)) { + return true; + } + } + return false; +} + +static bool grpc_proxy_mapper_list_map_address( + grpc_exec_ctx* exec_ctx, grpc_proxy_mapper_list* list, + const grpc_resolved_address* address, const grpc_channel_args* args, + grpc_resolved_address** new_address, grpc_channel_args** new_args) { + for (size_t i = 0; i < list->num_mappers; ++i) { + if (grpc_proxy_mapper_map_address(exec_ctx, list->list[i], address, args, + new_address, new_args)) { return true; } } @@ -101,11 +114,20 @@ void grpc_proxy_mapper_register(bool at_start, grpc_proxy_mapper* mapper) { grpc_proxy_mapper_list_register(&g_proxy_mapper_list, at_start, mapper); } -bool grpc_proxy_mappers_map(grpc_exec_ctx* exec_ctx, - const grpc_resolved_address* address, - const grpc_channel_args* args, - grpc_resolved_address** new_address, - grpc_channel_args** new_args) { - return grpc_proxy_mapper_list_map(exec_ctx, &g_proxy_mapper_list, address, - args, new_address, new_args); +bool grpc_proxy_mappers_map_name(grpc_exec_ctx* exec_ctx, + const char* server_uri, + const grpc_channel_args* args, + char** name_to_resolve, + grpc_channel_args** new_args) { + return grpc_proxy_mapper_list_map_name(exec_ctx, &g_proxy_mapper_list, + server_uri, args, name_to_resolve, + new_args); +} +bool grpc_proxy_mappers_map_address(grpc_exec_ctx* exec_ctx, + const grpc_resolved_address* address, + const grpc_channel_args* args, + grpc_resolved_address** new_address, + grpc_channel_args** new_args) { + return grpc_proxy_mapper_list_map_address( + exec_ctx, &g_proxy_mapper_list, address, args, new_address, new_args); } diff --git a/src/core/ext/client_channel/proxy_mapper_registry.h b/src/core/ext/client_channel/proxy_mapper_registry.h index b76af8d4564..742b57a2d49 100644 --- a/src/core/ext/client_channel/proxy_mapper_registry.h +++ b/src/core/ext/client_channel/proxy_mapper_registry.h @@ -44,10 +44,16 @@ void grpc_proxy_mapper_registry_shutdown(); /// the list. Otherwise, it will be added to the end. void grpc_proxy_mapper_register(bool at_start, grpc_proxy_mapper* mapper); -bool grpc_proxy_mappers_map(grpc_exec_ctx* exec_ctx, - const grpc_resolved_address* address, - const grpc_channel_args* args, - grpc_resolved_address** new_address, - grpc_channel_args** new_args); +bool grpc_proxy_mappers_map_name(grpc_exec_ctx* exec_ctx, + const char* server_uri, + const grpc_channel_args* args, + char** name_to_resolve, + grpc_channel_args** new_args); + +bool grpc_proxy_mappers_map_address(grpc_exec_ctx* exec_ctx, + const grpc_resolved_address* address, + const grpc_channel_args* args, + grpc_resolved_address** new_address, + grpc_channel_args** new_args); #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H */ diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c index abbbfdfd644..aa036e883ba 100644 --- a/src/core/ext/client_channel/subchannel.c +++ b/src/core/ext/client_channel/subchannel.c @@ -336,8 +336,8 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx, grpc_set_initial_connect_string(&addr, &c->initial_connect_string); grpc_resolved_address *new_address = NULL; grpc_channel_args *new_args = NULL; - if (grpc_proxy_mappers_map(exec_ctx, addr, args->args, &new_address, - &new_args)) { + if (grpc_proxy_mappers_map_address(exec_ctx, addr, args->args, &new_address, + &new_args)) { GPR_ASSERT(new_address != NULL); gpr_free(addr); addr = new_address;