Merge pull request #7611 from markdroth/http_connect

HTTP CONNECT handshaker
pull/8177/head^2
Mark D. Roth 8 years ago committed by GitHub
commit 942c264861
  1. 8
      BUILD
  2. 3
      CMakeLists.txt
  3. 61
      Makefile
  4. 1
      binding.gyp
  5. 4
      build.yaml
  6. 1
      config.m4
  7. 3
      gRPC-Core.podspec
  8. 2
      grpc.gemspec
  9. 2
      package.xml
  10. 2
      src/core/ext/client_config/client_channel.c
  11. 275
      src/core/ext/client_config/http_connect_handshaker.c
  12. 47
      src/core/ext/client_config/http_connect_handshaker.h
  13. 1
      src/core/ext/client_config/lb_policy_factory.h
  14. 11
      src/core/ext/client_config/resolver_result.c
  15. 7
      src/core/ext/client_config/resolver_result.h
  16. 2
      src/core/ext/client_config/subchannel.h
  17. 7
      src/core/ext/client_config/subchannel_index.c
  18. 4
      src/core/ext/lb_policy/grpclb/grpclb.c
  19. 1
      src/core/ext/lb_policy/pick_first/pick_first.c
  20. 1
      src/core/ext/lb_policy/round_robin/round_robin.c
  21. 37
      src/core/ext/resolver/dns/native/dns_resolver.c
  22. 2
      src/core/ext/resolver/sockaddr/sockaddr_resolver.c
  23. 8
      src/core/ext/transport/chttp2/client/insecure/channel_create.c
  24. 8
      src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
  25. 3
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  26. 20
      src/core/lib/http/format_request.c
  27. 2
      src/core/lib/http/format_request.h
  28. 2
      src/core/lib/http/httpcli.c
  29. 6
      src/core/lib/http/httpcli.h
  30. 31
      src/core/lib/http/parser.c
  31. 4
      src/core/lib/http/parser.h
  32. 3
      src/core/lib/iomgr/endpoint.h
  33. 12
      src/core/lib/iomgr/exec_ctx.h
  34. 2
      src/core/lib/iomgr/socket_windows.c
  35. 1
      src/python/grpcio/grpc_core_dependencies.py
  36. 129
      test/core/end2end/fixtures/h2_http_proxy.c
  37. 481
      test/core/end2end/fixtures/http_proxy.c
  38. 41
      test/core/end2end/fixtures/http_proxy.h
  39. 1
      test/core/end2end/gen_build_yaml.py
  40. 17
      test/core/end2end/tests/no_logging.c
  41. 10
      test/core/http/parser_test.c
  42. 2
      test/core/http/request_fuzzer.c
  43. 2
      test/core/http/response_fuzzer.c
  44. 2
      tools/doxygen/Doxyfile.core.internal
  45. 40
      tools/run_tests/sources_and_headers.json
  46. 4825
      tools/run_tests/tests.json
  47. 56
      vsprojects/buildtests_c.sln
  48. 3
      vsprojects/vcxproj/grpc/grpc.vcxproj
  49. 6
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  50. 3
      vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
  51. 6
      vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
  52. 3
      vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
  53. 6
      vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
  54. 3
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  55. 6
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
  56. 191
      vsprojects/vcxproj/test/end2end/fixtures/h2_http_proxy_nosec_test/h2_http_proxy_nosec_test.vcxproj
  57. 24
      vsprojects/vcxproj/test/end2end/fixtures/h2_http_proxy_nosec_test/h2_http_proxy_nosec_test.vcxproj.filters
  58. 202
      vsprojects/vcxproj/test/end2end/fixtures/h2_http_proxy_test/h2_http_proxy_test.vcxproj
  59. 24
      vsprojects/vcxproj/test/end2end/fixtures/h2_http_proxy_test/h2_http_proxy_test.vcxproj.filters

