Merge branch 'master' into revert-23294-revert-23182-server-builder

pull/23345/head
Karthik Ravi Shankar 4 years ago
commit 7aadac509c
  1. 2
      BUILD
  2. 1
      BUILD.gn
  3. 2
      CMakeLists.txt
  4. 32
      Makefile
  5. 2
      Rakefile
  6. 5
      build_autogenerated.yaml
  7. 1
      config.m4
  8. 1
      config.w32
  9. 1
      gRPC-Core.podspec
  10. 2
      grpc.def
  11. 1
      grpc.gemspec
  12. 2
      grpc.gyp
  13. 8
      include/grpc/grpc_security.h
  14. 5
      include/grpcpp/grpcpp.h
  15. 2
      include/grpcpp/impl/codegen/client_context_impl.h
  16. 4
      include/grpcpp/security/credentials_impl.h
  17. 1
      package.xml
  18. 1
      setup.py
  19. 7
      src/abseil-cpp/preprocessed_builds.yaml.gen.py
  20. 142
      src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
  21. 3
      src/core/ext/filters/http/http_filters_plugin.cc
  22. 88
      src/core/ext/filters/http/message_compress/message_decompress_filter.cc
  23. 4
      src/core/ext/filters/http/message_compress/message_decompress_filter.h
  24. 106
      src/core/ext/filters/message_size/message_size_filter.cc
  25. 6
      src/core/ext/filters/message_size/message_size_filter.h
  26. 21
      src/core/lib/security/security_connector/ssl_utils.cc
  27. 5
      src/core/lib/security/transport/auth_filters.h
  28. 4
      src/core/plugin_registry/grpc_plugin_registry.cc
  29. 4
      src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
  30. 13
      src/core/tsi/alts/handshaker/alts_handshaker_client.cc
  31. 26
      src/cpp/server/server_builder.cc
  32. 2
      src/php/README.md
  33. 5
      src/python/grpcio/_parallel_compile_patch.py
  34. 40
      src/python/grpcio/commands.py
  35. 1
      src/python/grpcio/grpc_core_dependencies.py
  36. 153
      src/ruby/end2end/call_credentials_timeout_driver.rb
  37. 5
      src/ruby/end2end/end2end_common.rb
  38. 27
      src/ruby/ext/grpc/rb_call_credentials.c
  39. 4
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  40. 6
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  41. 14
      src/ruby/spec/support/services.rb
  42. 332
      test/core/end2end/tests/max_message_length.cc
  43. 32
      test/core/security/security_connector_test.cc
  44. 2
      test/core/surface/public_headers_must_be_c89.c
  45. 1
      test/core/tsi/ssl_transport_security_test.cc
  46. 3
      test/cpp/microbenchmarks/bm_call_create.cc
  47. 3
      tools/buildgen/extract_metadata_from_bazel_xml.py
  48. 38
      tools/distrib/install_all_python_modules.sh
  49. 2
      tools/dockerfile/grpc_artifact_python_manylinux2010_x64/Dockerfile
  50. 2
      tools/dockerfile/grpc_artifact_python_manylinux2010_x86/Dockerfile
  51. 30
      tools/dockerfile/grpc_artifact_python_manylinux2014_x64/Dockerfile
  52. 30
      tools/dockerfile/grpc_artifact_python_manylinux2014_x86/Dockerfile
  53. 1
      tools/doxygen/Doxyfile.c++.internal
  54. 1
      tools/doxygen/Doxyfile.core.internal
  55. 8
      tools/interop_matrix/client_matrix.py
  56. 108
      tools/interop_matrix/run_interop_matrix_tests.py
  57. 22
      tools/run_tests/artifacts/artifact_targets.py
  58. 1
      tools/run_tests/helper_scripts/run_ruby_end2end_tests.sh

@ -1043,6 +1043,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/retry_throttle.cc", "src/core/ext/filters/client_channel/retry_throttle.cc",
"src/core/ext/filters/client_channel/server_address.cc", "src/core/ext/filters/client_channel/server_address.cc",
"src/core/ext/filters/client_channel/service_config.cc", "src/core/ext/filters/client_channel/service_config.cc",
"src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc",
"src/core/ext/filters/client_channel/service_config_parser.cc", "src/core/ext/filters/client_channel/service_config_parser.cc",
"src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel_pool_interface.cc", "src/core/ext/filters/client_channel/subchannel_pool_interface.cc",
@ -1184,6 +1185,7 @@ grpc_cc_library(
language = "c++", language = "c++",
deps = [ deps = [
"grpc_base", "grpc_base",
"grpc_message_size_filter",
], ],
) )

