Merge pull request #9557 from markdroth/proxy_mapper_api

Add proxy mapper method for overriding the name to resolve.
pull/9578/head
Mark D. Roth 8 years ago committed by GitHub
commit 7bd2a627f6
  1. 44
      src/core/ext/client_channel/client_channel.c
  2. 2
      src/core/ext/client_channel/client_channel_plugin.c
  3. 51
      src/core/ext/client_channel/http_proxy.c
  4. 4
      src/core/ext/client_channel/http_proxy.h
  5. 25
      src/core/ext/client_channel/proxy_mapper.c
  6. 36
      src/core/ext/client_channel/proxy_mapper.h
  7. 52
      src/core/ext/client_channel/proxy_mapper_registry.c
  8. 16
      src/core/ext/client_channel/proxy_mapper_registry.h
  9. 4
      src/core/ext/client_channel/subchannel.c

@ -44,8 +44,8 @@
#include <grpc/support/useful.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"
#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");

@ -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);

@ -40,10 +40,13 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#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);
}

@ -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 */

@ -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) {

@ -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 */

@ -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);
}

@ -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 */

@ -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;

Loading…
Cancel
Save