@ -292,6 +292,7 @@ cc_library(
"src/core/ext/client_config/client_channel.h", "src/core/ext/client_config/client_channel.h",
"src/core/ext/client_config/client_channel_factory.h", "src/core/ext/client_config/client_channel_factory.h",
"src/core/ext/client_config/connector.h", "src/core/ext/client_config/connector.h",
"src/core/ext/client_config/http_connect_handshaker.h",
"src/core/ext/client_config/initial_connect_string.h", "src/core/ext/client_config/initial_connect_string.h",
"src/core/ext/client_config/lb_policy.h", "src/core/ext/client_config/lb_policy.h",
"src/core/ext/client_config/lb_policy_factory.h", "src/core/ext/client_config/lb_policy_factory.h",
@ -470,6 +471,7 @@ cc_library(
"src/core/ext/client_config/client_config_plugin.c", "src/core/ext/client_config/client_config_plugin.c",
"src/core/ext/client_config/connector.c", "src/core/ext/client_config/connector.c",
"src/core/ext/client_config/default_initial_connect_string.c", "src/core/ext/client_config/default_initial_connect_string.c",
"src/core/ext/client_config/http_connect_handshaker.c",
"src/core/ext/client_config/initial_connect_string.c", "src/core/ext/client_config/initial_connect_string.c",
"src/core/ext/client_config/lb_policy.c", "src/core/ext/client_config/lb_policy.c",
"src/core/ext/client_config/lb_policy_factory.c", "src/core/ext/client_config/lb_policy_factory.c",
@ -666,6 +668,7 @@ cc_library(
"src/core/ext/client_config/client_channel.h", "src/core/ext/client_config/client_channel.h",
"src/core/ext/client_config/client_channel_factory.h", "src/core/ext/client_config/client_channel_factory.h",
"src/core/ext/client_config/connector.h", "src/core/ext/client_config/connector.h",
"src/core/ext/client_config/http_connect_handshaker.h",
"src/core/ext/client_config/initial_connect_string.h", "src/core/ext/client_config/initial_connect_string.h",
"src/core/ext/client_config/lb_policy.h", "src/core/ext/client_config/lb_policy.h",
"src/core/ext/client_config/lb_policy_factory.h", "src/core/ext/client_config/lb_policy_factory.h",
@ -826,6 +829,7 @@ cc_library(
"src/core/ext/client_config/client_config_plugin.c", "src/core/ext/client_config/client_config_plugin.c",
"src/core/ext/client_config/connector.c", "src/core/ext/client_config/connector.c",
"src/core/ext/client_config/default_initial_connect_string.c", "src/core/ext/client_config/default_initial_connect_string.c",
"src/core/ext/client_config/http_connect_handshaker.c",
"src/core/ext/client_config/initial_connect_string.c", "src/core/ext/client_config/initial_connect_string.c",
"src/core/ext/client_config/lb_policy.c", "src/core/ext/client_config/lb_policy.c",
"src/core/ext/client_config/lb_policy_factory.c", "src/core/ext/client_config/lb_policy_factory.c",
@ -1017,6 +1021,7 @@ cc_library(
"src/core/ext/client_config/client_channel.h", "src/core/ext/client_config/client_channel.h",
"src/core/ext/client_config/client_channel_factory.h", "src/core/ext/client_config/client_channel_factory.h",
"src/core/ext/client_config/connector.h", "src/core/ext/client_config/connector.h",
"src/core/ext/client_config/http_connect_handshaker.h",
"src/core/ext/client_config/initial_connect_string.h", "src/core/ext/client_config/initial_connect_string.h",
"src/core/ext/client_config/lb_policy.h", "src/core/ext/client_config/lb_policy.h",
"src/core/ext/client_config/lb_policy_factory.h", "src/core/ext/client_config/lb_policy_factory.h",
@ -1170,6 +1175,7 @@ cc_library(
"src/core/ext/client_config/client_config_plugin.c", "src/core/ext/client_config/client_config_plugin.c",
"src/core/ext/client_config/connector.c", "src/core/ext/client_config/connector.c",
"src/core/ext/client_config/default_initial_connect_string.c", "src/core/ext/client_config/default_initial_connect_string.c",
"src/core/ext/client_config/http_connect_handshaker.c",
"src/core/ext/client_config/initial_connect_string.c", "src/core/ext/client_config/initial_connect_string.c",
"src/core/ext/client_config/lb_policy.c", "src/core/ext/client_config/lb_policy.c",
"src/core/ext/client_config/lb_policy_factory.c", "src/core/ext/client_config/lb_policy_factory.c",
@ -2315,6 +2321,7 @@ objc_library(
"src/core/ext/client_config/client_config_plugin.c", "src/core/ext/client_config/client_config_plugin.c",
"src/core/ext/client_config/connector.c", "src/core/ext/client_config/connector.c",
"src/core/ext/client_config/default_initial_connect_string.c", "src/core/ext/client_config/default_initial_connect_string.c",
"src/core/ext/client_config/http_connect_handshaker.c",
"src/core/ext/client_config/initial_connect_string.c", "src/core/ext/client_config/initial_connect_string.c",
"src/core/ext/client_config/lb_policy.c", "src/core/ext/client_config/lb_policy.c",
"src/core/ext/client_config/lb_policy_factory.c", "src/core/ext/client_config/lb_policy_factory.c",
@ -2513,6 +2520,7 @@ objc_library(
"src/core/ext/client_config/client_channel.h", "src/core/ext/client_config/client_channel.h",
"src/core/ext/client_config/client_channel_factory.h", "src/core/ext/client_config/client_channel_factory.h",
"src/core/ext/client_config/connector.h", "src/core/ext/client_config/connector.h",
"src/core/ext/client_config/http_connect_handshaker.h",
"src/core/ext/client_config/initial_connect_string.h", "src/core/ext/client_config/initial_connect_string.h",
"src/core/ext/client_config/lb_policy.h", "src/core/ext/client_config/lb_policy.h",
"src/core/ext/client_config/lb_policy_factory.h", "src/core/ext/client_config/lb_policy_factory.h",

@ -439,6 +439,7 @@ add_library(grpc
src/core/ext/client_config/client_config_plugin.c src/core/ext/client_config/client_config_plugin.c
src/core/ext/client_config/connector.c src/core/ext/client_config/connector.c
src/core/ext/client_config/default_initial_connect_string.c src/core/ext/client_config/default_initial_connect_string.c
src/core/ext/client_config/http_connect_handshaker.c
src/core/ext/client_config/initial_connect_string.c src/core/ext/client_config/initial_connect_string.c
src/core/ext/client_config/lb_policy.c src/core/ext/client_config/lb_policy.c
src/core/ext/client_config/lb_policy_factory.c src/core/ext/client_config/lb_policy_factory.c
@ -670,6 +671,7 @@ add_library(grpc_cronet
src/core/ext/client_config/client_config_plugin.c src/core/ext/client_config/client_config_plugin.c
src/core/ext/client_config/connector.c src/core/ext/client_config/connector.c
src/core/ext/client_config/default_initial_connect_string.c src/core/ext/client_config/default_initial_connect_string.c
src/core/ext/client_config/http_connect_handshaker.c
src/core/ext/client_config/initial_connect_string.c src/core/ext/client_config/initial_connect_string.c
src/core/ext/client_config/lb_policy.c src/core/ext/client_config/lb_policy.c
src/core/ext/client_config/lb_policy_factory.c src/core/ext/client_config/lb_policy_factory.c
@ -899,6 +901,7 @@ add_library(grpc_unsecure
src/core/ext/client_config/client_config_plugin.c src/core/ext/client_config/client_config_plugin.c
src/core/ext/client_config/connector.c src/core/ext/client_config/connector.c
src/core/ext/client_config/default_initial_connect_string.c src/core/ext/client_config/default_initial_connect_string.c
src/core/ext/client_config/http_connect_handshaker.c
src/core/ext/client_config/initial_connect_string.c src/core/ext/client_config/initial_connect_string.c
src/core/ext/client_config/lb_policy.c src/core/ext/client_config/lb_policy.c
src/core/ext/client_config/lb_policy_factory.c src/core/ext/client_config/lb_policy_factory.c

@ -1134,6 +1134,7 @@ h2_fd_test: $(BINDIR)/$(CONFIG)/h2_fd_test
h2_full_test: $(BINDIR)/$(CONFIG)/h2_full_test h2_full_test: $(BINDIR)/$(CONFIG)/h2_full_test
h2_full+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_test h2_full+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_test
h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test
h2_http_proxy_test: $(BINDIR)/$(CONFIG)/h2_http_proxy_test
h2_load_reporting_test: $(BINDIR)/$(CONFIG)/h2_load_reporting_test h2_load_reporting_test: $(BINDIR)/$(CONFIG)/h2_load_reporting_test
h2_oauth2_test: $(BINDIR)/$(CONFIG)/h2_oauth2_test h2_oauth2_test: $(BINDIR)/$(CONFIG)/h2_oauth2_test
h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test
@ -1150,6 +1151,7 @@ h2_fd_nosec_test: $(BINDIR)/$(CONFIG)/h2_fd_nosec_test
h2_full_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_nosec_test h2_full_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_nosec_test
h2_full+pipe_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test h2_full+pipe_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test
h2_full+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test h2_full+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test
h2_http_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test
h2_load_reporting_nosec_test: $(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test h2_load_reporting_nosec_test: $(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test
h2_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test h2_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test
h2_sockpair_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test h2_sockpair_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test
@ -1355,6 +1357,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/h2_full_test \ $(BINDIR)/$(CONFIG)/h2_full_test \
$(BINDIR)/$(CONFIG)/h2_full+pipe_test \ $(BINDIR)/$(CONFIG)/h2_full+pipe_test \
$(BINDIR)/$(CONFIG)/h2_full+trace_test \ $(BINDIR)/$(CONFIG)/h2_full+trace_test \
$(BINDIR)/$(CONFIG)/h2_http_proxy_test \
$(BINDIR)/$(CONFIG)/h2_load_reporting_test \ $(BINDIR)/$(CONFIG)/h2_load_reporting_test \
$(BINDIR)/$(CONFIG)/h2_oauth2_test \ $(BINDIR)/$(CONFIG)/h2_oauth2_test \
$(BINDIR)/$(CONFIG)/h2_proxy_test \ $(BINDIR)/$(CONFIG)/h2_proxy_test \
@ -1371,6 +1374,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/h2_full_nosec_test \ $(BINDIR)/$(CONFIG)/h2_full_nosec_test \
$(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test \ $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test \
$(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test \ $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test \
$(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test \
$(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test \ $(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test \
$(BINDIR)/$(CONFIG)/h2_proxy_nosec_test \ $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test \
$(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test \
@ -2672,6 +2676,7 @@ LIBGRPC_SRC = \
src/core/ext/client_config/client_config_plugin.c \ src/core/ext/client_config/client_config_plugin.c \
src/core/ext/client_config/connector.c \ src/core/ext/client_config/connector.c \
src/core/ext/client_config/default_initial_connect_string.c \ src/core/ext/client_config/default_initial_connect_string.c \
src/core/ext/client_config/http_connect_handshaker.c \
src/core/ext/client_config/initial_connect_string.c \ src/core/ext/client_config/initial_connect_string.c \
src/core/ext/client_config/lb_policy.c \ src/core/ext/client_config/lb_policy.c \
src/core/ext/client_config/lb_policy_factory.c \ src/core/ext/client_config/lb_policy_factory.c \
@ -2921,6 +2926,7 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/client_config/client_config_plugin.c \ src/core/ext/client_config/client_config_plugin.c \
src/core/ext/client_config/connector.c \ src/core/ext/client_config/connector.c \
src/core/ext/client_config/default_initial_connect_string.c \ src/core/ext/client_config/default_initial_connect_string.c \
src/core/ext/client_config/http_connect_handshaker.c \
src/core/ext/client_config/initial_connect_string.c \ src/core/ext/client_config/initial_connect_string.c \
src/core/ext/client_config/lb_policy.c \ src/core/ext/client_config/lb_policy.c \
src/core/ext/client_config/lb_policy_factory.c \ src/core/ext/client_config/lb_policy_factory.c \
@ -3050,6 +3056,7 @@ LIBGRPC_TEST_UTIL_SRC = \
test/core/end2end/data/test_root_cert.c \ test/core/end2end/data/test_root_cert.c \
test/core/security/oauth2_utils.c \ test/core/security/oauth2_utils.c \
test/core/end2end/cq_verifier.c \ test/core/end2end/cq_verifier.c \
test/core/end2end/fixtures/http_proxy.c \
test/core/end2end/fixtures/proxy.c \ test/core/end2end/fixtures/proxy.c \
test/core/iomgr/endpoint_tests.c \ test/core/iomgr/endpoint_tests.c \
test/core/util/grpc_profiler.c \ test/core/util/grpc_profiler.c \
@ -3215,6 +3222,7 @@ endif
LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
test/core/end2end/cq_verifier.c \ test/core/end2end/cq_verifier.c \
test/core/end2end/fixtures/http_proxy.c \
test/core/end2end/fixtures/proxy.c \ test/core/end2end/fixtures/proxy.c \
test/core/iomgr/endpoint_tests.c \ test/core/iomgr/endpoint_tests.c \
test/core/util/grpc_profiler.c \ test/core/util/grpc_profiler.c \
@ -3375,6 +3383,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/client_config/client_config_plugin.c \ src/core/ext/client_config/client_config_plugin.c \
src/core/ext/client_config/connector.c \ src/core/ext/client_config/connector.c \
src/core/ext/client_config/default_initial_connect_string.c \ src/core/ext/client_config/default_initial_connect_string.c \
src/core/ext/client_config/http_connect_handshaker.c \
src/core/ext/client_config/initial_connect_string.c \ src/core/ext/client_config/initial_connect_string.c \
src/core/ext/client_config/lb_policy.c \ src/core/ext/client_config/lb_policy.c \
src/core/ext/client_config/lb_policy_factory.c \ src/core/ext/client_config/lb_policy_factory.c \
@ -14699,6 +14708,38 @@ endif
endif endif
H2_HTTP_PROXY_TEST_SRC = \
test/core/end2end/fixtures/h2_http_proxy.c \
H2_HTTP_PROXY_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_HTTP_PROXY_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/h2_http_proxy_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/h2_http_proxy_test: $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_test
endif
$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_h2_http_proxy_test: $(H2_HTTP_PROXY_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(H2_HTTP_PROXY_TEST_OBJS:.o=.dep)
endif
endif
H2_LOAD_REPORTING_TEST_SRC = \ H2_LOAD_REPORTING_TEST_SRC = \
test/core/end2end/fixtures/h2_load_reporting.c \ test/core/end2end/fixtures/h2_load_reporting.c \
@ -15139,6 +15180,26 @@ ifneq ($(NO_DEPS),true)
endif endif
H2_HTTP_PROXY_NOSEC_TEST_SRC = \
test/core/end2end/fixtures/h2_http_proxy.c \
H2_HTTP_PROXY_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_HTTP_PROXY_NOSEC_TEST_SRC))))
$(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(H2_HTTP_PROXY_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_http_proxy_nosec_test
$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_http_proxy.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_h2_http_proxy_nosec_test: $(H2_HTTP_PROXY_NOSEC_TEST_OBJS:.o=.dep)
ifneq ($(NO_DEPS),true)
-include $(H2_HTTP_PROXY_NOSEC_TEST_OBJS:.o=.dep)
endif
H2_LOAD_REPORTING_NOSEC_TEST_SRC = \ H2_LOAD_REPORTING_NOSEC_TEST_SRC = \
test/core/end2end/fixtures/h2_load_reporting.c \ test/core/end2end/fixtures/h2_load_reporting.c \

@ -714,6 +714,7 @@
'src/core/ext/client_config/client_config_plugin.c', 'src/core/ext/client_config/client_config_plugin.c',
'src/core/ext/client_config/connector.c', 'src/core/ext/client_config/connector.c',
'src/core/ext/client_config/default_initial_connect_string.c', 'src/core/ext/client_config/default_initial_connect_string.c',
'src/core/ext/client_config/http_connect_handshaker.c',
'src/core/ext/client_config/initial_connect_string.c', 'src/core/ext/client_config/initial_connect_string.c',
'src/core/ext/client_config/lb_policy.c', 'src/core/ext/client_config/lb_policy.c',
'src/core/ext/client_config/lb_policy_factory.c', 'src/core/ext/client_config/lb_policy_factory.c',

@ -349,6 +349,7 @@ filegroups:
- src/core/ext/client_config/client_channel.h - src/core/ext/client_config/client_channel.h
- src/core/ext/client_config/client_channel_factory.h - src/core/ext/client_config/client_channel_factory.h
- src/core/ext/client_config/connector.h - src/core/ext/client_config/connector.h
- src/core/ext/client_config/http_connect_handshaker.h
- src/core/ext/client_config/initial_connect_string.h - src/core/ext/client_config/initial_connect_string.h
- src/core/ext/client_config/lb_policy.h - src/core/ext/client_config/lb_policy.h
- src/core/ext/client_config/lb_policy_factory.h - src/core/ext/client_config/lb_policy_factory.h
@ -368,6 +369,7 @@ filegroups:
- src/core/ext/client_config/client_config_plugin.c - src/core/ext/client_config/client_config_plugin.c
- src/core/ext/client_config/connector.c - src/core/ext/client_config/connector.c
- src/core/ext/client_config/default_initial_connect_string.c - src/core/ext/client_config/default_initial_connect_string.c
- src/core/ext/client_config/http_connect_handshaker.c
- src/core/ext/client_config/initial_connect_string.c - src/core/ext/client_config/initial_connect_string.c
- src/core/ext/client_config/lb_policy.c - src/core/ext/client_config/lb_policy.c
- src/core/ext/client_config/lb_policy_factory.c - src/core/ext/client_config/lb_policy_factory.c
@ -503,6 +505,7 @@ filegroups:
build: test build: test
headers: headers:
- test/core/end2end/cq_verifier.h - test/core/end2end/cq_verifier.h
- test/core/end2end/fixtures/http_proxy.h
- test/core/end2end/fixtures/proxy.h - test/core/end2end/fixtures/proxy.h
- test/core/iomgr/endpoint_tests.h - test/core/iomgr/endpoint_tests.h
- test/core/util/grpc_profiler.h - test/core/util/grpc_profiler.h
@ -515,6 +518,7 @@ filegroups:
- test/core/util/slice_splitter.h - test/core/util/slice_splitter.h
src: src:
- test/core/end2end/cq_verifier.c - test/core/end2end/cq_verifier.c
- test/core/end2end/fixtures/http_proxy.c
- test/core/end2end/fixtures/proxy.c - test/core/end2end/fixtures/proxy.c
- test/core/iomgr/endpoint_tests.c - test/core/iomgr/endpoint_tests.c
- test/core/util/grpc_profiler.c - test/core/util/grpc_profiler.c

@ -233,6 +233,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/client_config/client_config_plugin.c \ src/core/ext/client_config/client_config_plugin.c \
src/core/ext/client_config/connector.c \ src/core/ext/client_config/connector.c \
src/core/ext/client_config/default_initial_connect_string.c \ src/core/ext/client_config/default_initial_connect_string.c \
src/core/ext/client_config/http_connect_handshaker.c \
src/core/ext/client_config/initial_connect_string.c \ src/core/ext/client_config/initial_connect_string.c \
src/core/ext/client_config/lb_policy.c \ src/core/ext/client_config/lb_policy.c \
src/core/ext/client_config/lb_policy_factory.c \ src/core/ext/client_config/lb_policy_factory.c \

@ -379,6 +379,7 @@ Pod::Spec.new do |s|
'src/core/ext/client_config/client_channel.h', 'src/core/ext/client_config/client_channel.h',
'src/core/ext/client_config/client_channel_factory.h', 'src/core/ext/client_config/client_channel_factory.h',
'src/core/ext/client_config/connector.h', 'src/core/ext/client_config/connector.h',
'src/core/ext/client_config/http_connect_handshaker.h',
'src/core/ext/client_config/initial_connect_string.h', 'src/core/ext/client_config/initial_connect_string.h',
'src/core/ext/client_config/lb_policy.h', 'src/core/ext/client_config/lb_policy.h',
'src/core/ext/client_config/lb_policy_factory.h', 'src/core/ext/client_config/lb_policy_factory.h',
@ -561,6 +562,7 @@ Pod::Spec.new do |s|
'src/core/ext/client_config/client_config_plugin.c', 'src/core/ext/client_config/client_config_plugin.c',
'src/core/ext/client_config/connector.c', 'src/core/ext/client_config/connector.c',
'src/core/ext/client_config/default_initial_connect_string.c', 'src/core/ext/client_config/default_initial_connect_string.c',
'src/core/ext/client_config/http_connect_handshaker.c',
'src/core/ext/client_config/initial_connect_string.c', 'src/core/ext/client_config/initial_connect_string.c',
'src/core/ext/client_config/lb_policy.c', 'src/core/ext/client_config/lb_policy.c',
'src/core/ext/client_config/lb_policy_factory.c', 'src/core/ext/client_config/lb_policy_factory.c',
@ -748,6 +750,7 @@ Pod::Spec.new do |s|
'src/core/ext/client_config/client_channel.h', 'src/core/ext/client_config/client_channel.h',
'src/core/ext/client_config/client_channel_factory.h', 'src/core/ext/client_config/client_channel_factory.h',
'src/core/ext/client_config/connector.h', 'src/core/ext/client_config/connector.h',
'src/core/ext/client_config/http_connect_handshaker.h',
'src/core/ext/client_config/initial_connect_string.h', 'src/core/ext/client_config/initial_connect_string.h',
'src/core/ext/client_config/lb_policy.h', 'src/core/ext/client_config/lb_policy.h',
'src/core/ext/client_config/lb_policy_factory.h', 'src/core/ext/client_config/lb_policy_factory.h',

@ -299,6 +299,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/client_config/client_channel.h ) s.files += %w( src/core/ext/client_config/client_channel.h )
s.files += %w( src/core/ext/client_config/client_channel_factory.h ) s.files += %w( src/core/ext/client_config/client_channel_factory.h )
s.files += %w( src/core/ext/client_config/connector.h ) s.files += %w( src/core/ext/client_config/connector.h )
s.files += %w( src/core/ext/client_config/http_connect_handshaker.h )
s.files += %w( src/core/ext/client_config/initial_connect_string.h ) s.files += %w( src/core/ext/client_config/initial_connect_string.h )
s.files += %w( src/core/ext/client_config/lb_policy.h ) s.files += %w( src/core/ext/client_config/lb_policy.h )
s.files += %w( src/core/ext/client_config/lb_policy_factory.h ) s.files += %w( src/core/ext/client_config/lb_policy_factory.h )
@ -481,6 +482,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/client_config/client_config_plugin.c ) s.files += %w( src/core/ext/client_config/client_config_plugin.c )
s.files += %w( src/core/ext/client_config/connector.c ) s.files += %w( src/core/ext/client_config/connector.c )
s.files += %w( src/core/ext/client_config/default_initial_connect_string.c ) s.files += %w( src/core/ext/client_config/default_initial_connect_string.c )
s.files += %w( src/core/ext/client_config/http_connect_handshaker.c )
s.files += %w( src/core/ext/client_config/initial_connect_string.c ) s.files += %w( src/core/ext/client_config/initial_connect_string.c )
s.files += %w( src/core/ext/client_config/lb_policy.c ) s.files += %w( src/core/ext/client_config/lb_policy.c )
s.files += %w( src/core/ext/client_config/lb_policy_factory.c ) s.files += %w( src/core/ext/client_config/lb_policy_factory.c )

@ -306,6 +306,7 @@
<file baseinstalldir="/" name="src/core/ext/client_config/client_channel.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/client_channel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/client_channel_factory.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/client_channel_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/connector.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/connector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/http_connect_handshaker.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/initial_connect_string.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/initial_connect_string.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/lb_policy.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/lb_policy_factory.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy_factory.h" role="src" />
@ -488,6 +489,7 @@
<file baseinstalldir="/" name="src/core/ext/client_config/client_config_plugin.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/client_config_plugin.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/connector.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/connector.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/default_initial_connect_string.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/default_initial_connect_string.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/http_connect_handshaker.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/initial_connect_string.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/initial_connect_string.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/lb_policy.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/lb_policy_factory.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/client_config/lb_policy_factory.c" role="src" />

@ -177,6 +177,8 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
if (chand->resolver_result != NULL) { if (chand->resolver_result != NULL) {
grpc_lb_policy_args lb_policy_args; grpc_lb_policy_args lb_policy_args;
lb_policy_args.server_name =
grpc_resolver_result_get_server_name(chand->resolver_result);
lb_policy_args.addresses = lb_policy_args.addresses =
grpc_resolver_result_get_addresses(chand->resolver_result); grpc_resolver_result_get_addresses(chand->resolver_result);
lb_policy_args.additional_args = lb_policy_args.additional_args =

@ -0,0 +1,275 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/ext/client_config/http_connect_handshaker.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/slice_buffer.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/client_config/uri_parser.h"
#include "src/core/lib/http/format_request.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/support/env.h"
typedef struct http_connect_handshaker {
// Base class. Must be first.
grpc_handshaker base;
char* proxy_server;
char* server_name;
// State saved while performing the handshake.
grpc_endpoint* endpoint;
grpc_channel_args* args;
grpc_handshaker_done_cb cb;
void* user_data;
// Objects for processing the HTTP CONNECT request and response.
gpr_slice_buffer write_buffer;
gpr_slice_buffer* read_buffer; // Ownership passes through this object.
grpc_closure request_done_closure;
grpc_closure response_read_closure;
grpc_http_parser http_parser;
grpc_http_response http_response;
grpc_timer timeout_timer;
gpr_refcount refcount;
} http_connect_handshaker;
// Unref and clean up handshaker.
static void http_connect_handshaker_unref(http_connect_handshaker* handshaker) {
if (gpr_unref(&handshaker->refcount)) {
gpr_free(handshaker->proxy_server);
gpr_free(handshaker->server_name);
gpr_slice_buffer_destroy(&handshaker->write_buffer);
grpc_http_parser_destroy(&handshaker->http_parser);
grpc_http_response_destroy(&handshaker->http_response);
gpr_free(handshaker);
}
}
// Callback invoked when deadline is exceeded.
static void on_timeout(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) {
http_connect_handshaker* handshaker = arg;
if (error == GRPC_ERROR_NONE) { // Timer fired, rather than being cancelled.
grpc_endpoint_shutdown(exec_ctx, handshaker->endpoint);
}
http_connect_handshaker_unref(handshaker);
}
// Callback invoked when finished writing HTTP CONNECT request.
static void on_write_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
http_connect_handshaker* handshaker = arg;
if (error != GRPC_ERROR_NONE) {
// If the write failed, invoke the callback immediately with the error.
handshaker->cb(exec_ctx, handshaker->endpoint, handshaker->args,
handshaker->read_buffer, handshaker->user_data,
GRPC_ERROR_REF(error));
} else {
// Otherwise, read the response.
grpc_endpoint_read(exec_ctx, handshaker->endpoint, handshaker->read_buffer,
&handshaker->response_read_closure);
}
}
// Callback invoked for reading HTTP CONNECT response.
static void on_read_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
http_connect_handshaker* handshaker = arg;
if (error != GRPC_ERROR_NONE) {
GRPC_ERROR_REF(error); // Take ref to pass to the handshake-done callback.
goto done;
}
// Add buffer to parser.
for (size_t i = 0; i < handshaker->read_buffer->count; ++i) {
if (GPR_SLICE_LENGTH(handshaker->read_buffer->slices[i]) > 0) {
size_t body_start_offset = 0;
error = grpc_http_parser_parse(&handshaker->http_parser,
handshaker->read_buffer->slices[i],
&body_start_offset);
if (error != GRPC_ERROR_NONE) goto done;
if (handshaker->http_parser.state == GRPC_HTTP_BODY) {
// We've gotten back a successul response, so stop the timeout timer.
grpc_timer_cancel(exec_ctx, &handshaker->timeout_timer);
// Remove the data we've already read from the read buffer,
// leaving only the leftover bytes (if any).
gpr_slice_buffer tmp_buffer;
gpr_slice_buffer_init(&tmp_buffer);
if (body_start_offset <
GPR_SLICE_LENGTH(handshaker->read_buffer->slices[i])) {
gpr_slice_buffer_add(
&tmp_buffer,
gpr_slice_split_tail(&handshaker->read_buffer->slices[i],
body_start_offset));
}
gpr_slice_buffer_addn(&tmp_buffer,
&handshaker->read_buffer->slices[i + 1],
handshaker->read_buffer->count - i - 1);
gpr_slice_buffer_swap(handshaker->read_buffer, &tmp_buffer);
gpr_slice_buffer_destroy(&tmp_buffer);
break;
}
}
}
// If we're not done reading the response, read more data.
// TODO(roth): In practice, I suspect that the response to a CONNECT
// request will never include a body, in which case this check is
// sufficient. However, the language of RFC-2817 doesn't explicitly
// forbid the response from including a body. If there is a body,
// it's possible that we might have parsed part but not all of the
// body, in which case this check will cause us to fail to parse the
// remainder of the body. If that ever becomes an issue, we may
// need to fix the HTTP parser to understand when the body is
// complete (e.g., handling chunked transfer encoding or looking
// at the Content-Length: header).
if (handshaker->http_parser.state != GRPC_HTTP_BODY) {
gpr_slice_buffer_reset_and_unref(handshaker->read_buffer);
grpc_endpoint_read(exec_ctx, handshaker->endpoint, handshaker->read_buffer,
&handshaker->response_read_closure);
return;
}
// Make sure we got a 2xx response.
if (handshaker->http_response.status < 200 ||
handshaker->http_response.status >= 300) {
char* msg;
gpr_asprintf(&msg, "HTTP proxy returned response code %d",
handshaker->http_response.status);
error = GRPC_ERROR_CREATE(msg);
gpr_free(msg);
}
done:
// Invoke handshake-done callback.
handshaker->cb(exec_ctx, handshaker->endpoint, handshaker->args,
handshaker->read_buffer, handshaker->user_data, error);
}
//
// Public handshaker methods
//
static void http_connect_handshaker_destroy(grpc_exec_ctx* exec_ctx,
grpc_handshaker* handshaker_in) {
http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
http_connect_handshaker_unref(handshaker);
}
static void http_connect_handshaker_shutdown(grpc_exec_ctx* exec_ctx,
grpc_handshaker* handshaker) {}
static void http_connect_handshaker_do_handshake(
grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker_in,
grpc_endpoint* endpoint, grpc_channel_args* args,
gpr_slice_buffer* read_buffer, gpr_timespec deadline,
grpc_tcp_server_acceptor* acceptor, grpc_handshaker_done_cb cb,
void* user_data) {
http_connect_handshaker* handshaker = (http_connect_handshaker*)handshaker_in;
// Save state in the handshaker object.
handshaker->endpoint = endpoint;
handshaker->args = args;
handshaker->cb = cb;
handshaker->user_data = user_data;
handshaker->read_buffer = read_buffer;
// Send HTTP CONNECT request.
gpr_log(GPR_INFO, "Connecting to server %s via HTTP proxy %s",
handshaker->server_name, handshaker->proxy_server);
grpc_httpcli_request request;
memset(&request, 0, sizeof(request));
request.host = handshaker->proxy_server;
request.http.method = "CONNECT";
request.http.path = handshaker->server_name;
request.handshaker = &grpc_httpcli_plaintext;
gpr_slice request_slice = grpc_httpcli_format_connect_request(&request);
gpr_slice_buffer_add(&handshaker->write_buffer, request_slice);
grpc_endpoint_write(exec_ctx, endpoint, &handshaker->write_buffer,
&handshaker->request_done_closure);
// Set timeout timer. The timer gets a reference to the handshaker.
gpr_ref(&handshaker->refcount);
grpc_timer_init(exec_ctx, &handshaker->timeout_timer,
gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC),
on_timeout, handshaker, gpr_now(GPR_CLOCK_MONOTONIC));
}
static const struct grpc_handshaker_vtable http_connect_handshaker_vtable = {
http_connect_handshaker_destroy, http_connect_handshaker_shutdown,
http_connect_handshaker_do_handshake};
grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server,
const char* server_name) {
GPR_ASSERT(proxy_server != NULL);
GPR_ASSERT(server_name != NULL);
http_connect_handshaker* handshaker =
gpr_malloc(sizeof(http_connect_handshaker));
memset(handshaker, 0, sizeof(*handshaker));
grpc_handshaker_init(&http_connect_handshaker_vtable, &handshaker->base);
handshaker->proxy_server = gpr_strdup(proxy_server);
handshaker->server_name = gpr_strdup(server_name);
gpr_slice_buffer_init(&handshaker->write_buffer);
grpc_closure_init(&handshaker->request_done_closure, on_write_done,
handshaker);
grpc_closure_init(&handshaker->response_read_closure, on_read_done,
handshaker);
grpc_http_parser_init(&handshaker->http_parser, GRPC_HTTP_RESPONSE,
&handshaker->http_response);
gpr_ref_init(&handshaker->refcount, 1);
return &handshaker->base;
}
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;
}

@ -0,0 +1,47 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CLIENT_CONFIG_HTTP_CONNECT_HANDSHAKER_H
#define GRPC_CORE_EXT_CLIENT_CONFIG_HTTP_CONNECT_HANDSHAKER_H
#include "src/core/lib/channel/handshaker.h"
/// Does NOT take ownership of \a proxy_server or \a server_name.
grpc_handshaker* grpc_http_connect_handshaker_create(const char* proxy_server,
const char* server_name);
/// 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();
#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_HTTP_CONNECT_HANDSHAKER_H */

@ -90,6 +90,7 @@ void grpc_lb_addresses_destroy(grpc_lb_addresses *addresses,
/* TODO(roth, ctiller): Consider replacing this struct with /* TODO(roth, ctiller): Consider replacing this struct with
grpc_channel_args. See comment in resolver_result.h for details. */ grpc_channel_args. See comment in resolver_result.h for details. */
typedef struct grpc_lb_policy_args { typedef struct grpc_lb_policy_args {
const char *server_name;
grpc_lb_addresses *addresses; grpc_lb_addresses *addresses;
grpc_client_channel_factory *client_channel_factory; grpc_client_channel_factory *client_channel_factory;
/* Can be used to pass implementation-specific parameters to the LB policy. */ /* Can be used to pass implementation-specific parameters to the LB policy. */

@ -40,17 +40,19 @@
struct grpc_resolver_result { struct grpc_resolver_result {
gpr_refcount refs; gpr_refcount refs;
char* server_name;
grpc_lb_addresses* addresses; grpc_lb_addresses* addresses;
char* lb_policy_name; char* lb_policy_name;
grpc_channel_args* lb_policy_args; grpc_channel_args* lb_policy_args;
}; };
grpc_resolver_result* grpc_resolver_result_create( grpc_resolver_result* grpc_resolver_result_create(
grpc_lb_addresses* addresses, const char* lb_policy_name, const char* server_name, grpc_lb_addresses* addresses,
grpc_channel_args* lb_policy_args) { const char* lb_policy_name, grpc_channel_args* lb_policy_args) {
grpc_resolver_result* result = gpr_malloc(sizeof(*result)); grpc_resolver_result* result = gpr_malloc(sizeof(*result));
memset(result, 0, sizeof(*result)); memset(result, 0, sizeof(*result));
gpr_ref_init(&result->refs, 1); gpr_ref_init(&result->refs, 1);
result->server_name = gpr_strdup(server_name);
result->addresses = addresses; result->addresses = addresses;
result->lb_policy_name = gpr_strdup(lb_policy_name); result->lb_policy_name = gpr_strdup(lb_policy_name);
result->lb_policy_args = lb_policy_args; result->lb_policy_args = lb_policy_args;
@ -64,6 +66,7 @@ void grpc_resolver_result_ref(grpc_resolver_result* result) {
void grpc_resolver_result_unref(grpc_exec_ctx* exec_ctx, void grpc_resolver_result_unref(grpc_exec_ctx* exec_ctx,
grpc_resolver_result* result) { grpc_resolver_result* result) {
if (gpr_unref(&result->refs)) { if (gpr_unref(&result->refs)) {
gpr_free(result->server_name);
grpc_lb_addresses_destroy(result->addresses, NULL /* user_data_destroy */); grpc_lb_addresses_destroy(result->addresses, NULL /* user_data_destroy */);
gpr_free(result->lb_policy_name); gpr_free(result->lb_policy_name);
grpc_channel_args_destroy(result->lb_policy_args); grpc_channel_args_destroy(result->lb_policy_args);
@ -71,6 +74,10 @@ void grpc_resolver_result_unref(grpc_exec_ctx* exec_ctx,
} }
} }
const char* grpc_resolver_result_get_server_name(grpc_resolver_result* result) {
return result->server_name;
}
grpc_lb_addresses* grpc_resolver_result_get_addresses( grpc_lb_addresses* grpc_resolver_result_get_addresses(
grpc_resolver_result* result) { grpc_resolver_result* result) {
return result->addresses; return result->addresses;

@ -50,12 +50,15 @@ typedef struct grpc_resolver_result grpc_resolver_result;
/// Takes ownership of \a addresses and \a lb_policy_args. /// Takes ownership of \a addresses and \a lb_policy_args.
grpc_resolver_result* grpc_resolver_result_create( grpc_resolver_result* grpc_resolver_result_create(
grpc_lb_addresses* addresses, const char* lb_policy_name, const char* server_name, grpc_lb_addresses* addresses,
grpc_channel_args* lb_policy_args); const char* lb_policy_name, grpc_channel_args* lb_policy_args);
void grpc_resolver_result_ref(grpc_resolver_result* result); void grpc_resolver_result_ref(grpc_resolver_result* result);
void grpc_resolver_result_unref(grpc_exec_ctx* exec_ctx, void grpc_resolver_result_unref(grpc_exec_ctx* exec_ctx,
grpc_resolver_result* result); grpc_resolver_result* result);
/// Caller does NOT take ownership of result.
const char* grpc_resolver_result_get_server_name(grpc_resolver_result* result);
/// Caller does NOT take ownership of result. /// Caller does NOT take ownership of result.
grpc_lb_addresses* grpc_resolver_result_get_addresses( grpc_lb_addresses* grpc_resolver_result_get_addresses(
grpc_resolver_result* result); grpc_resolver_result* result);

@ -162,6 +162,8 @@ struct grpc_subchannel_args {
size_t filter_count; size_t filter_count;
/** Channel arguments to be supplied to the newly created channel */ /** Channel arguments to be supplied to the newly created channel */
const grpc_channel_args *args; const grpc_channel_args *args;
/** Server name */
const char *server_name;
/** Address to connect to */ /** Address to connect to */
struct sockaddr *addr; struct sockaddr *addr;
size_t addr_len; size_t addr_len;

@ -38,6 +38,7 @@
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/avl.h> #include <grpc/support/avl.h>
#include <grpc/support/string_util.h>
#include <grpc/support/tls.h> #include <grpc/support/tls.h>
#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_args.h"
@ -85,6 +86,7 @@ static grpc_subchannel_key *create_key(
} else { } else {
k->args.filters = NULL; k->args.filters = NULL;
} }
k->args.server_name = gpr_strdup(args->server_name);
k->args.addr_len = args->addr_len; k->args.addr_len = args->addr_len;
k->args.addr = gpr_malloc(args->addr_len); k->args.addr = gpr_malloc(args->addr_len);
if (k->args.addr_len > 0) { if (k->args.addr_len > 0) {
@ -111,6 +113,8 @@ static int subchannel_key_compare(grpc_subchannel_key *a,
if (c != 0) return c; if (c != 0) return c;
c = GPR_ICMP(a->args.filter_count, b->args.filter_count); c = GPR_ICMP(a->args.filter_count, b->args.filter_count);
if (c != 0) return c; if (c != 0) return c;
c = strcmp(a->args.server_name, b->args.server_name);
if (c != 0) return c;
if (a->args.addr_len) { if (a->args.addr_len) {
c = memcmp(a->args.addr, b->args.addr, a->args.addr_len); c = memcmp(a->args.addr, b->args.addr, a->args.addr_len);
if (c != 0) return c; if (c != 0) return c;
@ -126,9 +130,10 @@ static int subchannel_key_compare(grpc_subchannel_key *a,
void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx, void grpc_subchannel_key_destroy(grpc_exec_ctx *exec_ctx,
grpc_subchannel_key *k) { grpc_subchannel_key *k) {
grpc_connector_unref(exec_ctx, k->connector); grpc_connector_unref(exec_ctx, k->connector);
gpr_free(k->args.addr);
gpr_free((grpc_channel_args *)k->args.filters); gpr_free((grpc_channel_args *)k->args.filters);
grpc_channel_args_destroy((grpc_channel_args *)k->args.args); grpc_channel_args_destroy((grpc_channel_args *)k->args.args);
gpr_free((void *)k->args.server_name);
gpr_free(k->args.addr);
gpr_free(k); gpr_free(k);
} }

@ -283,6 +283,7 @@ typedef struct glb_lb_policy {
/** mutex protecting remaining members */ /** mutex protecting remaining members */
gpr_mu mu; gpr_mu mu;
const char *server_name;
grpc_client_channel_factory *cc_factory; grpc_client_channel_factory *cc_factory;
/** for communicating with the LB server */ /** for communicating with the LB server */
@ -438,6 +439,7 @@ static grpc_lb_policy *create_rr(grpc_exec_ctx *exec_ctx,
grpc_lb_policy_args args; grpc_lb_policy_args args;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.server_name = glb_policy->server_name;
args.client_channel_factory = glb_policy->cc_factory; args.client_channel_factory = glb_policy->cc_factory;
args.addresses = process_serverlist(serverlist); args.addresses = process_serverlist(serverlist);
@ -563,6 +565,7 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
* policy is only instantiated and used in that case. * policy is only instantiated and used in that case.
* *
* Create a client channel over them to communicate with a LB service */ * Create a client channel over them to communicate with a LB service */
glb_policy->server_name = gpr_strdup(args->server_name);
glb_policy->cc_factory = args->client_channel_factory; glb_policy->cc_factory = args->client_channel_factory;
GPR_ASSERT(glb_policy->cc_factory != NULL); GPR_ASSERT(glb_policy->cc_factory != NULL);
@ -629,6 +632,7 @@ static void glb_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
glb_lb_policy *glb_policy = (glb_lb_policy *)pol; glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
GPR_ASSERT(glb_policy->pending_picks == NULL); GPR_ASSERT(glb_policy->pending_picks == NULL);
GPR_ASSERT(glb_policy->pending_pings == NULL); GPR_ASSERT(glb_policy->pending_pings == NULL);
gpr_free((void *)glb_policy->server_name);
grpc_channel_destroy(glb_policy->lb_channel); grpc_channel_destroy(glb_policy->lb_channel);
glb_policy->lb_channel = NULL; glb_policy->lb_channel = NULL;
grpc_connectivity_state_destroy(exec_ctx, &glb_policy->state_tracker); grpc_connectivity_state_destroy(exec_ctx, &glb_policy->state_tracker);

@ -466,6 +466,7 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
} }
memset(&sc_args, 0, sizeof(grpc_subchannel_args)); memset(&sc_args, 0, sizeof(grpc_subchannel_args));
sc_args.server_name = args->server_name;
sc_args.addr = sc_args.addr =
(struct sockaddr *)(&args->addresses->addresses[i].address.addr); (struct sockaddr *)(&args->addresses->addresses[i].address.addr);
sc_args.addr_len = args->addresses->addresses[i].address.len; sc_args.addr_len = args->addresses->addresses[i].address.len;

@ -629,6 +629,7 @@ static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
if (args->addresses->addresses[i].is_balancer) continue; if (args->addresses->addresses[i].is_balancer) continue;
memset(&sc_args, 0, sizeof(grpc_subchannel_args)); memset(&sc_args, 0, sizeof(grpc_subchannel_args));
sc_args.server_name = args->server_name;
sc_args.addr = sc_args.addr =
(struct sockaddr *)(&args->addresses->addresses[i].address.addr); (struct sockaddr *)(&args->addresses->addresses[i].address.addr);
sc_args.addr_len = args->addresses->addresses[i].address.len; sc_args.addr_len = args->addresses->addresses[i].address.len;

@ -37,6 +37,8 @@
#include <grpc/support/host_port.h> #include <grpc/support/host_port.h>
#include <grpc/support/string_util.h> #include <grpc/support/string_util.h>
#include "src/core/ext/client_config/http_connect_handshaker.h"
#include "src/core/ext/client_config/lb_policy_registry.h"
#include "src/core/ext/client_config/resolver_registry.h" #include "src/core/ext/client_config/resolver_registry.h"
#include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/timer.h"
@ -53,8 +55,10 @@ typedef struct {
grpc_resolver base; grpc_resolver base;
/** refcount */ /** refcount */
gpr_refcount refs; gpr_refcount refs;
/** name to resolve */ /** target name */
char *name; char *target_name;
/** name to resolve (usually the same as target_name) */
char *name_to_resolve;
/** default port to use */ /** default port to use */
char *default_port; char *default_port;
/** load balancing policy name */ /** load balancing policy name */
@ -63,7 +67,7 @@ typedef struct {
/** mutex guarding the rest of the state */ /** mutex guarding the rest of the state */
gpr_mu mu; gpr_mu mu;
/** are we currently resolving? */ /** are we currently resolving? */
int resolving; bool resolving;
/** which version of the result have we published? */ /** which version of the result have we published? */
int published_version; int published_version;
/** which version of the result is current? */ /** which version of the result is current? */
@ -165,7 +169,7 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
grpc_resolver_result *result = NULL; grpc_resolver_result *result = NULL;
gpr_mu_lock(&r->mu); gpr_mu_lock(&r->mu);
GPR_ASSERT(r->resolving); GPR_ASSERT(r->resolving);
r->resolving = 0; r->resolving = false;
if (r->addresses != NULL) { if (r->addresses != NULL) {
grpc_lb_addresses *addresses = grpc_lb_addresses *addresses =
grpc_lb_addresses_create(r->addresses->naddrs); grpc_lb_addresses_create(r->addresses->naddrs);
@ -176,7 +180,8 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
NULL /* balancer_name */, NULL /* user_data */); NULL /* balancer_name */, NULL /* user_data */);
} }
grpc_resolved_addresses_destroy(r->addresses); grpc_resolved_addresses_destroy(r->addresses);
result = grpc_resolver_result_create(addresses, r->lb_policy_name, NULL); result = grpc_resolver_result_create(r->target_name, addresses,
r->lb_policy_name, NULL);
} else { } else {
gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now); gpr_timespec next_try = gpr_backoff_step(&r->backoff_state, now);
@ -211,9 +216,9 @@ static void dns_start_resolving_locked(grpc_exec_ctx *exec_ctx,
dns_resolver *r) { dns_resolver *r) {
GRPC_RESOLVER_REF(&r->base, "dns-resolving"); GRPC_RESOLVER_REF(&r->base, "dns-resolving");
GPR_ASSERT(!r->resolving); GPR_ASSERT(!r->resolving);
r->resolving = 1; r->resolving = true;
r->addresses = NULL; r->addresses = NULL;
grpc_resolve_address(exec_ctx, r->name, r->default_port, grpc_resolve_address(exec_ctx, r->name_to_resolve, r->default_port,
grpc_closure_create(dns_on_resolved, r), &r->addresses); grpc_closure_create(dns_on_resolved, r), &r->addresses);
} }
@ -237,7 +242,8 @@ static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
if (r->resolved_result) { if (r->resolved_result) {
grpc_resolver_result_unref(exec_ctx, r->resolved_result); grpc_resolver_result_unref(exec_ctx, r->resolved_result);
} }
gpr_free(r->name); gpr_free(r->target_name);
gpr_free(r->name_to_resolve);
gpr_free(r->default_port); gpr_free(r->default_port);
gpr_free(r->lb_policy_name); gpr_free(r->lb_policy_name);
gpr_free(r); gpr_free(r);
@ -246,22 +252,23 @@ static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
static grpc_resolver *dns_create(grpc_resolver_args *args, static grpc_resolver *dns_create(grpc_resolver_args *args,
const char *default_port, const char *default_port,
const char *lb_policy_name) { const char *lb_policy_name) {
dns_resolver *r;
const char *path = args->uri->path;
if (0 != strcmp(args->uri->authority, "")) { if (0 != strcmp(args->uri->authority, "")) {
gpr_log(GPR_ERROR, "authority based dns uri's not supported"); gpr_log(GPR_ERROR, "authority based dns uri's not supported");
return NULL; return NULL;
} }
// Get name from args.
const char *path = args->uri->path;
if (path[0] == '/') ++path; if (path[0] == '/') ++path;
// Get proxy name, if any.
r = gpr_malloc(sizeof(dns_resolver)); char *proxy_name = grpc_get_http_proxy_server();
// Create resolver.
dns_resolver *r = gpr_malloc(sizeof(dns_resolver));
memset(r, 0, sizeof(*r)); memset(r, 0, sizeof(*r));
gpr_ref_init(&r->refs, 1); gpr_ref_init(&r->refs, 1);
gpr_mu_init(&r->mu); gpr_mu_init(&r->mu);
grpc_resolver_init(&r->base, &dns_resolver_vtable); grpc_resolver_init(&r->base, &dns_resolver_vtable);
r->name = gpr_strdup(path); r->target_name = gpr_strdup(path);
r->name_to_resolve = proxy_name == NULL ? gpr_strdup(path) : proxy_name;
r->default_port = gpr_strdup(default_port); r->default_port = gpr_strdup(default_port);
gpr_backoff_init(&r->backoff_state, BACKOFF_MULTIPLIER, BACKOFF_JITTER, gpr_backoff_init(&r->backoff_state, BACKOFF_MULTIPLIER, BACKOFF_JITTER,
BACKOFF_MIN_SECONDS * 1000, BACKOFF_MAX_SECONDS * 1000); BACKOFF_MIN_SECONDS * 1000, BACKOFF_MAX_SECONDS * 1000);

@ -121,7 +121,7 @@ static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
if (r->next_completion != NULL && !r->published) { if (r->next_completion != NULL && !r->published) {
r->published = true; r->published = true;
*r->target_result = grpc_resolver_result_create( *r->target_result = grpc_resolver_result_create(
grpc_lb_addresses_copy(r->addresses, NULL /* user_data_copy */), "", grpc_lb_addresses_copy(r->addresses, NULL /* user_data_copy */),
r->lb_policy_name, NULL); r->lb_policy_name, NULL);
grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL); grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL);
r->next_completion = NULL; r->next_completion = NULL;

@ -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"
@ -189,6 +190,13 @@ 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_name = grpc_get_http_proxy_server();
if (proxy_name != NULL) {
grpc_handshake_manager_add(
c->handshake_mgr,
grpc_http_connect_handshaker_create(proxy_name, args->server_name));
gpr_free(proxy_name);
}
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"
@ -251,6 +252,13 @@ 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_name = grpc_get_http_proxy_server();
if (proxy_name != NULL) {
grpc_handshake_manager_add(
c->handshake_mgr,
grpc_http_connect_handshaker_create(proxy_name, args->server_name));
gpr_free(proxy_name);
}
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;

@ -1928,7 +1928,8 @@ static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx,
grpc_error *parse_error = GRPC_ERROR_NONE; grpc_error *parse_error = GRPC_ERROR_NONE;
for (; i < t->read_buffer.count && parse_error == GRPC_ERROR_NONE; i++) { for (; i < t->read_buffer.count && parse_error == GRPC_ERROR_NONE; i++) {
parse_error = grpc_http_parser_parse(&parser, t->read_buffer.slices[i]); parse_error =
grpc_http_parser_parse(&parser, t->read_buffer.slices[i], NULL);
} }
if (parse_error == GRPC_ERROR_NONE && if (parse_error == GRPC_ERROR_NONE &&
(parse_error = grpc_http_parser_eof(&parser)) == GRPC_ERROR_NONE) { (parse_error = grpc_http_parser_eof(&parser)) == GRPC_ERROR_NONE) {

@ -44,7 +44,7 @@
#include "src/core/lib/support/string.h" #include "src/core/lib/support/string.h"
static void fill_common_header(const grpc_httpcli_request *request, static void fill_common_header(const grpc_httpcli_request *request,
gpr_strvec *buf) { gpr_strvec *buf, bool connection_close) {
size_t i; size_t i;
gpr_strvec_add(buf, gpr_strdup(request->http.path)); gpr_strvec_add(buf, gpr_strdup(request->http.path));
gpr_strvec_add(buf, gpr_strdup(" HTTP/1.0\r\n")); gpr_strvec_add(buf, gpr_strdup(" HTTP/1.0\r\n"));
@ -52,6 +52,7 @@ static void fill_common_header(const grpc_httpcli_request *request,
gpr_strvec_add(buf, gpr_strdup("Host: ")); gpr_strvec_add(buf, gpr_strdup("Host: "));
gpr_strvec_add(buf, gpr_strdup(request->host)); gpr_strvec_add(buf, gpr_strdup(request->host));
gpr_strvec_add(buf, gpr_strdup("\r\n")); gpr_strvec_add(buf, gpr_strdup("\r\n"));
if (connection_close)
gpr_strvec_add(buf, gpr_strdup("Connection: close\r\n")); gpr_strvec_add(buf, gpr_strdup("Connection: close\r\n"));
gpr_strvec_add(buf, gpr_strvec_add(buf,
gpr_strdup("User-Agent: " GRPC_HTTPCLI_USER_AGENT "\r\n")); gpr_strdup("User-Agent: " GRPC_HTTPCLI_USER_AGENT "\r\n"));
@ -71,7 +72,7 @@ gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request) {
gpr_strvec_init(&out); gpr_strvec_init(&out);
gpr_strvec_add(&out, gpr_strdup("GET ")); gpr_strvec_add(&out, gpr_strdup("GET "));
fill_common_header(request, &out); fill_common_header(request, &out, true);
gpr_strvec_add(&out, gpr_strdup("\r\n")); gpr_strvec_add(&out, gpr_strdup("\r\n"));
flat = gpr_strvec_flatten(&out, &flat_len); flat = gpr_strvec_flatten(&out, &flat_len);
@ -91,7 +92,7 @@ gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request,
gpr_strvec_init(&out); gpr_strvec_init(&out);
gpr_strvec_add(&out, gpr_strdup("POST ")); gpr_strvec_add(&out, gpr_strdup("POST "));
fill_common_header(request, &out); fill_common_header(request, &out, true);
if (body_bytes) { if (body_bytes) {
uint8_t has_content_type = 0; uint8_t has_content_type = 0;
for (i = 0; i < request->http.hdr_count; i++) { for (i = 0; i < request->http.hdr_count; i++) {
@ -118,3 +119,16 @@ gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request,
return gpr_slice_new(tmp, out_len, gpr_free); return gpr_slice_new(tmp, out_len, gpr_free);
} }
gpr_slice grpc_httpcli_format_connect_request(
const grpc_httpcli_request *request) {
gpr_strvec out;
gpr_strvec_init(&out);
gpr_strvec_add(&out, gpr_strdup("CONNECT "));
fill_common_header(request, &out, false);
gpr_strvec_add(&out, gpr_strdup("\r\n"));
size_t flat_len;
char *flat = gpr_strvec_flatten(&out, &flat_len);
gpr_strvec_destroy(&out);
return gpr_slice_new(flat, flat_len, gpr_free);
}

@ -41,5 +41,7 @@ gpr_slice grpc_httpcli_format_get_request(const grpc_httpcli_request *request);
gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request, gpr_slice grpc_httpcli_format_post_request(const grpc_httpcli_request *request,
const char *body_bytes, const char *body_bytes,
size_t body_size); size_t body_size);
gpr_slice grpc_httpcli_format_connect_request(
const grpc_httpcli_request *request);
#endif /* GRPC_CORE_LIB_HTTP_FORMAT_REQUEST_H */ #endif /* GRPC_CORE_LIB_HTTP_FORMAT_REQUEST_H */

@ -146,7 +146,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *user_data,
if (GPR_SLICE_LENGTH(req->incoming.slices[i])) { if (GPR_SLICE_LENGTH(req->incoming.slices[i])) {
req->have_read_byte = 1; req->have_read_byte = 1;
grpc_error *err = grpc_error *err =
grpc_http_parser_parse(&req->parser, req->incoming.slices[i]); grpc_http_parser_parse(&req->parser, req->incoming.slices[i], NULL);
if (err != GRPC_ERROR_NONE) { if (err != GRPC_ERROR_NONE) {
finish(exec_ctx, req, err); finish(exec_ctx, req, err);
return; return;

@ -93,8 +93,7 @@ void grpc_httpcli_context_destroy(grpc_httpcli_context *context);
'request' contains request parameters - these are caller owned and can be 'request' contains request parameters - these are caller owned and can be
destroyed once the call returns destroyed once the call returns
'deadline' contains a deadline for the request (or gpr_inf_future) 'deadline' contains a deadline for the request (or gpr_inf_future)
'on_response' is a callback to report results to (and 'user_data' is a user 'on_response' is a callback to report results to */
supplied pointer to pass to said call) */
void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
grpc_polling_entity *pollent, grpc_polling_entity *pollent,
const grpc_httpcli_request *request, const grpc_httpcli_request *request,
@ -113,8 +112,7 @@ void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
'deadline' contains a deadline for the request (or gpr_inf_future) 'deadline' contains a deadline for the request (or gpr_inf_future)
'em' points to a caller owned event manager that must be alive for the 'em' points to a caller owned event manager that must be alive for the
lifetime of the request lifetime of the request
'on_response' is a callback to report results to (and 'user_data' is a user 'on_response' is a callback to report results to
supplied pointer to pass to said call)
Does not support ?var1=val1&var2=val2 in the path. */ Does not support ?var1=val1&var2=val2 in the path. */
void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context, void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
grpc_polling_entity *pollent, grpc_polling_entity *pollent,

@ -33,6 +33,7 @@
#include "src/core/lib/http/parser.h" #include "src/core/lib/http/parser.h"
#include <stdbool.h>
#include <string.h> #include <string.h>
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
@ -200,7 +201,8 @@ done:
return error; return error;
} }
static grpc_error *finish_line(grpc_http_parser *parser) { static grpc_error *finish_line(grpc_http_parser *parser,
bool *found_body_start) {
grpc_error *err; grpc_error *err;
switch (parser->state) { switch (parser->state) {
case GRPC_HTTP_FIRST_LINE: case GRPC_HTTP_FIRST_LINE:
@ -211,6 +213,7 @@ static grpc_error *finish_line(grpc_http_parser *parser) {
case GRPC_HTTP_HEADERS: case GRPC_HTTP_HEADERS:
if (parser->cur_line_length == parser->cur_line_end_length) { if (parser->cur_line_length == parser->cur_line_end_length) {
parser->state = GRPC_HTTP_BODY; parser->state = GRPC_HTTP_BODY;
*found_body_start = true;
break; break;
} }
err = add_header(parser); err = add_header(parser);
@ -274,7 +277,8 @@ static bool check_line(grpc_http_parser *parser) {
return false; return false;
} }
static grpc_error *addbyte(grpc_http_parser *parser, uint8_t byte) { static grpc_error *addbyte(grpc_http_parser *parser, uint8_t byte,
bool *found_body_start) {
switch (parser->state) { switch (parser->state) {
case GRPC_HTTP_FIRST_LINE: case GRPC_HTTP_FIRST_LINE:
case GRPC_HTTP_HEADERS: case GRPC_HTTP_HEADERS:
@ -282,20 +286,18 @@ static grpc_error *addbyte(grpc_http_parser *parser, uint8_t byte) {
if (grpc_http1_trace) if (grpc_http1_trace)
gpr_log(GPR_ERROR, "HTTP client max line length (%d) exceeded", gpr_log(GPR_ERROR, "HTTP client max line length (%d) exceeded",
GRPC_HTTP_PARSER_MAX_HEADER_LENGTH); GRPC_HTTP_PARSER_MAX_HEADER_LENGTH);
return 0; return GRPC_ERROR_NONE;
} }
parser->cur_line[parser->cur_line_length] = byte; parser->cur_line[parser->cur_line_length] = byte;
parser->cur_line_length++; parser->cur_line_length++;
if (check_line(parser)) { if (check_line(parser)) {
return finish_line(parser); return finish_line(parser, found_body_start);
} else {
return GRPC_ERROR_NONE;
} }
GPR_UNREACHABLE_CODE(return 0); return GRPC_ERROR_NONE;
case GRPC_HTTP_BODY: case GRPC_HTTP_BODY:
return addbyte_body(parser, byte); return addbyte_body(parser, byte);
} }
GPR_UNREACHABLE_CODE(return 0); GPR_UNREACHABLE_CODE(return GRPC_ERROR_NONE);
} }
void grpc_http_parser_init(grpc_http_parser *parser, grpc_http_type type, void grpc_http_parser_init(grpc_http_parser *parser, grpc_http_type type,
@ -331,14 +333,15 @@ void grpc_http_response_destroy(grpc_http_response *response) {
gpr_free(response->hdrs); gpr_free(response->hdrs);
} }
grpc_error *grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice) { grpc_error *grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice,
size_t i; size_t *start_of_body) {
for (size_t i = 0; i < GPR_SLICE_LENGTH(slice); i++) {
for (i = 0; i < GPR_SLICE_LENGTH(slice); i++) { bool found_body_start = false;
grpc_error *err = addbyte(parser, GPR_SLICE_START_PTR(slice)[i]); grpc_error *err =
addbyte(parser, GPR_SLICE_START_PTR(slice)[i], &found_body_start);
if (err != GRPC_ERROR_NONE) return err; if (err != GRPC_ERROR_NONE) return err;
if (found_body_start && start_of_body != NULL) *start_of_body = i + 1;
} }
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }

@ -113,7 +113,9 @@ void grpc_http_parser_init(grpc_http_parser *parser, grpc_http_type type,
void *request_or_response); void *request_or_response);
void grpc_http_parser_destroy(grpc_http_parser *parser); void grpc_http_parser_destroy(grpc_http_parser *parser);
grpc_error *grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice); /* Sets \a start_of_body to the offset in \a slice of the start of the body. */
grpc_error *grpc_http_parser_parse(grpc_http_parser *parser, gpr_slice slice,
size_t *start_of_body);
grpc_error *grpc_http_parser_eof(grpc_http_parser *parser); grpc_error *grpc_http_parser_eof(grpc_http_parser *parser);
void grpc_http_request_destroy(grpc_http_request *request); void grpc_http_request_destroy(grpc_http_request *request);

@ -64,7 +64,8 @@ struct grpc_endpoint_vtable {
/* When data is available on the connection, calls the callback with slices. /* When data is available on the connection, calls the callback with slices.
Callback success indicates that the endpoint can accept more reads, failure Callback success indicates that the endpoint can accept more reads, failure
indicates the endpoint is closed. indicates the endpoint is closed.
Valid slices may be placed into \a slices even on callback success == 0. */ Valid slices may be placed into \a slices even when the callback is
invoked with error != GRPC_ERROR_NONE. */
void grpc_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, void grpc_endpoint_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
gpr_slice_buffer *slices, grpc_closure *cb); gpr_slice_buffer *slices, grpc_closure *cb);

@ -43,7 +43,6 @@
typedef struct grpc_workqueue grpc_workqueue; typedef struct grpc_workqueue grpc_workqueue;
typedef struct grpc_combiner grpc_combiner; typedef struct grpc_combiner grpc_combiner;
#ifndef GRPC_EXECUTION_CONTEXT_SANITIZER
/** Execution context. /** Execution context.
* A bag of data that collects information along a callstack. * A bag of data that collects information along a callstack.
* Generally created at public API entry points, and passed down as * Generally created at public API entry points, and passed down as
@ -58,12 +57,13 @@ typedef struct grpc_combiner grpc_combiner;
* should actively try to finish up and get this thread back to its owner * should actively try to finish up and get this thread back to its owner
* *
* CONVENTIONS: * CONVENTIONS:
* Instance of this must ALWAYS be constructed on the stack, never * - Instance of this must ALWAYS be constructed on the stack, never
* heap allocated. Instances and pointers to them must always be called * heap allocated.
* exec_ctx. Instances are always passed as the first argument * - Instances and pointers to them must always be called exec_ctx.
* to a function that takes it, and always as a pointer (grpc_exec_ctx * - Instances are always passed as the first argument to a function that
* is never copied). * takes it, and always as a pointer (grpc_exec_ctx is never copied).
*/ */
#ifndef GRPC_EXECUTION_CONTEXT_SANITIZER
struct grpc_exec_ctx { struct grpc_exec_ctx {
grpc_closure_list closure_list; grpc_closure_list closure_list;
/** currently active combiner: updated only via combiner.c */ /** currently active combiner: updated only via combiner.c */

@ -84,7 +84,7 @@ void grpc_winsocket_shutdown(grpc_winsocket *winsocket) {
DisconnectEx(winsocket->socket, NULL, 0, 0); DisconnectEx(winsocket->socket, NULL, 0, 0);
} else { } else {
char *utf8_message = gpr_format_message(WSAGetLastError()); char *utf8_message = gpr_format_message(WSAGetLastError());
gpr_log(GPR_ERROR, "Unable to retrieve DisconnectEx pointer : %s", gpr_log(GPR_INFO, "Unable to retrieve DisconnectEx pointer : %s",
utf8_message); utf8_message);
gpr_free(utf8_message); gpr_free(utf8_message);
} }

@ -227,6 +227,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/client_config/client_config_plugin.c', 'src/core/ext/client_config/client_config_plugin.c',
'src/core/ext/client_config/connector.c', 'src/core/ext/client_config/connector.c',
'src/core/ext/client_config/default_initial_connect_string.c', 'src/core/ext/client_config/default_initial_connect_string.c',
'src/core/ext/client_config/http_connect_handshaker.c',
'src/core/ext/client_config/initial_connect_string.c', 'src/core/ext/client_config/initial_connect_string.c',
'src/core/ext/client_config/lb_policy.c', 'src/core/ext/client_config/lb_policy.c',
'src/core/ext/client_config/lb_policy_factory.c', 'src/core/ext/client_config/lb_policy_factory.c',

@ -0,0 +1,129 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "test/core/end2end/end2end_tests.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
#include "src/core/ext/client_config/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/channel/http_server_filter.h"
#include "src/core/lib/support/env.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/end2end/fixtures/http_proxy.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
typedef struct fullstack_fixture_data {
char *server_addr;
grpc_end2end_http_proxy *proxy;
} fullstack_fixture_data;
static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
grpc_channel_args *client_args, grpc_channel_args *server_args) {
grpc_end2end_test_fixture f;
memset(&f, 0, sizeof(f));
fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data));
const int server_port = grpc_pick_unused_port_or_die();
gpr_join_host_port(&ffd->server_addr, "localhost", server_port);
ffd->proxy = grpc_end2end_http_proxy_create();
f.fixture_data = ffd;
f.cq = grpc_completion_queue_create(NULL);
return f;
}
void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args) {
fullstack_fixture_data *ffd = f->fixture_data;
char *proxy_uri;
gpr_asprintf(&proxy_uri, "http://%s",
grpc_end2end_http_proxy_get_proxy_name(ffd->proxy));
gpr_setenv("http_proxy", proxy_uri);
gpr_free(proxy_uri);
f->client = grpc_insecure_channel_create(ffd->server_addr, client_args, NULL);
GPR_ASSERT(f->client);
}
void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *server_args) {
fullstack_fixture_data *ffd = f->fixture_data;
if (f->server) {
grpc_server_destroy(f->server);
}
f->server = grpc_server_create(server_args, NULL);
grpc_server_register_completion_queue(f->server, f->cq, NULL);
GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->server_addr));
grpc_server_start(f->server);
}
void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) {
fullstack_fixture_data *ffd = f->fixture_data;
gpr_free(ffd->server_addr);
grpc_end2end_http_proxy_destroy(ffd->proxy);
gpr_free(ffd);
}
/* All test configurations */
static grpc_end2end_test_config configs[] = {
{"chttp2/fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
};
int main(int argc, char **argv) {
size_t i;
grpc_test_init(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
grpc_end2end_tests(argc, argv, configs[i]);
}
grpc_shutdown();
return 0;
}

@ -0,0 +1,481 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "test/core/end2end/fixtures/http_proxy.h"
#include <string.h>
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include <grpc/support/slice_buffer.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/pollset_set.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/iomgr/tcp_client.h"
#include "src/core/lib/iomgr/tcp_server.h"
#include "test/core/util/port.h"
struct grpc_end2end_http_proxy {
char* proxy_name;
gpr_thd_id thd;
grpc_tcp_server* server;
grpc_channel_args* channel_args;
gpr_mu* mu;
grpc_pollset* pollset;
gpr_atm shutdown;
};
//
// Connection handling
//
typedef struct proxy_connection {
grpc_endpoint* client_endpoint;
grpc_endpoint* server_endpoint;
gpr_refcount refcount;
grpc_pollset_set* pollset_set;
grpc_closure on_read_request_done;
grpc_closure on_server_connect_done;
grpc_closure on_write_response_done;
grpc_closure on_client_read_done;
grpc_closure on_client_write_done;
grpc_closure on_server_read_done;
grpc_closure on_server_write_done;
gpr_slice_buffer client_read_buffer;
gpr_slice_buffer client_deferred_write_buffer;
gpr_slice_buffer client_write_buffer;
gpr_slice_buffer server_read_buffer;
gpr_slice_buffer server_deferred_write_buffer;
gpr_slice_buffer server_write_buffer;
grpc_http_parser http_parser;
grpc_http_request http_request;
} proxy_connection;
// Helper function to destroy the proxy connection.
static void proxy_connection_unref(grpc_exec_ctx* exec_ctx,
proxy_connection* conn) {
if (gpr_unref(&conn->refcount)) {
grpc_endpoint_destroy(exec_ctx, conn->client_endpoint);
if (conn->server_endpoint != NULL)
grpc_endpoint_destroy(exec_ctx, conn->server_endpoint);
grpc_pollset_set_destroy(conn->pollset_set);
gpr_slice_buffer_destroy(&conn->client_read_buffer);
gpr_slice_buffer_destroy(&conn->client_deferred_write_buffer);
gpr_slice_buffer_destroy(&conn->client_write_buffer);
gpr_slice_buffer_destroy(&conn->server_read_buffer);
gpr_slice_buffer_destroy(&conn->server_deferred_write_buffer);
gpr_slice_buffer_destroy(&conn->server_write_buffer);
grpc_http_parser_destroy(&conn->http_parser);
grpc_http_request_destroy(&conn->http_request);
gpr_free(conn);
}
}
// Helper function to shut down the proxy connection.
// Does NOT take ownership of a reference to error.
static void proxy_connection_failed(grpc_exec_ctx* exec_ctx,
proxy_connection* conn, bool is_client,
const char* prefix, grpc_error* error) {
const char* msg = grpc_error_string(error);
gpr_log(GPR_INFO, "%s: %s", prefix, msg);
grpc_error_free_string(msg);
grpc_endpoint_shutdown(exec_ctx, conn->client_endpoint);
if (conn->server_endpoint != NULL)
grpc_endpoint_shutdown(exec_ctx, conn->server_endpoint);
proxy_connection_unref(exec_ctx, conn);
}
// Callback for writing proxy data to the client.
static void on_client_write_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
proxy_connection* conn = arg;
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(exec_ctx, conn, true /* is_client */,
"HTTP proxy client write", error);
return;
}
// Clear write buffer (the data we just wrote).
gpr_slice_buffer_reset_and_unref(&conn->client_write_buffer);
// If more data was read from the server since we started this write,
// write that data now.
if (conn->client_deferred_write_buffer.length > 0) {
gpr_slice_buffer_move_into(&conn->client_deferred_write_buffer,
&conn->client_write_buffer);
grpc_endpoint_write(exec_ctx, conn->client_endpoint,
&conn->client_write_buffer,
&conn->on_client_write_done);
} else {
// No more writes. Unref the connection.
proxy_connection_unref(exec_ctx, conn);
}
}
// Callback for writing proxy data to the backend server.
static void on_server_write_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
proxy_connection* conn = arg;
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(exec_ctx, conn, false /* is_client */,
"HTTP proxy server write", error);
return;
}
// Clear write buffer (the data we just wrote).
gpr_slice_buffer_reset_and_unref(&conn->server_write_buffer);
// If more data was read from the client since we started this write,
// write that data now.
if (conn->server_deferred_write_buffer.length > 0) {
gpr_slice_buffer_move_into(&conn->server_deferred_write_buffer,
&conn->server_write_buffer);
grpc_endpoint_write(exec_ctx, conn->server_endpoint,
&conn->server_write_buffer,
&conn->on_server_write_done);
} else {
// No more writes. Unref the connection.
proxy_connection_unref(exec_ctx, conn);
}
}
// Callback for reading data from the client, which will be proxied to
// the backend server.
static void on_client_read_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
proxy_connection* conn = arg;
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(exec_ctx, conn, true /* is_client */,
"HTTP proxy client read", error);
return;
}
// If there is already a pending write (i.e., server_write_buffer is
// not empty), then move the read data into server_deferred_write_buffer,
// and the next write will be requested in on_server_write_done(), when
// the current write is finished.
//
// Otherwise, move the read data into the write buffer and write it.
if (conn->server_write_buffer.length > 0) {
gpr_slice_buffer_move_into(&conn->client_read_buffer,
&conn->server_deferred_write_buffer);
} else {
gpr_slice_buffer_move_into(&conn->client_read_buffer,
&conn->server_write_buffer);
gpr_ref(&conn->refcount);
grpc_endpoint_write(exec_ctx, conn->server_endpoint,
&conn->server_write_buffer,
&conn->on_server_write_done);
}
// Read more data.
grpc_endpoint_read(exec_ctx, conn->client_endpoint, &conn->client_read_buffer,
&conn->on_client_read_done);
}
// Callback for reading data from the backend server, which will be
// proxied to the client.
static void on_server_read_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
proxy_connection* conn = arg;
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(exec_ctx, conn, false /* is_client */,
"HTTP proxy server read", error);
return;
}
// If there is already a pending write (i.e., client_write_buffer is
// not empty), then move the read data into client_deferred_write_buffer,
// and the next write will be requested in on_client_write_done(), when
// the current write is finished.
//
// Otherwise, move the read data into the write buffer and write it.
if (conn->client_write_buffer.length > 0) {
gpr_slice_buffer_move_into(&conn->server_read_buffer,
&conn->client_deferred_write_buffer);
} else {
gpr_slice_buffer_move_into(&conn->server_read_buffer,
&conn->client_write_buffer);
gpr_ref(&conn->refcount);
grpc_endpoint_write(exec_ctx, conn->client_endpoint,
&conn->client_write_buffer,
&conn->on_client_write_done);
}
// Read more data.
grpc_endpoint_read(exec_ctx, conn->server_endpoint, &conn->server_read_buffer,
&conn->on_server_read_done);
}
// Callback to write the HTTP response for the CONNECT request.
static void on_write_response_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
proxy_connection* conn = arg;
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(exec_ctx, conn, true /* is_client */,
"HTTP proxy write response", error);
return;
}
// Clear write buffer.
gpr_slice_buffer_reset_and_unref(&conn->client_write_buffer);
// Start reading from both client and server. One of the read
// requests inherits our ref to conn, but we need to take a new ref
// for the other one.
gpr_ref(&conn->refcount);
grpc_endpoint_read(exec_ctx, conn->client_endpoint, &conn->client_read_buffer,
&conn->on_client_read_done);
grpc_endpoint_read(exec_ctx, conn->server_endpoint, &conn->server_read_buffer,
&conn->on_server_read_done);
}
// Callback to connect to the backend server specified by the HTTP
// CONNECT request.
static void on_server_connect_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
proxy_connection* conn = arg;
if (error != GRPC_ERROR_NONE) {
// TODO(roth): Technically, in this case, we should handle the error
// by returning an HTTP response to the client indicating that the
// connection failed. However, for the purposes of this test code,
// it's fine to pretend this is a client-side error, which will
// cause the client connection to be dropped.
proxy_connection_failed(exec_ctx, conn, true /* is_client */,
"HTTP proxy server connect", error);
return;
}
// We've established a connection, so send back a 200 response code to
// the client.
// The write callback inherits our reference to conn.
gpr_slice slice =
gpr_slice_from_copied_string("HTTP/1.0 200 connected\r\n\r\n");
gpr_slice_buffer_add(&conn->client_write_buffer, slice);
grpc_endpoint_write(exec_ctx, conn->client_endpoint,
&conn->client_write_buffer,
&conn->on_write_response_done);
}
// Callback to read the HTTP CONNECT request.
// TODO(roth): Technically, for any of the failure modes handled by this
// function, we should handle the error by returning an HTTP response to
// the client indicating that the request failed. However, for the purposes
// of this test code, it's fine to pretend this is a client-side error,
// which will cause the client connection to be dropped.
static void on_read_request_done(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
proxy_connection* conn = arg;
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(exec_ctx, conn, true /* is_client */,
"HTTP proxy read request", error);
return;
}
// Read request and feed it to the parser.
for (size_t i = 0; i < conn->client_read_buffer.count; ++i) {
if (GPR_SLICE_LENGTH(conn->client_read_buffer.slices[i]) > 0) {
error = grpc_http_parser_parse(&conn->http_parser,
conn->client_read_buffer.slices[i], NULL);
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(exec_ctx, conn, true /* is_client */,
"HTTP proxy request parse", error);
GRPC_ERROR_UNREF(error);
return;
}
}
}
gpr_slice_buffer_reset_and_unref(&conn->client_read_buffer);
// If we're not done reading the request, read more data.
if (conn->http_parser.state != GRPC_HTTP_BODY) {
grpc_endpoint_read(exec_ctx, conn->client_endpoint,
&conn->client_read_buffer, &conn->on_read_request_done);
return;
}
// Make sure we got a CONNECT request.
if (strcmp(conn->http_request.method, "CONNECT") != 0) {
char* msg;
gpr_asprintf(&msg, "HTTP proxy got request method %s",
conn->http_request.method);
error = GRPC_ERROR_CREATE(msg);
gpr_free(msg);
proxy_connection_failed(exec_ctx, conn, true /* is_client */,
"HTTP proxy read request", error);
GRPC_ERROR_UNREF(error);
return;
}
// Resolve address.
grpc_resolved_addresses* resolved_addresses = NULL;
error = grpc_blocking_resolve_address(conn->http_request.path, "80",
&resolved_addresses);
if (error != GRPC_ERROR_NONE) {
proxy_connection_failed(exec_ctx, conn, true /* is_client */,
"HTTP proxy DNS lookup", error);
GRPC_ERROR_UNREF(error);
return;
}
GPR_ASSERT(resolved_addresses->naddrs >= 1);
// Connect to requested address.
// The connection callback inherits our reference to conn.
const gpr_timespec deadline = gpr_time_add(
gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(10, GPR_TIMESPAN));
grpc_tcp_client_connect(exec_ctx, &conn->on_server_connect_done,
&conn->server_endpoint, conn->pollset_set,
(struct sockaddr*)&resolved_addresses->addrs[0].addr,
resolved_addresses->addrs[0].len, deadline);
grpc_resolved_addresses_destroy(resolved_addresses);
}
static void on_accept(grpc_exec_ctx* exec_ctx, void* arg,
grpc_endpoint* endpoint, grpc_pollset* accepting_pollset,
grpc_tcp_server_acceptor* acceptor) {
grpc_end2end_http_proxy* proxy = arg;
// Instantiate proxy_connection.
proxy_connection* conn = gpr_malloc(sizeof(*conn));
memset(conn, 0, sizeof(*conn));
conn->client_endpoint = endpoint;
gpr_ref_init(&conn->refcount, 1);
conn->pollset_set = grpc_pollset_set_create();
grpc_pollset_set_add_pollset(exec_ctx, conn->pollset_set, proxy->pollset);
grpc_closure_init(&conn->on_read_request_done, on_read_request_done, conn);
grpc_closure_init(&conn->on_server_connect_done, on_server_connect_done,
conn);
grpc_closure_init(&conn->on_write_response_done, on_write_response_done,
conn);
grpc_closure_init(&conn->on_client_read_done, on_client_read_done, conn);
grpc_closure_init(&conn->on_client_write_done, on_client_write_done, conn);
grpc_closure_init(&conn->on_server_read_done, on_server_read_done, conn);
grpc_closure_init(&conn->on_server_write_done, on_server_write_done, conn);
gpr_slice_buffer_init(&conn->client_read_buffer);
gpr_slice_buffer_init(&conn->client_deferred_write_buffer);
gpr_slice_buffer_init(&conn->client_write_buffer);
gpr_slice_buffer_init(&conn->server_read_buffer);
gpr_slice_buffer_init(&conn->server_deferred_write_buffer);
gpr_slice_buffer_init(&conn->server_write_buffer);
grpc_http_parser_init(&conn->http_parser, GRPC_HTTP_REQUEST,
&conn->http_request);
grpc_endpoint_read(exec_ctx, conn->client_endpoint, &conn->client_read_buffer,
&conn->on_read_request_done);
}
//
// Proxy class
//
static void thread_main(void* arg) {
grpc_end2end_http_proxy* proxy = arg;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
do {
const gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC);
const gpr_timespec deadline =
gpr_time_add(now, gpr_time_from_seconds(1, GPR_TIMESPAN));
grpc_pollset_worker* worker = NULL;
gpr_mu_lock(proxy->mu);
GRPC_LOG_IF_ERROR(
"grpc_pollset_work",
grpc_pollset_work(&exec_ctx, proxy->pollset, &worker, now, deadline));
gpr_mu_unlock(proxy->mu);
grpc_exec_ctx_flush(&exec_ctx);
} while (!gpr_atm_acq_load(&proxy->shutdown));
grpc_exec_ctx_finish(&exec_ctx);
}
grpc_end2end_http_proxy* grpc_end2end_http_proxy_create() {
grpc_end2end_http_proxy* proxy = gpr_malloc(sizeof(*proxy));
memset(proxy, 0, sizeof(*proxy));
// Construct proxy address.
const int proxy_port = grpc_pick_unused_port_or_die();
gpr_join_host_port(&proxy->proxy_name, "localhost", proxy_port);
gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name);
// Create TCP server.
proxy->channel_args = grpc_channel_args_copy(NULL);
grpc_error* error =
grpc_tcp_server_create(NULL, proxy->channel_args, &proxy->server);
GPR_ASSERT(error == GRPC_ERROR_NONE);
// Bind to port.
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
grpc_sockaddr_set_port((struct sockaddr*)&addr, proxy_port);
int port;
error = grpc_tcp_server_add_port(proxy->server, (struct sockaddr*)&addr,
sizeof(addr), &port);
GPR_ASSERT(error == GRPC_ERROR_NONE);
GPR_ASSERT(port == proxy_port);
// Start server.
proxy->pollset = gpr_malloc(grpc_pollset_size());
grpc_pollset_init(proxy->pollset, &proxy->mu);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_tcp_server_start(&exec_ctx, proxy->server, &proxy->pollset, 1, on_accept,
proxy);
grpc_exec_ctx_finish(&exec_ctx);
// Start proxy thread.
gpr_thd_options opt = gpr_thd_options_default();
gpr_thd_options_set_joinable(&opt);
GPR_ASSERT(gpr_thd_new(&proxy->thd, thread_main, proxy, &opt));
return proxy;
}
static void destroy_pollset(grpc_exec_ctx* exec_ctx, void* arg,
grpc_error* error) {
grpc_pollset* pollset = arg;
grpc_pollset_destroy(pollset);
gpr_free(pollset);
}
void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) {
gpr_atm_rel_store(&proxy->shutdown, 1); // Signal proxy thread to shutdown.
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
gpr_thd_join(proxy->thd);
grpc_tcp_server_shutdown_listeners(&exec_ctx, proxy->server);
grpc_tcp_server_unref(&exec_ctx, proxy->server);
gpr_free(proxy->proxy_name);
grpc_channel_args_destroy(proxy->channel_args);
grpc_closure destroyed;
grpc_closure_init(&destroyed, destroy_pollset, proxy->pollset);
grpc_pollset_shutdown(&exec_ctx, proxy->pollset, &destroyed);
gpr_free(proxy);
grpc_exec_ctx_finish(&exec_ctx);
}
const char* grpc_end2end_http_proxy_get_proxy_name(
grpc_end2end_http_proxy* proxy) {
return proxy->proxy_name;
}

@ -0,0 +1,41 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
typedef struct grpc_end2end_http_proxy grpc_end2end_http_proxy;
grpc_end2end_http_proxy* grpc_end2end_http_proxy_create();
void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy);
const char* grpc_end2end_http_proxy_get_proxy_name(
grpc_end2end_http_proxy* proxy);

@ -60,6 +60,7 @@ END2END_FIXTURES = {
'h2_full+pipe': default_unsecure_fixture_options._replace( 'h2_full+pipe': default_unsecure_fixture_options._replace(
platforms=['linux']), platforms=['linux']),
'h2_full+trace': default_unsecure_fixture_options._replace(tracing=True), 'h2_full+trace': default_unsecure_fixture_options._replace(tracing=True),
'h2_http_proxy': default_unsecure_fixture_options._replace(ci_mac=False),
'h2_oauth2': default_secure_fixture_options._replace(ci_mac=False), 'h2_oauth2': default_secure_fixture_options._replace(ci_mac=False),
'h2_proxy': default_unsecure_fixture_options._replace(includes_proxy=True, 'h2_proxy': default_unsecure_fixture_options._replace(includes_proxy=True,
ci_mac=False), ci_mac=False),

@ -68,6 +68,13 @@ static void test_no_error_log(gpr_log_func_args *args) {
} }
} }
static gpr_atm g_log_func = (gpr_atm)gpr_default_log;
static void log_dispatcher_func(gpr_log_func_args *args) {
gpr_log_func log_func = (gpr_log_func)gpr_atm_no_barrier_load(&g_log_func);
log_func(args);
}
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
const char *test_name, const char *test_name,
grpc_channel_args *client_args, grpc_channel_args *client_args,
@ -263,12 +270,12 @@ static void test_invoke_10_simple_requests(grpc_end2end_test_config config) {
static void test_no_error_logging_in_entire_process( static void test_no_error_logging_in_entire_process(
grpc_end2end_test_config config) { grpc_end2end_test_config config) {
int i; int i;
gpr_set_log_function(test_no_error_log); gpr_atm_no_barrier_store(&g_log_func, (gpr_atm)test_no_error_log);
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
test_invoke_simple_request(config); test_invoke_simple_request(config);
} }
test_invoke_10_simple_requests(config); test_invoke_10_simple_requests(config);
gpr_set_log_function(gpr_default_log); gpr_atm_no_barrier_store(&g_log_func, (gpr_atm)gpr_default_log);
} }
static void test_no_logging_in_one_request(grpc_end2end_test_config config) { static void test_no_logging_in_one_request(grpc_end2end_test_config config) {
@ -278,16 +285,18 @@ static void test_no_logging_in_one_request(grpc_end2end_test_config config) {
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
simple_request_body(f); simple_request_body(f);
} }
gpr_set_log_function(test_no_log); gpr_atm_no_barrier_store(&g_log_func, (gpr_atm)test_no_log);
simple_request_body(f); simple_request_body(f);
gpr_set_log_function(gpr_default_log); gpr_atm_no_barrier_store(&g_log_func, (gpr_atm)gpr_default_log);
end_test(&f); end_test(&f);
config.tear_down_data(&f); config.tear_down_data(&f);
} }
void no_logging(grpc_end2end_test_config config) { void no_logging(grpc_end2end_test_config config) {
gpr_set_log_function(log_dispatcher_func);
test_no_logging_in_one_request(config); test_no_logging_in_one_request(config);
test_no_error_logging_in_entire_process(config); test_no_error_logging_in_entire_process(config);
gpr_set_log_function(gpr_default_log);
} }
void no_logging_pre_init(void) {} void no_logging_pre_init(void) {}

@ -62,7 +62,8 @@ static void test_request_succeeds(grpc_slice_split_mode split_mode,
grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request); grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request);
for (i = 0; i < num_slices; i++) { for (i = 0; i < num_slices; i++) {
GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i]) == GRPC_ERROR_NONE); GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i], NULL) ==
GRPC_ERROR_NONE);
gpr_slice_unref(slices[i]); gpr_slice_unref(slices[i]);
} }
GPR_ASSERT(grpc_http_parser_eof(&parser) == GRPC_ERROR_NONE); GPR_ASSERT(grpc_http_parser_eof(&parser) == GRPC_ERROR_NONE);
@ -118,7 +119,8 @@ static void test_succeeds(grpc_slice_split_mode split_mode, char *response_text,
grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response); grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response);
for (i = 0; i < num_slices; i++) { for (i = 0; i < num_slices; i++) {
GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i]) == GRPC_ERROR_NONE); GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i], NULL) ==
GRPC_ERROR_NONE);
gpr_slice_unref(slices[i]); gpr_slice_unref(slices[i]);
} }
GPR_ASSERT(grpc_http_parser_eof(&parser) == GRPC_ERROR_NONE); GPR_ASSERT(grpc_http_parser_eof(&parser) == GRPC_ERROR_NONE);
@ -171,7 +173,7 @@ static void test_fails(grpc_slice_split_mode split_mode, char *response_text) {
for (i = 0; i < num_slices; i++) { for (i = 0; i < num_slices; i++) {
if (GRPC_ERROR_NONE == error) { if (GRPC_ERROR_NONE == error) {
error = grpc_http_parser_parse(&parser, slices[i]); error = grpc_http_parser_parse(&parser, slices[i], NULL);
} }
gpr_slice_unref(slices[i]); gpr_slice_unref(slices[i]);
} }
@ -204,7 +206,7 @@ static void test_request_fails(grpc_slice_split_mode split_mode,
for (i = 0; i < num_slices; i++) { for (i = 0; i < num_slices; i++) {
if (error == GRPC_ERROR_NONE) { if (error == GRPC_ERROR_NONE) {
error = grpc_http_parser_parse(&parser, slices[i]); error = grpc_http_parser_parse(&parser, slices[i], NULL);
} }
gpr_slice_unref(slices[i]); gpr_slice_unref(slices[i]);
} }

@ -48,7 +48,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request); grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request);
gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size); gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size);
GRPC_ERROR_UNREF(grpc_http_parser_parse(&parser, slice)); GRPC_ERROR_UNREF(grpc_http_parser_parse(&parser, slice, NULL));
GRPC_ERROR_UNREF(grpc_http_parser_eof(&parser)); GRPC_ERROR_UNREF(grpc_http_parser_eof(&parser));
gpr_slice_unref(slice); gpr_slice_unref(slice);
grpc_http_parser_destroy(&parser); grpc_http_parser_destroy(&parser);

