Added channel_arg for proxy server and changed client to add handshaker.

pull/7611/head
Mark D. Roth 8 years ago
parent 1102a9eef7
commit 77613b2094
  1. 2
      include/grpc/impl/codegen/grpc_types.h
  2. 48
      src/core/ext/client_config/http_connect_handshaker.c
  3. 6
      src/core/ext/client_config/http_connect_handshaker.h
  4. 6
      src/core/ext/transport/chttp2/client/insecure/channel_create.c
  5. 6
      src/core/ext/transport/chttp2/client/secure/secure_channel_create.c

@ -165,6 +165,8 @@ typedef struct {
#define GRPC_ARG_MAX_METADATA_SIZE "grpc.max_metadata_size" #define GRPC_ARG_MAX_METADATA_SIZE "grpc.max_metadata_size"
/** If non-zero, allow the use of SO_REUSEPORT if it's available (default 1) */ /** If non-zero, allow the use of SO_REUSEPORT if it's available (default 1) */
#define GRPC_ARG_ALLOW_REUSEPORT "grpc.so_reuseport" #define GRPC_ARG_ALLOW_REUSEPORT "grpc.so_reuseport"
/** HTTP CONNECT proxy server to use from client. */
#define GRPC_ARG_HTTP_CONNECT_PROXY_SERVER "grpc.http_connect_proxy_server"
/** \} */ /** \} */
/** Result of a grpc call. If the caller satisfies the prerequisites of a /** Result of a grpc call. If the caller satisfies the prerequisites of a

@ -35,6 +35,8 @@
#include <grpc/impl/codegen/alloc.h> #include <grpc/impl/codegen/alloc.h>
#include <grpc/impl/codegen/log.h> #include <grpc/impl/codegen/log.h>
#include <grpc/impl/codegen/slice_buffer.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/http/format_request.h" #include "src/core/lib/http/format_request.h"
#include "src/core/lib/http/parser.h" #include "src/core/lib/http/parser.h"
@ -44,6 +46,8 @@ typedef struct http_connect_handshaker {
// Base class. Must be first. // Base class. Must be first.
grpc_handshaker base; grpc_handshaker base;
char* proxy_server;
// State saved while performing the handshake. // State saved while performing the handshake.
grpc_endpoint* endpoint; grpc_endpoint* endpoint;
grpc_channel_args* args; grpc_channel_args* args;
@ -51,9 +55,9 @@ typedef struct http_connect_handshaker {
void* user_data; void* user_data;
// Objects for processing the HTTP CONNECT request and response. // Objects for processing the HTTP CONNECT request and response.
grpc_slice_buffer request_buffer; gpr_slice_buffer request_buffer;
grpc_closure request_done_closure; grpc_closure request_done_closure;
grpc_slice_buffer response_buffer; gpr_slice_buffer response_buffer;
grpc_closure response_read_closure; grpc_closure response_read_closure;
grpc_http_parser http_parser; grpc_http_parser http_parser;
grpc_http_response http_response; grpc_http_response http_response;
@ -92,7 +96,7 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
// need to fix the HTTP parser to understand when the body is // need to fix the HTTP parser to understand when the body is
// complete (e.g., handling chunked transfer encoding or looking // complete (e.g., handling chunked transfer encoding or looking
// at the Content-Length: header). // at the Content-Length: header).
if (h->http_parser->state != GRPC_HTTP_BODY) { if (h->http_parser.state != GRPC_HTTP_BODY) {
grpc_endpoint_read(exec_ctx, h->endpoint, &h->response_buffer, grpc_endpoint_read(exec_ctx, h->endpoint, &h->response_buffer,
&h->response_read_closure); &h->response_read_closure);
return; return;
@ -109,11 +113,13 @@ static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
static void http_connect_handshaker_destroy(grpc_exec_ctx* exec_ctx, static void http_connect_handshaker_destroy(grpc_exec_ctx* exec_ctx,
grpc_handshaker* handshaker) { grpc_handshaker* handshaker) {
grpc_slice_buffer_destroy(&handshaker->request_buffer); http_connect_handshaker* h = (http_connect_handshaker*)handshaker;
grpc_slice_buffer_destroy(&handshaker->response_buffer); gpr_free(h->proxy_server);
grpc_http_parser_destroy(&handshaker->http_parser); gpr_slice_buffer_destroy(&h->request_buffer);
grpc_http_response_destroy(&handshaker->http_response); gpr_slice_buffer_destroy(&h->response_buffer);
gpr_free(handshaker); grpc_http_parser_destroy(&h->http_parser);
grpc_http_response_destroy(&h->http_response);
gpr_free(h);
} }
static void http_connect_handshaker_shutdown(grpc_exec_ctx* exec_ctx, static void http_connect_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
@ -141,13 +147,12 @@ static void http_connect_handshaker_do_handshake(
// Send HTTP CONNECT request. // Send HTTP CONNECT request.
grpc_httpcli_request request; grpc_httpcli_request request;
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
// FIXME: get proxy name from somewhere... request.host = gpr_strdup(h->proxy_server);
request.host = gpr_strdup("");
request.http.method = gpr_strdup("CONNECT"); request.http.method = gpr_strdup("CONNECT");
// FIXME: get server name from somewhere... // FIXME: get server name from somewhere...
request.http.path = gpr_strdup(""); request.http.path = gpr_strdup("");
request.handshaker = grpc_httpcli_plaintext; request.handshaker = &grpc_httpcli_plaintext;
gpr_slice request_slice = grpc_httpcli_format_connect_request(request); gpr_slice request_slice = grpc_httpcli_format_connect_request(&request);
gpr_slice_buffer_add(&h->request_buffer, request_slice); gpr_slice_buffer_add(&h->request_buffer, request_slice);
grpc_endpoint_write(exec_ctx, endpoint, &h->request_buffer, grpc_endpoint_write(exec_ctx, endpoint, &h->request_buffer,
&h->request_done_closure); &h->request_done_closure);
@ -157,10 +162,25 @@ static const struct grpc_handshaker_vtable http_connect_handshaker_vtable = {
http_connect_handshaker_destroy, http_connect_handshaker_shutdown, http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
http_connect_handshaker_do_handshake}; http_connect_handshaker_do_handshake};
grpc_handshaker* grpc_http_connect_handshaker_create() { char* grpc_get_http_connect_proxy_server_from_args(grpc_channel_args* args) {
for (size_t i = 0; i < args->num_args; ++i) {
if (strcmp(args->args[i].key, GRPC_ARG_HTTP_CONNECT_PROXY_SERVER) == 0) {
if (args->args[i].type != GRPC_ARG_STRING) {
gpr_log(GPR_ERROR, "%s: must be a string",
GRPC_ARG_HTTP_CONNECT_PROXY_SERVER);
break;
}
return gpr_strdup(args->args[i].value.string);
}
}
return NULL;
}
grpc_handshaker* grpc_http_connect_handshaker_create(char* proxy_server) {
http_connect_handshaker* handshaker = http_connect_handshaker* handshaker =
gpr_malloc(sizeof(http_connect_handshaker)); gpr_malloc(sizeof(http_connect_handshaker));
memset(handshaker, 0, sizeof(*handshaker)); memset(handshaker, 0, sizeof(*handshaker));
grpc_handshaker_init(http_connect_handshaker_vtable, &handshaker->base); grpc_handshaker_init(&http_connect_handshaker_vtable, &handshaker->base);
handshaker->proxy_server = proxy_server;
return (grpc_handshaker*)handshaker; return (grpc_handshaker*)handshaker;
} }

@ -36,6 +36,10 @@
#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/handshaker.h"
grpc_handshaker* grpc_http_connect_handshaker_create(); /// Caller takes ownership of returned string.
char* grpc_get_http_connect_proxy_server_from_args(grpc_channel_args *args);
/// Takes ownership of \a proxy_server.
grpc_handshaker* grpc_http_connect_handshaker_create(char* proxy_server);
#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_HTTP_CONNECT_HANDSHAKER_H */ #endif /* GRPC_CORE_EXT_CLIENT_CONFIG_HTTP_CONNECT_HANDSHAKER_H */

@ -41,6 +41,7 @@
#include <grpc/support/slice_buffer.h> #include <grpc/support/slice_buffer.h>
#include "src/core/ext/client_config/client_channel.h" #include "src/core/ext/client_config/client_channel.h"
#include "src/core/ext/client_config/http_connect_handshaker.h"
#include "src/core/ext/client_config/resolver_registry.h" #include "src/core/ext/client_config/resolver_registry.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_args.h"
@ -187,6 +188,11 @@ static grpc_subchannel *client_channel_factory_create_subchannel(
c->base.vtable = &connector_vtable; c->base.vtable = &connector_vtable;
gpr_ref_init(&c->refs, 1); gpr_ref_init(&c->refs, 1);
c->handshake_mgr = grpc_handshake_manager_create(); c->handshake_mgr = grpc_handshake_manager_create();
char *proxy_server = grpc_get_http_connect_proxy_server_from_args(final_args);
if (proxy_server != NULL) {
grpc_handshake_manager_add(
grpc_http_connect_handshaker_create(proxy_server), c->handshake_mgr);
}
args->args = final_args; args->args = final_args;
s = grpc_subchannel_create(exec_ctx, &c->base, args); s = grpc_subchannel_create(exec_ctx, &c->base, args);
grpc_connector_unref(exec_ctx, &c->base); grpc_connector_unref(exec_ctx, &c->base);

@ -41,6 +41,7 @@
#include <grpc/support/slice_buffer.h> #include <grpc/support/slice_buffer.h>
#include "src/core/ext/client_config/client_channel.h" #include "src/core/ext/client_config/client_channel.h"
#include "src/core/ext/client_config/http_connect_handshaker.h"
#include "src/core/ext/client_config/resolver_registry.h" #include "src/core/ext/client_config/resolver_registry.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_args.h"
@ -256,6 +257,11 @@ static grpc_subchannel *client_channel_factory_create_subchannel(
c->base.vtable = &connector_vtable; c->base.vtable = &connector_vtable;
c->security_connector = f->security_connector; c->security_connector = f->security_connector;
c->handshake_mgr = grpc_handshake_manager_create(); c->handshake_mgr = grpc_handshake_manager_create();
char *proxy_server = grpc_get_http_connect_proxy_server_from_args(final_args);
if (proxy_server != NULL) {
grpc_handshake_manager_add(
grpc_http_connect_handshaker_create(proxy_server), c->handshake_mgr);
}
gpr_mu_init(&c->mu); gpr_mu_init(&c->mu);
gpr_ref_init(&c->refs, 1); gpr_ref_init(&c->refs, 1);
args->args = final_args; args->args = final_args;

Loading…
Cancel
Save