@ -295,6 +295,7 @@ config("grpc_config") {
"src/core/ext/filters/client_channel/service_config.cc", "src/core/ext/filters/client_channel/service_config.cc",
"src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/service_config.h",
"src/core/ext/filters/client_channel/service_config_call_data.h", "src/core/ext/filters/client_channel/service_config_call_data.h",
"src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc",
"src/core/ext/filters/client_channel/service_config_parser.cc", "src/core/ext/filters/client_channel/service_config_parser.cc",
"src/core/ext/filters/client_channel/service_config_parser.h", "src/core/ext/filters/client_channel/service_config_parser.h",
"src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.cc",

@ -1376,6 +1376,7 @@ add_library(grpc
src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/service_config.cc
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
src/core/ext/filters/client_channel/service_config_parser.cc src/core/ext/filters/client_channel/service_config_parser.cc
src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc
@ -2114,6 +2115,7 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/retry_throttle.cc src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/server_address.cc src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/service_config.cc
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
src/core/ext/filters/client_channel/service_config_parser.cc src/core/ext/filters/client_channel/service_config_parser.cc
src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_pool_interface.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc

@ -3679,6 +3679,7 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc \
src/core/ext/filters/client_channel/service_config_parser.cc \ src/core/ext/filters/client_channel/service_config_parser.cc \
src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
@ -4149,18 +4150,18 @@ endif
ifeq ($(SYSTEM),MINGW32) ifeq ($(SYSTEM),MINGW32)
$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
$(E) "[LD] Linking $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr$(SHARED_VERSION_CORE)-dll -laddress_sorting$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else else
$(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(OPENSSL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
$(E) "[LD] Linking $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin) ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr -laddress_sorting -lupb $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.11 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr -laddress_sorting -lupb $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.11 -o $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.11 $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so.11
$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so $(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc$(SHARED_VERSION_CORE).so
endif endif
@ -4206,18 +4207,18 @@ endif
ifeq ($(SYSTEM),MINGW32) ifeq ($(SYSTEM),MINGW32)
$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP) $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
$(E) "[LD] Linking $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgrpc$(SHARED_VERSION_CORE)-dll -lgpr$(SHARED_VERSION_CORE)-dll -laddress_sorting$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else else
$(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(OPENSSL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(OPENSSL_DEP)
$(E) "[LD] Linking $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin) ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgrpc -lgpr -laddress_sorting -lupb $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.11 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgrpc -lgpr -laddress_sorting -lupb $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.11 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_CSHARP_EXT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so.11 $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so.11
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CORE).so
endif endif
@ -4391,6 +4392,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc \
src/core/ext/filters/client_channel/service_config_parser.cc \ src/core/ext/filters/client_channel/service_config_parser.cc \
src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \
@ -4774,18 +4776,18 @@ endif
ifeq ($(SYSTEM),MINGW32) ifeq ($(SYSTEM),MINGW32)
$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/upb$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
$(E) "[LD] Linking $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr$(SHARED_VERSION_CORE)-dll -laddress_sorting$(SHARED_VERSION_CORE)-dll -lupb$(SHARED_VERSION_CORE)-dll $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else else
$(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libaddress_sorting.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libupb.$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE): $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(UPB_DEP) $(GRPC_ABSEIL_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a
$(E) "[LD] Linking $@" $(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@` $(Q) mkdir -p `dirname $@`
ifeq ($(SYSTEM),Darwin) ifeq ($(SYSTEM),Darwin)
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr -laddress_sorting -lupb $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
else else
$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.11 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS) -lgpr -laddress_sorting -lupb $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.11 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBGRPC_UNSECURE_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(UPB_MERGE_LIBS) $(GRPC_ABSEIL_MERGE_LIBS) $(LDLIBS)
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.11 $(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so.11
$(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so $(Q) ln -sf $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure$(SHARED_VERSION_CORE).so
endif endif

@ -142,7 +142,7 @@ task 'gem:native' do
gem update --system --no-document && \ gem update --system --no-document && \
bundle && \ bundle && \
rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem \ rake native:#{plat} pkg/#{spec.full_name}-#{plat}.gem pkg/#{spec.full_name}.gem \
RUBY_CC_VERSION=2.7.0:2.6.0:2.5.0:2.4.0:2.3.0 \ RUBY_CC_VERSION=2.7.0:2.6.0:2.5.0:2.4.0:2.3.0 \
V=#{verbose} \ V=#{verbose} \
GRPC_CONFIG=#{grpc_config} GRPC_CONFIG=#{grpc_config}

@ -861,6 +861,7 @@ libs:
- src/core/ext/filters/client_channel/retry_throttle.cc - src/core/ext/filters/client_channel/retry_throttle.cc
- src/core/ext/filters/client_channel/server_address.cc - src/core/ext/filters/client_channel/server_address.cc
- src/core/ext/filters/client_channel/service_config.cc - src/core/ext/filters/client_channel/service_config.cc
- src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
- src/core/ext/filters/client_channel/service_config_parser.cc - src/core/ext/filters/client_channel/service_config_parser.cc
- src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel.cc
- src/core/ext/filters/client_channel/subchannel_pool_interface.cc - src/core/ext/filters/client_channel/subchannel_pool_interface.cc
@ -1296,6 +1297,7 @@ libs:
- absl/strings:strings - absl/strings:strings
- absl/container:inlined_vector - absl/container:inlined_vector
baselib: true baselib: true
deps_linkage: static
dll: true dll: true
generate_plugin_registry: true generate_plugin_registry: true
secure: true secure: true
@ -1311,6 +1313,7 @@ libs:
- gpr - gpr
- address_sorting - address_sorting
- upb - upb
deps_linkage: static
dll: only dll: only
- name: grpc_test_util - name: grpc_test_util
build: private build: private
@ -1854,6 +1857,7 @@ libs:
- src/core/ext/filters/client_channel/retry_throttle.cc - src/core/ext/filters/client_channel/retry_throttle.cc
- src/core/ext/filters/client_channel/server_address.cc - src/core/ext/filters/client_channel/server_address.cc
- src/core/ext/filters/client_channel/service_config.cc - src/core/ext/filters/client_channel/service_config.cc
- src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
- src/core/ext/filters/client_channel/service_config_parser.cc - src/core/ext/filters/client_channel/service_config_parser.cc
- src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel.cc
- src/core/ext/filters/client_channel/subchannel_pool_interface.cc - src/core/ext/filters/client_channel/subchannel_pool_interface.cc
@ -2214,6 +2218,7 @@ libs:
- absl/strings:strings - absl/strings:strings
- absl/container:inlined_vector - absl/container:inlined_vector
baselib: true baselib: true
deps_linkage: static
dll: true dll: true
generate_plugin_registry: true generate_plugin_registry: true
secure: false secure: false

@ -93,6 +93,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/retry_throttle.cc \ src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/server_address.cc \ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc \
src/core/ext/filters/client_channel/service_config_parser.cc \ src/core/ext/filters/client_channel/service_config_parser.cc \
src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \

@ -62,6 +62,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " + "src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " +
"src\\core\\ext\\filters\\client_channel\\server_address.cc " + "src\\core\\ext\\filters\\client_channel\\server_address.cc " +
"src\\core\\ext\\filters\\client_channel\\service_config.cc " + "src\\core\\ext\\filters\\client_channel\\service_config.cc " +
"src\\core\\ext\\filters\\client_channel\\service_config_channel_arg_filter.cc " +
"src\\core\\ext\\filters\\client_channel\\service_config_parser.cc " + "src\\core\\ext\\filters\\client_channel\\service_config_parser.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel_pool_interface.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel_pool_interface.cc " +

@ -279,6 +279,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/service_config.h',
'src/core/ext/filters/client_channel/service_config_call_data.h', 'src/core/ext/filters/client_channel/service_config_call_data.h',
'src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc',
'src/core/ext/filters/client_channel/service_config_parser.cc', 'src/core/ext/filters/client_channel/service_config_parser.cc',
'src/core/ext/filters/client_channel/service_config_parser.h', 'src/core/ext/filters/client_channel/service_config_parser.h',
'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel.cc',

@ -112,6 +112,8 @@ EXPORTS
grpc_access_token_credentials_create grpc_access_token_credentials_create
grpc_google_iam_credentials_create grpc_google_iam_credentials_create
grpc_sts_credentials_create grpc_sts_credentials_create
grpc_auth_metadata_context_copy
grpc_auth_metadata_context_reset
grpc_metadata_credentials_create_from_plugin grpc_metadata_credentials_create_from_plugin
grpc_secure_channel_create grpc_secure_channel_create
grpc_server_credentials_release grpc_server_credentials_release

@ -201,6 +201,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/service_config.cc ) s.files += %w( src/core/ext/filters/client_channel/service_config.cc )
s.files += %w( src/core/ext/filters/client_channel/service_config.h ) s.files += %w( src/core/ext/filters/client_channel/service_config.h )
s.files += %w( src/core/ext/filters/client_channel/service_config_call_data.h ) s.files += %w( src/core/ext/filters/client_channel/service_config_call_data.h )
s.files += %w( src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc )
s.files += %w( src/core/ext/filters/client_channel/service_config_parser.cc ) s.files += %w( src/core/ext/filters/client_channel/service_config_parser.cc )
s.files += %w( src/core/ext/filters/client_channel/service_config_parser.h ) s.files += %w( src/core/ext/filters/client_channel/service_config_parser.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc )

@ -488,6 +488,7 @@
'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc',
'src/core/ext/filters/client_channel/service_config_parser.cc', 'src/core/ext/filters/client_channel/service_config_parser.cc',
'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',
@ -1062,6 +1063,7 @@
'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc',
'src/core/ext/filters/client_channel/service_config_parser.cc', 'src/core/ext/filters/client_channel/service_config_parser.cc',
'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',

@ -390,6 +390,14 @@ typedef struct {
void* reserved; void* reserved;
} grpc_auth_metadata_context; } grpc_auth_metadata_context;
/** Performs a deep copy from \a from to \a to. **/
GRPCAPI void grpc_auth_metadata_context_copy(grpc_auth_metadata_context* from,
grpc_auth_metadata_context* to);
/** Releases internal resources held by \a context. **/
GRPCAPI void grpc_auth_metadata_context_reset(
grpc_auth_metadata_context* context);
/** Maximum number of metadata entries returnable by a credentials plugin via /** Maximum number of metadata entries returnable by a credentials plugin via
a synchronous return. */ a synchronous return. */
#define GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX 4 #define GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX 4

@ -21,8 +21,9 @@
/// The gRPC C++ API mainly consists of the following classes: /// The gRPC C++ API mainly consists of the following classes:
/// <br> /// <br>
/// - grpc::Channel, which represents the connection to an endpoint. See [the /// - grpc::Channel, which represents the connection to an endpoint. See [the
/// gRPC Concepts page](https://grpc.io/docs/guides/concepts.html) for more /// gRPC Concepts page](https://grpc.io/docs/what-is-grpc/core-concepts) for
/// details. Channels are created by the factory function grpc::CreateChannel. /// more details. Channels are created by the factory function
/// grpc::CreateChannel.
/// ///
/// - grpc::CompletionQueue, the producer-consumer queue used for all /// - grpc::CompletionQueue, the producer-consumer queue used for all
/// asynchronous communication with the gRPC runtime. /// asynchronous communication with the gRPC runtime.

@ -319,7 +319,7 @@ class ClientContext {
/// ///
/// It is legal to call this only before initial metadata is sent. /// It is legal to call this only before initial metadata is sent.
/// ///
/// \see https://grpc.io/docs/guides/auth.html /// \see https://grpc.io/docs/guides/auth
void set_credentials( void set_credentials(
const std::shared_ptr<grpc_impl::CallCredentials>& creds); const std::shared_ptr<grpc_impl::CallCredentials>& creds);

@ -62,7 +62,7 @@ std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
/// It can make various assertions, e.g., about the client’s identity, role /// It can make various assertions, e.g., about the client’s identity, role
/// for all the calls on that channel. /// for all the calls on that channel.
/// ///
/// \see https://grpc.io/docs/guides/auth.html /// \see https://grpc.io/docs/guides/auth
class ChannelCredentials : private grpc::GrpcLibraryCodegen { class ChannelCredentials : private grpc::GrpcLibraryCodegen {
public: public:
ChannelCredentials(); ChannelCredentials();
@ -107,7 +107,7 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen {
/// A call credentials object encapsulates the state needed by a client to /// A call credentials object encapsulates the state needed by a client to
/// authenticate with a server for a given call on a channel. /// authenticate with a server for a given call on a channel.
/// ///
/// \see https://grpc.io/docs/guides/auth.html /// \see https://grpc.io/docs/guides/auth
class CallCredentials : private grpc::GrpcLibraryCodegen { class CallCredentials : private grpc::GrpcLibraryCodegen {
public: public:
CallCredentials(); CallCredentials();

@ -181,6 +181,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_call_data.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_call_data.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_parser.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_parser.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_parser.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/service_config_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.cc" role="src" />

@ -383,6 +383,7 @@ COMMAND_CLASS = {
'build_py': commands.BuildPy, 'build_py': commands.BuildPy,
'build_ext': commands.BuildExt, 'build_ext': commands.BuildExt,
'gather': commands.Gather, 'gather': commands.Gather,
'clean': commands.Clean,
} }
# Ensure that package data is copied over before any commands have been run: # Ensure that package data is copied over before any commands have been run:

@ -69,8 +69,11 @@ def parse_bazel_rule(elem, package):
def read_bazel_build(package): def read_bazel_build(package):
"""Runs bazel query on given package file and returns all cc rules.""" """Runs bazel query on given package file and returns all cc rules."""
# Use a wrapper version of bazel in gRPC not to use system-wide bazel
# to avoid bazel conflict when running on Kokoro.
BAZEL_BIN = "../../tools/bazel"
result = subprocess.check_output( result = subprocess.check_output(
["bazel", "query", package + ":all", "--output", "xml"]) [BAZEL_BIN, "query", package + ":all", "--output", "xml"])
root = ET.fromstring(result) root = ET.fromstring(result)
return [ return [
parse_bazel_rule(elem, package) parse_bazel_rule(elem, package)
@ -203,7 +206,7 @@ def main():
builds = generate_builds("absl") builds = generate_builds("absl")
os.chdir(previous_dir) os.chdir(previous_dir)
with open(OUTPUT_PATH, 'w') as outfile: with open(OUTPUT_PATH, 'w') as outfile:
outfile.write(yaml.dump(builds, indent=2, sort_keys=True)) outfile.write(yaml.dump(builds, indent=2))
if __name__ == "__main__": if __name__ == "__main__":

@ -0,0 +1,142 @@
//
// Copyright 2020 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This filter reads GRPC_ARG_SERVICE_CONFIG and populates ServiceConfigCallData
// in the call context per call for direct channels.
#include <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/service_config_call_data.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/surface/channel_init.h"
namespace grpc_core {
namespace {
class ServiceConfigChannelArgChannelData {
public:
explicit ServiceConfigChannelArgChannelData(
const grpc_channel_element_args* args) {
const char* service_config_str = grpc_channel_args_find_string(
args->channel_args, GRPC_ARG_SERVICE_CONFIG);
if (service_config_str != nullptr) {
grpc_error* service_config_error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfig::Create(service_config_str, &service_config_error);
if (service_config_error == GRPC_ERROR_NONE) {
service_config_ = std::move(service_config);
} else {
gpr_log(GPR_ERROR, "%s", grpc_error_string(service_config_error));
}
GRPC_ERROR_UNREF(service_config_error);
}
}
RefCountedPtr<ServiceConfig> service_config() const {
return service_config_;
}
private:
RefCountedPtr<ServiceConfig> service_config_;
};
class ServiceConfigChannelArgCallData {
public:
ServiceConfigChannelArgCallData(grpc_call_element* elem,
const grpc_call_element_args* args) {
ServiceConfigChannelArgChannelData* chand =
static_cast<ServiceConfigChannelArgChannelData*>(elem->channel_data);
RefCountedPtr<ServiceConfig> service_config = chand->service_config();
if (service_config != nullptr) {
GPR_DEBUG_ASSERT(args->context != nullptr);
const auto* method_params_vector =
service_config->GetMethodParsedConfigVector(args->path);
args->arena->New<ServiceConfigCallData>(
std::move(service_config), method_params_vector, args->context);
}
}
};
grpc_error* ServiceConfigChannelArgInitCallElem(
grpc_call_element* elem, const grpc_call_element_args* args) {
ServiceConfigChannelArgCallData* calld =
static_cast<ServiceConfigChannelArgCallData*>(elem->call_data);
new (calld) ServiceConfigChannelArgCallData(elem, args);
return GRPC_ERROR_NONE;
}
void ServiceConfigChannelArgDestroyCallElem(
grpc_call_element* elem, const grpc_call_final_info* /* final_info */,
grpc_closure* /* then_schedule_closure */) {
ServiceConfigChannelArgCallData* calld =
static_cast<ServiceConfigChannelArgCallData*>(elem->call_data);
calld->~ServiceConfigChannelArgCallData();
}
grpc_error* ServiceConfigChannelArgInitChannelElem(
grpc_channel_element* elem, grpc_channel_element_args* args) {
ServiceConfigChannelArgChannelData* chand =
static_cast<ServiceConfigChannelArgChannelData*>(elem->channel_data);
new (chand) ServiceConfigChannelArgChannelData(args);
return GRPC_ERROR_NONE;
}
void ServiceConfigChannelArgDestroyChannelElem(grpc_channel_element* elem) {
ServiceConfigChannelArgChannelData* chand =
static_cast<ServiceConfigChannelArgChannelData*>(elem->channel_data);
chand->~ServiceConfigChannelArgChannelData();
}
const grpc_channel_filter ServiceConfigChannelArgFilter = {
grpc_call_next_op,
grpc_channel_next_op,
sizeof(ServiceConfigChannelArgCallData),
ServiceConfigChannelArgInitCallElem,
grpc_call_stack_ignore_set_pollset_or_pollset_set,
ServiceConfigChannelArgDestroyCallElem,
sizeof(ServiceConfigChannelArgChannelData),
ServiceConfigChannelArgInitChannelElem,
ServiceConfigChannelArgDestroyChannelElem,
grpc_channel_next_get_info,
"service_config_channel_arg"};
bool maybe_add_service_config_channel_arg_filter(
grpc_channel_stack_builder* builder, void* /* arg */) {
const grpc_channel_args* channel_args =
grpc_channel_stack_builder_get_channel_arguments(builder);
if (grpc_channel_args_want_minimal_stack(channel_args) ||
grpc_channel_args_find_string(channel_args, GRPC_ARG_SERVICE_CONFIG) ==
nullptr) {
return true;
}
return grpc_channel_stack_builder_prepend_filter(
builder, &ServiceConfigChannelArgFilter, nullptr, nullptr);
}
} // namespace
} // namespace grpc_core
void grpc_service_config_channel_arg_filter_init(void) {
grpc_channel_init_register_stage(
GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
grpc_core::maybe_add_service_config_channel_arg_filter, nullptr);
}
void grpc_service_config_channel_arg_filter_shutdown(void) {}

@ -38,7 +38,8 @@ static optional_filter compress_filter = {
&grpc_message_compress_filter, GRPC_ARG_ENABLE_PER_MESSAGE_COMPRESSION}; &grpc_message_compress_filter, GRPC_ARG_ENABLE_PER_MESSAGE_COMPRESSION};
static optional_filter decompress_filter = { static optional_filter decompress_filter = {
&grpc_message_decompress_filter, GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION}; &grpc_core::MessageDecompressFilter,
GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION};
static bool is_building_http_like_transport( static bool is_building_http_like_transport(
grpc_channel_stack_builder* builder) { grpc_channel_stack_builder* builder) {

@ -18,6 +18,8 @@
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
#include "src/core/ext/filters/http/message_compress/message_decompress_filter.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -27,7 +29,8 @@
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/string_util.h> #include <grpc/support/string_util.h>
#include "src/core/ext/filters/http/message_compress/message_decompress_filter.h" #include "absl/strings/str_format.h"
#include "src/core/ext/filters/message_size/message_size_filter.h"
#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/compression/algorithm_metadata.h" #include "src/core/lib/compression/algorithm_metadata.h"
#include "src/core/lib/compression/compression_args.h" #include "src/core/lib/compression/compression_args.h"
@ -37,14 +40,25 @@
#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/slice/slice_string_helpers.h"
namespace grpc_core {
namespace { namespace {
class ChannelData {}; class ChannelData {
public:
explicit ChannelData(const grpc_channel_element_args* args)
: max_recv_size_(GetMaxRecvSizeFromChannelArgs(args->channel_args)) {}
int max_recv_size() const { return max_recv_size_; }
private:
int max_recv_size_;
};
class CallData { class CallData {
public: public:
explicit CallData(const grpc_call_element_args& args) CallData(const grpc_call_element_args& args, const ChannelData* chand)
: call_combiner_(args.call_combiner) { : call_combiner_(args.call_combiner),
max_recv_message_length_(chand->max_recv_size()) {
// Initialize state for recv_initial_metadata_ready callback // Initialize state for recv_initial_metadata_ready callback
GRPC_CLOSURE_INIT(&on_recv_initial_metadata_ready_, GRPC_CLOSURE_INIT(&on_recv_initial_metadata_ready_,
OnRecvInitialMetadataReady, this, OnRecvInitialMetadataReady, this,
@ -59,6 +73,13 @@ class CallData {
GRPC_CLOSURE_INIT(&on_recv_trailing_metadata_ready_, GRPC_CLOSURE_INIT(&on_recv_trailing_metadata_ready_,
OnRecvTrailingMetadataReady, this, OnRecvTrailingMetadataReady, this,
grpc_schedule_on_exec_ctx); grpc_schedule_on_exec_ctx);
const MessageSizeParsedConfig* limits =
MessageSizeParsedConfig::GetFromCallContext(args.context);
if (limits != nullptr && limits->limits().max_recv_size >= 0 &&
(limits->limits().max_recv_size < max_recv_message_length_ ||
max_recv_message_length_ < 0)) {
max_recv_message_length_ = limits->limits().max_recv_size;
}
} }
~CallData() { grpc_slice_buffer_destroy_internal(&recv_slices_); } ~CallData() { grpc_slice_buffer_destroy_internal(&recv_slices_); }
@ -82,7 +103,7 @@ class CallData {
void MaybeResumeOnRecvTrailingMetadataReady(); void MaybeResumeOnRecvTrailingMetadataReady();
static void OnRecvTrailingMetadataReady(void* arg, grpc_error* error); static void OnRecvTrailingMetadataReady(void* arg, grpc_error* error);
grpc_core::CallCombiner* call_combiner_; CallCombiner* call_combiner_;
// Overall error for the call // Overall error for the call
grpc_error* error_ = GRPC_ERROR_NONE; grpc_error* error_ = GRPC_ERROR_NONE;
// Fields for handling recv_initial_metadata_ready callback // Fields for handling recv_initial_metadata_ready callback
@ -91,17 +112,18 @@ class CallData {
grpc_metadata_batch* recv_initial_metadata_ = nullptr; grpc_metadata_batch* recv_initial_metadata_ = nullptr;
// Fields for handling recv_message_ready callback // Fields for handling recv_message_ready callback
bool seen_recv_message_ready_ = false; bool seen_recv_message_ready_ = false;
int max_recv_message_length_;
grpc_message_compression_algorithm algorithm_ = GRPC_MESSAGE_COMPRESS_NONE; grpc_message_compression_algorithm algorithm_ = GRPC_MESSAGE_COMPRESS_NONE;
grpc_closure on_recv_message_ready_; grpc_closure on_recv_message_ready_;
grpc_closure* original_recv_message_ready_ = nullptr; grpc_closure* original_recv_message_ready_ = nullptr;
grpc_closure on_recv_message_next_done_; grpc_closure on_recv_message_next_done_;
grpc_core::OrphanablePtr<grpc_core::ByteStream>* recv_message_ = nullptr; OrphanablePtr<ByteStream>* recv_message_ = nullptr;
// recv_slices_ holds the slices read from the original recv_message stream. // recv_slices_ holds the slices read from the original recv_message stream.
// It is initialized during construction and reset when a new stream is // It is initialized during construction and reset when a new stream is
// created using it. // created using it.
grpc_slice_buffer recv_slices_; grpc_slice_buffer recv_slices_;
std::aligned_storage<sizeof(grpc_core::SliceBufferByteStream), std::aligned_storage<sizeof(SliceBufferByteStream),
alignof(grpc_core::SliceBufferByteStream)>::type alignof(SliceBufferByteStream)>::type
recv_replacement_stream_; recv_replacement_stream_;
// Fields for handling recv_trailing_metadata_ready callback // Fields for handling recv_trailing_metadata_ready callback
bool seen_recv_trailing_metadata_ready_ = false; bool seen_recv_trailing_metadata_ready_ = false;
@ -139,7 +161,7 @@ void CallData::OnRecvInitialMetadataReady(void* arg, grpc_error* error) {
calld->MaybeResumeOnRecvTrailingMetadataReady(); calld->MaybeResumeOnRecvTrailingMetadataReady();
grpc_closure* closure = calld->original_recv_initial_metadata_ready_; grpc_closure* closure = calld->original_recv_initial_metadata_ready_;
calld->original_recv_initial_metadata_ready_ = nullptr; calld->original_recv_initial_metadata_ready_ = nullptr;
grpc_core::Closure::Run(DEBUG_LOCATION, closure, GRPC_ERROR_REF(error)); Closure::Run(DEBUG_LOCATION, closure, GRPC_ERROR_REF(error));
} }
void CallData::MaybeResumeOnRecvMessageReady() { void CallData::MaybeResumeOnRecvMessageReady() {
@ -170,6 +192,19 @@ void CallData::OnRecvMessageReady(void* arg, grpc_error* error) {
0) { 0) {
return calld->ContinueRecvMessageReadyCallback(GRPC_ERROR_NONE); return calld->ContinueRecvMessageReadyCallback(GRPC_ERROR_NONE);
} }
if (calld->max_recv_message_length_ >= 0 &&
(*calld->recv_message_)->length() >
static_cast<uint32_t>(calld->max_recv_message_length_)) {
std::string message_string = absl::StrFormat(
"Received message larger than max (%u vs. %d)",
(*calld->recv_message_)->length(), calld->max_recv_message_length_);
GPR_DEBUG_ASSERT(calld->error_ == GRPC_ERROR_NONE);
calld->error_ = grpc_error_set_int(
GRPC_ERROR_CREATE_FROM_COPIED_STRING(message_string.c_str()),
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_RESOURCE_EXHAUSTED);
return calld->ContinueRecvMessageReadyCallback(
GRPC_ERROR_REF(calld->error_));
}
grpc_slice_buffer_destroy_internal(&calld->recv_slices_); grpc_slice_buffer_destroy_internal(&calld->recv_slices_);
grpc_slice_buffer_init(&calld->recv_slices_); grpc_slice_buffer_init(&calld->recv_slices_);
return calld->ContinueReadingRecvMessage(); return calld->ContinueReadingRecvMessage();
@ -241,9 +276,9 @@ void CallData::FinishRecvMessage() {
// Initializing recv_replacement_stream_ with decompressed_slices removes // Initializing recv_replacement_stream_ with decompressed_slices removes
// all the slices from decompressed_slices leaving it empty. // all the slices from decompressed_slices leaving it empty.
new (&recv_replacement_stream_) new (&recv_replacement_stream_)
grpc_core::SliceBufferByteStream(&decompressed_slices, recv_flags); SliceBufferByteStream(&decompressed_slices, recv_flags);
recv_message_->reset(reinterpret_cast<grpc_core::SliceBufferByteStream*>( recv_message_->reset(
&recv_replacement_stream_)); reinterpret_cast<SliceBufferByteStream*>(&recv_replacement_stream_));
recv_message_ = nullptr; recv_message_ = nullptr;
} }
ContinueRecvMessageReadyCallback(GRPC_ERROR_REF(error_)); ContinueRecvMessageReadyCallback(GRPC_ERROR_REF(error_));
@ -254,7 +289,7 @@ void CallData::ContinueRecvMessageReadyCallback(grpc_error* error) {
// The surface will clean up the receiving stream if there is an error. // The surface will clean up the receiving stream if there is an error.
grpc_closure* closure = original_recv_message_ready_; grpc_closure* closure = original_recv_message_ready_;
original_recv_message_ready_ = nullptr; original_recv_message_ready_ = nullptr;
grpc_core::Closure::Run(DEBUG_LOCATION, closure, error); Closure::Run(DEBUG_LOCATION, closure, error);
} }
void CallData::MaybeResumeOnRecvTrailingMetadataReady() { void CallData::MaybeResumeOnRecvTrailingMetadataReady() {
@ -283,7 +318,7 @@ void CallData::OnRecvTrailingMetadataReady(void* arg, grpc_error* error) {
calld->error_ = GRPC_ERROR_NONE; calld->error_ = GRPC_ERROR_NONE;
grpc_closure* closure = calld->original_recv_trailing_metadata_ready_; grpc_closure* closure = calld->original_recv_trailing_metadata_ready_;
calld->original_recv_trailing_metadata_ready_ = nullptr; calld->original_recv_trailing_metadata_ready_ = nullptr;
grpc_core::Closure::Run(DEBUG_LOCATION, closure, error); Closure::Run(DEBUG_LOCATION, closure, error);
} }
void CallData::DecompressStartTransportStreamOpBatch( void CallData::DecompressStartTransportStreamOpBatch(
@ -322,37 +357,44 @@ void DecompressStartTransportStreamOpBatch(
calld->DecompressStartTransportStreamOpBatch(elem, batch); calld->DecompressStartTransportStreamOpBatch(elem, batch);
} }
static grpc_error* DecompressInitCallElem(grpc_call_element* elem, grpc_error* DecompressInitCallElem(grpc_call_element* elem,
const grpc_call_element_args* args) { const grpc_call_element_args* args) {
new (elem->call_data) CallData(*args); ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
new (elem->call_data) CallData(*args, chand);
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }
static void DecompressDestroyCallElem( void DecompressDestroyCallElem(grpc_call_element* elem,
grpc_call_element* elem, const grpc_call_final_info* /*final_info*/, const grpc_call_final_info* /*final_info*/,
grpc_closure* /*ignored*/) { grpc_closure* /*ignored*/) {
CallData* calld = static_cast<CallData*>(elem->call_data); CallData* calld = static_cast<CallData*>(elem->call_data);
calld->~CallData(); calld->~CallData();
} }
static grpc_error* DecompressInitChannelElem( grpc_error* DecompressInitChannelElem(grpc_channel_element* elem,
grpc_channel_element* /*elem*/, grpc_channel_element_args* /*args*/) { grpc_channel_element_args* args) {
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
new (chand) ChannelData(args);
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }
void DecompressDestroyChannelElem(grpc_channel_element* /*elem*/) {} void DecompressDestroyChannelElem(grpc_channel_element* elem) {
ChannelData* chand = static_cast<ChannelData*>(elem->channel_data);
chand->~ChannelData();
}
} // namespace } // namespace
const grpc_channel_filter grpc_message_decompress_filter = { const grpc_channel_filter MessageDecompressFilter = {
DecompressStartTransportStreamOpBatch, DecompressStartTransportStreamOpBatch,
grpc_channel_next_op, grpc_channel_next_op,
sizeof(CallData), sizeof(CallData),
DecompressInitCallElem, DecompressInitCallElem,
grpc_call_stack_ignore_set_pollset_or_pollset_set, grpc_call_stack_ignore_set_pollset_or_pollset_set,
DecompressDestroyCallElem, DecompressDestroyCallElem,
0, // sizeof(ChannelData) sizeof(ChannelData),
DecompressInitChannelElem, DecompressInitChannelElem,
DecompressDestroyChannelElem, DecompressDestroyChannelElem,
grpc_channel_next_get_info, grpc_channel_next_get_info,
"message_decompress"}; "message_decompress"};
} // namespace grpc_core

@ -23,7 +23,9 @@
#include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/channel_stack.h"
extern const grpc_channel_filter grpc_message_decompress_filter; namespace grpc_core {
extern const grpc_channel_filter MessageDecompressFilter;
} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_MESSAGE_DECOMPRESS_FILTER_H \ #endif /* GRPC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_MESSAGE_DECOMPRESS_FILTER_H \
*/ */

@ -45,6 +45,25 @@ namespace {
size_t g_message_size_parser_index; size_t g_message_size_parser_index;
} // namespace } // namespace
//
// MessageSizeParsedConfig
//
const MessageSizeParsedConfig* MessageSizeParsedConfig::GetFromCallContext(
const grpc_call_context_element* context) {
if (context == nullptr) return nullptr;
auto* svc_cfg_call_data = static_cast<ServiceConfigCallData*>(
context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
if (svc_cfg_call_data == nullptr) return nullptr;
return static_cast<const MessageSizeParsedConfig*>(
svc_cfg_call_data->GetMethodParsedConfig(
MessageSizeParser::ParserIndex()));
}
//
// MessageSizeParser
//
std::unique_ptr<ServiceConfigParser::ParsedConfig> std::unique_ptr<ServiceConfigParser::ParsedConfig>
MessageSizeParser::ParsePerMethodParams(const Json& json, grpc_error** error) { MessageSizeParser::ParsePerMethodParams(const Json& json, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
@ -97,12 +116,26 @@ void MessageSizeParser::Register() {
} }
size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; } size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; }
int GetMaxRecvSizeFromChannelArgs(const grpc_channel_args* args) {
if (grpc_channel_args_want_minimal_stack(args)) return -1;
return grpc_channel_args_find_integer(
args, GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH,
{GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH, -1, INT_MAX});
}
int GetMaxSendSizeFromChannelArgs(const grpc_channel_args* args) {
if (grpc_channel_args_want_minimal_stack(args)) return -1;
return grpc_channel_args_find_integer(
args, GRPC_ARG_MAX_SEND_MESSAGE_LENGTH,
{GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH, -1, INT_MAX});
}
} // namespace grpc_core } // namespace grpc_core
namespace { namespace {
struct channel_data { struct channel_data {
grpc_core::MessageSizeParsedConfig::message_size_limits limits; grpc_core::MessageSizeParsedConfig::message_size_limits limits;
grpc_core::RefCountedPtr<grpc_core::ServiceConfig> svc_cfg;
}; };
struct call_data { struct call_data {
@ -118,24 +151,8 @@ struct call_data {
// Note: Per-method config is only available on the client, so we // Note: Per-method config is only available on the client, so we
// apply the max request size to the send limit and the max response // apply the max request size to the send limit and the max response
// size to the receive limit. // size to the receive limit.
const grpc_core::MessageSizeParsedConfig* limits = nullptr; const grpc_core::MessageSizeParsedConfig* limits =
grpc_core::ServiceConfigCallData* svc_cfg_call_data = nullptr; grpc_core::MessageSizeParsedConfig::GetFromCallContext(args.context);
if (args.context != nullptr) {
svc_cfg_call_data = static_cast<grpc_core::ServiceConfigCallData*>(
args.context[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
}
if (svc_cfg_call_data != nullptr) {
limits = static_cast<const grpc_core::MessageSizeParsedConfig*>(
svc_cfg_call_data->GetMethodParsedConfig(
grpc_core::MessageSizeParser::ParserIndex()));
} else if (chand.svc_cfg != nullptr) {
const auto* objs_vector =
chand.svc_cfg->GetMethodParsedConfigVector(args.path);
if (objs_vector != nullptr) {
limits = static_cast<const grpc_core::MessageSizeParsedConfig*>(
(*objs_vector)[grpc_core::MessageSizeParser::ParserIndex()].get());
}
}
if (limits != nullptr) { if (limits != nullptr) {
if (limits->limits().max_send_size >= 0 && if (limits->limits().max_send_size >= 0 &&
(limits->limits().max_send_size < this->limits.max_send_size || (limits->limits().max_send_size < this->limits.max_send_size ||
@ -288,35 +305,11 @@ static void message_size_destroy_call_elem(
calld->~call_data(); calld->~call_data();
} }
static int default_size(const grpc_channel_args* args,
int without_minimal_stack) {
if (grpc_channel_args_want_minimal_stack(args)) {
return -1;
}
return without_minimal_stack;
}
grpc_core::MessageSizeParsedConfig::message_size_limits get_message_size_limits( grpc_core::MessageSizeParsedConfig::message_size_limits get_message_size_limits(
const grpc_channel_args* channel_args) { const grpc_channel_args* channel_args) {
grpc_core::MessageSizeParsedConfig::message_size_limits lim; grpc_core::MessageSizeParsedConfig::message_size_limits lim;
lim.max_send_size = lim.max_send_size = grpc_core::GetMaxSendSizeFromChannelArgs(channel_args);
default_size(channel_args, GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH); lim.max_recv_size = grpc_core::GetMaxRecvSizeFromChannelArgs(channel_args);
lim.max_recv_size =
default_size(channel_args, GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH);
for (size_t i = 0; i < channel_args->num_args; ++i) {
if (strcmp(channel_args->args[i].key, GRPC_ARG_MAX_SEND_MESSAGE_LENGTH) ==
0) {
const grpc_integer_options options = {lim.max_send_size, -1, INT_MAX};
lim.max_send_size =
grpc_channel_arg_get_integer(&channel_args->args[i], options);
}
if (strcmp(channel_args->args[i].key,
GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH) == 0) {
const grpc_integer_options options = {lim.max_recv_size, -1, INT_MAX};
lim.max_recv_size =
grpc_channel_arg_get_integer(&channel_args->args[i], options);
}
}
return lim; return lim;
} }
@ -327,26 +320,6 @@ static grpc_error* message_size_init_channel_elem(
channel_data* chand = static_cast<channel_data*>(elem->channel_data); channel_data* chand = static_cast<channel_data*>(elem->channel_data);
new (chand) channel_data(); new (chand) channel_data();
chand->limits = get_message_size_limits(args->channel_args); chand->limits = get_message_size_limits(args->channel_args);
// TODO(yashykt): We only need to read GRPC_ARG_SERVICE_CONFIG in the case of
// direct channels. (Service config is otherwise stored in the call_context by
// client_channel filter.) If we ever need a second filter that also needs to
// parse GRPC_ARG_SERVICE_CONFIG, we should refactor this code and add a
// separate filter that reads GRPC_ARG_SERVICE_CONFIG and saves the parsed
// config in the call_context.
const grpc_arg* channel_arg =
grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
const char* service_config_str = grpc_channel_arg_get_string(channel_arg);
if (service_config_str != nullptr) {
grpc_error* service_config_error = GRPC_ERROR_NONE;
auto svc_cfg = grpc_core::ServiceConfig::Create(service_config_str,
&service_config_error);
if (service_config_error == GRPC_ERROR_NONE) {
chand->svc_cfg = std::move(svc_cfg);
} else {
gpr_log(GPR_ERROR, "%s", grpc_error_string(service_config_error));
}
GRPC_ERROR_UNREF(service_config_error);
}
return GRPC_ERROR_NONE; return GRPC_ERROR_NONE;
} }
@ -387,6 +360,9 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder,
void* /*arg*/) { void* /*arg*/) {
const grpc_channel_args* channel_args = const grpc_channel_args* channel_args =
grpc_channel_stack_builder_get_channel_arguments(builder); grpc_channel_stack_builder_get_channel_arguments(builder);
if (grpc_channel_args_want_minimal_stack(channel_args)) {
return true;
}
bool enable = false; bool enable = false;
grpc_core::MessageSizeParsedConfig::message_size_limits lim = grpc_core::MessageSizeParsedConfig::message_size_limits lim =
get_message_size_limits(channel_args); get_message_size_limits(channel_args);

@ -40,6 +40,9 @@ class MessageSizeParsedConfig : public ServiceConfigParser::ParsedConfig {
const message_size_limits& limits() const { return limits_; } const message_size_limits& limits() const { return limits_; }
static const MessageSizeParsedConfig* GetFromCallContext(
const grpc_call_context_element* context);
private: private:
message_size_limits limits_; message_size_limits limits_;
}; };
@ -54,6 +57,9 @@ class MessageSizeParser : public ServiceConfigParser::Parser {
static size_t ParserIndex(); static size_t ParserIndex();
}; };
int GetMaxRecvSizeFromChannelArgs(const grpc_channel_args* args);
int GetMaxSendSizeFromChannelArgs(const grpc_channel_args* args);
} // namespace grpc_core } // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */ #endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */

@ -257,7 +257,8 @@ grpc_core::RefCountedPtr<grpc_auth_context> grpc_ssl_peer_to_auth_context(
transport_security_type); transport_security_type);
const char* spiffe_data = nullptr; const char* spiffe_data = nullptr;
size_t spiffe_length = 0; size_t spiffe_length = 0;
int spiffe_id_count = 0; int uri_count = 0;
bool has_spiffe_id = false;
for (i = 0; i < peer->property_count; i++) { for (i = 0; i < peer->property_count; i++) {
const tsi_peer_property* prop = &peer->properties[i]; const tsi_peer_property* prop = &peer->properties[i];
if (prop->name == nullptr) continue; if (prop->name == nullptr) continue;
@ -290,11 +291,12 @@ grpc_core::RefCountedPtr<grpc_auth_context> grpc_ssl_peer_to_auth_context(
ctx.get(), GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME, ctx.get(), GRPC_TRANSPORT_SECURITY_LEVEL_PROPERTY_NAME,
prop->value.data, prop->value.length); prop->value.data, prop->value.length);
} else if (strcmp(prop->name, TSI_X509_URI_PEER_PROPERTY) == 0) { } else if (strcmp(prop->name, TSI_X509_URI_PEER_PROPERTY) == 0) {
uri_count++;
absl::string_view spiffe_id(prop->value.data, prop->value.length); absl::string_view spiffe_id(prop->value.data, prop->value.length);
if (IsSpiffeId(spiffe_id)) { if (IsSpiffeId(spiffe_id)) {
spiffe_data = prop->value.data; spiffe_data = prop->value.data;
spiffe_length = prop->value.length; spiffe_length = prop->value.length;
spiffe_id_count += 1; has_spiffe_id = true;
} }
} }
} }
@ -302,16 +304,17 @@ grpc_core::RefCountedPtr<grpc_auth_context> grpc_ssl_peer_to_auth_context(
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
ctx.get(), peer_identity_property_name) == 1); ctx.get(), peer_identity_property_name) == 1);
} }
// SPIFFE ID should be unique. If we find more than one SPIFFE IDs, we log // A valid SPIFFE certificate can only have exact one URI SAN field.
// the error without returning the error. if (has_spiffe_id) {
if (spiffe_id_count > 1) { if (uri_count == 1) {
gpr_log(GPR_INFO, "Invalid SPIFFE ID: SPIFFE ID should be unique.");
}
if (spiffe_id_count == 1) {
GPR_ASSERT(spiffe_length > 0); GPR_ASSERT(spiffe_length > 0);
GPR_ASSERT(spiffe_data != nullptr); GPR_ASSERT(spiffe_data != nullptr);
grpc_auth_context_add_property(ctx.get(), GRPC_PEER_SPIFFE_ID_PROPERTY_NAME, grpc_auth_context_add_property(ctx.get(),
GRPC_PEER_SPIFFE_ID_PROPERTY_NAME,
spiffe_data, spiffe_length); spiffe_data, spiffe_length);
} else {
gpr_log(GPR_INFO, "Invalid SPIFFE ID: multiple URI SANs.");
}
} }
return ctx; return ctx;
} }

@ -32,9 +32,4 @@ void grpc_auth_metadata_context_build(
const grpc_slice& call_method, grpc_auth_context* auth_context, const grpc_slice& call_method, grpc_auth_context* auth_context,
grpc_auth_metadata_context* auth_md_context); grpc_auth_metadata_context* auth_md_context);
void grpc_auth_metadata_context_copy(grpc_auth_metadata_context* from,
grpc_auth_metadata_context* to);
void grpc_auth_metadata_context_reset(grpc_auth_metadata_context* context);
#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H */ #endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H */

@ -64,6 +64,8 @@ void grpc_max_age_filter_init(void);
void grpc_max_age_filter_shutdown(void); void grpc_max_age_filter_shutdown(void);
void grpc_message_size_filter_init(void); void grpc_message_size_filter_init(void);
void grpc_message_size_filter_shutdown(void); void grpc_message_size_filter_shutdown(void);
void grpc_service_config_channel_arg_filter_init(void);
void grpc_service_config_channel_arg_filter_shutdown(void);
void grpc_client_authority_filter_init(void); void grpc_client_authority_filter_init(void);
void grpc_client_authority_filter_shutdown(void); void grpc_client_authority_filter_shutdown(void);
void grpc_workaround_cronet_compression_filter_init(void); void grpc_workaround_cronet_compression_filter_init(void);
@ -114,6 +116,8 @@ void grpc_register_built_in_plugins(void) {
grpc_max_age_filter_shutdown); grpc_max_age_filter_shutdown);
grpc_register_plugin(grpc_message_size_filter_init, grpc_register_plugin(grpc_message_size_filter_init,
grpc_message_size_filter_shutdown); grpc_message_size_filter_shutdown);
grpc_register_plugin(grpc_service_config_channel_arg_filter_init,
grpc_service_config_channel_arg_filter_shutdown);
grpc_register_plugin(grpc_client_authority_filter_init, grpc_register_plugin(grpc_client_authority_filter_init,
grpc_client_authority_filter_shutdown); grpc_client_authority_filter_shutdown);
grpc_register_plugin(grpc_workaround_cronet_compression_filter_init, grpc_register_plugin(grpc_workaround_cronet_compression_filter_init,

@ -64,6 +64,8 @@ void grpc_max_age_filter_init(void);
void grpc_max_age_filter_shutdown(void); void grpc_max_age_filter_shutdown(void);
void grpc_message_size_filter_init(void); void grpc_message_size_filter_init(void);
void grpc_message_size_filter_shutdown(void); void grpc_message_size_filter_shutdown(void);
void grpc_service_config_channel_arg_filter_init(void);
void grpc_service_config_channel_arg_filter_shutdown(void);
void grpc_client_authority_filter_init(void); void grpc_client_authority_filter_init(void);
void grpc_client_authority_filter_shutdown(void); void grpc_client_authority_filter_shutdown(void);
void grpc_workaround_cronet_compression_filter_init(void); void grpc_workaround_cronet_compression_filter_init(void);
@ -114,6 +116,8 @@ void grpc_register_built_in_plugins(void) {
grpc_max_age_filter_shutdown); grpc_max_age_filter_shutdown);
grpc_register_plugin(grpc_message_size_filter_init, grpc_register_plugin(grpc_message_size_filter_init,
grpc_message_size_filter_shutdown); grpc_message_size_filter_shutdown);
grpc_register_plugin(grpc_service_config_channel_arg_filter_init,
grpc_service_config_channel_arg_filter_shutdown);
grpc_register_plugin(grpc_client_authority_filter_init, grpc_register_plugin(grpc_client_authority_filter_init,
grpc_client_authority_filter_shutdown); grpc_client_authority_filter_shutdown);
grpc_register_plugin(grpc_workaround_cronet_compression_filter_init, grpc_register_plugin(grpc_workaround_cronet_compression_filter_init,

@ -263,7 +263,13 @@ void alts_handshaker_client_handle_response(alts_handshaker_client* c,
} }
tsi_handshaker_result* result = nullptr; tsi_handshaker_result* result = nullptr;
if (is_handshake_finished_properly(resp)) { if (is_handshake_finished_properly(resp)) {
tsi_result status =
alts_tsi_handshaker_result_create(resp, client->is_client, &result); alts_tsi_handshaker_result_create(resp, client->is_client, &result);
if (status != TSI_OK) {
gpr_log(GPR_ERROR, "alts_tsi_handshaker_result_create() failed");
handle_response_done(client, status, nullptr, 0, nullptr);
return;
}
alts_tsi_handshaker_result_set_unused_bytes( alts_tsi_handshaker_result_set_unused_bytes(
result, &client->recv_bytes, result, &client->recv_bytes,
grpc_gcp_HandshakerResp_bytes_consumed(resp)); grpc_gcp_HandshakerResp_bytes_consumed(resp));
@ -658,6 +664,12 @@ static void handshaker_client_destruct(alts_handshaker_client* c) {
// TODO(apolcyn): we could remove this indirection and call // TODO(apolcyn): we could remove this indirection and call
// grpc_call_unref inline if there was an internal variant of // grpc_call_unref inline if there was an internal variant of
// grpc_call_unref that didn't need to flush an ExecCtx. // grpc_call_unref that didn't need to flush an ExecCtx.
if (grpc_core::ExecCtx::Get() == nullptr) {
// Unref handshaker call if there is no exec_ctx, e.g., in the case of
// Envoy ALTS transport socket.
grpc_call_unref(client->call);
} else {
// Using existing exec_ctx to unref handshaker call.
grpc_core::ExecCtx::Run( grpc_core::ExecCtx::Run(
DEBUG_LOCATION, DEBUG_LOCATION,
GRPC_CLOSURE_CREATE(handshaker_call_unref, client->call, GRPC_CLOSURE_CREATE(handshaker_call_unref, client->call,
@ -665,6 +677,7 @@ static void handshaker_client_destruct(alts_handshaker_client* c) {
GRPC_ERROR_NONE); GRPC_ERROR_NONE);
} }
} }
}
static const alts_handshaker_client_vtable vtable = { static const alts_handshaker_client_vtable vtable = {
handshaker_client_start_client, handshaker_client_start_server, handshaker_client_start_client, handshaker_client_start_server,

@ -218,31 +218,17 @@ ServerBuilder& ServerBuilder::AddListeningPort(
} }
std::unique_ptr<grpc::Server> ServerBuilder::BuildAndStart() { std::unique_ptr<grpc::Server> ServerBuilder::BuildAndStart() {
ChannelArguments args; grpc::ChannelArguments args;
for (const auto& option : options_) {
option->UpdateArguments(&args);
option->UpdatePlugins(&plugins_);
}
if (max_receive_message_size_ >= -1) { if (max_receive_message_size_ >= -1) {
grpc_channel_args c_args = args.c_channel_args();
const grpc_arg* arg =
grpc_channel_args_find(&c_args, GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH);
// Some option has set max_receive_message_length and it is also set
// directly on the ServerBuilder.
if (arg != nullptr) {
gpr_log(
GPR_ERROR,
"gRPC ServerBuilder receives multiple max_receive_message_length");
}
args.SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, max_receive_message_size_); args.SetInt(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, max_receive_message_size_);
} }
// The default message size is -1 (max), so no need to explicitly set it for if (max_send_message_size_ >= -1) {
// -1.
if (max_send_message_size_ >= 0) {
args.SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, max_send_message_size_); args.SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, max_send_message_size_);
} }
for (const auto& option : options_) {
option->UpdateArguments(&args);
option->UpdatePlugins(&plugins_);
}
args.SetInt(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET, args.SetInt(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
enabled_compression_algorithms_bitset_); enabled_compression_algorithms_bitset_);
if (maybe_default_compression_level_.is_set) { if (maybe_default_compression_level_.is_set) {

@ -96,7 +96,7 @@ composer package as well. Add this to your project's `composer.json` file.
```json ```json
"require": { "require": {
"grpc/grpc": "~v1.30.0" "grpc/grpc": "~1.30.0"
} }
``` ```

@ -22,7 +22,10 @@ import os
try: try:
BUILD_EXT_COMPILER_JOBS = int( BUILD_EXT_COMPILER_JOBS = int(
os.environ.get('GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS', '1')) os.environ['GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS'])
except KeyError:
import multiprocessing
BUILD_EXT_COMPILER_JOBS = multiprocessing.cpu_count()
except ValueError: except ValueError:
BUILD_EXT_COMPILER_JOBS = 1 BUILD_EXT_COMPILER_JOBS = 1

@ -13,6 +13,8 @@
# limitations under the License. # limitations under the License.
"""Provides distutils command classes for the GRPC Python setup process.""" """Provides distutils command classes for the GRPC Python setup process."""
from __future__ import print_function
import distutils import distutils
import glob import glob
import os import os
@ -290,3 +292,41 @@ class Gather(setuptools.Command):
self.distribution.install_requires) self.distribution.install_requires)
if self.test and self.distribution.tests_require: if self.test and self.distribution.tests_require:
self.distribution.fetch_build_eggs(self.distribution.tests_require) self.distribution.fetch_build_eggs(self.distribution.tests_require)
class Clean(setuptools.Command):
"""Command to clean build artifacts."""
description = 'Clean build artifacts.'
user_options = []
_FILE_PATTERNS = (
'python_build',
'src/python/grpcio/__pycache__/',
'src/python/grpcio/grpc/_cython/cygrpc.cpp',
'src/python/grpcio/grpc/_cython/*.so',
'src/python/grpcio/grpcio.egg-info/',
)
_CURRENT_DIRECTORY = os.path.normpath(
os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../.."))
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
for path_spec in self._FILE_PATTERNS:
this_glob = os.path.normpath(
os.path.join(Clean._CURRENT_DIRECTORY, path_spec))
abs_paths = glob.glob(this_glob)
for path in abs_paths:
if not str(path).startswith(Clean._CURRENT_DIRECTORY):
raise ValueError(
"Cowardly refusing to delete {}.".format(path))
print("Removing {}".format(os.path.relpath(path)))
if os.path.isfile(path):
os.remove(str(path))
else:
shutil.rmtree(str(path))

@ -71,6 +71,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/retry_throttle.cc', 'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/server_address.cc', 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/service_config.cc',
'src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc',
'src/core/ext/filters/client_channel/service_config_parser.cc', 'src/core/ext/filters/client_channel/service_config_parser.cc',
'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc',

@ -0,0 +1,153 @@
#!/usr/bin/env ruby
#
# Copyright 2016 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
this_dir = File.expand_path(File.dirname(__FILE__))
protos_lib_dir = File.join(this_dir, 'lib')
grpc_lib_dir = File.join(File.dirname(this_dir), 'lib')
$LOAD_PATH.unshift(grpc_lib_dir) unless $LOAD_PATH.include?(grpc_lib_dir)
$LOAD_PATH.unshift(protos_lib_dir) unless $LOAD_PATH.include?(protos_lib_dir)
$LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir)
require 'grpc'
require 'end2end_common'
def create_channel_creds
test_root = File.join(File.dirname(__FILE__), '..', 'spec', 'testdata')
files = ['ca.pem', 'client.key', 'client.pem']
creds = files.map { |f| File.open(File.join(test_root, f)).read }
GRPC::Core::ChannelCredentials.new(creds[0], creds[1], creds[2])
end
def client_cert
test_root = File.join(File.dirname(__FILE__), '..', 'spec', 'testdata')
cert = File.open(File.join(test_root, 'client.pem')).read
fail unless cert.is_a?(String)
cert
end
def create_server_creds
test_root = File.join(File.dirname(__FILE__), '..', 'spec', 'testdata')
GRPC.logger.info("test root: #{test_root}")
files = ['ca.pem', 'server1.key', 'server1.pem']
creds = files.map { |f| File.open(File.join(test_root, f)).read }
GRPC::Core::ServerCredentials.new(
creds[0],
[{ private_key: creds[1], cert_chain: creds[2] }],
true) # force client auth
end
# Useful to update a value within a do block
class MutableValue
attr_accessor :value
def initialize(value)
@value = value
end
end
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def main
server_runner = ServerRunner.new(EchoServerImpl)
server_runner.server_creds = create_server_creds
server_port = server_runner.run
channel_args = {
GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr'
}
token_fetch_attempts = MutableValue.new(0)
token_fetch_attempts_mu = Mutex.new
jwt_aud_uri_extraction_success_count = MutableValue.new(0)
jwt_aud_uri_extraction_success_count_mu = Mutex.new
expected_jwt_aud_uri = 'https://foo.test.google.fr/echo.EchoServer'
jwt_aud_uri_failure_values = []
times_out_first_time_auth_proc = proc do |args|
# We check the value of jwt_aud_uri not necessarily as a test for
# the correctness of jwt_aud_uri w.r.t. its expected semantics, but
# more for as an indirect way to check for memory corruption.
jwt_aud_uri_extraction_success_count_mu.synchronize do
if args[:jwt_aud_uri] == expected_jwt_aud_uri
jwt_aud_uri_extraction_success_count.value += 1
else
jwt_aud_uri_failure_values << args[:jwt_aud_uri]
end
end
token_fetch_attempts_mu.synchronize do
old_val = token_fetch_attempts.value
token_fetch_attempts.value += 1
if old_val.zero?
STDERR.puts 'call creds plugin sleeping for 4 seconds'
sleep 4
STDERR.puts 'call creds plugin done with 4 second sleep'
raise 'test exception thrown purposely from call creds plugin'
end
end
{ 'authorization' => 'fake_val' }.merge(args)
end
channel_creds = create_channel_creds.compose(
GRPC::Core::CallCredentials.new(times_out_first_time_auth_proc))
stub = Echo::EchoServer::Stub.new("localhost:#{server_port}",
channel_creds,
channel_args: channel_args)
STDERR.puts 'perform a first few RPCs to try to get things into a bad state...'
threads = []
got_at_least_one_failure = MutableValue.new(false)
2000.times do
threads << Thread.new do
begin
# 2 seconds is chosen as deadline here because it is less than the 4 second
# sleep that the first call creds user callback does. The idea here is that
# a lot of RPCs will be made concurrently all with 2 second deadlines, and they
# will all queue up onto the call creds user callback thread, and will all
# have to wait for the first 4 second sleep to finish. When the deadlines
# of the associated calls fire ~2 seconds in, some of their C-core data
# will have ownership dropped, and they will hit the user-after-free in
# https://github.com/grpc/grpc/issues/19195 if this isn't handled correctly.
stub.echo(Echo::EchoRequest.new(request: 'hello'), deadline: Time.now + 2)
rescue GRPC::BadStatus
got_at_least_one_failure.value = true
# We don't care if these RPCs succeed or fail. The purpose of these
# RPCs is just to try to induce a specific use-after-free bug, and to get
# the call credentials callback thread into a bad state.
end
end
end
threads.each(&:join)
unless got_at_least_one_failure.value
fail 'expected at least one of the initial RPCs to fail'
end
# Expect three more RPCs to succeed
STDERR.puts 'now perform another RPC and expect OK...'
stub.echo(Echo::EchoRequest.new(request: 'hello'), deadline: Time.now + 10)
STDERR.puts 'now perform another RPC and expect OK...'
stub.echo(Echo::EchoRequest.new(request: 'hello'), deadline: Time.now + 10)
STDERR.puts 'now perform another RPC and expect OK...'
stub.echo(Echo::EchoRequest.new(request: 'hello'), deadline: Time.now + 10)
jwt_aud_uri_extraction_success_count_mu.synchronize do
if jwt_aud_uri_extraction_success_count.value != 2003
fail "Expected to get jwt_aud_uri:#{expected_jwt_aud_uri} passed to call creds
user callback 2003 times, but it was only passed to the call creds user callback
#{jwt_aud_uri_extraction_success_count.value} times. This suggests that either:
a) the expected jwt_aud_uri value is incorrect
b) there is some corruption of the jwt_aud_uri argument
Here are are the values of the jwt_aud_uri parameter that were passed to the call
creds user callback that did not match #{expected_jwt_aud_uri}:
#{jwt_aud_uri_failure_values}"
end
end
server_runner.stop
end
main

@ -43,14 +43,17 @@ end
# ServerRunner starts an "echo server" that test clients can make calls to # ServerRunner starts an "echo server" that test clients can make calls to
class ServerRunner class ServerRunner
attr_accessor :server_creds
def initialize(service_impl, rpc_server_args: {}) def initialize(service_impl, rpc_server_args: {})
@service_impl = service_impl @service_impl = service_impl
@rpc_server_args = rpc_server_args @rpc_server_args = rpc_server_args
@server_creds = :this_port_is_insecure
end end
def run def run
@srv = new_rpc_server_for_testing(@rpc_server_args) @srv = new_rpc_server_for_testing(@rpc_server_args)
port = @srv.add_http2_port('0.0.0.0:0', :this_port_is_insecure) port = @srv.add_http2_port('0.0.0.0:0', @server_creds)
@srv.handle(@service_impl) @srv.handle(@service_impl)
@thd = Thread.new do @thd = Thread.new do

@ -56,6 +56,28 @@ typedef struct callback_params {
static VALUE grpc_rb_call_credentials_callback(VALUE callback_args) { static VALUE grpc_rb_call_credentials_callback(VALUE callback_args) {
VALUE result = rb_hash_new(); VALUE result = rb_hash_new();
if (gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
VALUE callback_args_as_str =
rb_funcall(callback_args, rb_intern("to_s"), 0);
VALUE callback_source_info = rb_funcall(rb_ary_entry(callback_args, 0),
rb_intern("source_location"), 0);
if (callback_source_info != Qnil) {
VALUE source_filename = rb_ary_entry(callback_source_info, 0);
VALUE source_line_number = rb_funcall(
rb_ary_entry(callback_source_info, 1), rb_intern("to_s"), 0);
gpr_log(GPR_DEBUG,
"GRPC_RUBY: grpc_rb_call_credentials invoking user callback "
"(source_filename:%s line_number:%s) with arguments:%s",
StringValueCStr(source_filename),
StringValueCStr(source_line_number),
StringValueCStr(callback_args_as_str));
} else {
gpr_log(GPR_DEBUG,
"GRPC_RUBY: grpc_rb_call_credentials invoking user callback "
"(failed to get source filename ane line) with arguments:%s",
StringValueCStr(callback_args_as_str));
}
}
VALUE metadata = rb_funcall(rb_ary_entry(callback_args, 0), rb_intern("call"), VALUE metadata = rb_funcall(rb_ary_entry(callback_args, 0), rb_intern("call"),
1, rb_ary_entry(callback_args, 1)); 1, rb_ary_entry(callback_args, 1));
rb_hash_aset(result, rb_str_new2("metadata"), metadata); rb_hash_aset(result, rb_str_new2("metadata"), metadata);
@ -109,6 +131,7 @@ static void grpc_rb_call_credentials_callback_with_gil(void* param) {
params->callback(params->user_data, md_ary.metadata, md_ary.count, status, params->callback(params->user_data, md_ary.metadata, md_ary.count, status,
error_details); error_details);
grpc_rb_metadata_array_destroy_including_entries(&md_ary); grpc_rb_metadata_array_destroy_including_entries(&md_ary);
grpc_auth_metadata_context_reset(&params->context);
gpr_free(params); gpr_free(params);
} }
@ -118,9 +141,9 @@ static int grpc_rb_call_credentials_plugin_get_metadata(
grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX],
size_t* num_creds_md, grpc_status_code* status, size_t* num_creds_md, grpc_status_code* status,
const char** error_details) { const char** error_details) {
callback_params* params = gpr_malloc(sizeof(callback_params)); callback_params* params = gpr_zalloc(sizeof(callback_params));
params->get_metadata = (VALUE)state; params->get_metadata = (VALUE)state;
params->context = context; grpc_auth_metadata_context_copy(&context, &params->context);
params->user_data = user_data; params->user_data = user_data;
params->callback = cb; params->callback = cb;

@ -135,6 +135,8 @@ grpc_google_refresh_token_credentials_create_type grpc_google_refresh_token_cred
grpc_access_token_credentials_create_type grpc_access_token_credentials_create_import; grpc_access_token_credentials_create_type grpc_access_token_credentials_create_import;
grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import; grpc_google_iam_credentials_create_type grpc_google_iam_credentials_create_import;
grpc_sts_credentials_create_type grpc_sts_credentials_create_import; grpc_sts_credentials_create_type grpc_sts_credentials_create_import;
grpc_auth_metadata_context_copy_type grpc_auth_metadata_context_copy_import;
grpc_auth_metadata_context_reset_type grpc_auth_metadata_context_reset_import;
grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import; grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import;
grpc_secure_channel_create_type grpc_secure_channel_create_import; grpc_secure_channel_create_type grpc_secure_channel_create_import;
grpc_server_credentials_release_type grpc_server_credentials_release_import; grpc_server_credentials_release_type grpc_server_credentials_release_import;
@ -407,6 +409,8 @@ void grpc_rb_load_imports(HMODULE library) {
grpc_access_token_credentials_create_import = (grpc_access_token_credentials_create_type) GetProcAddress(library, "grpc_access_token_credentials_create"); grpc_access_token_credentials_create_import = (grpc_access_token_credentials_create_type) GetProcAddress(library, "grpc_access_token_credentials_create");
grpc_google_iam_credentials_create_import = (grpc_google_iam_credentials_create_type) GetProcAddress(library, "grpc_google_iam_credentials_create"); grpc_google_iam_credentials_create_import = (grpc_google_iam_credentials_create_type) GetProcAddress(library, "grpc_google_iam_credentials_create");
grpc_sts_credentials_create_import = (grpc_sts_credentials_create_type) GetProcAddress(library, "grpc_sts_credentials_create"); grpc_sts_credentials_create_import = (grpc_sts_credentials_create_type) GetProcAddress(library, "grpc_sts_credentials_create");
grpc_auth_metadata_context_copy_import = (grpc_auth_metadata_context_copy_type) GetProcAddress(library, "grpc_auth_metadata_context_copy");
grpc_auth_metadata_context_reset_import = (grpc_auth_metadata_context_reset_type) GetProcAddress(library, "grpc_auth_metadata_context_reset");
grpc_metadata_credentials_create_from_plugin_import = (grpc_metadata_credentials_create_from_plugin_type) GetProcAddress(library, "grpc_metadata_credentials_create_from_plugin"); grpc_metadata_credentials_create_from_plugin_import = (grpc_metadata_credentials_create_from_plugin_type) GetProcAddress(library, "grpc_metadata_credentials_create_from_plugin");
grpc_secure_channel_create_import = (grpc_secure_channel_create_type) GetProcAddress(library, "grpc_secure_channel_create"); grpc_secure_channel_create_import = (grpc_secure_channel_create_type) GetProcAddress(library, "grpc_secure_channel_create");
grpc_server_credentials_release_import = (grpc_server_credentials_release_type) GetProcAddress(library, "grpc_server_credentials_release"); grpc_server_credentials_release_import = (grpc_server_credentials_release_type) GetProcAddress(library, "grpc_server_credentials_release");

@ -380,6 +380,12 @@ extern grpc_google_iam_credentials_create_type grpc_google_iam_credentials_creat
typedef grpc_call_credentials*(*grpc_sts_credentials_create_type)(const grpc_sts_credentials_options* options, void* reserved); typedef grpc_call_credentials*(*grpc_sts_credentials_create_type)(const grpc_sts_credentials_options* options, void* reserved);
extern grpc_sts_credentials_create_type grpc_sts_credentials_create_import; extern grpc_sts_credentials_create_type grpc_sts_credentials_create_import;
#define grpc_sts_credentials_create grpc_sts_credentials_create_import #define grpc_sts_credentials_create grpc_sts_credentials_create_import
typedef void(*grpc_auth_metadata_context_copy_type)(grpc_auth_metadata_context* from, grpc_auth_metadata_context* to);
extern grpc_auth_metadata_context_copy_type grpc_auth_metadata_context_copy_import;
#define grpc_auth_metadata_context_copy grpc_auth_metadata_context_copy_import
typedef void(*grpc_auth_metadata_context_reset_type)(grpc_auth_metadata_context* context);
extern grpc_auth_metadata_context_reset_type grpc_auth_metadata_context_reset_import;
#define grpc_auth_metadata_context_reset grpc_auth_metadata_context_reset_import
typedef grpc_call_credentials*(*grpc_metadata_credentials_create_from_plugin_type)(grpc_metadata_credentials_plugin plugin, grpc_security_level min_security_level, void* reserved); typedef grpc_call_credentials*(*grpc_metadata_credentials_create_from_plugin_type)(grpc_metadata_credentials_plugin plugin, grpc_security_level min_security_level, void* reserved);
extern grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import; extern grpc_metadata_credentials_create_from_plugin_type grpc_metadata_credentials_create_from_plugin_import;
#define grpc_metadata_credentials_create_from_plugin grpc_metadata_credentials_create_from_plugin_import #define grpc_metadata_credentials_create_from_plugin grpc_metadata_credentials_create_from_plugin_import

@ -17,12 +17,18 @@ require 'spec_helper'
# A test message # A test message
class EchoMsg class EchoMsg
def self.marshal(_o) attr_reader :msg
''
def initialize(msg: '')
@msg = msg
end end
def self.unmarshal(_o) def self.marshal(o)
EchoMsg.new o.msg
end
def self.unmarshal(msg)
EchoMsg.new(msg: msg)
end end
end end

@ -29,6 +29,7 @@
#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/metadata.h"
#include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/cq_verifier.h"
@ -466,6 +467,328 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
grpc_byte_buffer_destroy(response_payload); grpc_byte_buffer_destroy(response_payload);
grpc_byte_buffer_destroy(recv_payload); grpc_byte_buffer_destroy(recv_payload);
grpc_call_unref(c);
if (s != nullptr) grpc_call_unref(s);
cq_verifier_destroy(cqv);
end_test(&f);
config.tear_down_data(&f);
}
static grpc_metadata gzip_compression_override() {
grpc_metadata gzip_compression_override;
gzip_compression_override.key = GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST;
gzip_compression_override.value = grpc_slice_from_static_string("gzip");
memset(&gzip_compression_override.internal_data, 0,
sizeof(gzip_compression_override.internal_data));
return gzip_compression_override;
}
// Test receive message limit with compressed request larger than the limit
static void test_max_receive_message_length_on_compressed_request(
grpc_end2end_test_config config, bool minimal_stack) {
gpr_log(GPR_INFO,
"test max receive message length on compressed request with "
"minimal_stack=%d",
minimal_stack);
grpc_end2end_test_fixture f;
grpc_call* c = nullptr;
grpc_call* s = nullptr;
cq_verifier* cqv;
grpc_op ops[6];
grpc_op* op;
grpc_slice request_payload_slice = grpc_slice_malloc(1024);
memset(GRPC_SLICE_START_PTR(request_payload_slice), 'a', 1024);
grpc_byte_buffer* request_payload =
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_byte_buffer* recv_payload = nullptr;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
grpc_slice details, status_details;
int was_cancelled = 2;
// Set limit via channel args.
grpc_arg arg[2];
arg[0] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH), 5);
arg[1] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MINIMAL_STACK), minimal_stack);
grpc_channel_args* server_args =
grpc_channel_args_copy_and_add(nullptr, arg, 2);
f = begin_test(config, "test_max_request_message_length", nullptr,
server_args);
{
grpc_core::ExecCtx exec_ctx;
grpc_channel_args_destroy(server_args);
}
cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
grpc_slice_from_static_string("/service/method"),
nullptr, gpr_inf_future(GPR_CLOCK_REALTIME),
nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
grpc_metadata compression_md = gzip_compression_override();
memset(ops, 0, sizeof(ops));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 1;
op->data.send_initial_metadata.metadata = &compression_md;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message.send_message = request_payload;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->flags = 0;
op->reserved = nullptr;
op++;
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
nullptr);
GPR_ASSERT(GRPC_CALL_OK == error);
error =
grpc_server_request_call(f.server, &s, &call_details,
&request_metadata_recv, f.cq, f.cq, tag(101));
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
cq_verify(cqv);
memset(ops, 0, sizeof(ops));
op = ops;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message.recv_message = &recv_payload;
op->flags = 0;
op->reserved = nullptr;
op++;
if (minimal_stack) {
/* Expect the RPC to proceed normally for a minimal stack */
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
status_details = grpc_slice_from_static_string("xyz");
op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = nullptr;
op++;
}
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
nullptr);
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
cq_verify(cqv);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
if (minimal_stack) {
/* We do not perform message size checks for minimal stack. */
GPR_ASSERT(status == GRPC_STATUS_OK);
} else {
GPR_ASSERT(was_cancelled == 1);
GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
GPR_ASSERT(grpc_slice_str_cmp(
details, "Received message larger than max (29 vs. 5)") ==
0);
}
grpc_slice_unref(details);
grpc_slice_unref(request_payload_slice);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_byte_buffer_destroy(request_payload);
grpc_byte_buffer_destroy(recv_payload);
grpc_call_unref(c);
if (s != nullptr) grpc_call_unref(s);
cq_verifier_destroy(cqv);
end_test(&f);
config.tear_down_data(&f);
}
// Test receive message limit with compressed response larger than the limit.
static void test_max_receive_message_length_on_compressed_response(
grpc_end2end_test_config config, bool minimal_stack) {
gpr_log(GPR_INFO,
"testing max receive message length on compressed response with "
"minimal_stack=%d",
minimal_stack);
grpc_end2end_test_fixture f;
grpc_call* c = nullptr;
grpc_call* s = nullptr;
cq_verifier* cqv;
grpc_op ops[6];
grpc_op* op;
grpc_slice response_payload_slice = grpc_slice_malloc(1024);
memset(GRPC_SLICE_START_PTR(response_payload_slice), 'a', 1024);
grpc_byte_buffer* response_payload =
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
grpc_byte_buffer* recv_payload = nullptr;
grpc_metadata_array initial_metadata_recv;
grpc_metadata_array trailing_metadata_recv;
grpc_metadata_array request_metadata_recv;
grpc_call_details call_details;
grpc_status_code status;
grpc_call_error error;
grpc_slice details;
int was_cancelled = 2;
// Set limit via channel args.
grpc_arg arg[2];
arg[0] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH), 5);
arg[1] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MINIMAL_STACK), minimal_stack);
grpc_channel_args* client_args =
grpc_channel_args_copy_and_add(nullptr, arg, 2);
f = begin_test(config, "test_max_response_message_length", client_args,
nullptr);
{
grpc_core::ExecCtx exec_ctx;
grpc_channel_args_destroy(client_args);
}
cqv = cq_verifier_create(f.cq);
c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
grpc_slice_from_static_string("/service/method"),
nullptr, gpr_inf_future(GPR_CLOCK_REALTIME),
nullptr);
GPR_ASSERT(c);
grpc_metadata_array_init(&initial_metadata_recv);
grpc_metadata_array_init(&trailing_metadata_recv);
grpc_metadata_array_init(&request_metadata_recv);
grpc_call_details_init(&call_details);
memset(ops, 0, sizeof(ops));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 0;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message.recv_message = &recv_payload;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
op->data.recv_status_on_client.status = &status;
op->data.recv_status_on_client.status_details = &details;
op->flags = 0;
op->reserved = nullptr;
op++;
error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
nullptr);
GPR_ASSERT(GRPC_CALL_OK == error);
error =
grpc_server_request_call(f.server, &s, &call_details,
&request_metadata_recv, f.cq, f.cq, tag(101));
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
cq_verify(cqv);
grpc_metadata compression_md = gzip_compression_override();
memset(ops, 0, sizeof(ops));
op = ops;
op->op = GRPC_OP_SEND_INITIAL_METADATA;
op->data.send_initial_metadata.count = 1;
op->data.send_initial_metadata.metadata = &compression_md;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
op->data.recv_close_on_server.cancelled = &was_cancelled;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message.send_message = response_payload;
op->flags = 0;
op->reserved = nullptr;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = 0;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
grpc_slice status_details = grpc_slice_from_static_string("xyz");
op->data.send_status_from_server.status_details = &status_details;
op->flags = 0;
op->reserved = nullptr;
op++;
error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
nullptr);
GPR_ASSERT(GRPC_CALL_OK == error);
CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
cq_verify(cqv);
GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
if (minimal_stack) {
/* We do not perform message size checks for minimal stack. */
GPR_ASSERT(status == GRPC_STATUS_OK);
} else {
GPR_ASSERT(status == GRPC_STATUS_RESOURCE_EXHAUSTED);
GPR_ASSERT(grpc_slice_str_cmp(
details, "Received message larger than max (29 vs. 5)") ==
0);
}
grpc_slice_unref(details);
grpc_slice_unref(response_payload_slice);
grpc_metadata_array_destroy(&initial_metadata_recv);
grpc_metadata_array_destroy(&trailing_metadata_recv);
grpc_metadata_array_destroy(&request_metadata_recv);
grpc_call_details_destroy(&call_details);
grpc_byte_buffer_destroy(response_payload);
grpc_byte_buffer_destroy(recv_payload);
grpc_call_unref(c); grpc_call_unref(c);
if (s != nullptr) grpc_call_unref(s); if (s != nullptr) grpc_call_unref(s);
@ -500,6 +823,15 @@ void max_message_length(grpc_end2end_test_config config) {
test_max_message_length_on_response(config, false /* send_limit */, test_max_message_length_on_response(config, false /* send_limit */,
true /* use_service_config */, true /* use_service_config */,
true /* use_string_json_value */); true /* use_string_json_value */);
/* The following tests are not useful for inproc transport and do not work
* with our simple proxy. */
if (strcmp(config.name, "inproc") != 0 &&
(config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) == 0) {
test_max_receive_message_length_on_compressed_request(config, false);
test_max_receive_message_length_on_compressed_request(config, true);
test_max_receive_message_length_on_compressed_response(config, false);
test_max_receive_message_length_on_compressed_response(config, true);
}
} }
void max_message_length_pre_init(void) {} void max_message_length_pre_init(void) {}

@ -472,16 +472,13 @@ static void test_spiffe_id_peer_to_auth_context(void) {
GPR_ASSERT(check_spiffe_id(invalid_ctx.get(), nullptr, false)); GPR_ASSERT(check_spiffe_id(invalid_ctx.get(), nullptr, false));
tsi_peer_destruct(&invalid_peer); tsi_peer_destruct(&invalid_peer);
invalid_ctx.reset(DEBUG_LOCATION, "test"); invalid_ctx.reset(DEBUG_LOCATION, "test");
// A valid SPIFFE ID with other URI fields should be plumbed. // A valid SPIFFE ID should be plumbed.
tsi_peer valid_peer; tsi_peer valid_peer;
std::vector<std::string> valid_spiffe_id = {"spiffe://foo.bar.com/wl", std::string valid_spiffe_id = "spiffe://foo.bar.com/wl";
"https://xyz"}; GPR_ASSERT(tsi_construct_peer(1, &valid_peer) == TSI_OK);
GPR_ASSERT(tsi_construct_peer(valid_spiffe_id.size(), &valid_peer) == TSI_OK);
for (i = 0; i < valid_spiffe_id.size(); i++) {
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_X509_URI_PEER_PROPERTY, valid_spiffe_id[i].c_str(), TSI_X509_URI_PEER_PROPERTY, valid_spiffe_id.c_str(),
&valid_peer.properties[i]) == TSI_OK); &valid_peer.properties[0]) == TSI_OK);
}
grpc_core::RefCountedPtr<grpc_auth_context> valid_ctx = grpc_core::RefCountedPtr<grpc_auth_context> valid_ctx =
grpc_ssl_peer_to_auth_context(&valid_peer, grpc_ssl_peer_to_auth_context(&valid_peer,
GRPC_SSL_TRANSPORT_SECURITY_TYPE); GRPC_SSL_TRANSPORT_SECURITY_TYPE);
@ -507,6 +504,25 @@ static void test_spiffe_id_peer_to_auth_context(void) {
GPR_ASSERT(check_spiffe_id(multiple_ctx.get(), nullptr, false)); GPR_ASSERT(check_spiffe_id(multiple_ctx.get(), nullptr, false));
tsi_peer_destruct(&multiple_peer); tsi_peer_destruct(&multiple_peer);
multiple_ctx.reset(DEBUG_LOCATION, "test"); multiple_ctx.reset(DEBUG_LOCATION, "test");
// A valid SPIFFE certificate should only has one URI SAN field.
// SPIFFE ID should not be plumbed if there are multiple URIs.
tsi_peer multiple_uri_peer;
std::vector<std::string> multiple_uri = {"spiffe://foo.bar.com/wl",
"https://xyz", "ssh://foo.bar.com/"};
GPR_ASSERT(tsi_construct_peer(multiple_uri.size(), &multiple_uri_peer) ==
TSI_OK);
for (i = 0; i < multiple_spiffe_id.size(); i++) {
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_X509_URI_PEER_PROPERTY, multiple_uri[i].c_str(),
&multiple_uri_peer.properties[i]) == TSI_OK);
}
grpc_core::RefCountedPtr<grpc_auth_context> multiple_uri_ctx =
grpc_ssl_peer_to_auth_context(&multiple_uri_peer,
GRPC_SSL_TRANSPORT_SECURITY_TYPE);
GPR_ASSERT(multiple_uri_ctx != nullptr);
GPR_ASSERT(check_spiffe_id(multiple_uri_ctx.get(), nullptr, false));
tsi_peer_destruct(&multiple_uri_peer);
multiple_uri_ctx.reset(DEBUG_LOCATION, "test");
} }
static const char* roots_for_override_api = "roots for override api"; static const char* roots_for_override_api = "roots for override api";

@ -179,6 +179,8 @@ int main(int argc, char **argv) {
printf("%lx", (unsigned long) grpc_access_token_credentials_create); printf("%lx", (unsigned long) grpc_access_token_credentials_create);
printf("%lx", (unsigned long) grpc_google_iam_credentials_create); printf("%lx", (unsigned long) grpc_google_iam_credentials_create);
printf("%lx", (unsigned long) grpc_sts_credentials_create); printf("%lx", (unsigned long) grpc_sts_credentials_create);
printf("%lx", (unsigned long) grpc_auth_metadata_context_copy);
printf("%lx", (unsigned long) grpc_auth_metadata_context_reset);
printf("%lx", (unsigned long) grpc_metadata_credentials_create_from_plugin); printf("%lx", (unsigned long) grpc_metadata_credentials_create_from_plugin);
printf("%lx", (unsigned long) grpc_secure_channel_create); printf("%lx", (unsigned long) grpc_secure_channel_create);
printf("%lx", (unsigned long) grpc_server_credentials_release); printf("%lx", (unsigned long) grpc_server_credentials_release);

@ -895,6 +895,7 @@ void ssl_tsi_test_extract_x509_subject_names() {
GPR_ASSERT(check_subject_alt_name(&peer, "foo.test.domain.com") == 1); GPR_ASSERT(check_subject_alt_name(&peer, "foo.test.domain.com") == 1);
GPR_ASSERT(check_subject_alt_name(&peer, "bar.test.domain.com") == 1); GPR_ASSERT(check_subject_alt_name(&peer, "bar.test.domain.com") == 1);
// Check URI // Check URI
// Note that a valid SPIFFE certificate should only have one URI.
GPR_ASSERT(check_subject_alt_name(&peer, "spiffe://foo.com/bar/baz") == 1); GPR_ASSERT(check_subject_alt_name(&peer, "spiffe://foo.com/bar/baz") == 1);
GPR_ASSERT( GPR_ASSERT(
check_subject_alt_name(&peer, "https://foo.test.domain.com/test") == 1); check_subject_alt_name(&peer, "https://foo.test.domain.com/test") == 1);

@ -529,9 +529,10 @@ static void BM_IsolatedFilter(benchmark::State& state) {
grpc_call_final_info final_info; grpc_call_final_info final_info;
TestOp test_op_data; TestOp test_op_data;
const int kArenaSize = 4096; const int kArenaSize = 4096;
grpc_call_context_element context[GRPC_CONTEXT_COUNT] = {};
grpc_call_element_args call_args{call_stack, grpc_call_element_args call_args{call_stack,
nullptr, nullptr,
nullptr, context,
method, method,
start_time, start_time,
deadline, deadline,

@ -589,6 +589,7 @@ _BUILD_EXTRA_METADATA = {
'build': 'all', 'build': 'all',
'baselib': True, 'baselib': True,
'secure': True, 'secure': True,
'deps_linkage': 'static',
'dll': True, 'dll': True,
'generate_plugin_registry': True 'generate_plugin_registry': True
}, },
@ -622,6 +623,7 @@ _BUILD_EXTRA_METADATA = {
'grpc_csharp_ext': { 'grpc_csharp_ext': {
'language': 'c', 'language': 'c',
'build': 'all', 'build': 'all',
'deps_linkage': 'static',
'dll': 'only' 'dll': 'only'
}, },
'grpc_unsecure': { 'grpc_unsecure': {
@ -629,6 +631,7 @@ _BUILD_EXTRA_METADATA = {
'build': 'all', 'build': 'all',
'baselib': True, 'baselib': True,
'secure': False, 'secure': False,
'deps_linkage': 'static',
'dll': True, 'dll': True,
'generate_plugin_registry': True 'generate_plugin_registry': True
}, },

@ -0,0 +1,38 @@
#!/bin/bash
# Copyright 2020 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
echo "It's recommended that you run this script from a virtual environment."
set -e
BASEDIR=$(dirname "$0")
BASEDIR=$(realpath "$BASEDIR")/../..
(cd "$BASEDIR";
pip install --upgrade cython;
python setup.py install;
pushd tools/distrib/python/grpcio_tools;
../make_grpcio_tools.py
GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install .
popd;
pushd src/python;
for PACKAGE in ./grpcio_*; do
pushd "${PACKAGE}";
python setup.py preprocess;
python setup.py install;
popd;
done
popd;
)

@ -13,6 +13,7 @@
# limitations under the License. # limitations under the License.
# Docker file for building gRPC manylinux Python artifacts. # Docker file for building gRPC manylinux Python artifacts.
# Updated: 2020-06-25
FROM quay.io/pypa/manylinux2010_x86_64 FROM quay.io/pypa/manylinux2010_x86_64
@ -28,3 +29,4 @@ RUN /opt/python/cp35-cp35m/bin/pip install --upgrade cython
RUN /opt/python/cp36-cp36m/bin/pip install --upgrade cython RUN /opt/python/cp36-cp36m/bin/pip install --upgrade cython
RUN /opt/python/cp37-cp37m/bin/pip install --upgrade cython RUN /opt/python/cp37-cp37m/bin/pip install --upgrade cython
RUN /opt/python/cp38-cp38/bin/pip install --upgrade cython RUN /opt/python/cp38-cp38/bin/pip install --upgrade cython
RUN /opt/python/cp39-cp39/bin/pip install --upgrade cython

@ -13,6 +13,7 @@
# limitations under the License. # limitations under the License.
# Docker file for building gRPC manylinux Python artifacts. # Docker file for building gRPC manylinux Python artifacts.
# Updated: 2020-06-25
FROM quay.io/pypa/manylinux2010_i686 FROM quay.io/pypa/manylinux2010_i686
@ -28,3 +29,4 @@ RUN /opt/python/cp35-cp35m/bin/pip install --upgrade cython
RUN /opt/python/cp36-cp36m/bin/pip install --upgrade cython RUN /opt/python/cp36-cp36m/bin/pip install --upgrade cython
RUN /opt/python/cp37-cp37m/bin/pip install --upgrade cython RUN /opt/python/cp37-cp37m/bin/pip install --upgrade cython
RUN /opt/python/cp38-cp38/bin/pip install --upgrade cython RUN /opt/python/cp38-cp38/bin/pip install --upgrade cython
RUN /opt/python/cp39-cp39/bin/pip install --upgrade cython

@ -0,0 +1,30 @@
# Copyright 2020 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Docker file for building gRPC manylinux Python artifacts.
# Updated: 2020-06-25
FROM quay.io/pypa/manylinux2014_x86_64
# Update the package manager
RUN yum update -y
RUN yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel
###################################
# Install Python build requirements
RUN /opt/python/cp35-cp35m/bin/pip install --upgrade cython
RUN /opt/python/cp36-cp36m/bin/pip install --upgrade cython
RUN /opt/python/cp37-cp37m/bin/pip install --upgrade cython
RUN /opt/python/cp38-cp38/bin/pip install --upgrade cython
RUN /opt/python/cp39-cp39/bin/pip install --upgrade cython

@ -0,0 +1,30 @@
# Copyright 2020 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Docker file for building gRPC manylinux Python artifacts.
# Updated: 2020-06-25
FROM quay.io/pypa/manylinux2014_i686
# Update the package manager
RUN yum update -y
RUN yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel
###################################
# Install Python build requirements
RUN /opt/python/cp35-cp35m/bin/pip install --upgrade cython
RUN /opt/python/cp36-cp36m/bin/pip install --upgrade cython
RUN /opt/python/cp37-cp37m/bin/pip install --upgrade cython
RUN /opt/python/cp38-cp38/bin/pip install --upgrade cython
RUN /opt/python/cp39-cp39/bin/pip install --upgrade cython

@ -1162,6 +1162,7 @@ src/core/ext/filters/client_channel/server_address.h \
src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/service_config.h \ src/core/ext/filters/client_channel/service_config.h \
src/core/ext/filters/client_channel/service_config_call_data.h \ src/core/ext/filters/client_channel/service_config_call_data.h \
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc \
src/core/ext/filters/client_channel/service_config_parser.cc \ src/core/ext/filters/client_channel/service_config_parser.cc \
src/core/ext/filters/client_channel/service_config_parser.h \ src/core/ext/filters/client_channel/service_config_parser.h \
src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.cc \

@ -965,6 +965,7 @@ src/core/ext/filters/client_channel/server_address.h \
src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/service_config.cc \
src/core/ext/filters/client_channel/service_config.h \ src/core/ext/filters/client_channel/service_config.h \
src/core/ext/filters/client_channel/service_config_call_data.h \ src/core/ext/filters/client_channel/service_config_call_data.h \
src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc \
src/core/ext/filters/client_channel/service_config_parser.cc \ src/core/ext/filters/client_channel/service_config_parser.cc \
src/core/ext/filters/client_channel/service_config_parser.h \ src/core/ext/filters/client_channel/service_config_parser.h \
src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel.cc \

@ -105,6 +105,7 @@ LANG_RELEASE_MATRIX = {
('v1.25.0', ReleaseInfo()), ('v1.25.0', ReleaseInfo()),
('v1.26.0', ReleaseInfo()), ('v1.26.0', ReleaseInfo()),
('v1.27.3', ReleaseInfo()), ('v1.27.3', ReleaseInfo()),
('v1.30.0', ReleaseInfo()),
]), ]),
'go': 'go':
OrderedDict([ OrderedDict([
@ -219,8 +220,7 @@ LANG_RELEASE_MATRIX = {
('v1.27.2', ReleaseInfo()), ('v1.27.2', ReleaseInfo()),
('v1.28.1', ReleaseInfo()), ('v1.28.1', ReleaseInfo()),
('v1.29.0', ReleaseInfo()), ('v1.29.0', ReleaseInfo()),
('v1.30.0', ReleaseInfo()), ('v1.30.2', ReleaseInfo()),
('v1.30.1', ReleaseInfo()),
]), ]),
'python': 'python':
OrderedDict([ OrderedDict([
@ -276,6 +276,7 @@ LANG_RELEASE_MATRIX = {
('v1.25.0', ReleaseInfo(runtimes=['python'])), ('v1.25.0', ReleaseInfo(runtimes=['python'])),
('v1.26.0', ReleaseInfo(runtimes=['python'])), ('v1.26.0', ReleaseInfo(runtimes=['python'])),
('v1.27.3', ReleaseInfo(runtimes=['python'])), ('v1.27.3', ReleaseInfo(runtimes=['python'])),
('v1.30.0', ReleaseInfo(runtimes=['python'])),
]), ]),
'node': 'node':
OrderedDict([ OrderedDict([
@ -334,6 +335,7 @@ LANG_RELEASE_MATRIX = {
# go ahead and upload the docker image for new releases. # go ahead and upload the docker image for new releases.
('v1.26.0', ReleaseInfo()), ('v1.26.0', ReleaseInfo()),
('v1.27.3', ReleaseInfo()), ('v1.27.3', ReleaseInfo()),
('v1.30.0', ReleaseInfo()),
]), ]),
'php': 'php':
OrderedDict([ OrderedDict([
@ -365,6 +367,7 @@ LANG_RELEASE_MATRIX = {
('v1.25.0', ReleaseInfo()), ('v1.25.0', ReleaseInfo()),
('v1.26.0', ReleaseInfo()), ('v1.26.0', ReleaseInfo()),
('v1.27.3', ReleaseInfo()), ('v1.27.3', ReleaseInfo()),
('v1.30.0', ReleaseInfo()),
]), ]),
'csharp': 'csharp':
OrderedDict([ OrderedDict([
@ -401,5 +404,6 @@ LANG_RELEASE_MATRIX = {
('v1.25.0', ReleaseInfo()), ('v1.25.0', ReleaseInfo()),
('v1.26.0', ReleaseInfo()), ('v1.26.0', ReleaseInfo()),
('v1.27.3', ReleaseInfo()), ('v1.27.3', ReleaseInfo()),
('v1.30.0', ReleaseInfo()),
]), ]),
} }

@ -203,69 +203,29 @@ def _generate_test_case_jobspecs(lang, runtime, release, suite_name):
return job_spec_list return job_spec_list
def _pull_images_for_lang(lang, images): def _pull_image_for_lang(lang, image, release):
"""Pull all images for given lang from container registry.""" """Pull an image for a given language form the image registry."""
jobset.message('START',
'Downloading images for language "%s"' % lang,
do_newline=True)
download_specs = []
for release, image in images:
# Pull the image and warm it up.
# First time we use an image with "docker run", it takes time to unpack
# the image and later this delay would fail our test cases.
cmdline = [ cmdline = [
'time gcloud docker -- pull %s && time docker run --rm=true %s /bin/true' 'time gcloud docker -- pull %s && time docker run --rm=true %s /bin/true'
% (image, image) % (image, image)
] ]
spec = jobset.JobSpec(cmdline=cmdline, return jobset.JobSpec(cmdline=cmdline,
shortname='pull_image_%s' % (image), shortname='pull_image_{}'.format(image),
timeout_seconds=_PULL_IMAGE_TIMEOUT_SECONDS, timeout_seconds=_PULL_IMAGE_TIMEOUT_SECONDS,
shell=True, shell=True,
flake_retries=2) flake_retries=2)
download_specs.append(spec)
# too many image downloads at once tend to get stuck
max_pull_jobs = min(args.jobs, _MAX_PARALLEL_DOWNLOADS)
num_failures, resultset = jobset.run(download_specs,
newline_on_success=True,
maxjobs=max_pull_jobs)
if num_failures:
jobset.message('FAILED',
'Failed to download some images',
do_newline=True)
return False
else:
jobset.message('SUCCESS',
'All images downloaded successfully.',
do_newline=True)
return True
def _run_tests_for_lang(lang, runtime, images, xml_report_tree): def _test_release(lang, runtime, release, image, xml_report_tree, skip_tests):
"""Find and run all test cases for a language.
images is a list of (<release-tag>, <image-full-path>) tuple.
"""
skip_tests = False
if not _pull_images_for_lang(lang, images):
jobset.message(
'FAILED',
'Image download failed. Skipping tests for language "%s"' % lang,
do_newline=True)
skip_tests = True
total_num_failures = 0 total_num_failures = 0
for release, image in images:
suite_name = '%s__%s_%s' % (lang, runtime, release) suite_name = '%s__%s_%s' % (lang, runtime, release)
job_spec_list = _generate_test_case_jobspecs(lang, runtime, release, job_spec_list = _generate_test_case_jobspecs(lang, runtime, release,
suite_name) suite_name)
if not job_spec_list: if not job_spec_list:
jobset.message('FAILED', jobset.message('FAILED', 'No test cases were found.', do_newline=True)
'No test cases were found.',
do_newline=True)
total_num_failures += 1 total_num_failures += 1
continue else:
num_failures, resultset = jobset.run(job_spec_list, num_failures, resultset = jobset.run(job_spec_list,
newline_on_success=True, newline_on_success=True,
add_env={'docker_image': image}, add_env={'docker_image': image},
@ -277,20 +237,62 @@ def _run_tests_for_lang(lang, runtime, images, xml_report_tree):
if skip_tests: if skip_tests:
jobset.message('FAILED', 'Tests were skipped', do_newline=True) jobset.message('FAILED', 'Tests were skipped', do_newline=True)
total_num_failures += 1 total_num_failures += 1
elif num_failures: if num_failures:
jobset.message('FAILED', 'Some tests failed', do_newline=True)
total_num_failures += num_failures total_num_failures += num_failures
else:
jobset.message('SUCCESS', 'All tests passed', do_newline=True)
report_utils.append_junit_xml_results(xml_report_tree, resultset, report_utils.append_junit_xml_results(xml_report_tree, resultset,
'grpc_interop_matrix', suite_name, 'grpc_interop_matrix', suite_name,
str(uuid.uuid4())) str(uuid.uuid4()))
return total_num_failures
def _run_tests_for_lang(lang, runtime, images, xml_report_tree):
"""Find and run all test cases for a language.
images is a list of (<release-tag>, <image-full-path>) tuple.
"""
skip_tests = False
total_num_failures = 0
# cleanup all downloaded docker images max_pull_jobs = min(args.jobs, _MAX_PARALLEL_DOWNLOADS)
for _, image in images: max_chunk_size = max_pull_jobs
chunk_count = (len(images) + max_chunk_size) // max_chunk_size
for chunk_index in range(chunk_count):
chunk_start = chunk_index * max_chunk_size
chunk_size = min(max_chunk_size, len(images) - chunk_start)
chunk_end = chunk_start + chunk_size
pull_specs = []
if not skip_tests:
for release, image in images[chunk_start:chunk_end]:
pull_specs.append(_pull_image_for_lang(lang, image, release))
# NOTE(rbellevi): We batch docker pull operations to maximize
# parallelism, without letting the disk usage grow unbounded.
pull_failures, _ = jobset.run(pull_specs,
newline_on_success=True,
maxjobs=max_pull_jobs)
if pull_failures:
jobset.message(
'FAILED',
'Image download failed. Skipping tests for language "%s"' %
lang,
do_newline=True)
skip_tests = True
for release, image in images[chunk_start:chunk_end]:
total_num_failures += _test_release(lang, runtime, release, image,
xml_report_tree, skip_tests)
if not args.keep: if not args.keep:
for _, image in images[chunk_start:chunk_end]:
_cleanup_docker_image(image) _cleanup_docker_image(image)
if not total_num_failures:
jobset.message('SUCCESS',
'All {} tests passed'.format(lang),
do_newline=True)
else:
jobset.message('FAILED',
'Some {} tests failed'.format(lang),
do_newline=True)
return total_num_failures return total_num_failures

@ -350,8 +350,20 @@ def targets():
CSharpExtArtifact('linux', 'android', arch_abi='armeabi-v7a'), CSharpExtArtifact('linux', 'android', arch_abi='armeabi-v7a'),
CSharpExtArtifact('linux', 'android', arch_abi='x86'), CSharpExtArtifact('linux', 'android', arch_abi='x86'),
CSharpExtArtifact('macos', 'ios'), CSharpExtArtifact('macos', 'ios'),
# TODO(https://github.com/grpc/grpc/issues/20283) PythonArtifact('manylinux2014', 'x64', 'cp35-cp35m'),
# Add manylinux2010_x86 targets once this issue is resolved. PythonArtifact('manylinux2014', 'x64', 'cp36-cp36m'),
PythonArtifact('manylinux2014', 'x64', 'cp37-cp37m'),
PythonArtifact('manylinux2014', 'x64', 'cp38-cp38'),
PythonArtifact('manylinux2014', 'x86', 'cp35-cp35m'),
PythonArtifact('manylinux2014', 'x86', 'cp36-cp36m'),
PythonArtifact('manylinux2014', 'x86', 'cp37-cp37m'),
PythonArtifact('manylinux2014', 'x86', 'cp38-cp38'),
PythonArtifact('manylinux2010', 'x64', 'cp27-cp27m'),
PythonArtifact('manylinux2010', 'x64', 'cp27-cp27mu'),
PythonArtifact('manylinux2010', 'x64', 'cp35-cp35m'),
PythonArtifact('manylinux2010', 'x64', 'cp36-cp36m'),
PythonArtifact('manylinux2010', 'x64', 'cp37-cp37m'),
PythonArtifact('manylinux2010', 'x64', 'cp38-cp38'),
PythonArtifact('manylinux2010', 'x86', 'cp27-cp27m'), PythonArtifact('manylinux2010', 'x86', 'cp27-cp27m'),
PythonArtifact('manylinux2010', 'x86', 'cp27-cp27mu'), PythonArtifact('manylinux2010', 'x86', 'cp27-cp27mu'),
PythonArtifact('manylinux2010', 'x86', 'cp35-cp35m'), PythonArtifact('manylinux2010', 'x86', 'cp35-cp35m'),
@ -364,12 +376,6 @@ def targets():
PythonArtifact('linux_extra', 'armv6', '2.7'), PythonArtifact('linux_extra', 'armv6', '2.7'),
PythonArtifact('linux_extra', 'armv6', '3.5'), PythonArtifact('linux_extra', 'armv6', '3.5'),
PythonArtifact('linux_extra', 'armv6', '3.6'), PythonArtifact('linux_extra', 'armv6', '3.6'),
PythonArtifact('manylinux2010', 'x64', 'cp27-cp27m'),
PythonArtifact('manylinux2010', 'x64', 'cp27-cp27mu'),
PythonArtifact('manylinux2010', 'x64', 'cp35-cp35m'),
PythonArtifact('manylinux2010', 'x64', 'cp36-cp36m'),
PythonArtifact('manylinux2010', 'x64', 'cp37-cp37m'),
PythonArtifact('manylinux2010', 'x64', 'cp38-cp38'),
PythonArtifact('macos', 'x64', 'python2.7'), PythonArtifact('macos', 'x64', 'python2.7'),
PythonArtifact('macos', 'x64', 'python3.5'), PythonArtifact('macos', 'x64', 'python3.5'),
PythonArtifact('macos', 'x64', 'python3.6'), PythonArtifact('macos', 'x64', 'python3.6'),

@ -35,4 +35,5 @@ time ruby src/ruby/end2end/graceful_sig_stop_driver.rb || EXIT_CODE=1
time ruby src/ruby/end2end/errors_load_before_grpc_lib.rb || EXIT_CODE=1 time ruby src/ruby/end2end/errors_load_before_grpc_lib.rb || EXIT_CODE=1
time ruby src/ruby/end2end/logger_load_before_grpc_lib.rb || EXIT_CODE=1 time ruby src/ruby/end2end/logger_load_before_grpc_lib.rb || EXIT_CODE=1
time ruby src/ruby/end2end/status_codes_load_before_grpc_lib.rb || EXIT_CODE=1 time ruby src/ruby/end2end/status_codes_load_before_grpc_lib.rb || EXIT_CODE=1
time ruby src/ruby/end2end/call_credentials_timeout_driver.rb || EXIT_CODE=1
exit $EXIT_CODE exit $EXIT_CODE

Loading…
Cancel
Save