@ -47,7 +47,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
memset(&response, 0, sizeof(response)); memset(&response, 0, sizeof(response));
grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response); grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response);
gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size); gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size);
GRPC_ERROR_UNREF(grpc_http_parser_parse(&parser, slice)); GRPC_ERROR_UNREF(grpc_http_parser_parse(&parser, slice, NULL));
GRPC_ERROR_UNREF(grpc_http_parser_eof(&parser)); GRPC_ERROR_UNREF(grpc_http_parser_eof(&parser));
gpr_slice_unref(slice); gpr_slice_unref(slice);
grpc_http_parser_destroy(&parser); grpc_http_parser_destroy(&parser);

@ -916,6 +916,7 @@ src/core/lib/tsi/transport_security_interface.h \
src/core/ext/client_config/client_channel.h \ src/core/ext/client_config/client_channel.h \
src/core/ext/client_config/client_channel_factory.h \ src/core/ext/client_config/client_channel_factory.h \
src/core/ext/client_config/connector.h \ src/core/ext/client_config/connector.h \
src/core/ext/client_config/http_connect_handshaker.h \
src/core/ext/client_config/initial_connect_string.h \ src/core/ext/client_config/initial_connect_string.h \
src/core/ext/client_config/lb_policy.h \ src/core/ext/client_config/lb_policy.h \
src/core/ext/client_config/lb_policy_factory.h \ src/core/ext/client_config/lb_policy_factory.h \
@ -1098,6 +1099,7 @@ src/core/ext/client_config/client_channel_factory.c \
src/core/ext/client_config/client_config_plugin.c \ src/core/ext/client_config/client_config_plugin.c \
src/core/ext/client_config/connector.c \ src/core/ext/client_config/connector.c \
src/core/ext/client_config/default_initial_connect_string.c \ src/core/ext/client_config/default_initial_connect_string.c \
src/core/ext/client_config/http_connect_handshaker.c \
src/core/ext/client_config/initial_connect_string.c \ src/core/ext/client_config/initial_connect_string.c \
src/core/ext/client_config/lb_policy.c \ src/core/ext/client_config/lb_policy.c \
src/core/ext/client_config/lb_policy_factory.c \ src/core/ext/client_config/lb_policy_factory.c \

