blob: f8a2d06b8a8f3af72a7aebbb715e7ac3cfd9689a [file] [log] [blame]
Mark D. Rothd58a9852017-01-18 08:28:57 -08001/*
2 *
3 * Copyright 2016, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Craig Tiller9eb0fde2017-03-31 16:59:30 -070034#include "src/core/ext/filters/client_channel/http_proxy.h"
Mark D. Rothd58a9852017-01-18 08:28:57 -080035
36#include <stdbool.h>
37#include <string.h>
38
39#include <grpc/support/alloc.h>
40#include <grpc/support/log.h>
41#include <grpc/support/string_util.h>
42
Craig Tiller9eb0fde2017-03-31 16:59:30 -070043#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
44#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
45#include "src/core/ext/filters/client_channel/uri_parser.h"
Mark D. Rothdc9bee72017-02-07 12:29:14 -080046#include "src/core/lib/channel/channel_args.h"
Mark D. Rothd58a9852017-01-18 08:28:57 -080047#include "src/core/lib/support/env.h"
48
David Garcia Quintasdcb71e02017-03-06 10:16:26 -080049static char* grpc_get_http_proxy_server(grpc_exec_ctx* exec_ctx) {
Mark D. Rothd58a9852017-01-18 08:28:57 -080050 char* uri_str = gpr_getenv("http_proxy");
51 if (uri_str == NULL) return NULL;
David Garcia Quintasdcb71e02017-03-06 10:16:26 -080052 grpc_uri* uri =
53 grpc_uri_parse(exec_ctx, uri_str, false /* suppress_errors */);
Mark D. Rothd58a9852017-01-18 08:28:57 -080054 char* proxy_name = NULL;
55 if (uri == NULL || uri->authority == NULL) {
56 gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var");
57 goto done;
58 }
59 if (strcmp(uri->scheme, "http") != 0) {
60 gpr_log(GPR_ERROR, "'%s' scheme not supported in proxy URI", uri->scheme);
61 goto done;
62 }
63 if (strchr(uri->authority, '@') != NULL) {
64 gpr_log(GPR_ERROR, "userinfo not supported in proxy URI");
65 goto done;
66 }
67 proxy_name = gpr_strdup(uri->authority);
68done:
69 gpr_free(uri_str);
70 grpc_uri_destroy(uri);
71 return proxy_name;
72}
Mark D. Rothdc9bee72017-02-07 12:29:14 -080073
74static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
75 grpc_proxy_mapper* mapper,
76 const char* server_uri,
77 const grpc_channel_args* args,
78 char** name_to_resolve,
79 grpc_channel_args** new_args) {
David Garcia Quintasdcb71e02017-03-06 10:16:26 -080080 *name_to_resolve = grpc_get_http_proxy_server(exec_ctx);
Mark D. Rothdc9bee72017-02-07 12:29:14 -080081 if (*name_to_resolve == NULL) return false;
David Garcia Quintasdcb71e02017-03-06 10:16:26 -080082 grpc_uri* uri =
83 grpc_uri_parse(exec_ctx, server_uri, false /* suppress_errors */);
Mark D. Rothdc9bee72017-02-07 12:29:14 -080084 if (uri == NULL || uri->path[0] == '\0') {
85 gpr_log(GPR_ERROR,
86 "'http_proxy' environment variable set, but cannot "
87 "parse server URI '%s' -- not using proxy",
88 server_uri);
89 if (uri != NULL) grpc_uri_destroy(uri);
90 return false;
91 }
Mark D. Roth38788592017-02-09 09:28:53 -080092 if (strcmp(uri->scheme, "unix") == 0) {
93 gpr_log(GPR_INFO, "not using proxy for Unix domain socket '%s'",
94 server_uri);
95 grpc_uri_destroy(uri);
96 return false;
97 }
Mark D. Rothdc9bee72017-02-07 12:29:14 -080098 grpc_arg new_arg;
99 new_arg.key = GRPC_ARG_HTTP_CONNECT_SERVER;
100 new_arg.type = GRPC_ARG_STRING;
101 new_arg.value.string = uri->path[0] == '/' ? uri->path + 1 : uri->path;
102 *new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
103 grpc_uri_destroy(uri);
104 return true;
105}
106
107static bool proxy_mapper_map_address(grpc_exec_ctx* exec_ctx,
108 grpc_proxy_mapper* mapper,
109 const grpc_resolved_address* address,
110 const grpc_channel_args* args,
111 grpc_resolved_address** new_address,
112 grpc_channel_args** new_args) {
113 return false;
114}
115
116static void proxy_mapper_destroy(grpc_proxy_mapper* mapper) {}
117
118static const grpc_proxy_mapper_vtable proxy_mapper_vtable = {
119 proxy_mapper_map_name, proxy_mapper_map_address, proxy_mapper_destroy};
120
121static grpc_proxy_mapper proxy_mapper = {&proxy_mapper_vtable};
122
123void grpc_register_http_proxy_mapper() {
124 grpc_proxy_mapper_register(true /* at_start */, &proxy_mapper);
125}