@ -3752,6 +3752,23 @@
"third_party": false, "third_party": false,
"type": "target" "type": "target"
}, },
{
"deps": [
"end2end_tests",
"gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
],
"headers": [],
"language": "c",
"name": "h2_http_proxy_test",
"src": [
"test/core/end2end/fixtures/h2_http_proxy.c"
],
"third_party": false,
"type": "target"
},
{ {
"deps": [ "deps": [
"end2end_tests", "end2end_tests",
@ -4024,6 +4041,23 @@
"third_party": false, "third_party": false,
"type": "target" "type": "target"
}, },
{
"deps": [
"end2end_nosec_tests",
"gpr",
"gpr_test_util",
"grpc_test_util_unsecure",
"grpc_unsecure"
],
"headers": [],
"language": "c",
"name": "h2_http_proxy_nosec_test",
"src": [
"test/core/end2end/fixtures/h2_http_proxy.c"
],
"third_party": false,
"type": "target"
},
{ {
"deps": [ "deps": [
"end2end_nosec_tests", "end2end_nosec_tests",
@ -6217,6 +6251,7 @@
"src/core/ext/client_config/client_channel.h", "src/core/ext/client_config/client_channel.h",
"src/core/ext/client_config/client_channel_factory.h", "src/core/ext/client_config/client_channel_factory.h",
"src/core/ext/client_config/connector.h", "src/core/ext/client_config/connector.h",
"src/core/ext/client_config/http_connect_handshaker.h",
"src/core/ext/client_config/initial_connect_string.h", "src/core/ext/client_config/initial_connect_string.h",
"src/core/ext/client_config/lb_policy.h", "src/core/ext/client_config/lb_policy.h",
"src/core/ext/client_config/lb_policy_factory.h", "src/core/ext/client_config/lb_policy_factory.h",
@ -6242,6 +6277,8 @@
"src/core/ext/client_config/connector.c", "src/core/ext/client_config/connector.c",
"src/core/ext/client_config/connector.h", "src/core/ext/client_config/connector.h",
"src/core/ext/client_config/default_initial_connect_string.c", "src/core/ext/client_config/default_initial_connect_string.c",
"src/core/ext/client_config/http_connect_handshaker.c",
"src/core/ext/client_config/http_connect_handshaker.h",
"src/core/ext/client_config/initial_connect_string.c", "src/core/ext/client_config/initial_connect_string.c",
"src/core/ext/client_config/initial_connect_string.h", "src/core/ext/client_config/initial_connect_string.h",
"src/core/ext/client_config/lb_policy.c", "src/core/ext/client_config/lb_policy.c",
@ -6488,6 +6525,7 @@
], ],
"headers": [ "headers": [
"test/core/end2end/cq_verifier.h", "test/core/end2end/cq_verifier.h",
"test/core/end2end/fixtures/http_proxy.h",
"test/core/end2end/fixtures/proxy.h", "test/core/end2end/fixtures/proxy.h",
"test/core/iomgr/endpoint_tests.h", "test/core/iomgr/endpoint_tests.h",
"test/core/util/grpc_profiler.h", "test/core/util/grpc_profiler.h",
@ -6504,6 +6542,8 @@
"src": [ "src": [
"test/core/end2end/cq_verifier.c", "test/core/end2end/cq_verifier.c",
"test/core/end2end/cq_verifier.h", "test/core/end2end/cq_verifier.h",
"test/core/end2end/fixtures/http_proxy.c",
"test/core/end2end/fixtures/http_proxy.h",
"test/core/end2end/fixtures/proxy.c", "test/core/end2end/fixtures/proxy.c",
"test/core/end2end/fixtures/proxy.h", "test/core/end2end/fixtures/proxy.h",
"test/core/iomgr/endpoint_tests.c", "test/core/iomgr/endpoint_tests.c",

File diff suppressed because it is too large Load Diff

@ -804,6 +804,30 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full_test", "vcxproj\tes
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_http_proxy_nosec_test", "vcxproj\test/end2end/fixtures\h2_http_proxy_nosec_test\h2_http_proxy_nosec_test.vcxproj", "{58EA8DAE-6E50-45A3-0CCC-5165D824380E}"
ProjectSection(myProperties) = preProject
lib = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_http_proxy_test", "vcxproj\test/end2end/fixtures\h2_http_proxy_test\h2_http_proxy_test.vcxproj", "{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}"
ProjectSection(myProperties) = preProject
lib = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_load_reporting_nosec_test", "vcxproj\test/end2end/fixtures\h2_load_reporting_nosec_test\h2_load_reporting_nosec_test.vcxproj", "{4B9EBBAE-D838-EC09-0B10-2D4520FBC0FF}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_load_reporting_nosec_test", "vcxproj\test/end2end/fixtures\h2_load_reporting_nosec_test\h2_load_reporting_nosec_test.vcxproj", "{4B9EBBAE-D838-EC09-0B10-2D4520FBC0FF}"
ProjectSection(myProperties) = preProject ProjectSection(myProperties) = preProject
lib = "False" lib = "False"
@ -2759,6 +2783,38 @@ Global
{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|Win32.Build.0 = Release|Win32 {EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|Win32.Build.0 = Release|Win32
{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|x64.ActiveCfg = Release|x64 {EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|x64.ActiveCfg = Release|x64
{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|x64.Build.0 = Release|x64 {EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|x64.Build.0 = Release|x64
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Debug|Win32.ActiveCfg = Debug|Win32
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Debug|x64.ActiveCfg = Debug|x64
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Release|Win32.ActiveCfg = Release|Win32
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Release|x64.ActiveCfg = Release|x64
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Debug|Win32.Build.0 = Debug|Win32
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Debug|x64.Build.0 = Debug|x64
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Release|Win32.Build.0 = Release|Win32
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Release|x64.Build.0 = Release|x64
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Debug-DLL|Win32.Build.0 = Debug|Win32
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Debug-DLL|x64.ActiveCfg = Debug|x64
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Debug-DLL|x64.Build.0 = Debug|x64
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Release-DLL|Win32.ActiveCfg = Release|Win32
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Release-DLL|Win32.Build.0 = Release|Win32
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Release-DLL|x64.ActiveCfg = Release|x64
{58EA8DAE-6E50-45A3-0CCC-5165D824380E}.Release-DLL|x64.Build.0 = Release|x64
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Debug|Win32.ActiveCfg = Debug|Win32
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Debug|x64.ActiveCfg = Debug|x64
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Release|Win32.ActiveCfg = Release|Win32
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Release|x64.ActiveCfg = Release|x64
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Debug|Win32.Build.0 = Debug|Win32
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Debug|x64.Build.0 = Debug|x64
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Release|Win32.Build.0 = Release|Win32
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Release|x64.Build.0 = Release|x64
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Debug-DLL|Win32.Build.0 = Debug|Win32
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Debug-DLL|x64.ActiveCfg = Debug|x64
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Debug-DLL|x64.Build.0 = Debug|x64
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Release-DLL|Win32.ActiveCfg = Release|Win32
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Release-DLL|Win32.Build.0 = Release|Win32
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Release-DLL|x64.ActiveCfg = Release|x64
{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}.Release-DLL|x64.Build.0 = Release|x64
{4B9EBBAE-D838-EC09-0B10-2D4520FBC0FF}.Debug|Win32.ActiveCfg = Debug|Win32 {4B9EBBAE-D838-EC09-0B10-2D4520FBC0FF}.Debug|Win32.ActiveCfg = Debug|Win32
{4B9EBBAE-D838-EC09-0B10-2D4520FBC0FF}.Debug|x64.ActiveCfg = Debug|x64 {4B9EBBAE-D838-EC09-0B10-2D4520FBC0FF}.Debug|x64.ActiveCfg = Debug|x64
{4B9EBBAE-D838-EC09-0B10-2D4520FBC0FF}.Release|Win32.ActiveCfg = Release|Win32 {4B9EBBAE-D838-EC09-0B10-2D4520FBC0FF}.Release|Win32.ActiveCfg = Release|Win32

@ -425,6 +425,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\connector.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\connector.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\http_connect_handshaker.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_factory.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_factory.h" />
@ -759,6 +760,8 @@
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\default_initial_connect_string.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\default_initial_connect_string.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\http_connect_handshaker.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy.c">

@ -451,6 +451,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\default_initial_connect_string.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\default_initial_connect_string.c">
<Filter>src\core\ext\client_config</Filter> <Filter>src\core\ext\client_config</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\http_connect_handshaker.c">
<Filter>src\core\ext\client_config</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.c">
<Filter>src\core\ext\client_config</Filter> <Filter>src\core\ext\client_config</Filter>
</ClCompile> </ClCompile>
@ -1052,6 +1055,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\connector.h"> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\connector.h">
<Filter>src\core\ext\client_config</Filter> <Filter>src\core\ext\client_config</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\http_connect_handshaker.h">
<Filter>src\core\ext\client_config</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.h"> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.h">
<Filter>src\core\ext\client_config</Filter> <Filter>src\core\ext\client_config</Filter>
</ClInclude> </ClInclude>

@ -176,6 +176,7 @@
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\data\ssl_test_data.h" /> <ClInclude Include="$(SolutionDir)\..\test\core\end2end\data\ssl_test_data.h" />
<ClInclude Include="$(SolutionDir)\..\test\core\security\oauth2_utils.h" /> <ClInclude Include="$(SolutionDir)\..\test\core\security\oauth2_utils.h" />
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.h" /> <ClInclude Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.h" />
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.h" />
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h" /> <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h" />
<ClInclude Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.h" /> <ClInclude Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.h" />
<ClInclude Include="$(SolutionDir)\..\test\core\util\grpc_profiler.h" /> <ClInclude Include="$(SolutionDir)\..\test\core\util\grpc_profiler.h" />
@ -282,6 +283,8 @@
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.c"> <ClCompile Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c"> <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.c"> <ClCompile Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.c">

@ -19,6 +19,9 @@
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.c"> <ClCompile Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.c">
<Filter>test\core\end2end</Filter> <Filter>test\core\end2end</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.c">
<Filter>test\core\end2end\fixtures</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c"> <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c">
<Filter>test\core\end2end\fixtures</Filter> <Filter>test\core\end2end\fixtures</Filter>
</ClCompile> </ClCompile>
@ -410,6 +413,9 @@
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.h"> <ClInclude Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.h">
<Filter>test\core\end2end</Filter> <Filter>test\core\end2end</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.h">
<Filter>test\core\end2end\fixtures</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h"> <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h">
<Filter>test\core\end2end\fixtures</Filter> <Filter>test\core\end2end\fixtures</Filter>
</ClInclude> </ClInclude>

@ -148,6 +148,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.h" /> <ClInclude Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.h" />
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.h" />
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h" /> <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h" />
<ClInclude Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.h" /> <ClInclude Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.h" />
<ClInclude Include="$(SolutionDir)\..\test\core\util\grpc_profiler.h" /> <ClInclude Include="$(SolutionDir)\..\test\core\util\grpc_profiler.h" />
@ -162,6 +163,8 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.c"> <ClCompile Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c"> <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.c"> <ClCompile Include="$(SolutionDir)\..\test\core\iomgr\endpoint_tests.c">

@ -4,6 +4,9 @@
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.c"> <ClCompile Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.c">
<Filter>test\core\end2end</Filter> <Filter>test\core\end2end</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.c">
<Filter>test\core\end2end\fixtures</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c"> <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.c">
<Filter>test\core\end2end\fixtures</Filter> <Filter>test\core\end2end\fixtures</Filter>
</ClCompile> </ClCompile>
@ -42,6 +45,9 @@
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.h"> <ClInclude Include="$(SolutionDir)\..\test\core\end2end\cq_verifier.h">
<Filter>test\core\end2end</Filter> <Filter>test\core\end2end</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\http_proxy.h">
<Filter>test\core\end2end\fixtures</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h"> <ClInclude Include="$(SolutionDir)\..\test\core\end2end\fixtures\proxy.h">
<Filter>test\core\end2end\fixtures</Filter> <Filter>test\core\end2end\fixtures</Filter>
</ClInclude> </ClInclude>

@ -391,6 +391,7 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\connector.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\connector.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\http_connect_handshaker.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_factory.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy_factory.h" />
@ -675,6 +676,8 @@
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\default_initial_connect_string.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\default_initial_connect_string.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\http_connect_handshaker.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.c">
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\lb_policy.c">

@ -376,6 +376,9 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\default_initial_connect_string.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\default_initial_connect_string.c">
<Filter>src\core\ext\client_config</Filter> <Filter>src\core\ext\client_config</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\http_connect_handshaker.c">
<Filter>src\core\ext\client_config</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.c"> <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.c">
<Filter>src\core\ext\client_config</Filter> <Filter>src\core\ext\client_config</Filter>
</ClCompile> </ClCompile>
@ -890,6 +893,9 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\connector.h"> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\connector.h">
<Filter>src\core\ext\client_config</Filter> <Filter>src\core\ext\client_config</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\http_connect_handshaker.h">
<Filter>src\core\ext\client_config</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.h"> <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.h">
<Filter>src\core\ext\client_config</Filter> <Filter>src\core\ext\client_config</Filter>
</ClInclude> </ClInclude>

@ -0,0 +1,191 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{58EA8DAE-6E50-45A3-0CCC-5165D824380E}</ProjectGuid>
<IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
<IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
<PlatformToolset>v100</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)\..\vsprojects\global.props" />
<Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
<Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<TargetName>h2_http_proxy_nosec_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TargetName>h2_http_proxy_nosec_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_http_proxy.c">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_nosec_tests\end2end_nosec_tests.vcxproj">
<Project>{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
<Project>{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj">
<Project>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
<Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
<Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
</Target>
</Project>

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_http_proxy.c">
<Filter>test\core\end2end\fixtures</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="test">
<UniqueIdentifier>{318aaada-bfb3-a91b-9ec7-50f91d2553fe}</UniqueIdentifier>
</Filter>
<Filter Include="test\core">
<UniqueIdentifier>{6ac28876-f5a4-067a-c4f3-a40fea67e0d8}</UniqueIdentifier>
</Filter>
<Filter Include="test\core\end2end">
<UniqueIdentifier>{116ee744-756f-b125-d1fa-367f891887c7}</UniqueIdentifier>
</Filter>
<Filter Include="test\core\end2end\fixtures">
<UniqueIdentifier>{48a717b7-dce8-8e65-4a42-cc4396074f3a}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

@ -0,0 +1,202 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C9076E5F-7297-67C2-F786-3CC4F26D8F8A}</ProjectGuid>
<IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
<IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
<PlatformToolset>v100</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)\..\vsprojects\global.props" />
<Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
<Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
<Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<TargetName>h2_http_proxy_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
<Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
<Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TargetName>h2_http_proxy_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
<Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
<Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
<MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
<GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_http_proxy.c">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
<Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
<Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
<Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
<Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
</ProjectReference>
<ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
<Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
<Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
<Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
</Target>
</Project>

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_http_proxy.c">
<Filter>test\core\end2end\fixtures</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="test">
<UniqueIdentifier>{b725acb1-7722-0738-5c04-6b70cf1f75a4}</UniqueIdentifier>
</Filter>
<Filter Include="test\core">
<UniqueIdentifier>{4a10c467-2c7d-9051-e9bf-a24684cfa755}</UniqueIdentifier>
</Filter>
<Filter Include="test\core\end2end">
<UniqueIdentifier>{4837a689-69d2-7fd8-99e6-d7a44dd77a6d}</UniqueIdentifier>
</Filter>
<Filter Include="test\core\end2end\fixtures">
<UniqueIdentifier>{e7d5a1d8-129c-4b79-0afe-3f453bcd9c49}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
Loading…
Cancel
Save