Merge remote-tracking branch 'upstream/master' into void_cast

pull/7928/head
yang-g 8 years ago
commit 9979b026ab
  1. 54
      BUILD
  2. 66
      CMakeLists.txt
  3. 2
      INSTALL.md
  4. 331
      Makefile
  5. 6
      Rakefile
  6. 3
      binding.gyp
  7. 68
      build.yaml
  8. 3
      config.m4
  9. 16
      doc/fail_fast.md
  10. 14
      doc/wait-for-ready.md
  11. 4
      examples/csharp/.nuget/packages.config
  12. 4
      examples/csharp/helloworld-from-cli/Greeter/project.json
  13. 4
      examples/csharp/helloworld-from-cli/GreeterClient/project.json
  14. 4
      examples/csharp/helloworld-from-cli/GreeterServer/project.json
  15. 10
      examples/csharp/helloworld/Greeter/Greeter.csproj
  16. 10
      examples/csharp/helloworld/Greeter/packages.config
  17. 10
      examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
  18. 8
      examples/csharp/helloworld/GreeterClient/packages.config
  19. 10
      examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
  20. 8
      examples/csharp/helloworld/GreeterServer/packages.config
  21. 2
      examples/csharp/helloworld/generate_protos.bat
  22. 10
      examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
  23. 8
      examples/csharp/route_guide/RouteGuide/packages.config
  24. 10
      examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
  25. 8
      examples/csharp/route_guide/RouteGuideClient/packages.config
  26. 10
      examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
  27. 10
      examples/csharp/route_guide/RouteGuideServer/packages.config
  28. 2
      examples/csharp/route_guide/generate_protos.bat
  29. 2
      examples/node/README.md
  30. 2
      examples/php/run_greeter_client.sh
  31. 57
      examples/python/README.md
  32. 2
      examples/python/helloworld/README.md
  33. 2
      examples/python/multiplex/README.md
  34. 9
      gRPC-Core.podspec
  35. 7
      grpc.gemspec
  36. 2
      include/grpc++/ext/reflection.grpc.pb.h
  37. 4
      include/grpc++/grpc++.h
  38. 6
      include/grpc++/impl/codegen/call.h
  39. 11
      include/grpc++/impl/codegen/client_context.h
  40. 10
      include/grpc++/impl/codegen/completion_queue.h
  41. 64
      include/grpc++/impl/codegen/method_handler_impl.h
  42. 3
      include/grpc++/impl/codegen/rpc_method.h
  43. 1
      include/grpc++/impl/codegen/rpc_service_method.h
  44. 14
      include/grpc++/impl/codegen/server_context.h
  45. 11
      include/grpc++/impl/codegen/service_type.h
  46. 107
      include/grpc++/impl/codegen/sync_stream.h
  47. 5
      include/grpc++/impl/server_builder_plugin.h
  48. 15
      include/grpc/impl/codegen/grpc_types.h
  49. 11
      include/grpc/impl/codegen/port_platform.h
  50. 6
      package.xml
  51. 4
      setup.py
  52. 77
      src/compiler/cpp_generator.cc
  53. 4
      src/core/ext/census/gen/README.md
  54. 81
      src/core/ext/census/gen/trace_context.pb.c
  55. 99
      src/core/ext/census/gen/trace_context.pb.h
  56. 466
      src/core/ext/client_config/client_channel.c
  57. 292
      src/core/ext/client_config/subchannel_call_holder.c
  58. 99
      src/core/ext/client_config/subchannel_call_holder.h
  59. 13
      src/core/ext/transport/chttp2/transport/chttp2_transport.c
  60. 2
      src/core/ext/transport/chttp2/transport/frame.h
  61. 10
      src/core/ext/transport/chttp2/transport/hpack_encoder.c
  62. 1
      src/core/ext/transport/chttp2/transport/hpack_encoder.h
  63. 2
      src/core/ext/transport/chttp2/transport/internal.h
  64. 12
      src/core/ext/transport/chttp2/transport/writing.c
  65. 176
      src/core/lib/channel/http_client_filter.c
  66. 3
      src/core/lib/channel/http_client_filter.h
  67. 79
      src/core/lib/channel/http_server_filter.c
  68. 6
      src/core/lib/security/context/security_context.c
  69. 12
      src/core/lib/security/context/security_context.h
  70. 180
      src/core/lib/support/percent_encoding.c
  71. 78
      src/core/lib/support/percent_encoding.h
  72. 11
      src/core/lib/surface/server.c
  73. 15
      src/core/lib/transport/static_metadata.c
  74. 98
      src/core/lib/transport/static_metadata.h
  75. 1
      src/core/lib/transport/transport.h
  76. 0
      src/cpp/client/channel_cc.cc
  77. 1
      src/cpp/client/client_context.cc
  78. 0
      src/cpp/client/credentials_cc.cc
  79. 0
      src/cpp/common/completion_queue_cc.cc
  80. 15
      src/cpp/server/server_builder.cc
  81. 0
      src/cpp/server/server_cc.cc
  82. 0
      src/cpp/util/byte_buffer_cc.cc
  83. 0
      src/cpp/util/slice_cc.cc
  84. 0
      src/cpp/util/time_cc.cc
  85. 18
      src/csharp/Grpc.Auth/Grpc.Auth.csproj
  86. 7
      src/csharp/Grpc.Auth/packages.config
  87. 9
      src/csharp/Grpc.Auth/project.json
  88. 11
      src/csharp/Grpc.Core.Tests/project.json
  89. 14
      src/csharp/Grpc.Core/GrpcEnvironment.cs
  90. 18
      src/csharp/Grpc.Core/Internal/NativeExtension.cs
  91. 4
      src/csharp/Grpc.Core/project.json
  92. 14
      src/csharp/Grpc.Examples.MathClient/project.json
  93. 14
      src/csharp/Grpc.Examples.MathServer/project.json
  94. 6
      src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
  95. 4
      src/csharp/Grpc.Examples.Tests/packages.config
  96. 11
      src/csharp/Grpc.Examples.Tests/project.json
  97. 7
      src/csharp/Grpc.Examples/Grpc.Examples.csproj
  98. 4
      src/csharp/Grpc.Examples/packages.config
  99. 16
      src/csharp/Grpc.Examples/project.json
  100. 6
      src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
  101. Some files were not shown because too many files have changed in this diff Show More

54
BUILD

@ -52,6 +52,7 @@ cc_library(
"src/core/lib/support/block_annotate.h",
"src/core/lib/support/env.h",
"src/core/lib/support/murmur_hash.h",
"src/core/lib/support/percent_encoding.h",
"src/core/lib/support/stack_lockfree.h",
"src/core/lib/support/string.h",
"src/core/lib/support/string_windows.h",
@ -79,6 +80,7 @@ cc_library(
"src/core/lib/support/log_posix.c",
"src/core/lib/support/log_windows.c",
"src/core/lib/support/murmur_hash.c",
"src/core/lib/support/percent_encoding.c",
"src/core/lib/support/slice.c",
"src/core/lib/support/slice_buffer.c",
"src/core/lib/support/stack_lockfree.c",
@ -299,7 +301,6 @@ cc_library(
"src/core/ext/client_config/resolver_registry.h",
"src/core/ext/client_config/resolver_result.h",
"src/core/ext/client_config/subchannel.h",
"src/core/ext/client_config/subchannel_call_holder.h",
"src/core/ext/client_config/subchannel_index.h",
"src/core/ext/client_config/uri_parser.h",
"src/core/ext/lb_policy/grpclb/grpclb.h",
@ -312,6 +313,7 @@ cc_library(
"src/core/ext/census/census_interface.h",
"src/core/ext/census/census_rpc_stats.h",
"src/core/ext/census/gen/census.pb.h",
"src/core/ext/census/gen/trace_context.pb.h",
"src/core/ext/census/grpc_filter.h",
"src/core/ext/census/mlog.h",
"src/core/ext/census/resource.h",
@ -474,7 +476,6 @@ cc_library(
"src/core/ext/client_config/resolver_registry.c",
"src/core/ext/client_config/resolver_result.c",
"src/core/ext/client_config/subchannel.c",
"src/core/ext/client_config/subchannel_call_holder.c",
"src/core/ext/client_config/subchannel_index.c",
"src/core/ext/client_config/uri_parser.c",
"src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
@ -493,6 +494,7 @@ cc_library(
"src/core/ext/census/base_resources.c",
"src/core/ext/census/context.c",
"src/core/ext/census/gen/census.pb.c",
"src/core/ext/census/gen/trace_context.pb.c",
"src/core/ext/census/grpc_context.c",
"src/core/ext/census/grpc_filter.c",
"src/core/ext/census/grpc_plugin.c",
@ -671,7 +673,6 @@ cc_library(
"src/core/ext/client_config/resolver_registry.h",
"src/core/ext/client_config/resolver_result.h",
"src/core/ext/client_config/subchannel.h",
"src/core/ext/client_config/subchannel_call_holder.h",
"src/core/ext/client_config/subchannel_index.h",
"src/core/ext/client_config/uri_parser.h",
"src/core/lib/security/context/security_context.h",
@ -830,7 +831,6 @@ cc_library(
"src/core/ext/client_config/resolver_registry.c",
"src/core/ext/client_config/resolver_result.c",
"src/core/ext/client_config/subchannel.c",
"src/core/ext/client_config/subchannel_call_holder.c",
"src/core/ext/client_config/subchannel_index.c",
"src/core/ext/client_config/uri_parser.c",
"src/core/lib/http/httpcli_security_connector.c",
@ -1024,7 +1024,6 @@ cc_library(
"src/core/ext/client_config/resolver_registry.h",
"src/core/ext/client_config/resolver_result.h",
"src/core/ext/client_config/subchannel.h",
"src/core/ext/client_config/subchannel_call_holder.h",
"src/core/ext/client_config/subchannel_index.h",
"src/core/ext/client_config/uri_parser.h",
"src/core/ext/load_reporting/load_reporting.h",
@ -1037,6 +1036,7 @@ cc_library(
"src/core/ext/census/census_interface.h",
"src/core/ext/census/census_rpc_stats.h",
"src/core/ext/census/gen/census.pb.h",
"src/core/ext/census/gen/trace_context.pb.h",
"src/core/ext/census/grpc_filter.h",
"src/core/ext/census/mlog.h",
"src/core/ext/census/resource.h",
@ -1174,7 +1174,6 @@ cc_library(
"src/core/ext/client_config/resolver_registry.c",
"src/core/ext/client_config/resolver_result.c",
"src/core/ext/client_config/subchannel.c",
"src/core/ext/client_config/subchannel_call_holder.c",
"src/core/ext/client_config/subchannel_index.c",
"src/core/ext/client_config/uri_parser.c",
"src/core/ext/resolver/dns/native/dns_resolver.c",
@ -1189,6 +1188,7 @@ cc_library(
"src/core/ext/census/base_resources.c",
"src/core/ext/census/context.c",
"src/core/ext/census/gen/census.pb.c",
"src/core/ext/census/gen/trace_context.pb.c",
"src/core/ext/census/grpc_context.c",
"src/core/ext/census/grpc_filter.c",
"src/core/ext/census/grpc_plugin.c",
@ -1337,39 +1337,39 @@ cc_library(
"src/core/lib/transport/timeout_encoding.h",
"src/core/lib/transport/transport.h",
"src/core/lib/transport/transport_impl.h",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/client/secure_credentials.cc",
"src/cpp/common/auth_property_iterator.cc",
"src/cpp/common/secure_auth_context.cc",
"src/cpp/common/secure_channel_arguments.cc",
"src/cpp/common/secure_create_auth_context.cc",
"src/cpp/server/insecure_server_credentials.cc",
"src/cpp/server/secure_server_credentials.cc",
"src/cpp/client/channel.cc",
"src/cpp/client/channel_cc.cc",
"src/cpp/client/client_context.cc",
"src/cpp/client/create_channel.cc",
"src/cpp/client/create_channel_internal.cc",
"src/cpp/client/create_channel_posix.cc",
"src/cpp/client/credentials.cc",
"src/cpp/client/credentials_cc.cc",
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/channel_filter.cc",
"src/cpp/common/completion_queue.cc",
"src/cpp/common/completion_queue_cc.cc",
"src/cpp/common/core_codegen.cc",
"src/cpp/common/rpc_method.cc",
"src/cpp/server/async_generic_service.cc",
"src/cpp/server/create_default_thread_pool.cc",
"src/cpp/server/dynamic_thread_pool.cc",
"src/cpp/server/insecure_server_credentials.cc",
"src/cpp/server/server.cc",
"src/cpp/server/server_builder.cc",
"src/cpp/server/server_cc.cc",
"src/cpp/server/server_context.cc",
"src/cpp/server/server_credentials.cc",
"src/cpp/server/server_posix.cc",
"src/cpp/util/byte_buffer.cc",
"src/cpp/util/slice.cc",
"src/cpp/util/byte_buffer_cc.cc",
"src/cpp/util/slice_cc.cc",
"src/cpp/util/status.cc",
"src/cpp/util/string_ref.cc",
"src/cpp/util/time.cc",
"src/cpp/util/time_cc.cc",
"src/core/lib/channel/channel_args.c",
"src/core/lib/channel/channel_stack.c",
"src/core/lib/channel/channel_stack_builder.c",
@ -1747,34 +1747,34 @@ cc_library(
"src/core/lib/transport/timeout_encoding.h",
"src/core/lib/transport/transport.h",
"src/core/lib/transport/transport_impl.h",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/common/insecure_create_auth_context.cc",
"src/cpp/client/channel.cc",
"src/cpp/server/insecure_server_credentials.cc",
"src/cpp/client/channel_cc.cc",
"src/cpp/client/client_context.cc",
"src/cpp/client/create_channel.cc",
"src/cpp/client/create_channel_internal.cc",
"src/cpp/client/create_channel_posix.cc",
"src/cpp/client/credentials.cc",
"src/cpp/client/credentials_cc.cc",
"src/cpp/client/generic_stub.cc",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/common/channel_arguments.cc",
"src/cpp/common/channel_filter.cc",
"src/cpp/common/completion_queue.cc",
"src/cpp/common/completion_queue_cc.cc",
"src/cpp/common/core_codegen.cc",
"src/cpp/common/rpc_method.cc",
"src/cpp/server/async_generic_service.cc",
"src/cpp/server/create_default_thread_pool.cc",
"src/cpp/server/dynamic_thread_pool.cc",
"src/cpp/server/insecure_server_credentials.cc",
"src/cpp/server/server.cc",
"src/cpp/server/server_builder.cc",
"src/cpp/server/server_cc.cc",
"src/cpp/server/server_context.cc",
"src/cpp/server/server_credentials.cc",
"src/cpp/server/server_posix.cc",
"src/cpp/util/byte_buffer.cc",
"src/cpp/util/slice.cc",
"src/cpp/util/byte_buffer_cc.cc",
"src/cpp/util/slice_cc.cc",
"src/cpp/util/status.cc",
"src/cpp/util/string_ref.cc",
"src/cpp/util/time.cc",
"src/cpp/util/time_cc.cc",
"src/core/lib/channel/channel_args.c",
"src/core/lib/channel/channel_stack.c",
"src/core/lib/channel/channel_stack_builder.c",
@ -2069,6 +2069,7 @@ objc_library(
"src/core/lib/support/log_posix.c",
"src/core/lib/support/log_windows.c",
"src/core/lib/support/murmur_hash.c",
"src/core/lib/support/percent_encoding.c",
"src/core/lib/support/slice.c",
"src/core/lib/support/slice_buffer.c",
"src/core/lib/support/stack_lockfree.c",
@ -2142,6 +2143,7 @@ objc_library(
"src/core/lib/support/block_annotate.h",
"src/core/lib/support/env.h",
"src/core/lib/support/murmur_hash.h",
"src/core/lib/support/percent_encoding.h",
"src/core/lib/support/stack_lockfree.h",
"src/core/lib/support/string.h",
"src/core/lib/support/string_windows.h",
@ -2320,7 +2322,6 @@ objc_library(
"src/core/ext/client_config/resolver_registry.c",
"src/core/ext/client_config/resolver_result.c",
"src/core/ext/client_config/subchannel.c",
"src/core/ext/client_config/subchannel_call_holder.c",
"src/core/ext/client_config/subchannel_index.c",
"src/core/ext/client_config/uri_parser.c",
"src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
@ -2339,6 +2340,7 @@ objc_library(
"src/core/ext/census/base_resources.c",
"src/core/ext/census/context.c",
"src/core/ext/census/gen/census.pb.c",
"src/core/ext/census/gen/trace_context.pb.c",
"src/core/ext/census/grpc_context.c",
"src/core/ext/census/grpc_filter.c",
"src/core/ext/census/grpc_plugin.c",
@ -2519,7 +2521,6 @@ objc_library(
"src/core/ext/client_config/resolver_registry.h",
"src/core/ext/client_config/resolver_result.h",
"src/core/ext/client_config/subchannel.h",
"src/core/ext/client_config/subchannel_call_holder.h",
"src/core/ext/client_config/subchannel_index.h",
"src/core/ext/client_config/uri_parser.h",
"src/core/ext/lb_policy/grpclb/grpclb.h",
@ -2532,6 +2533,7 @@ objc_library(
"src/core/ext/census/census_interface.h",
"src/core/ext/census/census_rpc_stats.h",
"src/core/ext/census/gen/census.pb.h",
"src/core/ext/census/gen/trace_context.pb.h",
"src/core/ext/census/grpc_filter.h",
"src/core/ext/census/mlog.h",
"src/core/ext/census/resource.h",

@ -192,6 +192,7 @@ add_library(gpr
src/core/lib/support/log_posix.c
src/core/lib/support/log_windows.c
src/core/lib/support/murmur_hash.c
src/core/lib/support/percent_encoding.c
src/core/lib/support/slice.c
src/core/lib/support/slice_buffer.c
src/core/lib/support/stack_lockfree.c
@ -448,7 +449,6 @@ add_library(grpc
src/core/ext/client_config/resolver_registry.c
src/core/ext/client_config/resolver_result.c
src/core/ext/client_config/subchannel.c
src/core/ext/client_config/subchannel_call_holder.c
src/core/ext/client_config/subchannel_index.c
src/core/ext/client_config/uri_parser.c
src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
@ -470,6 +470,7 @@ add_library(grpc
src/core/ext/census/base_resources.c
src/core/ext/census/context.c
src/core/ext/census/gen/census.pb.c
src/core/ext/census/gen/trace_context.pb.c
src/core/ext/census/grpc_context.c
src/core/ext/census/grpc_filter.c
src/core/ext/census/grpc_plugin.c
@ -680,7 +681,6 @@ add_library(grpc_cronet
src/core/ext/client_config/resolver_registry.c
src/core/ext/client_config/resolver_result.c
src/core/ext/client_config/subchannel.c
src/core/ext/client_config/subchannel_call_holder.c
src/core/ext/client_config/subchannel_index.c
src/core/ext/client_config/uri_parser.c
src/core/lib/http/httpcli_security_connector.c
@ -912,7 +912,6 @@ add_library(grpc_unsecure
src/core/ext/client_config/resolver_registry.c
src/core/ext/client_config/resolver_result.c
src/core/ext/client_config/subchannel.c
src/core/ext/client_config/subchannel_call_holder.c
src/core/ext/client_config/subchannel_index.c
src/core/ext/client_config/uri_parser.c
src/core/ext/resolver/dns/native/dns_resolver.c
@ -930,6 +929,7 @@ add_library(grpc_unsecure
src/core/ext/census/base_resources.c
src/core/ext/census/context.c
src/core/ext/census/gen/census.pb.c
src/core/ext/census/gen/trace_context.pb.c
src/core/ext/census/grpc_context.c
src/core/ext/census/grpc_filter.c
src/core/ext/census/grpc_plugin.c
@ -1005,39 +1005,39 @@ endif()
add_library(grpc++
src/cpp/client/insecure_credentials.cc
src/cpp/client/secure_credentials.cc
src/cpp/common/auth_property_iterator.cc
src/cpp/common/secure_auth_context.cc
src/cpp/common/secure_channel_arguments.cc
src/cpp/common/secure_create_auth_context.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/secure_server_credentials.cc
src/cpp/client/channel.cc
src/cpp/client/channel_cc.cc
src/cpp/client/client_context.cc
src/cpp/client/create_channel.cc
src/cpp/client/create_channel_internal.cc
src/cpp/client/create_channel_posix.cc
src/cpp/client/credentials.cc
src/cpp/client/credentials_cc.cc
src/cpp/client/generic_stub.cc
src/cpp/client/insecure_credentials.cc
src/cpp/common/channel_arguments.cc
src/cpp/common/channel_filter.cc
src/cpp/common/completion_queue.cc
src/cpp/common/completion_queue_cc.cc
src/cpp/common/core_codegen.cc
src/cpp/common/rpc_method.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/server.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_cc.cc
src/cpp/server/server_context.cc
src/cpp/server/server_credentials.cc
src/cpp/server/server_posix.cc
src/cpp/util/byte_buffer.cc
src/cpp/util/slice.cc
src/cpp/util/byte_buffer_cc.cc
src/cpp/util/slice_cc.cc
src/cpp/util/status.cc
src/cpp/util/string_ref.cc
src/cpp/util/time.cc
src/cpp/util/time_cc.cc
src/core/lib/channel/channel_args.c
src/core/lib/channel/channel_stack.c
src/core/lib/channel/channel_stack_builder.c
@ -1367,34 +1367,34 @@ endif()
add_library(grpc++_unsecure
src/cpp/client/insecure_credentials.cc
src/cpp/common/insecure_create_auth_context.cc
src/cpp/client/channel.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/client/channel_cc.cc
src/cpp/client/client_context.cc
src/cpp/client/create_channel.cc
src/cpp/client/create_channel_internal.cc
src/cpp/client/create_channel_posix.cc
src/cpp/client/credentials.cc
src/cpp/client/credentials_cc.cc
src/cpp/client/generic_stub.cc
src/cpp/client/insecure_credentials.cc
src/cpp/common/channel_arguments.cc
src/cpp/common/channel_filter.cc
src/cpp/common/completion_queue.cc
src/cpp/common/completion_queue_cc.cc
src/cpp/common/core_codegen.cc
src/cpp/common/rpc_method.cc
src/cpp/server/async_generic_service.cc
src/cpp/server/create_default_thread_pool.cc
src/cpp/server/dynamic_thread_pool.cc
src/cpp/server/insecure_server_credentials.cc
src/cpp/server/server.cc
src/cpp/server/server_builder.cc
src/cpp/server/server_cc.cc
src/cpp/server/server_context.cc
src/cpp/server/server_credentials.cc
src/cpp/server/server_posix.cc
src/cpp/util/byte_buffer.cc
src/cpp/util/slice.cc
src/cpp/util/byte_buffer_cc.cc
src/cpp/util/slice_cc.cc
src/cpp/util/status.cc
src/cpp/util/string_ref.cc
src/cpp/util/time.cc
src/cpp/util/time_cc.cc
src/core/lib/channel/channel_args.c
src/core/lib/channel/channel_stack.c
src/core/lib/channel/channel_stack_builder.c
@ -1751,6 +1751,30 @@ if (gRPC_INSTALL)
endif()
add_executable(gen_percent_encoding_tables
tools/codegen/core/gen_percent_encoding_tables.c
)
target_include_directories(gen_percent_encoding_tables
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
)
if (gRPC_INSTALL)
install(TARGETS gen_percent_encoding_tables EXPORT gRPCTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endif()
add_executable(grpc_create_jwt
test/core/security/create_jwt.c
)

@ -9,7 +9,7 @@ refer to these documents
* [Java](https://github.com/grpc/grpc-java)
* [Node](src/node): `npm install grpc`
* [Objective-C](src/objective-c)
* [PHP](src/php): `pecl install grpc-beta`
* [PHP](src/php): `pecl install grpc`
* [Python](src/python/grpcio): `pip install grpcio`
* [Ruby](src/ruby): `gem install grpc`

@ -930,6 +930,7 @@ fling_stream_test: $(BINDIR)/$(CONFIG)/fling_stream_test
fling_test: $(BINDIR)/$(CONFIG)/fling_test
gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables
gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters
gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
goaway_server_test: $(BINDIR)/$(CONFIG)/goaway_server_test
gpr_avl_test: $(BINDIR)/$(CONFIG)/gpr_avl_test
gpr_backoff_test: $(BINDIR)/$(CONFIG)/gpr_backoff_test
@ -939,6 +940,7 @@ gpr_env_test: $(BINDIR)/$(CONFIG)/gpr_env_test
gpr_histogram_test: $(BINDIR)/$(CONFIG)/gpr_histogram_test
gpr_host_port_test: $(BINDIR)/$(CONFIG)/gpr_host_port_test
gpr_log_test: $(BINDIR)/$(CONFIG)/gpr_log_test
gpr_percent_encoding_test: $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test
gpr_slice_buffer_test: $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test
gpr_slice_test: $(BINDIR)/$(CONFIG)/gpr_slice_test
gpr_stack_lockfree_test: $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test
@ -993,6 +995,8 @@ murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test
nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test
nanopb_fuzzer_serverlist_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test
no_server_test: $(BINDIR)/$(CONFIG)/no_server_test
percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer
percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer
resolve_address_test: $(BINDIR)/$(CONFIG)/resolve_address_test
secure_channel_create_test: $(BINDIR)/$(CONFIG)/secure_channel_create_test
secure_endpoint_test: $(BINDIR)/$(CONFIG)/secure_endpoint_test
@ -1118,9 +1122,7 @@ server_registered_method_bad_client_test: $(BINDIR)/$(CONFIG)/server_registered_
simple_request_bad_client_test: $(BINDIR)/$(CONFIG)/simple_request_bad_client_test
unknown_frame_bad_client_test: $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test
window_overflow_bad_client_test: $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test
bad_ssl_alpn_server: $(BINDIR)/$(CONFIG)/bad_ssl_alpn_server
bad_ssl_cert_server: $(BINDIR)/$(CONFIG)/bad_ssl_cert_server
bad_ssl_alpn_test: $(BINDIR)/$(CONFIG)/bad_ssl_alpn_test
bad_ssl_cert_test: $(BINDIR)/$(CONFIG)/bad_ssl_cert_test
h2_census_test: $(BINDIR)/$(CONFIG)/h2_census_test
h2_compress_test: $(BINDIR)/$(CONFIG)/h2_compress_test
@ -1159,6 +1161,8 @@ http_response_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/http_response_fuzzer_te
json_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry
nanopb_fuzzer_response_test_one_entry: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry
nanopb_fuzzer_serverlist_test_one_entry: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry
percent_decode_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry
percent_encode_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry
server_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry
uri_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry
@ -1258,6 +1262,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/gpr_histogram_test \
$(BINDIR)/$(CONFIG)/gpr_host_port_test \
$(BINDIR)/$(CONFIG)/gpr_log_test \
$(BINDIR)/$(CONFIG)/gpr_percent_encoding_test \
$(BINDIR)/$(CONFIG)/gpr_slice_buffer_test \
$(BINDIR)/$(CONFIG)/gpr_slice_test \
$(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test \
@ -1335,9 +1340,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/simple_request_bad_client_test \
$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \
$(BINDIR)/$(CONFIG)/window_overflow_bad_client_test \
$(BINDIR)/$(CONFIG)/bad_ssl_alpn_server \
$(BINDIR)/$(CONFIG)/bad_ssl_cert_server \
$(BINDIR)/$(CONFIG)/bad_ssl_alpn_test \
$(BINDIR)/$(CONFIG)/bad_ssl_cert_test \
$(BINDIR)/$(CONFIG)/h2_census_test \
$(BINDIR)/$(CONFIG)/h2_compress_test \
@ -1376,6 +1379,8 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry \
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry \
$(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry \
$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/server_fuzzer_one_entry \
$(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry \
@ -1592,6 +1597,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/gpr_host_port_test || ( echo test gpr_host_port_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_log_test"
$(Q) $(BINDIR)/$(CONFIG)/gpr_log_test || ( echo test gpr_log_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_percent_encoding_test"
$(Q) $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test || ( echo test gpr_percent_encoding_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_slice_buffer_test"
$(Q) $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test || ( echo test gpr_slice_buffer_test failed ; exit 1 )
$(E) "[RUN] Testing gpr_slice_test"
@ -1732,8 +1739,6 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test || ( echo test unknown_frame_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing window_overflow_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test || ( echo test window_overflow_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing bad_ssl_alpn_test"
$(Q) $(BINDIR)/$(CONFIG)/bad_ssl_alpn_test || ( echo test bad_ssl_alpn_test failed ; exit 1 )
$(E) "[RUN] Testing bad_ssl_cert_test"
$(Q) $(BINDIR)/$(CONFIG)/bad_ssl_cert_test || ( echo test bad_ssl_cert_test failed ; exit 1 )
@ -1825,7 +1830,7 @@ test_python: static_c
tools: tools_c tools_cxx
tools_c: privatelibs_c $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token $(BINDIR)/$(CONFIG)/grpc_verify_jwt
tools_c: privatelibs_c $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token $(BINDIR)/$(CONFIG)/grpc_verify_jwt
tools_cxx: privatelibs_cxx
@ -2374,6 +2379,7 @@ LIBGPR_SRC = \
src/core/lib/support/log_posix.c \
src/core/lib/support/log_windows.c \
src/core/lib/support/murmur_hash.c \
src/core/lib/support/percent_encoding.c \
src/core/lib/support/slice.c \
src/core/lib/support/slice_buffer.c \
src/core/lib/support/stack_lockfree.c \
@ -2664,7 +2670,6 @@ LIBGRPC_SRC = \
src/core/ext/client_config/resolver_registry.c \
src/core/ext/client_config/resolver_result.c \
src/core/ext/client_config/subchannel.c \
src/core/ext/client_config/subchannel_call_holder.c \
src/core/ext/client_config/subchannel_index.c \
src/core/ext/client_config/uri_parser.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
@ -2686,6 +2691,7 @@ LIBGRPC_SRC = \
src/core/ext/census/base_resources.c \
src/core/ext/census/context.c \
src/core/ext/census/gen/census.pb.c \
src/core/ext/census/gen/trace_context.pb.c \
src/core/ext/census/grpc_context.c \
src/core/ext/census/grpc_filter.c \
src/core/ext/census/grpc_plugin.c \
@ -2914,7 +2920,6 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/client_config/resolver_registry.c \
src/core/ext/client_config/resolver_result.c \
src/core/ext/client_config/subchannel.c \
src/core/ext/client_config/subchannel_call_holder.c \
src/core/ext/client_config/subchannel_index.c \
src/core/ext/client_config/uri_parser.c \
src/core/lib/http/httpcli_security_connector.c \
@ -3373,7 +3378,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/client_config/resolver_registry.c \
src/core/ext/client_config/resolver_result.c \
src/core/ext/client_config/subchannel.c \
src/core/ext/client_config/subchannel_call_holder.c \
src/core/ext/client_config/subchannel_index.c \
src/core/ext/client_config/uri_parser.c \
src/core/ext/resolver/dns/native/dns_resolver.c \
@ -3391,6 +3395,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/census/base_resources.c \
src/core/ext/census/context.c \
src/core/ext/census/gen/census.pb.c \
src/core/ext/census/gen/trace_context.pb.c \
src/core/ext/census/grpc_context.c \
src/core/ext/census/grpc_filter.c \
src/core/ext/census/grpc_plugin.c \
@ -3549,39 +3554,39 @@ endif
LIBGRPC++_SRC = \
src/cpp/client/insecure_credentials.cc \
src/cpp/client/secure_credentials.cc \
src/cpp/common/auth_property_iterator.cc \
src/cpp/common/secure_auth_context.cc \
src/cpp/common/secure_channel_arguments.cc \
src/cpp/common/secure_create_auth_context.cc \
src/cpp/server/insecure_server_credentials.cc \
src/cpp/server/secure_server_credentials.cc \
src/cpp/client/channel.cc \
src/cpp/client/channel_cc.cc \
src/cpp/client/client_context.cc \
src/cpp/client/create_channel.cc \
src/cpp/client/create_channel_internal.cc \
src/cpp/client/create_channel_posix.cc \
src/cpp/client/credentials.cc \
src/cpp/client/credentials_cc.cc \
src/cpp/client/generic_stub.cc \
src/cpp/client/insecure_credentials.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
src/cpp/common/completion_queue.cc \
src/cpp/common/completion_queue_cc.cc \
src/cpp/common/core_codegen.cc \
src/cpp/common/rpc_method.cc \
src/cpp/server/async_generic_service.cc \
src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/insecure_server_credentials.cc \
src/cpp/server/server.cc \
src/cpp/server/server_builder.cc \
src/cpp/server/server_cc.cc \
src/cpp/server/server_context.cc \
src/cpp/server/server_credentials.cc \
src/cpp/server/server_posix.cc \
src/cpp/util/byte_buffer.cc \
src/cpp/util/slice.cc \
src/cpp/util/byte_buffer_cc.cc \
src/cpp/util/slice_cc.cc \
src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time.cc \
src/cpp/util/time_cc.cc \
src/core/lib/channel/channel_args.c \
src/core/lib/channel/channel_stack.c \
src/core/lib/channel/channel_stack_builder.c \
@ -4020,7 +4025,7 @@ endif
LIBGRPC++_TEST_CONFIG_SRC = \
test/cpp/util/test_config.cc \
test/cpp/util/test_config_cc.cc \
PUBLIC_HEADERS_CXX += \
@ -4189,34 +4194,34 @@ $(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/tes
LIBGRPC++_UNSECURE_SRC = \
src/cpp/client/insecure_credentials.cc \
src/cpp/common/insecure_create_auth_context.cc \
src/cpp/client/channel.cc \
src/cpp/server/insecure_server_credentials.cc \
src/cpp/client/channel_cc.cc \
src/cpp/client/client_context.cc \
src/cpp/client/create_channel.cc \
src/cpp/client/create_channel_internal.cc \
src/cpp/client/create_channel_posix.cc \
src/cpp/client/credentials.cc \
src/cpp/client/credentials_cc.cc \
src/cpp/client/generic_stub.cc \
src/cpp/client/insecure_credentials.cc \
src/cpp/common/channel_arguments.cc \
src/cpp/common/channel_filter.cc \
src/cpp/common/completion_queue.cc \
src/cpp/common/completion_queue_cc.cc \
src/cpp/common/core_codegen.cc \
src/cpp/common/rpc_method.cc \
src/cpp/server/async_generic_service.cc \
src/cpp/server/create_default_thread_pool.cc \
src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/insecure_server_credentials.cc \
src/cpp/server/server.cc \
src/cpp/server/server_builder.cc \
src/cpp/server/server_cc.cc \
src/cpp/server/server_context.cc \
src/cpp/server/server_credentials.cc \
src/cpp/server/server_posix.cc \
src/cpp/util/byte_buffer.cc \
src/cpp/util/slice.cc \
src/cpp/util/byte_buffer_cc.cc \
src/cpp/util/slice_cc.cc \
src/cpp/util/status.cc \
src/cpp/util/string_ref.cc \
src/cpp/util/time.cc \
src/cpp/util/time_cc.cc \
src/core/lib/channel/channel_args.c \
src/core/lib/channel/channel_stack.c \
src/core/lib/channel/channel_stack_builder.c \
@ -6770,6 +6775,7 @@ LIBEND2END_TESTS_SRC = \
test/core/end2end/tests/max_message_length.c \
test/core/end2end/tests/negative_deadline.c \
test/core/end2end/tests/network_status_change.c \
test/core/end2end/tests/no_logging.c \
test/core/end2end/tests/no_op.c \
test/core/end2end/tests/payload.c \
test/core/end2end/tests/ping.c \
@ -6780,6 +6786,7 @@ LIBEND2END_TESTS_SRC = \
test/core/end2end/tests/server_finishes_request.c \
test/core/end2end/tests/shutdown_finishes_calls.c \
test/core/end2end/tests/shutdown_finishes_tags.c \
test/core/end2end/tests/simple_cacheable_request.c \
test/core/end2end/tests/simple_delayed_request.c \
test/core/end2end/tests/simple_metadata.c \
test/core/end2end/tests/simple_request.c \
@ -6850,6 +6857,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \
test/core/end2end/tests/max_message_length.c \
test/core/end2end/tests/negative_deadline.c \
test/core/end2end/tests/network_status_change.c \
test/core/end2end/tests/no_logging.c \
test/core/end2end/tests/no_op.c \
test/core/end2end/tests/payload.c \
test/core/end2end/tests/ping.c \
@ -6860,6 +6868,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \
test/core/end2end/tests/server_finishes_request.c \
test/core/end2end/tests/shutdown_finishes_calls.c \
test/core/end2end/tests/shutdown_finishes_tags.c \
test/core/end2end/tests/simple_cacheable_request.c \
test/core/end2end/tests/simple_delayed_request.c \
test/core/end2end/tests/simple_metadata.c \
test/core/end2end/tests/simple_request.c \
@ -7884,6 +7893,38 @@ endif
endif
GEN_PERCENT_ENCODING_TABLES_SRC = \
tools/codegen/core/gen_percent_encoding_tables.c \
GEN_PERCENT_ENCODING_TABLES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GEN_PERCENT_ENCODING_TABLES_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/gen_percent_encoding_tables: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/gen_percent_encoding_tables: $(GEN_PERCENT_ENCODING_TABLES_OBJS)
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GEN_PERCENT_ENCODING_TABLES_OBJS) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
endif
$(OBJDIR)/$(CONFIG)/tools/codegen/core/gen_percent_encoding_tables.o:
deps_gen_percent_encoding_tables: $(GEN_PERCENT_ENCODING_TABLES_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GEN_PERCENT_ENCODING_TABLES_OBJS:.o=.dep)
endif
endif
GOAWAY_SERVER_TEST_SRC = \
test/core/end2end/goaway_server_test.c \
@ -8172,6 +8213,38 @@ endif
endif
GPR_PERCENT_ENCODING_TEST_SRC = \
test/core/support/percent_encoding_test.c \
GPR_PERCENT_ENCODING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_PERCENT_ENCODING_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/gpr_percent_encoding_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/gpr_percent_encoding_test: $(GPR_PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(GPR_PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test
endif
$(OBJDIR)/$(CONFIG)/test/core/support/percent_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_gpr_percent_encoding_test: $(GPR_PERCENT_ENCODING_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(GPR_PERCENT_ENCODING_TEST_OBJS:.o=.dep)
endif
endif
GPR_SLICE_BUFFER_TEST_SRC = \
test/core/support/slice_buffer_test.c \
@ -9900,6 +9973,70 @@ endif
endif
PERCENT_DECODE_FUZZER_SRC = \
test/core/support/percent_decode_fuzzer.c \
PERCENT_DECODE_FUZZER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_DECODE_FUZZER_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer
endif
$(OBJDIR)/$(CONFIG)/test/core/support/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(PERCENT_DECODE_FUZZER_OBJS:.o=.dep)
endif
endif
PERCENT_ENCODE_FUZZER_SRC = \
test/core/support/percent_encode_fuzzer.c \
PERCENT_ENCODE_FUZZER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_ENCODE_FUZZER_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LDXX) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer
endif
$(OBJDIR)/$(CONFIG)/test/core/support/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(PERCENT_ENCODE_FUZZER_OBJS:.o=.dep)
endif
endif
RESOLVE_ADDRESS_TEST_SRC = \
test/core/iomgr/resolve_address_test.c \
@ -14181,38 +14318,6 @@ ifneq ($(NO_DEPS),true)
endif
BAD_SSL_ALPN_SERVER_SRC = \
test/core/bad_ssl/servers/alpn.c \
BAD_SSL_ALPN_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BAD_SSL_ALPN_SERVER_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bad_ssl_alpn_server: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/bad_ssl_alpn_server: $(BAD_SSL_ALPN_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(BAD_SSL_ALPN_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_alpn_server
endif
$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/servers/alpn.o: $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_bad_ssl_alpn_server: $(BAD_SSL_ALPN_SERVER_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BAD_SSL_ALPN_SERVER_OBJS:.o=.dep)
endif
endif
BAD_SSL_CERT_SERVER_SRC = \
test/core/bad_ssl/servers/cert.c \
@ -14245,38 +14350,6 @@ endif
endif
BAD_SSL_ALPN_TEST_SRC = \
test/core/bad_ssl/bad_ssl_test.c \
BAD_SSL_ALPN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BAD_SSL_ALPN_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/bad_ssl_alpn_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/bad_ssl_alpn_test: $(BAD_SSL_ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(BAD_SSL_ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_alpn_test
endif
$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/bad_ssl_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_bad_ssl_alpn_test: $(BAD_SSL_ALPN_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(BAD_SSL_ALPN_TEST_OBJS:.o=.dep)
endif
endif
BAD_SSL_CERT_TEST_SRC = \
test/core/bad_ssl/bad_ssl_test.c \
@ -15373,6 +15446,76 @@ endif
endif
PERCENT_DECODE_FUZZER_ONE_ENTRY_SRC = \
test/core/support/percent_decode_fuzzer.c \
test/core/util/one_corpus_entry_fuzzer.c \
PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_DECODE_FUZZER_ONE_ENTRY_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry
endif
$(OBJDIR)/$(CONFIG)/test/core/support/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
endif
endif
PERCENT_ENCODE_FUZZER_ONE_ENTRY_SRC = \
test/core/support/percent_encode_fuzzer.c \
test/core/util/one_corpus_entry_fuzzer.c \
PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry
endif
$(OBJDIR)/$(CONFIG)/test/core/support/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
endif
endif
SERVER_FUZZER_ONE_ENTRY_SRC = \
test/core/end2end/fuzzers/server_fuzzer.c \
test/core/util/one_corpus_entry_fuzzer.c \
@ -15535,7 +15678,7 @@ test/cpp/util/proto_file_parser.cc: $(OPENSSL_DEP)
test/cpp/util/proto_reflection_descriptor_database.cc: $(OPENSSL_DEP)
test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP)
test/cpp/util/subprocess.cc: $(OPENSSL_DEP)
test/cpp/util/test_config.cc: $(OPENSSL_DEP)
test/cpp/util/test_config_cc.cc: $(OPENSSL_DEP)
test/cpp/util/test_credentials_provider.cc: $(OPENSSL_DEP)
endif

@ -100,13 +100,15 @@ desc 'Build the native gem file under rake_compiler_dock'
task 'gem:native' do
verbose = ENV['V'] || '0'
grpc_config = ENV['GRPC_CONFIG'] || 'opt'
if RUBY_PLATFORM =~ /darwin/
FileUtils.touch 'grpc_c.32.ruby'
FileUtils.touch 'grpc_c.64.ruby'
system "rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose}"
system "rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
else
Rake::Task['dlls'].execute
docker_for_windows "bundle && rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose}"
docker_for_windows "bundle && rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
end
end

@ -516,6 +516,7 @@
'src/core/lib/support/log_posix.c',
'src/core/lib/support/log_windows.c',
'src/core/lib/support/murmur_hash.c',
'src/core/lib/support/percent_encoding.c',
'src/core/lib/support/slice.c',
'src/core/lib/support/slice_buffer.c',
'src/core/lib/support/stack_lockfree.c',
@ -720,7 +721,6 @@
'src/core/ext/client_config/resolver_registry.c',
'src/core/ext/client_config/resolver_result.c',
'src/core/ext/client_config/subchannel.c',
'src/core/ext/client_config/subchannel_call_holder.c',
'src/core/ext/client_config/subchannel_index.c',
'src/core/ext/client_config/uri_parser.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
@ -742,6 +742,7 @@
'src/core/ext/census/base_resources.c',
'src/core/ext/census/context.c',
'src/core/ext/census/gen/census.pb.c',
'src/core/ext/census/gen/trace_context.pb.c',
'src/core/ext/census/grpc_context.c',
'src/core/ext/census/grpc_filter.c',
'src/core/ext/census/grpc_plugin.c',

@ -24,6 +24,7 @@ filegroups:
- src/core/ext/census/census_interface.h
- src/core/ext/census/census_rpc_stats.h
- src/core/ext/census/gen/census.pb.h
- src/core/ext/census/gen/trace_context.pb.h
- src/core/ext/census/grpc_filter.h
- src/core/ext/census/mlog.h
- src/core/ext/census/resource.h
@ -32,6 +33,7 @@ filegroups:
- src/core/ext/census/base_resources.c
- src/core/ext/census/context.c
- src/core/ext/census/gen/census.pb.c
- src/core/ext/census/gen/trace_context.pb.c
- src/core/ext/census/grpc_context.c
- src/core/ext/census/grpc_filter.c
- src/core/ext/census/grpc_plugin.c
@ -81,6 +83,7 @@ filegroups:
- src/core/lib/support/block_annotate.h
- src/core/lib/support/env.h
- src/core/lib/support/murmur_hash.h
- src/core/lib/support/percent_encoding.h
- src/core/lib/support/stack_lockfree.h
- src/core/lib/support/string.h
- src/core/lib/support/string_windows.h
@ -109,6 +112,7 @@ filegroups:
- src/core/lib/support/log_posix.c
- src/core/lib/support/log_windows.c
- src/core/lib/support/murmur_hash.c
- src/core/lib/support/percent_encoding.c
- src/core/lib/support/slice.c
- src/core/lib/support/slice_buffer.c
- src/core/lib/support/stack_lockfree.c
@ -350,7 +354,6 @@ filegroups:
- src/core/ext/client_config/resolver_registry.h
- src/core/ext/client_config/resolver_result.h
- src/core/ext/client_config/subchannel.h
- src/core/ext/client_config/subchannel_call_holder.h
- src/core/ext/client_config/subchannel_index.h
- src/core/ext/client_config/uri_parser.h
src:
@ -370,7 +373,6 @@ filegroups:
- src/core/ext/client_config/resolver_registry.c
- src/core/ext/client_config/resolver_result.c
- src/core/ext/client_config/subchannel.c
- src/core/ext/client_config/subchannel_call_holder.c
- src/core/ext/client_config/subchannel_index.c
- src/core/ext/client_config/uri_parser.c
plugin: grpc_client_config
@ -702,33 +704,31 @@ filegroups:
- src/cpp/server/dynamic_thread_pool.h
- src/cpp/server/thread_pool_interface.h
src:
- src/cpp/client/channel.cc
- src/cpp/client/channel_cc.cc
- src/cpp/client/client_context.cc
- src/cpp/client/create_channel.cc
- src/cpp/client/create_channel_internal.cc
- src/cpp/client/create_channel_posix.cc
- src/cpp/client/credentials.cc
- src/cpp/client/credentials_cc.cc
- src/cpp/client/generic_stub.cc
- src/cpp/client/insecure_credentials.cc
- src/cpp/common/channel_arguments.cc
- src/cpp/common/channel_filter.cc
- src/cpp/common/completion_queue.cc
- src/cpp/common/completion_queue_cc.cc
- src/cpp/common/core_codegen.cc
- src/cpp/common/rpc_method.cc
- src/cpp/server/async_generic_service.cc
- src/cpp/server/create_default_thread_pool.cc
- src/cpp/server/dynamic_thread_pool.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/server.cc
- src/cpp/server/server_builder.cc
- src/cpp/server/server_cc.cc
- src/cpp/server/server_context.cc
- src/cpp/server/server_credentials.cc
- src/cpp/server/server_posix.cc
- src/cpp/util/byte_buffer.cc
- src/cpp/util/slice.cc
- src/cpp/util/byte_buffer_cc.cc
- src/cpp/util/slice_cc.cc
- src/cpp/util/status.cc
- src/cpp/util/string_ref.cc
- src/cpp/util/time.cc
- src/cpp/util/time_cc.cc
uses:
- grpc_base
- grpc++_codegen_base
@ -973,11 +973,13 @@ libs:
- src/cpp/common/secure_auth_context.h
- src/cpp/server/secure_server_credentials.h
src:
- src/cpp/client/insecure_credentials.cc
- src/cpp/client/secure_credentials.cc
- src/cpp/common/auth_property_iterator.cc
- src/cpp/common/secure_auth_context.cc
- src/cpp/common/secure_channel_arguments.cc
- src/cpp/common/secure_create_auth_context.cc
- src/cpp/server/insecure_server_credentials.cc
- src/cpp/server/secure_server_credentials.cc
deps:
- grpc
@ -1014,7 +1016,7 @@ libs:
headers:
- test/cpp/util/test_config.h
src:
- test/cpp/util/test_config.cc
- test/cpp/util/test_config_cc.cc
- name: grpc++_test_util
build: private
language: c++
@ -1048,7 +1050,9 @@ libs:
build: all
language: c++
src:
- src/cpp/client/insecure_credentials.cc
- src/cpp/common/insecure_create_auth_context.cc
- src/cpp/server/insecure_server_credentials.cc
deps:
- gpr
- grpc_unsecure
@ -1576,6 +1580,12 @@ targets:
src:
- tools/codegen/core/gen_legal_metadata_characters.c
deps: []
- name: gen_percent_encoding_tables
build: tool
language: c
src:
- tools/codegen/core/gen_percent_encoding_tables.c
deps: []
- name: goaway_server_test
cpu_cost: 0.1
build: test
@ -1655,6 +1665,14 @@ targets:
deps:
- gpr_test_util
- gpr
- name: gpr_percent_encoding_test
build: test
language: c
src:
- test/core/support/percent_encoding_test.c
deps:
- gpr_test_util
- gpr
- name: gpr_slice_buffer_test
build: test
language: c
@ -2216,6 +2234,32 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: percent_decode_fuzzer
build: fuzzer
language: c
src:
- test/core/support/percent_decode_fuzzer.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
corpus_dirs:
- test/core/support/percent_decode_corpus
maxlen: 32
- name: percent_encode_fuzzer
build: fuzzer
language: c
src:
- test/core/support/percent_encode_fuzzer.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
corpus_dirs:
- test/core/support/percent_encode_corpus
maxlen: 32
- name: resolve_address_test
build: test
language: c

@ -57,6 +57,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/support/log_posix.c \
src/core/lib/support/log_windows.c \
src/core/lib/support/murmur_hash.c \
src/core/lib/support/percent_encoding.c \
src/core/lib/support/slice.c \
src/core/lib/support/slice_buffer.c \
src/core/lib/support/stack_lockfree.c \
@ -239,7 +240,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/client_config/resolver_registry.c \
src/core/ext/client_config/resolver_result.c \
src/core/ext/client_config/subchannel.c \
src/core/ext/client_config/subchannel_call_holder.c \
src/core/ext/client_config/subchannel_index.c \
src/core/ext/client_config/uri_parser.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
@ -261,6 +261,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/census/base_resources.c \
src/core/ext/census/context.c \
src/core/ext/census/gen/census.pb.c \
src/core/ext/census/gen/trace_context.pb.c \
src/core/ext/census/grpc_context.c \
src/core/ext/census/grpc_filter.c \
src/core/ext/census/grpc_plugin.c \

@ -1,15 +1 @@
gRPC Fail Fast Semantics
========================
Fail fast requests allow terminating requests (with status UNAVAILABLE) prior
to the deadline of the request being met.
gRPC implementations of fail fast can terminate requests whenever a channel is
in the TRANSIENT_FAILURE or SHUTDOWN states. If the channel is in any other
state (CONNECTING, READY, or IDLE) the request should not be terminated.
Fail fast SHOULD be the default for gRPC implementations, with an option to
switch to non fail fast.
The opposite of fail fast is 'ignore connectivity'.
Moved to wait-for-ready.md

@ -0,0 +1,14 @@
gRPC Wait for Ready Semantics
=============================
If an RPC is issued but the channel is in `TRANSIENT_FAILURE` or `SHUTDOWN`
states, the RPC is unable to be transmited promptly. By default, gRPC
implementations SHOULD fail such RPCs immediately. This is known as "fail fast,"
but usage of the term is historical. RPCs SHOULD NOT fail as a result of the
channel being in other states (`CONNECTING`, `READY`, or `IDLE`).
gRPC implementations MAY provide a per-RPC option to not fail RPCs as a result
of the channel being in `TRANSIENT_FAILURE` state. Instead, the implementation
queues the RPCs until the channel is `READY`. This is known as "wait for ready."
The RPCs SHOULD still fail before `READY` if there are unrelated reasons, such
as the channel is `SHUTDOWN` or the RPC's deadline is reached.

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Grpc.Tools" version="0.6.0" />
</packages>

@ -5,8 +5,8 @@
"debugType": "portable",
},
"dependencies": {
"Google.Protobuf": "3.0.0-beta3",
"Grpc": "1.0.0-pre1",
"Google.Protobuf": "3.0.0",
"Grpc": "1.0.0",
},
"frameworks": {
"net45": {

@ -6,8 +6,8 @@
"emitEntryPoint": "true"
},
"dependencies": {
"Google.Protobuf": "3.0.0-beta3",
"Grpc": "1.0.0-pre1",
"Google.Protobuf": "3.0.0",
"Grpc": "1.0.0",
"Greeter": {
"target": "project"
}

@ -6,8 +6,8 @@
"emitEntryPoint": "true"
},
"dependencies": {
"Google.Protobuf": "3.0.0-beta3",
"Grpc": "1.0.0-pre1",
"Google.Protobuf": "3.0.0",
"Grpc": "1.0.0",
"Greeter": {
"target": "project"
}

@ -33,16 +33,16 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
<HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@ -61,11 +61,11 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
</Target>
</Project>

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
<package id="Grpc.Tools" version="0.15.0" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
<package id="Grpc" version="1.0.0" targetFramework="net45" />
<package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
<package id="Grpc.Tools" version="1.0.0" targetFramework="net45" />
</packages>

@ -33,16 +33,16 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
<HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@ -59,11 +59,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
</Target>
</Project>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
<package id="Grpc" version="1.0.0" targetFramework="net45" />
<package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
</packages>

@ -33,16 +33,16 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
<HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@ -59,11 +59,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
</Target>
</Project>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
<package id="Grpc" version="1.0.0" targetFramework="net45" />
<package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
</packages>

@ -34,7 +34,7 @@ setlocal
@rem enter this directory
cd /d %~dp0
set TOOLS_PATH=packages\Grpc.Tools.0.15.0\tools\windows_x86
set TOOLS_PATH=packages\Grpc.Tools.1.0.0\tools\windows_x86
%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe

@ -33,11 +33,11 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -52,7 +52,7 @@
<Reference Include="System.Xml" />
<Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
<HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@ -74,12 +74,12 @@
</None>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
<package id="Grpc" version="1.0.0" targetFramework="net45" />
<package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
</packages>

@ -35,11 +35,11 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -49,7 +49,7 @@
<Reference Include="System.Core" />
<Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
<HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
@ -71,12 +71,12 @@
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
<package id="Grpc" version="1.0.0" targetFramework="net45" />
<package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
</packages>

@ -35,11 +35,11 @@
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
<HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
<HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -54,7 +54,7 @@
<Reference Include="System.Xml" />
<Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
<HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@ -72,12 +72,12 @@
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
<Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="Grpc" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
<package id="Ix-Async" version="1.2.5" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
<package id="Grpc" version="1.0.0" targetFramework="net45" />
<package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="Grpc.Tools" version="0.15.0" targetFramework="net45" />
<package id="Grpc.Tools" version="1.0.0" targetFramework="net45" />
</packages>

@ -34,7 +34,7 @@ setlocal
@rem enter this directory
cd /d %~dp0
set TOOLS_PATH=packages\Grpc.Tools.0.15.0\tools\windows_x86
set TOOLS_PATH=packages\Grpc.Tools.1.0.0\tools\windows_x86
%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe

@ -39,7 +39,7 @@ There are two ways to generate the code needed to work with protocol buffers in
$ # from this directory
$ node ./dynamic_codegen/greeter_client.js
$ # OR
$ node ./dynamic_codegen/greeter_client.js
$ node ./static_codegen/greeter_client.js
```
TUTORIAL

@ -30,5 +30,5 @@
set -e
cd $(dirname $0)
php $extension_dir -d extension=grpc.so -d max_execution_time=300 \
php -d extension=grpc.so -d max_execution_time=300 \
greeter_client.php $1

@ -1,56 +1 @@
gRPC in 3 minutes (Python)
========================
Background
-------------
For this sample, we've already generated the server and client stubs from
[helloworld.proto][] and we'll be using a specific reference platform.
Install gRPC:
```sh
$ pip install grpcio
```
Or, to install it system wide:
```sh
$ sudo pip install grpcio
```
If you're on Windows, make sure you installed the `pip.exe` component when you
installed Python. Invoke as above but with `pip.exe` instead of `pip` (you may
also need to invoke from a `cmd.exe` ran as administrator):
```sh
$ pip.exe install grpcio
```
Download the example
```sh
$ # Clone the repository to get the example code:
$ git clone https://github.com/grpc/grpc
$ # Navigate to the "hello, world" Python example:
$ cd grpc/examples/python/helloworld
```
Try it!
-------
- Run the server
```sh
$ python2.7 greeter_server.py &
```
- Run the client
```sh
$ python2.7 greeter_client.py
```
Tutorial
--------
You can find a more detailed tutorial in [gRPC Basics: Python][]
[helloworld.proto]:../protos/helloworld.proto
[Install gRPC Python]:../../src/python#installation
[gRPC Basics: Python]:http://www.grpc.io/docs/tutorials/basic/python.html
[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs/quickstart/python.html)

@ -1 +1 @@
[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs)
[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs/quickstart/python.html)

@ -1 +1,3 @@
An example showing two stubs sharing a channel and two servicers sharing a server.
More complete documentation lives at [grpc.io](http://www.grpc.io/docs/tutorials/basic/python.html).

@ -201,6 +201,7 @@ Pod::Spec.new do |s|
'src/core/lib/support/block_annotate.h',
'src/core/lib/support/env.h',
'src/core/lib/support/murmur_hash.h',
'src/core/lib/support/percent_encoding.h',
'src/core/lib/support/stack_lockfree.h',
'src/core/lib/support/string.h',
'src/core/lib/support/string_windows.h',
@ -228,6 +229,7 @@ Pod::Spec.new do |s|
'src/core/lib/support/log_posix.c',
'src/core/lib/support/log_windows.c',
'src/core/lib/support/murmur_hash.c',
'src/core/lib/support/percent_encoding.c',
'src/core/lib/support/slice.c',
'src/core/lib/support/slice_buffer.c',
'src/core/lib/support/stack_lockfree.c',
@ -390,7 +392,6 @@ Pod::Spec.new do |s|
'src/core/ext/client_config/resolver_registry.h',
'src/core/ext/client_config/resolver_result.h',
'src/core/ext/client_config/subchannel.h',
'src/core/ext/client_config/subchannel_call_holder.h',
'src/core/ext/client_config/subchannel_index.h',
'src/core/ext/client_config/uri_parser.h',
'src/core/ext/lb_policy/grpclb/grpclb.h',
@ -407,6 +408,7 @@ Pod::Spec.new do |s|
'src/core/ext/census/census_interface.h',
'src/core/ext/census/census_rpc_stats.h',
'src/core/ext/census/gen/census.pb.h',
'src/core/ext/census/gen/trace_context.pb.h',
'src/core/ext/census/grpc_filter.h',
'src/core/ext/census/mlog.h',
'src/core/ext/census/resource.h',
@ -569,7 +571,6 @@ Pod::Spec.new do |s|
'src/core/ext/client_config/resolver_registry.c',
'src/core/ext/client_config/resolver_result.c',
'src/core/ext/client_config/subchannel.c',
'src/core/ext/client_config/subchannel_call_holder.c',
'src/core/ext/client_config/subchannel_index.c',
'src/core/ext/client_config/uri_parser.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
@ -591,6 +592,7 @@ Pod::Spec.new do |s|
'src/core/ext/census/base_resources.c',
'src/core/ext/census/context.c',
'src/core/ext/census/gen/census.pb.c',
'src/core/ext/census/gen/trace_context.pb.c',
'src/core/ext/census/grpc_context.c',
'src/core/ext/census/grpc_filter.c',
'src/core/ext/census/grpc_plugin.c',
@ -607,6 +609,7 @@ Pod::Spec.new do |s|
'src/core/lib/support/block_annotate.h',
'src/core/lib/support/env.h',
'src/core/lib/support/murmur_hash.h',
'src/core/lib/support/percent_encoding.h',
'src/core/lib/support/stack_lockfree.h',
'src/core/lib/support/string.h',
'src/core/lib/support/string_windows.h',
@ -751,7 +754,6 @@ Pod::Spec.new do |s|
'src/core/ext/client_config/resolver_registry.h',
'src/core/ext/client_config/resolver_result.h',
'src/core/ext/client_config/subchannel.h',
'src/core/ext/client_config/subchannel_call_holder.h',
'src/core/ext/client_config/subchannel_index.h',
'src/core/ext/client_config/uri_parser.h',
'src/core/ext/lb_policy/grpclb/grpclb.h',
@ -768,6 +770,7 @@ Pod::Spec.new do |s|
'src/core/ext/census/census_interface.h',
'src/core/ext/census/census_rpc_stats.h',
'src/core/ext/census/gen/census.pb.h',
'src/core/ext/census/gen/trace_context.pb.h',
'src/core/ext/census/grpc_filter.h',
'src/core/ext/census/mlog.h',
'src/core/ext/census/resource.h',

@ -29,6 +29,7 @@ Gem::Specification.new do |s|
s.add_dependency 'google-protobuf', '~> 3.0'
s.add_dependency 'googleauth', '~> 0.5.1'
s.add_dependency 'concurrent-ruby'
s.add_development_dependency 'bundler', '~> 1.9'
s.add_development_dependency 'facter', '~> 2.4'
@ -90,6 +91,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/support/block_annotate.h )
s.files += %w( src/core/lib/support/env.h )
s.files += %w( src/core/lib/support/murmur_hash.h )
s.files += %w( src/core/lib/support/percent_encoding.h )
s.files += %w( src/core/lib/support/stack_lockfree.h )
s.files += %w( src/core/lib/support/string.h )
s.files += %w( src/core/lib/support/string_windows.h )
@ -117,6 +119,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/support/log_posix.c )
s.files += %w( src/core/lib/support/log_windows.c )
s.files += %w( src/core/lib/support/murmur_hash.c )
s.files += %w( src/core/lib/support/percent_encoding.c )
s.files += %w( src/core/lib/support/slice.c )
s.files += %w( src/core/lib/support/slice_buffer.c )
s.files += %w( src/core/lib/support/stack_lockfree.c )
@ -309,7 +312,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/client_config/resolver_registry.h )
s.files += %w( src/core/ext/client_config/resolver_result.h )
s.files += %w( src/core/ext/client_config/subchannel.h )
s.files += %w( src/core/ext/client_config/subchannel_call_holder.h )
s.files += %w( src/core/ext/client_config/subchannel_index.h )
s.files += %w( src/core/ext/client_config/uri_parser.h )
s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.h )
@ -326,6 +328,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/census/census_interface.h )
s.files += %w( src/core/ext/census/census_rpc_stats.h )
s.files += %w( src/core/ext/census/gen/census.pb.h )
s.files += %w( src/core/ext/census/gen/trace_context.pb.h )
s.files += %w( src/core/ext/census/grpc_filter.h )
s.files += %w( src/core/ext/census/mlog.h )
s.files += %w( src/core/ext/census/resource.h )
@ -488,7 +491,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/client_config/resolver_registry.c )
s.files += %w( src/core/ext/client_config/resolver_result.c )
s.files += %w( src/core/ext/client_config/subchannel.c )
s.files += %w( src/core/ext/client_config/subchannel_call_holder.c )
s.files += %w( src/core/ext/client_config/subchannel_index.c )
s.files += %w( src/core/ext/client_config/uri_parser.c )
s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2.c )
@ -510,6 +512,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/census/base_resources.c )
s.files += %w( src/core/ext/census/context.c )
s.files += %w( src/core/ext/census/gen/census.pb.c )
s.files += %w( src/core/ext/census/gen/trace_context.pb.c )
s.files += %w( src/core/ext/census/grpc_context.c )
s.files += %w( src/core/ext/census/grpc_filter.c )
s.files += %w( src/core/ext/census/grpc_plugin.c )

@ -74,6 +74,7 @@
#include <grpc++/impl/codegen/async_stream.h>
#include <grpc++/impl/codegen/async_unary_call.h>
#include <grpc++/impl/codegen/method_handler_impl.h>
#include <grpc++/impl/codegen/proto_utils.h>
#include <grpc++/impl/codegen/rpc_method.h>
#include <grpc++/impl/codegen/service_type.h>
@ -174,6 +175,7 @@ class ServerReflection GRPC_FINAL {
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
};
typedef Service StreamedUnaryService;
};
} // namespace v1alpha

@ -51,6 +51,9 @@
#ifndef GRPCXX_GRPCXX_H
#define GRPCXX_GRPCXX_H
// Pragma for http://include-what-you-use.org/ tool, tells that following
// headers are not private for grpc++.h and are part of its interface.
// IWYU pragma: begin_exports
#include <grpc/grpc.h>
#include <grpc++/channel.h>
@ -62,5 +65,6 @@
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc++/server_posix.h>
// IWYU pragma: end_exports
#endif // GRPCXX_GRPCXX_H

@ -662,10 +662,10 @@ class Call GRPC_FINAL {
call_hook_->PerformOpsOnCall(ops, this);
}
grpc_call* call() { return call_; }
CompletionQueue* cq() { return cq_; }
grpc_call* call() const { return call_; }
CompletionQueue* cq() const { return cq_; }
int max_message_size() { return max_message_size_; }
int max_message_size() const { return max_message_size_; }
private:
CallHook* call_hook_;

@ -225,6 +225,9 @@ class ClientContext {
/// EXPERIMENTAL: Set this request to be idempotent
void set_idempotent(bool idempotent) { idempotent_ = idempotent; }
/// EXPERIMENTAL: Set this request to be cacheable
void set_cacheable(bool cacheable) { cacheable_ = cacheable; }
/// EXPERIMENTAL: Trigger fail-fast or not on this request
void set_fail_fast(bool fail_fast) { fail_fast_ = fail_fast; }
@ -307,6 +310,10 @@ class ClientContext {
};
static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
// Should be used for framework-level extensions only.
// Applications never need to call this method.
grpc_call* c_call() { return call_; }
private:
// Disallow copy and assign.
ClientContext(const ClientContext&);
@ -342,7 +349,8 @@ class ClientContext {
uint32_t initial_metadata_flags() const {
return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) |
(fail_fast_ ? 0 : GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY);
(fail_fast_ ? 0 : GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY) |
(cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0);
}
grpc::string authority() { return authority_; }
@ -350,6 +358,7 @@ class ClientContext {
bool initial_metadata_received_;
bool fail_fast_;
bool idempotent_;
bool cacheable_;
std::shared_ptr<Channel> channel_;
grpc::mutex mu_;
grpc_call* call_;

@ -68,8 +68,10 @@ template <class R>
class ServerReader;
template <class W>
class ServerWriter;
namespace internal {
template <class W, class R>
class ServerReaderWriter;
class ServerReaderWriterBody;
}
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@ -178,15 +180,15 @@ class CompletionQueue : private GrpcLibraryCodegen {
template <class W>
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::ServerReaderWriter;
friend class ::grpc::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
friend class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class BidiStreamingHandler;
template <class Streamer, bool WriteNeeded>
friend class TemplatedBidiStreamingHandler;
friend class UnknownMethodHandler;
friend class ::grpc::Server;
friend class ::grpc::ServerContext;

@ -167,20 +167,22 @@ class ServerStreamingHandler : public MethodHandler {
};
// A wrapper class of an application provided bidi-streaming handler.
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler : public MethodHandler {
// This also applies to server-streamed implementation of a unary method
// with the additional requirement that such methods must have done a
// write for status to be ok
// Since this is used by more than 1 class, the service is not passed in.
// Instead, it is expected to be an implicitly-captured argument of func
// (through bind or something along those lines)
template <class Streamer, bool WriteNeeded>
class TemplatedBidiStreamingHandler : public MethodHandler {
public:
BidiStreamingHandler(
std::function<Status(ServiceType*, ServerContext*,
ServerReaderWriter<ResponseType, RequestType>*)>
func,
ServiceType* service)
: func_(func), service_(service) {}
TemplatedBidiStreamingHandler(
std::function<Status(ServerContext*, Streamer*)> func)
: func_(func), write_needed_(WriteNeeded) {}
void RunHandler(const HandlerParameter& param) GRPC_FINAL {
ServerReaderWriter<ResponseType, RequestType> stream(param.call,
param.server_context);
Status status = func_(service_, param.server_context, &stream);
Streamer stream(param.call, param.server_context);
Status status = func_(param.server_context, &stream);
CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
if (!param.server_context->sent_initial_metadata_) {
@ -189,6 +191,12 @@ class BidiStreamingHandler : public MethodHandler {
if (param.server_context->compression_level_set()) {
ops.set_compression_level(param.server_context->compression_level());
}
if (write_needed_ && status.ok()) {
// If we needed a write but never did one, we need to mark the
// status as a fail
status = Status(StatusCode::INTERNAL,
"Service did not provide response message");
}
}
ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
param.call->PerformOps(&ops);
@ -196,10 +204,36 @@ class BidiStreamingHandler : public MethodHandler {
}
private:
std::function<Status(ServiceType*, ServerContext*,
ServerReaderWriter<ResponseType, RequestType>*)>
func_;
ServiceType* service_;
std::function<Status(ServerContext*, Streamer*)> func_;
const bool write_needed_;
};
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler
: public TemplatedBidiStreamingHandler<
ServerReaderWriter<ResponseType, RequestType>, false> {
public:
BidiStreamingHandler(
std::function<Status(ServiceType*, ServerContext*,
ServerReaderWriter<ResponseType, RequestType>*)>
func,
ServiceType* service)
: TemplatedBidiStreamingHandler<
ServerReaderWriter<ResponseType, RequestType>, false>(std::bind(
func, service, std::placeholders::_1, std::placeholders::_2)) {}
};
template <class RequestType, class ResponseType>
class StreamedUnaryHandler
: public TemplatedBidiStreamingHandler<
ServerUnaryStreamer<RequestType, ResponseType>, true> {
public:
explicit StreamedUnaryHandler(
std::function<Status(ServerContext*,
ServerUnaryStreamer<RequestType, ResponseType>*)>
func)
: TemplatedBidiStreamingHandler<
ServerUnaryStreamer<RequestType, ResponseType>, true>(func) {}
};
// Handle unknown method by returning UNIMPLEMENTED error.

@ -60,11 +60,12 @@ class RpcMethod {
const char* name() const { return name_; }
RpcType method_type() const { return method_type_; }
void SetMethodType(RpcType type) { method_type_ = type; }
void* channel_tag() const { return channel_tag_; }
private:
const char* const name_;
const RpcType method_type_;
RpcType method_type_;
void* const channel_tag_;
};

@ -82,6 +82,7 @@ class RpcServiceMethod : public RpcMethod {
// if MethodHandler is nullptr, then this is an async method
MethodHandler* handler() const { return handler_.get(); }
void ResetHandler() { handler_.reset(); }
void SetHandler(MethodHandler* handler) { handler_.reset(handler); }
private:
void* server_tag_;

@ -65,8 +65,10 @@ template <class R>
class ServerReader;
template <class W>
class ServerWriter;
namespace internal {
template <class W, class R>
class ServerReaderWriter;
class ServerReaderWriterBody;
}
template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
@ -166,6 +168,10 @@ class ServerContext {
async_notify_when_done_tag_ = tag;
}
// Should be used for framework-level extensions only.
// Applications never need to call this method.
grpc_call* c_call() { return call_; }
private:
friend class ::grpc::testing::InteropServerContextInspector;
friend class ::grpc::ServerInterface;
@ -183,15 +189,15 @@ class ServerContext {
template <class W>
friend class ::grpc::ServerWriter;
template <class W, class R>
friend class ::grpc::ServerReaderWriter;
friend class ::grpc::internal::ServerReaderWriterBody;
template <class ServiceType, class RequestType, class ResponseType>
friend class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ClientStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class BidiStreamingHandler;
template <class Streamer, bool WriteNeeded>
friend class TemplatedBidiStreamingHandler;
friend class UnknownMethodHandler;
friend class ::grpc::ClientContext;

@ -147,6 +147,17 @@ class Service {
methods_[index].reset();
}
void MarkMethodStreamedUnary(int index,
MethodHandler* streamed_unary_method) {
GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() &&
"Cannot mark an async or generic method Streamed Unary");
methods_[index]->SetHandler(streamed_unary_method);
// From the server's point of view, streamed unary is a special
// case of BIDI_STREAMING that has 1 read and 1 write, in that order.
methods_[index]->SetMethodType(::grpc::RpcMethod::BIDI_STREAMING);
}
private:
friend class Server;
friend class ServerInterface;

@ -79,6 +79,9 @@ class ReaderInterface {
public:
virtual ~ReaderInterface() {}
/// Upper bound on the next message size available for reading on this stream
virtual bool NextMessageSize(uint32_t* sz) = 0;
/// Blocking read a message and parse to \a msg. Returns \a true on success.
/// This is thread-safe with respect to \a Write or \WritesDone methods on
/// the same stream. It should not be called concurrently with another \a
@ -157,6 +160,11 @@ class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
cq_.Pluck(&ops); /// status ignored
}
bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
*sz = call_.max_message_size();
return true;
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
if (!context_->initial_metadata_received_) {
@ -302,6 +310,11 @@ class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
cq_.Pluck(&ops); // status ignored
}
bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
*sz = call_.max_message_size();
return true;
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
if (!context_->initial_metadata_received_) {
@ -369,6 +382,11 @@ class ServerReader GRPC_FINAL : public ServerReaderInterface<R> {
call_->cq()->Pluck(&ops);
}
bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
*sz = call_->max_message_size();
return true;
}
bool Read(R* msg) GRPC_OVERRIDE {
CallOpSet<CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
@ -434,12 +452,15 @@ class ServerReaderWriterInterface : public ServerStreamingInterface,
public WriterInterface<W>,
public ReaderInterface<R> {};
// Actual implementation of bi-directional streaming
namespace internal {
template <class W, class R>
class ServerReaderWriter GRPC_FINAL : public ServerReaderWriterInterface<W, R> {
class ServerReaderWriterBody GRPC_FINAL {
public:
ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
ServerReaderWriterBody(Call* call, ServerContext* ctx)
: call_(call), ctx_(ctx) {}
void SendInitialMetadata() GRPC_OVERRIDE {
void SendInitialMetadata() {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
CallOpSet<CallOpSendInitialMetadata> ops;
@ -453,15 +474,19 @@ class ServerReaderWriter GRPC_FINAL : public ServerReaderWriterInterface<W, R> {
call_->cq()->Pluck(&ops);
}
bool Read(R* msg) GRPC_OVERRIDE {
bool NextMessageSize(uint32_t* sz) {
*sz = call_->max_message_size();
return true;
}
bool Read(R* msg) {
CallOpSet<CallOpRecvMessage<R>> ops;
ops.RecvMessage(msg);
call_->PerformOps(&ops);
return call_->cq()->Pluck(&ops) && ops.got_message;
}
using WriterInterface<W>::Write;
bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
bool Write(const W& msg, const WriteOptions& options) {
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> ops;
if (!ops.SendMessage(msg, options).ok()) {
return false;
@ -482,6 +507,76 @@ class ServerReaderWriter GRPC_FINAL : public ServerReaderWriterInterface<W, R> {
Call* const call_;
ServerContext* const ctx_;
};
}
// class to represent the user API for a bidirectional streaming call
template <class W, class R>
class ServerReaderWriter GRPC_FINAL : public ServerReaderWriterInterface<W, R> {
public:
ServerReaderWriter(Call* call, ServerContext* ctx) : body_(call, ctx) {}
void SendInitialMetadata() GRPC_OVERRIDE { body_.SendInitialMetadata(); }
bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
return body_.NextMessageSize(sz);
}
bool Read(R* msg) GRPC_OVERRIDE { return body_.Read(msg); }
using WriterInterface<W>::Write;
bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
return body_.Write(msg, options);
}
private:
internal::ServerReaderWriterBody<W, R> body_;
};
/// A class to represent a flow-controlled unary call. This is something
/// of a hybrid between conventional unary and streaming. This is invoked
/// through a unary call on the client side, but the server responds to it
/// as though it were a single-ping-pong streaming call. The server can use
/// the \a NextMessageSize method to determine an upper-bound on the size of
/// the message.
/// A key difference relative to streaming: ServerUnaryStreamer
/// must have exactly 1 Read and exactly 1 Write, in that order, to function
/// correctly. Otherwise, the RPC is in error.
template <class RequestType, class ResponseType>
class ServerUnaryStreamer GRPC_FINAL
: public ServerReaderWriterInterface<ResponseType, RequestType> {
public:
ServerUnaryStreamer(Call* call, ServerContext* ctx)
: body_(call, ctx), read_done_(false), write_done_(false) {}
void SendInitialMetadata() GRPC_OVERRIDE { body_.SendInitialMetadata(); }
bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
return body_.NextMessageSize(sz);
}
bool Read(RequestType* request) GRPC_OVERRIDE {
if (read_done_) {
return false;
}
read_done_ = true;
return body_.Read(request);
}
using WriterInterface<ResponseType>::Write;
bool Write(const ResponseType& response,
const WriteOptions& options) GRPC_OVERRIDE {
if (write_done_ || !read_done_) {
return false;
}
write_done_ = true;
return body_.Write(response, options);
}
private:
internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
bool read_done_;
bool write_done_;
};
} // namespace grpc

@ -41,6 +41,7 @@
namespace grpc {
class ServerInitializer;
class ChannelArguments;
class ServerBuilderPlugin {
public:
@ -58,6 +59,10 @@ class ServerBuilderPlugin {
// ServerBuilderOption::UpdatePlugins
virtual void ChangeArguments(const grpc::string& name, void* value) = 0;
// UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(),
// before the Server instance is created.
virtual void UpdateChannelArguments(ChannelArguments* args) {}
virtual bool has_sync_methods() const { return false; }
virtual bool has_async_methods() const { return false; }
};

@ -142,6 +142,11 @@ typedef struct {
/** How much memory to use for hpack encoding. Int valued, bytes. */
#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \
"grpc.http2.hpack_table_size.encoder"
/** How big a frame are we willing to receive via HTTP2.
Min 16384, max 16777215.
Larger values give lower CPU usage for large messages, but more head of line
blocking for small messages. */
#define GRPC_ARG_HTTP2_MAX_FRAME_SIZE "grpc.http2.max_frame_size"
/** Default authority to pass if none specified on call construction. A string.
* */
#define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
@ -222,10 +227,14 @@ typedef enum grpc_call_error {
#define GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST (0x00000010u)
/** Signal that the call should not return UNAVAILABLE before it has started */
#define GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY (0x00000020u)
/** Signal that the call is cacheable. GRPC is free to use GET verb */
#define GRPC_INITIAL_METADATA_CACHEABLE_REQUEST (0x00000040u)
/** Mask of all valid flags */
#define GRPC_INITIAL_METADATA_USED_MASK \
(GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST | \
GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY)
#define GRPC_INITIAL_METADATA_USED_MASK \
(GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST | \
GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY | \
GRPC_INITIAL_METADATA_CACHEABLE_REQUEST)
/** A single metadata element */
typedef struct grpc_metadata {

@ -234,6 +234,7 @@
#define GPR_ARCH_32 1
#endif /* _LP64 */
#elif defined(__APPLE__)
#include <Availability.h>
#include <TargetConditionals.h>
#ifndef _BSD_SOURCE
#define _BSD_SOURCE
@ -246,8 +247,18 @@
#define GPR_PTHREAD_TLS 1
#else /* TARGET_OS_IPHONE */
#define GPR_PLATFORM_STRING "osx"
#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7
#define GPR_CPU_IPHONE 1
#define GPR_PTHREAD_TLS 1
#else /* __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 */
#define GPR_CPU_POSIX 1
#define GPR_GCC_TLS 1
#endif
#else /* __MAC_OS_X_VERSION_MIN_REQUIRED */
#define GPR_CPU_POSIX 1
#define GPR_GCC_TLS 1
#endif
#define GPR_POSIX_CRASH_HANDLER 1
#endif
#define GPR_GCC_ATOMIC 1

@ -98,6 +98,7 @@
<file baseinstalldir="/" name="src/core/lib/support/block_annotate.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/env.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/murmur_hash.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/percent_encoding.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/string_windows.h" role="src" />
@ -125,6 +126,7 @@
<file baseinstalldir="/" name="src/core/lib/support/log_posix.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/log_windows.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/murmur_hash.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/percent_encoding.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/slice.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/slice_buffer.c" role="src" />
<file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.c" role="src" />
@ -317,7 +319,6 @@
<file baseinstalldir="/" name="src/core/ext/client_config/resolver_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/resolver_result.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/subchannel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/subchannel_call_holder.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/subchannel_index.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/uri_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/grpclb.h" role="src" />
@ -334,6 +335,7 @@
<file baseinstalldir="/" name="src/core/ext/census/census_interface.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/census_rpc_stats.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/gen/trace_context.pb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/grpc_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/mlog.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/resource.h" role="src" />
@ -496,7 +498,6 @@
<file baseinstalldir="/" name="src/core/ext/client_config/resolver_registry.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/resolver_result.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/subchannel.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/subchannel_call_holder.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/subchannel_index.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/client_config/uri_parser.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2.c" role="src" />
@ -518,6 +519,7 @@
<file baseinstalldir="/" name="src/core/ext/census/base_resources.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/context.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/gen/trace_context.pb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/grpc_context.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/grpc_filter.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/census/grpc_plugin.c" role="src" />

@ -198,12 +198,14 @@ PACKAGE_DIRECTORIES = {
INSTALL_REQUIRES = (
'six>=1.5.2',
'enum34>=1.0.4',
'futures>=2.2.0',
# TODO(atash): eventually split the grpcio package into a metapackage
# depending on protobuf and the runtime component (independent of protobuf)
'protobuf>=3.0.0',
)
if not PY3:
INSTALL_REQUIRES += ('futures>=2.2.0',)
SETUP_REQUIRES = INSTALL_REQUIRES + (
'sphinx>=1.3',
'sphinx_rtd_theme>=0.1.8',

@ -130,6 +130,7 @@ grpc::string GetHeaderIncludes(File *file, const Parameters &params) {
static const char *headers_strs[] = {
"grpc++/impl/codegen/async_stream.h",
"grpc++/impl/codegen/async_unary_call.h",
"grpc++/impl/codegen/method_handler_impl.h",
"grpc++/impl/codegen/proto_utils.h",
"grpc++/impl/codegen/rpc_method.h",
"grpc++/impl/codegen/service_type.h",
@ -604,6 +605,57 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method,
printer->Print(*vars, "};\n");
}
void PrintHeaderServerMethodStreamedUnary(
Printer *printer, const Method *method,
std::map<grpc::string, grpc::string> *vars) {
(*vars)["Method"] = method->name();
(*vars)["Request"] = method->input_type_name();
(*vars)["Response"] = method->output_type_name();
if (method->NoStreaming()) {
printer->Print(*vars, "template <class BaseClass>\n");
printer->Print(*vars,
"class WithStreamedUnaryMethod_$Method$ : "
"public BaseClass {\n");
printer->Print(
" private:\n"
" void BaseClassMustBeDerivedFromService(const Service *service) "
"{}\n");
printer->Print(" public:\n");
printer->Indent();
printer->Print(*vars,
"WithStreamedUnaryMethod_$Method$() {\n"
" ::grpc::Service::MarkMethodStreamedUnary($Idx$,\n"
" new ::grpc::StreamedUnaryHandler< $Request$, "
"$Response$>(std::bind"
"(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
"Streamed$Method$, this, std::placeholders::_1, "
"std::placeholders::_2)));\n"
"}\n");
printer->Print(*vars,
"~WithStreamedUnaryMethod_$Method$() GRPC_OVERRIDE {\n"
" BaseClassMustBeDerivedFromService(this);\n"
"}\n");
printer->Print(
*vars,
"// disable regular version of this method\n"
"::grpc::Status $Method$("
"::grpc::ServerContext* context, const $Request$* request, "
"$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n"
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
printer->Print(*vars,
"// replace default version of method with streamed unary\n"
"virtual ::grpc::Status Streamed$Method$("
"::grpc::ServerContext* context, "
"::grpc::ServerUnaryStreamer< "
"$Request$,$Response$>* server_unary_streamer)"
" = 0;\n");
printer->Outdent();
printer->Print(*vars, "};\n");
}
}
void PrintHeaderServerMethodGeneric(
Printer *printer, const Method *method,
std::map<grpc::string, grpc::string> *vars) {
@ -770,6 +822,28 @@ void PrintHeaderService(Printer *printer, const Service *service,
PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
}
// Server side - Streamed Unary
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["Idx"] = as_string(i);
PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(),
vars);
}
printer->Print("typedef ");
for (int i = 0; i < service->method_count(); ++i) {
(*vars)["method_name"] = service->method(i).get()->name();
if (service->method(i)->NoStreaming()) {
printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
}
}
printer->Print("Service");
for (int i = 0; i < service->method_count(); ++i) {
if (service->method(i)->NoStreaming()) {
printer->Print(" >");
}
}
printer->Print(" StreamedUnaryService;\n");
printer->Outdent();
printer->Print("};\n");
printer->Print(service->GetTrailingComments().c_str());
@ -1080,6 +1154,9 @@ void PrintSourceService(Printer *printer, const Service *service,
(*vars)["Idx"] = as_string(i);
if (method->NoStreaming()) {
(*vars)["StreamingType"] = "NORMAL_RPC";
// NOTE: There is no reason to consider streamed-unary as a separate
// category here since this part is setting up the client-side stub
// and this appears as a NORMAL_RPC from the client-side.
} else if (method->ClientOnlyStreaming()) {
(*vars)["StreamingType"] = "CLIENT_STREAMING";
} else if (method->ServerOnlyStreaming()) {

@ -4,3 +4,7 @@ Files generated for use by Census stats and trace recording subsystem.
* census.pb.{h,c} - Generated from src/core/ext/census/census.proto, using the
script `tools/codegen/core/gen_nano_proto.sh src/proto/census/census.proto
$PWD/src/core/ext/census/gen src/core/ext/census/gen`
* trace_context.pb.{h,c} - Generated from
src/core/ext/census/trace_context.proto, using the script
`tools/codegen/core/gen_nano_proto.sh src/proto/census/trace_context.proto
$PWD/src/core/ext/census/gen src/core/ext/census/gen`

@ -0,0 +1,81 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.3.5-dev */
#include "src/core/ext/census/gen/trace_context.pb.h"
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
const pb_field_t google_trace_TraceId_fields[3] = {
PB_FIELD( 1, FIXED64 , OPTIONAL, STATIC , FIRST, google_trace_TraceId, hi, hi, 0),
PB_FIELD( 2, FIXED64 , OPTIONAL, STATIC , OTHER, google_trace_TraceId, lo, hi, 0),
PB_LAST_FIELD
};
const pb_field_t google_trace_TraceContext_fields[4] = {
PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, google_trace_TraceContext, trace_id, trace_id, &google_trace_TraceId_fields),
PB_FIELD( 2, FIXED64 , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, span_id, trace_id, 0),
PB_FIELD( 3, BOOL , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, is_sampled, span_id, 0),
PB_LAST_FIELD
};
/* Check that field information fits in pb_field_t */
#if !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_32BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in 8 or 16 bit
* field descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(google_trace_TraceContext, trace_id) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_trace_TraceId_google_trace_TraceContext)
#endif
#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
/* If you get an error here, it means that you need to define PB_FIELD_16BIT
* compile-time option. You can do that in pb.h or on compiler command line.
*
* The reason you need to do this is that some of your messages contain tag
* numbers or field sizes that are larger than what can fit in the default
* 8 bit descriptors.
*/
PB_STATIC_ASSERT((pb_membersize(google_trace_TraceContext, trace_id) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_trace_TraceId_google_trace_TraceContext)
#endif

@ -0,0 +1,99 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* Automatically generated nanopb header */
/* Generated by nanopb-0.3.5-dev */
#ifndef GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H
#define GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H
#include "third_party/nanopb/pb.h"
#if PB_PROTO_HEADER_VERSION != 30
#error Regenerate this file with the current version of nanopb generator.
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Struct definitions */
typedef struct _google_trace_TraceId {
bool has_hi;
uint64_t hi;
bool has_lo;
uint64_t lo;
} google_trace_TraceId;
typedef struct _google_trace_TraceContext {
bool has_trace_id;
google_trace_TraceId trace_id;
bool has_span_id;
uint64_t span_id;
bool has_is_sampled;
bool is_sampled;
} google_trace_TraceContext;
/* Default values for struct fields */
/* Initializer values for message structs */
#define google_trace_TraceId_init_default {false, 0, false, 0}
#define google_trace_TraceContext_init_default {false, google_trace_TraceId_init_default, false, 0, false, 0}
#define google_trace_TraceId_init_zero {false, 0, false, 0}
#define google_trace_TraceContext_init_zero {false, google_trace_TraceId_init_zero, false, 0, false, 0}
/* Field tags (for use in manual encoding/decoding) */
#define google_trace_TraceId_hi_tag 1
#define google_trace_TraceId_lo_tag 2
#define google_trace_TraceContext_trace_id_tag 1
#define google_trace_TraceContext_span_id_tag 2
#define google_trace_TraceContext_is_sampled_tag 3
/* Struct field encoding specification for nanopb */
extern const pb_field_t google_trace_TraceId_fields[3];
extern const pb_field_t google_trace_TraceContext_fields[4];
/* Maximum encoded size of messages (where known) */
#define google_trace_TraceId_size 18
#define google_trace_TraceContext_size 31
/* Message IDs (where set with "msgid" option) */
#ifdef PB_MSGID
#define TRACE_CONTEXT_MESSAGES \
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

@ -33,6 +33,7 @@
#include "src/core/ext/client_config/client_channel.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
@ -41,10 +42,11 @@
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>
#include "src/core/ext/client_config/subchannel_call_holder.h"
#include "src/core/ext/client_config/subchannel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/surface/channel.h"
@ -52,13 +54,15 @@
/* Client channel implementation */
typedef grpc_subchannel_call_holder call_data;
/*************************************************************************
* CHANNEL-WIDE FUNCTIONS
*/
typedef struct client_channel_channel_data {
/** resolver for this channel */
grpc_resolver *resolver;
/** have we started resolving this channel */
int started_resolving;
bool started_resolving;
/** mutex protecting client configuration, including all
variables below in this data structure */
@ -74,7 +78,7 @@ typedef struct client_channel_channel_data {
/** connectivity state being tracked */
grpc_connectivity_state_tracker state_tracker;
/** when an lb_policy arrives, should we try to exit idle */
int exit_idle_when_lb_policy_arrives;
bool exit_idle_when_lb_policy_arrives;
/** owning stack */
grpc_channel_stack *owning_stack;
/** interested parties (owned) */
@ -82,10 +86,8 @@ typedef struct client_channel_channel_data {
} channel_data;
/** We create one watcher for each new lb_policy that is returned from a
resolver,
to watch for state changes from the lb_policy. When a state change is seen,
we
update the channel, and create a new watcher */
resolver, to watch for state changes from the lb_policy. When a state
change is seen, we update the channel, and create a new watcher. */
typedef struct {
channel_data *chand;
grpc_closure on_changed;
@ -93,22 +95,6 @@ typedef struct {
grpc_lb_policy *lb_policy;
} lb_policy_connectivity_watcher;
typedef struct {
grpc_closure closure;
grpc_call_element *elem;
} waiting_call;
static char *cc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
return grpc_subchannel_call_holder_get_peer(exec_ctx, elem->call_data);
}
static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_transport_stream_op *op) {
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
grpc_subchannel_call_holder_perform_op(exec_ctx, elem->call_data, op);
}
static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand,
grpc_lb_policy *lb_policy,
grpc_connectivity_state current_state);
@ -177,13 +163,13 @@ static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand,
&w->on_changed);
}
static void cc_on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
channel_data *chand = arg;
grpc_lb_policy *lb_policy = NULL;
grpc_lb_policy *old_lb_policy;
grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
int exit_idle = 0;
bool exit_idle = false;
grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy");
if (chand->resolver_result != NULL) {
@ -221,8 +207,8 @@ static void cc_on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
}
if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) {
GRPC_LB_POLICY_REF(lb_policy, "exit_idle");
exit_idle = 1;
chand->exit_idle_when_lb_policy_arrives = 0;
exit_idle = true;
chand->exit_idle_when_lb_policy_arrives = false;
}
if (error == GRPC_ERROR_NONE && chand->resolver) {
@ -330,6 +316,188 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
gpr_mu_unlock(&chand->mu);
}
/* Constructor for channel_data */
static void cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
channel_data *chand = elem->channel_data;
memset(chand, 0, sizeof(*chand));
GPR_ASSERT(args->is_last);
GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
gpr_mu_init(&chand->mu);
grpc_closure_init(&chand->on_resolver_result_changed,
on_resolver_result_changed, chand);
chand->owning_stack = args->channel_stack;
grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
"client_channel");
chand->interested_parties = grpc_pollset_set_create();
}
/* Destructor for channel_data */
static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
channel_data *chand = elem->channel_data;
if (chand->resolver != NULL) {
grpc_resolver_shutdown(exec_ctx, chand->resolver);
GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel");
}
if (chand->lb_policy != NULL) {
grpc_pollset_set_del_pollset_set(exec_ctx,
chand->lb_policy->interested_parties,
chand->interested_parties);
GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel");
}
grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
grpc_pollset_set_destroy(chand->interested_parties);
gpr_mu_destroy(&chand->mu);
}
/*************************************************************************
* PER-CALL FUNCTIONS
*/
#define GET_CALL(call_data) \
((grpc_subchannel_call *)(gpr_atm_acq_load(&(call_data)->subchannel_call)))
#define CANCELLED_CALL ((grpc_subchannel_call *)1)
typedef enum {
GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING,
GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
} subchannel_creation_phase;
/** Call data. Holds a pointer to grpc_subchannel_call and the
associated machinery to create such a pointer.
Handles queueing of stream ops until a call object is ready, waiting
for initial metadata before trying to create a call object,
and handling cancellation gracefully. */
typedef struct client_channel_call_data {
/** either 0 for no call, 1 for cancelled, or a pointer to a
grpc_subchannel_call */
gpr_atm subchannel_call;
gpr_mu mu;
subchannel_creation_phase creation_phase;
grpc_connected_subchannel *connected_subchannel;
grpc_polling_entity *pollent;
grpc_transport_stream_op *waiting_ops;
size_t waiting_ops_count;
size_t waiting_ops_capacity;
grpc_closure next_step;
grpc_call_stack *owning_call;
} call_data;
static void add_waiting_locked(call_data *calld, grpc_transport_stream_op *op) {
GPR_TIMER_BEGIN("add_waiting_locked", 0);
if (calld->waiting_ops_count == calld->waiting_ops_capacity) {
calld->waiting_ops_capacity = GPR_MAX(3, 2 * calld->waiting_ops_capacity);
calld->waiting_ops =
gpr_realloc(calld->waiting_ops,
calld->waiting_ops_capacity * sizeof(*calld->waiting_ops));
}
calld->waiting_ops[calld->waiting_ops_count++] = *op;
GPR_TIMER_END("add_waiting_locked", 0);
}
static void fail_locked(grpc_exec_ctx *exec_ctx, call_data *calld,
grpc_error *error) {
size_t i;
for (i = 0; i < calld->waiting_ops_count; i++) {
grpc_transport_stream_op_finish_with_failure(
exec_ctx, &calld->waiting_ops[i], GRPC_ERROR_REF(error));
}
calld->waiting_ops_count = 0;
GRPC_ERROR_UNREF(error);
}
typedef struct {
grpc_transport_stream_op *ops;
size_t nops;
grpc_subchannel_call *call;
} retry_ops_args;
static void retry_ops(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) {
retry_ops_args *a = args;
size_t i;
for (i = 0; i < a->nops; i++) {
grpc_subchannel_call_process_op(exec_ctx, a->call, &a->ops[i]);
}
GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, a->call, "retry_ops");
gpr_free(a->ops);
gpr_free(a);
}
static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
retry_ops_args *a = gpr_malloc(sizeof(*a));
a->ops = calld->waiting_ops;
a->nops = calld->waiting_ops_count;
a->call = GET_CALL(calld);
if (a->call == CANCELLED_CALL) {
gpr_free(a);
fail_locked(exec_ctx, calld, GRPC_ERROR_CANCELLED);
return;
}
calld->waiting_ops = NULL;
calld->waiting_ops_count = 0;
calld->waiting_ops_capacity = 0;
GRPC_SUBCHANNEL_CALL_REF(a->call, "retry_ops");
grpc_exec_ctx_sched(exec_ctx, grpc_closure_create(retry_ops, a),
GRPC_ERROR_NONE, NULL);
}
static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
call_data *calld = arg;
gpr_mu_lock(&calld->mu);
GPR_ASSERT(calld->creation_phase ==
GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL);
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
if (calld->connected_subchannel == NULL) {
gpr_atm_no_barrier_store(&calld->subchannel_call, 1);
fail_locked(exec_ctx, calld, GRPC_ERROR_CREATE_REFERENCING(
"Failed to create subchannel", &error, 1));
} else if (1 == gpr_atm_acq_load(&calld->subchannel_call)) {
/* already cancelled before subchannel became ready */
fail_locked(exec_ctx, calld,
GRPC_ERROR_CREATE_REFERENCING(
"Cancelled before creating subchannel", &error, 1));
} else {
grpc_subchannel_call *subchannel_call = NULL;
grpc_error *new_error = grpc_connected_subchannel_create_call(
exec_ctx, calld->connected_subchannel, calld->pollent,
&subchannel_call);
if (new_error != GRPC_ERROR_NONE) {
new_error = grpc_error_add_child(new_error, error);
subchannel_call = CANCELLED_CALL;
fail_locked(exec_ctx, calld, new_error);
}
gpr_atm_rel_store(&calld->subchannel_call,
(gpr_atm)(uintptr_t)subchannel_call);
retry_waiting_locked(exec_ctx, calld);
}
gpr_mu_unlock(&calld->mu);
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
}
static char *cc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) {
call_data *calld = elem->call_data;
grpc_subchannel_call *subchannel_call = GET_CALL(calld);
if (subchannel_call == NULL || subchannel_call == CANCELLED_CALL) {
return NULL;
} else {
return grpc_subchannel_call_get_peer(exec_ctx, subchannel_call);
}
}
typedef struct {
grpc_metadata_batch *initial_metadata;
uint32_t initial_metadata_flags;
@ -339,11 +507,11 @@ typedef struct {
grpc_closure closure;
} continue_picking_args;
static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *arg,
grpc_metadata_batch *initial_metadata,
uint32_t initial_metadata_flags,
grpc_connected_subchannel **connected_subchannel,
grpc_closure *on_ready);
static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_metadata_batch *initial_metadata,
uint32_t initial_metadata_flags,
grpc_connected_subchannel **connected_subchannel,
grpc_closure *on_ready);
static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
@ -352,22 +520,21 @@ static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg,
/* cancelled, do nothing */
} else if (error != GRPC_ERROR_NONE) {
grpc_exec_ctx_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_REF(error), NULL);
} else if (cc_pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata,
cpa->initial_metadata_flags,
cpa->connected_subchannel, cpa->on_ready)) {
} else if (pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata,
cpa->initial_metadata_flags,
cpa->connected_subchannel, cpa->on_ready)) {
grpc_exec_ctx_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE, NULL);
}
gpr_free(cpa);
}
static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
grpc_metadata_batch *initial_metadata,
uint32_t initial_metadata_flags,
grpc_connected_subchannel **connected_subchannel,
grpc_closure *on_ready) {
GPR_TIMER_BEGIN("cc_pick_subchannel", 0);
static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_metadata_batch *initial_metadata,
uint32_t initial_metadata_flags,
grpc_connected_subchannel **connected_subchannel,
grpc_closure *on_ready) {
GPR_TIMER_BEGIN("pick_subchannel", 0);
grpc_call_element *elem = elemp;
channel_data *chand = elem->channel_data;
call_data *calld = elem->call_data;
continue_picking_args *cpa;
@ -391,23 +558,23 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
}
}
gpr_mu_unlock(&chand->mu);
GPR_TIMER_END("cc_pick_subchannel", 0);
return 1;
GPR_TIMER_END("pick_subchannel", 0);
return true;
}
if (chand->lb_policy != NULL) {
grpc_lb_policy *lb_policy = chand->lb_policy;
int r;
GRPC_LB_POLICY_REF(lb_policy, "cc_pick_subchannel");
GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel");
gpr_mu_unlock(&chand->mu);
r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollent,
initial_metadata, initial_metadata_flags,
connected_subchannel, on_ready);
GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "cc_pick_subchannel");
GPR_TIMER_END("cc_pick_subchannel", 0);
GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "pick_subchannel");
GPR_TIMER_END("pick_subchannel", 0);
return r;
}
if (chand->resolver != NULL && !chand->started_resolving) {
chand->started_resolving = 1;
chand->started_resolving = true;
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result,
&chand->on_resolver_result_changed);
@ -428,66 +595,143 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp,
}
gpr_mu_unlock(&chand->mu);
GPR_TIMER_END("cc_pick_subchannel", 0);
return 0;
GPR_TIMER_END("pick_subchannel", 0);
return false;
}
// The logic here is fairly complicated, due to (a) the fact that we
// need to handle the case where we receive the send op before the
// initial metadata op, and (b) the need for efficiency, especially in
// the streaming case.
// TODO(ctiller): Explain this more thoroughly.
static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_transport_stream_op *op) {
call_data *calld = elem->call_data;
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
/* try to (atomically) get the call */
grpc_subchannel_call *call = GET_CALL(calld);
GPR_TIMER_BEGIN("cc_start_transport_stream_op", 0);
if (call == CANCELLED_CALL) {
grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
GRPC_ERROR_CANCELLED);
GPR_TIMER_END("cc_start_transport_stream_op", 0);
return;
}
if (call != NULL) {
grpc_subchannel_call_process_op(exec_ctx, call, op);
GPR_TIMER_END("cc_start_transport_stream_op", 0);
return;
}
/* we failed; lock and figure out what to do */
gpr_mu_lock(&calld->mu);
retry:
/* need to recheck that another thread hasn't set the call */
call = GET_CALL(calld);
if (call == CANCELLED_CALL) {
gpr_mu_unlock(&calld->mu);
grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
GRPC_ERROR_CANCELLED);
GPR_TIMER_END("cc_start_transport_stream_op", 0);
return;
}
if (call != NULL) {
gpr_mu_unlock(&calld->mu);
grpc_subchannel_call_process_op(exec_ctx, call, op);
GPR_TIMER_END("cc_start_transport_stream_op", 0);
return;
}
/* if this is a cancellation, then we can raise our cancelled flag */
if (op->cancel_error != GRPC_ERROR_NONE) {
if (!gpr_atm_rel_cas(&calld->subchannel_call, 0,
(gpr_atm)(uintptr_t)CANCELLED_CALL)) {
goto retry;
} else {
switch (calld->creation_phase) {
case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING:
fail_locked(exec_ctx, calld, GRPC_ERROR_REF(op->cancel_error));
break;
case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL:
pick_subchannel(exec_ctx, elem, NULL, 0, &calld->connected_subchannel,
NULL);
break;
}
gpr_mu_unlock(&calld->mu);
grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
GRPC_ERROR_CANCELLED);
GPR_TIMER_END("cc_start_transport_stream_op", 0);
return;
}
}
/* if we don't have a subchannel, try to get one */
if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
calld->connected_subchannel == NULL &&
op->send_initial_metadata != NULL) {
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
grpc_closure_init(&calld->next_step, subchannel_ready, calld);
GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel");
if (pick_subchannel(exec_ctx, elem, op->send_initial_metadata,
op->send_initial_metadata_flags,
&calld->connected_subchannel, &calld->next_step)) {
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
}
}
/* if we've got a subchannel, then let's ask it to create a call */
if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
calld->connected_subchannel != NULL) {
grpc_subchannel_call *subchannel_call = NULL;
grpc_error *error = grpc_connected_subchannel_create_call(
exec_ctx, calld->connected_subchannel, calld->pollent,
&subchannel_call);
if (error != GRPC_ERROR_NONE) {
subchannel_call = CANCELLED_CALL;
fail_locked(exec_ctx, calld, GRPC_ERROR_REF(error));
grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
}
gpr_atm_rel_store(&calld->subchannel_call,
(gpr_atm)(uintptr_t)subchannel_call);
retry_waiting_locked(exec_ctx, calld);
goto retry;
}
/* nothing to be done but wait */
add_waiting_locked(calld, op);
gpr_mu_unlock(&calld->mu);
GPR_TIMER_END("cc_start_transport_stream_op", 0);
}
/* Constructor for call_data */
static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_call_element_args *args) {
grpc_subchannel_call_holder_init(elem->call_data, cc_pick_subchannel, elem,
args->call_stack);
static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
grpc_call_element_args *args) {
call_data *calld = elem->call_data;
gpr_atm_rel_store(&calld->subchannel_call, 0);
gpr_mu_init(&calld->mu);
calld->connected_subchannel = NULL;
calld->waiting_ops = NULL;
calld->waiting_ops_count = 0;
calld->waiting_ops_capacity = 0;
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
calld->owning_call = args->call_stack;
calld->pollent = NULL;
return GRPC_ERROR_NONE;
}
/* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info,
void *and_free_memory) {
grpc_subchannel_call_holder_destroy(exec_ctx, elem->call_data);
gpr_free(and_free_memory);
}
/* Constructor for channel_data */
static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
grpc_channel_element_args *args) {
channel_data *chand = elem->channel_data;
memset(chand, 0, sizeof(*chand));
GPR_ASSERT(args->is_last);
GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
gpr_mu_init(&chand->mu);
grpc_closure_init(&chand->on_resolver_result_changed,
cc_on_resolver_result_changed, chand);
chand->owning_stack = args->channel_stack;
grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
"client_channel");
chand->interested_parties = grpc_pollset_set_create();
}
/* Destructor for channel_data */
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {
channel_data *chand = elem->channel_data;
if (chand->resolver != NULL) {
grpc_resolver_shutdown(exec_ctx, chand->resolver);
GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel");
}
if (chand->lb_policy != NULL) {
grpc_pollset_set_del_pollset_set(exec_ctx,
chand->lb_policy->interested_parties,
chand->interested_parties);
GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel");
static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
const grpc_call_final_info *final_info,
void *and_free_memory) {
call_data *calld = elem->call_data;
grpc_subchannel_call *call = GET_CALL(calld);
if (call != NULL && call != CANCELLED_CALL) {
GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call");
}
grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
grpc_pollset_set_destroy(chand->interested_parties);
gpr_mu_destroy(&chand->mu);
GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING);
gpr_mu_destroy(&calld->mu);
GPR_ASSERT(calld->waiting_ops_count == 0);
gpr_free(calld->waiting_ops);
gpr_free(and_free_memory);
}
static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
@ -497,16 +741,20 @@ static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
calld->pollent = pollent;
}
/*************************************************************************
* EXPORTED SYMBOLS
*/
const grpc_channel_filter grpc_client_channel_filter = {
cc_start_transport_stream_op,
cc_start_transport_op,
sizeof(call_data),
init_call_elem,
cc_init_call_elem,
cc_set_pollset_or_pollset_set,
destroy_call_elem,
cc_destroy_call_elem,
sizeof(channel_data),
init_channel_elem,
destroy_channel_elem,
cc_init_channel_elem,
cc_destroy_channel_elem,
cc_get_peer,
"client-channel",
};
@ -523,7 +771,7 @@ void grpc_client_channel_set_resolver(grpc_exec_ctx *exec_ctx,
GRPC_RESOLVER_REF(resolver, "channel");
if (!grpc_closure_list_empty(chand->waiting_for_config_closures) ||
chand->exit_idle_when_lb_policy_arrives) {
chand->started_resolving = 1;
chand->started_resolving = true;
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
grpc_resolver_next(exec_ctx, resolver, &chand->resolver_result,
&chand->on_resolver_result_changed);
@ -541,10 +789,10 @@ grpc_connectivity_state grpc_client_channel_check_connectivity_state(
if (chand->lb_policy != NULL) {
grpc_lb_policy_exit_idle(exec_ctx, chand->lb_policy);
} else {
chand->exit_idle_when_lb_policy_arrives = 1;
chand->exit_idle_when_lb_policy_arrives = true;
if (!chand->started_resolving && chand->resolver != NULL) {
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
chand->started_resolving = 1;
chand->started_resolving = true;
grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result,
&chand->on_resolver_result_changed);
}

@ -1,292 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/ext/client_config/subchannel_call_holder.h"
#include <grpc/support/alloc.h>
#include "src/core/lib/profiling/timers.h"
#define GET_CALL(holder) \
((grpc_subchannel_call *)(gpr_atm_acq_load(&(holder)->subchannel_call)))
#define CANCELLED_CALL ((grpc_subchannel_call *)1)
static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *holder,
grpc_error *error);
static void retry_ops(grpc_exec_ctx *exec_ctx, void *retry_ops_args,
grpc_error *error);
static void add_waiting_locked(grpc_subchannel_call_holder *holder,
grpc_transport_stream_op *op);
static void fail_locked(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call_holder *holder, grpc_error *error);
static void retry_waiting_locked(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call_holder *holder);
void grpc_subchannel_call_holder_init(
grpc_subchannel_call_holder *holder,
grpc_subchannel_call_holder_pick_subchannel pick_subchannel,
void *pick_subchannel_arg, grpc_call_stack *owning_call) {
gpr_atm_rel_store(&holder->subchannel_call, 0);
holder->pick_subchannel = pick_subchannel;
holder->pick_subchannel_arg = pick_subchannel_arg;
gpr_mu_init(&holder->mu);
holder->connected_subchannel = NULL;
holder->waiting_ops = NULL;
holder->waiting_ops_count = 0;
holder->waiting_ops_capacity = 0;
holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
holder->owning_call = owning_call;
holder->pollent = NULL;
}
void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call_holder *holder) {
grpc_subchannel_call *call = GET_CALL(holder);
if (call != NULL && call != CANCELLED_CALL) {
GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "holder");
}
GPR_ASSERT(holder->creation_phase ==
GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING);
gpr_mu_destroy(&holder->mu);
GPR_ASSERT(holder->waiting_ops_count == 0);
gpr_free(holder->waiting_ops);
}
// The logic here is fairly complicated, due to (a) the fact that we
// need to handle the case where we receive the send op before the
// initial metadata op, and (b) the need for efficiency, especially in
// the streaming case.
// TODO(ctiller): Explain this more thoroughly.
void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call_holder *holder,
grpc_transport_stream_op *op) {
/* try to (atomically) get the call */
grpc_subchannel_call *call = GET_CALL(holder);
GPR_TIMER_BEGIN("grpc_subchannel_call_holder_perform_op", 0);
if (call == CANCELLED_CALL) {
grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
GRPC_ERROR_CANCELLED);
GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
return;
}
if (call != NULL) {
grpc_subchannel_call_process_op(exec_ctx, call, op);
GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
return;
}
/* we failed; lock and figure out what to do */
gpr_mu_lock(&holder->mu);
retry:
/* need to recheck that another thread hasn't set the call */
call = GET_CALL(holder);
if (call == CANCELLED_CALL) {
gpr_mu_unlock(&holder->mu);
grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
GRPC_ERROR_CANCELLED);
GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
return;
}
if (call != NULL) {
gpr_mu_unlock(&holder->mu);
grpc_subchannel_call_process_op(exec_ctx, call, op);
GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
return;
}
/* if this is a cancellation, then we can raise our cancelled flag */
if (op->cancel_error != GRPC_ERROR_NONE) {
if (!gpr_atm_rel_cas(&holder->subchannel_call, 0,
(gpr_atm)(uintptr_t)CANCELLED_CALL)) {
goto retry;
} else {
switch (holder->creation_phase) {
case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING:
fail_locked(exec_ctx, holder, GRPC_ERROR_REF(op->cancel_error));
break;
case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL:
holder->pick_subchannel(exec_ctx, holder->pick_subchannel_arg, NULL,
0, &holder->connected_subchannel, NULL);
break;
}
gpr_mu_unlock(&holder->mu);
grpc_transport_stream_op_finish_with_failure(exec_ctx, op,
GRPC_ERROR_CANCELLED);
GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
return;
}
}
/* if we don't have a subchannel, try to get one */
if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
holder->connected_subchannel == NULL &&
op->send_initial_metadata != NULL) {
holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
grpc_closure_init(&holder->next_step, subchannel_ready, holder);
GRPC_CALL_STACK_REF(holder->owning_call, "pick_subchannel");
if (holder->pick_subchannel(
exec_ctx, holder->pick_subchannel_arg, op->send_initial_metadata,
op->send_initial_metadata_flags, &holder->connected_subchannel,
&holder->next_step)) {
holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel");
}
}
/* if we've got a subchannel, then let's ask it to create a call */
if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
holder->connected_subchannel != NULL) {
grpc_subchannel_call *subchannel_call = NULL;
grpc_error *error = grpc_connected_subchannel_create_call(
exec_ctx, holder->connected_subchannel, holder->pollent,
&subchannel_call);
if (error != GRPC_ERROR_NONE) {
subchannel_call = CANCELLED_CALL;
fail_locked(exec_ctx, holder, GRPC_ERROR_REF(error));
grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error);
}
gpr_atm_rel_store(&holder->subchannel_call,
(gpr_atm)(uintptr_t)subchannel_call);
retry_waiting_locked(exec_ctx, holder);
goto retry;
}
/* nothing to be done but wait */
add_waiting_locked(holder, op);
gpr_mu_unlock(&holder->mu);
GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0);
}
static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {
grpc_subchannel_call_holder *holder = arg;
gpr_mu_lock(&holder->mu);
GPR_ASSERT(holder->creation_phase ==
GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL);
holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
if (holder->connected_subchannel == NULL) {
gpr_atm_no_barrier_store(&holder->subchannel_call, 1);
fail_locked(exec_ctx, holder,
GRPC_ERROR_CREATE_REFERENCING("Failed to create subchannel",
&error, 1));
} else if (1 == gpr_atm_acq_load(&holder->subchannel_call)) {
/* already cancelled before subchannel became ready */
fail_locked(exec_ctx, holder,
GRPC_ERROR_CREATE_REFERENCING(
"Cancelled before creating subchannel", &error, 1));
} else {
grpc_subchannel_call *subchannel_call = NULL;
grpc_error *new_error = grpc_connected_subchannel_create_call(
exec_ctx, holder->connected_subchannel, holder->pollent,
&subchannel_call);
if (new_error != GRPC_ERROR_NONE) {
new_error = grpc_error_add_child(new_error, error);
subchannel_call = CANCELLED_CALL;
fail_locked(exec_ctx, holder, new_error);
}
gpr_atm_rel_store(&holder->subchannel_call,
(gpr_atm)(uintptr_t)subchannel_call);
retry_waiting_locked(exec_ctx, holder);
}
gpr_mu_unlock(&holder->mu);
GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel");
}
typedef struct {
grpc_transport_stream_op *ops;
size_t nops;
grpc_subchannel_call *call;
} retry_ops_args;
static void retry_waiting_locked(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call_holder *holder) {
retry_ops_args *a = gpr_malloc(sizeof(*a));
a->ops = holder->waiting_ops;
a->nops = holder->waiting_ops_count;
a->call = GET_CALL(holder);
if (a->call == CANCELLED_CALL) {
gpr_free(a);
fail_locked(exec_ctx, holder, GRPC_ERROR_CANCELLED);
return;
}
holder->waiting_ops = NULL;
holder->waiting_ops_count = 0;
holder->waiting_ops_capacity = 0;
GRPC_SUBCHANNEL_CALL_REF(a->call, "retry_ops");
grpc_exec_ctx_sched(exec_ctx, grpc_closure_create(retry_ops, a),
GRPC_ERROR_NONE, NULL);
}
static void retry_ops(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) {
retry_ops_args *a = args;
size_t i;
for (i = 0; i < a->nops; i++) {
grpc_subchannel_call_process_op(exec_ctx, a->call, &a->ops[i]);
}
GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, a->call, "retry_ops");
gpr_free(a->ops);
gpr_free(a);
}
static void add_waiting_locked(grpc_subchannel_call_holder *holder,
grpc_transport_stream_op *op) {
GPR_TIMER_BEGIN("add_waiting_locked", 0);
if (holder->waiting_ops_count == holder->waiting_ops_capacity) {
holder->waiting_ops_capacity = GPR_MAX(3, 2 * holder->waiting_ops_capacity);
holder->waiting_ops =
gpr_realloc(holder->waiting_ops, holder->waiting_ops_capacity *
sizeof(*holder->waiting_ops));
}
holder->waiting_ops[holder->waiting_ops_count++] = *op;
GPR_TIMER_END("add_waiting_locked", 0);
}
static void fail_locked(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call_holder *holder,
grpc_error *error) {
size_t i;
for (i = 0; i < holder->waiting_ops_count; i++) {
grpc_transport_stream_op_finish_with_failure(
exec_ctx, &holder->waiting_ops[i], GRPC_ERROR_REF(error));
}
holder->waiting_ops_count = 0;
GRPC_ERROR_UNREF(error);
}
char *grpc_subchannel_call_holder_get_peer(
grpc_exec_ctx *exec_ctx, grpc_subchannel_call_holder *holder) {
grpc_subchannel_call *subchannel_call = GET_CALL(holder);
if (subchannel_call == NULL || subchannel_call == CANCELLED_CALL) {
return NULL;
} else {
return grpc_subchannel_call_get_peer(exec_ctx, subchannel_call);
}
}

@ -1,99 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_EXT_CLIENT_CONFIG_SUBCHANNEL_CALL_HOLDER_H
#define GRPC_CORE_EXT_CLIENT_CONFIG_SUBCHANNEL_CALL_HOLDER_H
#include "src/core/ext/client_config/subchannel.h"
#include "src/core/lib/iomgr/polling_entity.h"
/** Pick a subchannel for grpc_subchannel_call_holder;
Return 1 if subchannel is available immediately (in which case on_ready
should not be called), or 0 otherwise (in which case on_ready should be
called when the subchannel is available) */
typedef int (*grpc_subchannel_call_holder_pick_subchannel)(
grpc_exec_ctx *exec_ctx, void *arg, grpc_metadata_batch *initial_metadata,
uint32_t initial_metadata_flags,
grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready);
typedef enum {
GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING,
GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
} grpc_subchannel_call_holder_creation_phase;
/** Wrapper for holding a pointer to grpc_subchannel_call, and the
associated machinery to create such a pointer.
Handles queueing of stream ops until a call object is ready, waiting
for initial metadata before trying to create a call object,
and handling cancellation gracefully.
The channel filter uses this as their call_data. */
typedef struct grpc_subchannel_call_holder {
/** either 0 for no call, 1 for cancelled, or a pointer to a
grpc_subchannel_call */
gpr_atm subchannel_call;
/** Helper function to choose the subchannel on which to create
the call object. Channel filter delegates to the load
balancing policy (once it's ready). */
grpc_subchannel_call_holder_pick_subchannel pick_subchannel;
void *pick_subchannel_arg;
gpr_mu mu;
grpc_subchannel_call_holder_creation_phase creation_phase;
grpc_connected_subchannel *connected_subchannel;
grpc_polling_entity *pollent;
grpc_transport_stream_op *waiting_ops;
size_t waiting_ops_count;
size_t waiting_ops_capacity;
grpc_closure next_step;
grpc_call_stack *owning_call;
} grpc_subchannel_call_holder;
void grpc_subchannel_call_holder_init(
grpc_subchannel_call_holder *holder,
grpc_subchannel_call_holder_pick_subchannel pick_subchannel,
void *pick_subchannel_arg, grpc_call_stack *owning_call);
void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call_holder *holder);
void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call_holder *holder,
grpc_transport_stream_op *op);
char *grpc_subchannel_call_holder_get_peer(grpc_exec_ctx *exec_ctx,
grpc_subchannel_call_holder *holder);
#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_SUBCHANNEL_CALL_HOLDER_H */

@ -408,6 +408,19 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t,
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
(uint32_t)channel_args->args[i].value.integer);
}
} else if (0 == strcmp(channel_args->args[i].key,
GRPC_ARG_HTTP2_MAX_FRAME_SIZE)) {
if (channel_args->args[i].type != GRPC_ARG_INTEGER) {
gpr_log(GPR_ERROR, "%s: must be an integer",
GRPC_ARG_HTTP2_MAX_FRAME_SIZE);
} else if (channel_args->args[i].value.integer < 16384 ||
channel_args->args[i].value.integer > 16777215) {
gpr_log(GPR_ERROR, "%s: must be between 16384 and 16777215",
GRPC_ARG_HTTP2_MAX_FRAME_SIZE);
} else {
push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
(uint32_t)channel_args->args[i].value.integer);
}
}
}
}

@ -52,8 +52,6 @@ typedef struct grpc_chttp2_transport_parsing grpc_chttp2_transport_parsing;
#define GRPC_CHTTP2_FRAME_GOAWAY 7
#define GRPC_CHTTP2_FRAME_WINDOW_UPDATE 8
#define GRPC_CHTTP2_MAX_PAYLOAD_LENGTH ((1 << 14) - 1)
#define GRPC_CHTTP2_DATA_FLAG_END_STREAM 1
#define GRPC_CHTTP2_FLAG_ACK 1
#define GRPC_CHTTP2_DATA_FLAG_END_HEADERS 4

@ -78,6 +78,8 @@ typedef struct {
uint32_t stream_id;
gpr_slice_buffer *output;
grpc_transport_one_way_stats *stats;
/* maximum size of a frame */
size_t max_frame_size;
} framer_state;
/* fills p (which is expected to be 9 bytes long) with a data frame header */
@ -123,7 +125,7 @@ static void begin_frame(framer_state *st) {
needed */
static void ensure_space(framer_state *st, size_t need_bytes) {
if (st->output->length - st->output_length_at_start_of_frame + need_bytes <=
GRPC_CHTTP2_MAX_PAYLOAD_LENGTH) {
st->max_frame_size) {
return;
}
finish_frame(st, 0, 0);
@ -149,8 +151,8 @@ static void add_header_data(framer_state *st, gpr_slice slice) {
size_t len = GPR_SLICE_LENGTH(slice);
size_t remaining;
if (len == 0) return;
remaining = GRPC_CHTTP2_MAX_PAYLOAD_LENGTH +
st->output_length_at_start_of_frame - st->output->length;
remaining = st->max_frame_size + st->output_length_at_start_of_frame -
st->output->length;
if (len <= remaining) {
st->stats->header_bytes += len;
gpr_slice_buffer_add(st->output, slice);
@ -542,6 +544,7 @@ void grpc_chttp2_hpack_compressor_set_max_table_size(
void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
uint32_t stream_id,
grpc_metadata_batch *metadata, int is_eof,
size_t max_frame_size,
grpc_transport_one_way_stats *stats,
gpr_slice_buffer *outbuf) {
framer_state st;
@ -555,6 +558,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
st.output = outbuf;
st.is_first_frame = 1;
st.stats = stats;
st.max_frame_size = max_frame_size;
/* Encode a metadata batch; store the returned values, representing
a metadata element that needs to be unreffed back into the metadata

@ -91,6 +91,7 @@ void grpc_chttp2_hpack_compressor_set_max_usable_size(
void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t id,
grpc_metadata_batch *metadata, int is_eof,
size_t max_frame_size,
grpc_transport_one_way_stats *stats,
gpr_slice_buffer *outbuf);

@ -223,6 +223,8 @@ typedef struct {
uint8_t is_client;
/** callback for when writing is done */
grpc_closure done_cb;
/** maximum frame size */
uint32_t max_frame_size;
} grpc_chttp2_transport_writing;
struct grpc_chttp2_transport_parsing {

@ -51,6 +51,10 @@ int grpc_chttp2_unlocking_check_writes(
GPR_TIMER_BEGIN("grpc_chttp2_unlocking_check_writes", 0);
transport_writing->max_frame_size =
transport_global->settings[GRPC_ACKED_SETTINGS]
[GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE];
/* simple writes are queued to qbuf, and flushed here */
gpr_slice_buffer_swap(&transport_global->qbuf, &transport_writing->outbuf);
GPR_ASSERT(transport_global->qbuf.count == 0);
@ -206,14 +210,15 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
while (
grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) {
uint32_t max_outgoing =
(uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH,
(uint32_t)GPR_MIN(transport_writing->max_frame_size,
GPR_MIN(stream_writing->outgoing_window,
transport_writing->outgoing_window));
/* send initial metadata if it's available */
if (stream_writing->send_initial_metadata != NULL) {
grpc_chttp2_encode_header(
&transport_writing->hpack_compressor, stream_writing->id,
stream_writing->send_initial_metadata, 0, &stream_writing->stats,
stream_writing->send_initial_metadata, 0,
transport_writing->max_frame_size, &stream_writing->stats,
&transport_writing->outbuf);
stream_writing->send_initial_metadata = NULL;
stream_writing->sent_initial_metadata = 1;
@ -303,7 +308,8 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx,
} else {
grpc_chttp2_encode_header(
&transport_writing->hpack_compressor, stream_writing->id,
stream_writing->send_trailing_metadata, 1, &stream_writing->stats,
stream_writing->send_trailing_metadata, 1,
transport_writing->max_frame_size, &stream_writing->stats,
&transport_writing->outbuf);
}
if (!transport_writing->is_client && !stream_writing->read_closed) {

@ -43,6 +43,9 @@
#define EXPECTED_CONTENT_TYPE "application/grpc"
#define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1
/* default maximum size of payload eligable for GET request */
static const size_t kMaxPayloadSizeForGet = 2048;
typedef struct call_data {
grpc_linked_mdelem method;
grpc_linked_mdelem scheme;
@ -50,20 +53,39 @@ typedef struct call_data {
grpc_linked_mdelem te_trailers;
grpc_linked_mdelem content_type;
grpc_linked_mdelem user_agent;
grpc_linked_mdelem payload_bin;
grpc_metadata_batch *recv_initial_metadata;
uint8_t *payload_bytes;
/* Vars to read data off of send_message */
grpc_transport_stream_op send_op;
uint32_t send_length;
uint32_t send_flags;
gpr_slice incoming_slice;
grpc_slice_buffer_stream replacement_stream;
gpr_slice_buffer slices;
/* flag that indicates that all slices of send_messages aren't availble */
bool send_message_blocked;
/** Closure to call when finished with the hc_on_recv hook */
grpc_closure *on_done_recv;
grpc_closure *on_complete;
grpc_closure *post_send;
/** Receive closures are chained: we inject this closure as the on_done_recv
up-call on transport_op, and remember to call our on_done_recv member
after handling it. */
grpc_closure hc_on_recv;
grpc_closure hc_on_complete;
grpc_closure got_slice;
grpc_closure send_done;
} call_data;
typedef struct channel_data {
grpc_mdelem *static_scheme;
grpc_mdelem *user_agent;
size_t max_payload_size_for_get;
} channel_data;
typedef struct {
@ -119,6 +141,24 @@ static void hc_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, error);
}
static void hc_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_error *error) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
if (calld->payload_bytes) {
gpr_free(calld->payload_bytes);
calld->payload_bytes = NULL;
}
calld->on_complete->cb(exec_ctx, calld->on_complete->cb_arg, error);
}
static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
grpc_call_element *elem = elemp;
call_data *calld = elem->call_data;
gpr_slice_buffer_reset_and_unref(&calld->slices);
calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error);
}
static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
/* eat the things we'd like to set ourselves */
if (md->key == GRPC_MDSTR_METHOD) return NULL;
@ -129,22 +169,104 @@ static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) {
return md;
}
static void hc_mutate_op(grpc_call_element *elem,
static void continue_send_message(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem) {
call_data *calld = elem->call_data;
uint8_t *wrptr = calld->payload_bytes;
while (grpc_byte_stream_next(exec_ctx, calld->send_op.send_message,
&calld->incoming_slice, ~(size_t)0,
&calld->got_slice)) {
memcpy(wrptr, GPR_SLICE_START_PTR(calld->incoming_slice),
GPR_SLICE_LENGTH(calld->incoming_slice));
wrptr += GPR_SLICE_LENGTH(calld->incoming_slice);
gpr_slice_buffer_add(&calld->slices, calld->incoming_slice);
if (calld->send_length == calld->slices.length) {
calld->send_message_blocked = false;
break;
}
}
}
static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) {
grpc_call_element *elem = elemp;
call_data *calld = elem->call_data;
calld->send_message_blocked = false;
gpr_slice_buffer_add(&calld->slices, calld->incoming_slice);
if (calld->send_length == calld->slices.length) {
/* Pass down the original send_message op that was blocked.*/
grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices,
calld->send_flags);
calld->send_op.send_message = &calld->replacement_stream.base;
calld->post_send = calld->send_op.on_complete;
calld->send_op.on_complete = &calld->send_done;
grpc_call_next_op(exec_ctx, elem, &calld->send_op);
} else {
continue_send_message(exec_ctx, elem);
}
}
static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
grpc_transport_stream_op *op) {
/* grab pointers to our data from the call element */
call_data *calld = elem->call_data;
channel_data *channeld = elem->channel_data;
if (op->send_initial_metadata != NULL) {
/* Decide which HTTP VERB to use. We use GET if the request is marked
cacheable, and the operation contains both initial metadata and send
message, and the payload is below the size threshold, and all the data
for this request is immediately available. */
grpc_mdelem *method = GRPC_MDELEM_METHOD_POST;
calld->send_message_blocked = false;
if ((op->send_initial_metadata_flags &
GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) &&
op->send_message != NULL &&
op->send_message->length < channeld->max_payload_size_for_get) {
method = GRPC_MDELEM_METHOD_GET;
calld->send_message_blocked = true;
} else if (op->send_initial_metadata_flags &
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) {
method = GRPC_MDELEM_METHOD_PUT;
}
/* Attempt to read the data from send_message and create a header field. */
if (method == GRPC_MDELEM_METHOD_GET) {
/* allocate memory to hold the entire payload */
calld->payload_bytes = gpr_malloc(op->send_message->length);
/* read slices of send_message and copy into payload_bytes */
calld->send_op = *op;
calld->send_length = op->send_message->length;
calld->send_flags = op->send_message->flags;
continue_send_message(exec_ctx, elem);
if (calld->send_message_blocked == false) {
/* when all the send_message data is available, then create a MDELEM and
append to headers */
grpc_mdelem *payload_bin = grpc_mdelem_from_metadata_strings(
GRPC_MDSTR_GRPC_PAYLOAD_BIN,
grpc_mdstr_from_buffer(calld->payload_bytes,
op->send_message->length));
grpc_metadata_batch_add_tail(op->send_initial_metadata,
&calld->payload_bin, payload_bin);
calld->on_complete = op->on_complete;
op->on_complete = &calld->hc_on_complete;
op->send_message = NULL;
} else {
/* Not all data is available. Fall back to POST. */
gpr_log(GPR_DEBUG,
"Request is marked Cacheable but not all data is available.\
Falling back to POST");
method = GRPC_MDELEM_METHOD_POST;
}
}
grpc_metadata_batch_filter(op->send_initial_metadata, client_strip_filter,
elem);
/* Send : prefixed headers, which have to be before any application
layer headers. */
grpc_metadata_batch_add_head(
op->send_initial_metadata, &calld->method,
op->send_initial_metadata_flags &
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
? GRPC_MDELEM_METHOD_PUT
: GRPC_MDELEM_METHOD_POST);
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method,
method);
grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme,
channeld->static_scheme);
grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers,
@ -169,9 +291,16 @@ static void hc_start_transport_op(grpc_exec_ctx *exec_ctx,
grpc_transport_stream_op *op) {
GPR_TIMER_BEGIN("hc_start_transport_op", 0);
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
hc_mutate_op(elem, op);
hc_mutate_op(exec_ctx, elem, op);
GPR_TIMER_END("hc_start_transport_op", 0);
grpc_call_next_op(exec_ctx, elem, op);
call_data *calld = elem->call_data;
if (op->send_message != NULL && calld->send_message_blocked) {
/* Don't forward the op. send_message contains slices that aren't ready
yet. The call will be forwarded by the op_complete of slice read call.
*/
} else {
grpc_call_next_op(exec_ctx, elem, op);
}
}
/* Constructor for call_data */
@ -180,14 +309,23 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
grpc_call_element_args *args) {
call_data *calld = elem->call_data;
calld->on_done_recv = NULL;
calld->on_complete = NULL;
calld->payload_bytes = NULL;
gpr_slice_buffer_init(&calld->slices);
grpc_closure_init(&calld->hc_on_recv, hc_on_recv, elem);
grpc_closure_init(&calld->hc_on_complete, hc_on_complete, elem);
grpc_closure_init(&calld->got_slice, got_slice, elem);
grpc_closure_init(&calld->send_done, send_done, elem);
return GRPC_ERROR_NONE;
}
/* Destructor for call_data */
static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
const grpc_call_final_info *final_info,
void *ignored) {}
void *ignored) {
call_data *calld = elem->call_data;
gpr_slice_buffer_destroy(&calld->slices);
}
static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
unsigned i;
@ -210,6 +348,22 @@ static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
return GRPC_MDELEM_SCHEME_HTTP;
}
static size_t max_payload_size_from_args(const grpc_channel_args *args) {
if (args != NULL) {
for (size_t i = 0; i < args->num_args; ++i) {
if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET)) {
if (args->args[i].type != GRPC_ARG_INTEGER) {
gpr_log(GPR_ERROR, "%s: must be an integer",
GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET);
} else {
return (size_t)args->args[i].value.integer;
}
}
}
}
return kMaxPayloadSizeForGet;
}
static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
const char *transport_name) {
gpr_strvec v;
@ -268,6 +422,8 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
GPR_ASSERT(!args->is_last);
GPR_ASSERT(args->optional_transport != NULL);
chand->static_scheme = scheme_from_args(args->channel_args);
chand->max_payload_size_for_get =
max_payload_size_from_args(args->channel_args);
chand->user_agent = grpc_mdelem_from_metadata_strings(
GRPC_MDSTR_USER_AGENT,
user_agent_from_args(args->channel_args,

@ -41,4 +41,7 @@ extern const grpc_channel_filter grpc_http_client_filter;
/* Channel arg to override the http2 :scheme header */
#define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
/* Channel arg to determine maximum size of payload eligable for GET request */
#define GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET "grpc.max_payload_size_for_get"
#endif /* GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H */

@ -49,17 +49,32 @@ typedef struct call_data {
uint8_t seen_scheme;
uint8_t seen_te_trailers;
uint8_t seen_authority;
uint8_t seen_payload_bin;
grpc_linked_mdelem status;
grpc_linked_mdelem content_type;
/* flag to ensure payload_bin is delivered only once */
uint8_t payload_bin_delivered;
grpc_metadata_batch *recv_initial_metadata;
bool *recv_idempotent_request;
bool *recv_cacheable_request;
/** Closure to call when finished with the hs_on_recv hook */
grpc_closure *on_done_recv;
/** Closure to call when we retrieve read message from the payload-bin header
*/
grpc_closure *recv_message_ready;
grpc_closure *on_complete;
grpc_byte_stream **pp_recv_message;
gpr_slice_buffer read_slice_buffer;
grpc_slice_buffer_stream read_stream;
/** Receive closures are chained: we inject this closure as the on_done_recv
up-call on transport_op, and remember to call our on_done_recv member
after handling it. */
grpc_closure hs_on_recv;
grpc_closure hs_on_complete;
grpc_closure hs_recv_message_ready;
} call_data;
typedef struct channel_data { uint8_t unused; } channel_data;
@ -76,16 +91,20 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
/* Check if it is one of the headers we care about. */
if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST ||
md == GRPC_MDELEM_METHOD_PUT || md == GRPC_MDELEM_SCHEME_HTTP ||
md == GRPC_MDELEM_SCHEME_HTTPS ||
md == GRPC_MDELEM_METHOD_PUT || md == GRPC_MDELEM_METHOD_GET ||
md == GRPC_MDELEM_SCHEME_HTTP || md == GRPC_MDELEM_SCHEME_HTTPS ||
md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
/* swallow it */
if (md == GRPC_MDELEM_METHOD_POST) {
calld->seen_method = 1;
*calld->recv_idempotent_request = false;
*calld->recv_cacheable_request = false;
} else if (md == GRPC_MDELEM_METHOD_PUT) {
calld->seen_method = 1;
*calld->recv_idempotent_request = true;
} else if (md == GRPC_MDELEM_METHOD_GET) {
calld->seen_method = 1;
*calld->recv_cacheable_request = true;
} else if (md->key == GRPC_MDSTR_SCHEME) {
calld->seen_scheme = 1;
} else if (md == GRPC_MDELEM_TE_TRAILERS) {
@ -137,6 +156,16 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value));
calld->seen_authority = 1;
return authority;
} else if (md->key == GRPC_MDSTR_GRPC_PAYLOAD_BIN) {
/* Retrieve the payload from the value of the 'grpc-internal-payload-bin'
header field */
calld->seen_payload_bin = 1;
gpr_slice_buffer_init(&calld->read_slice_buffer);
gpr_slice_buffer_add(&calld->read_slice_buffer,
gpr_slice_ref(md->value->slice));
grpc_slice_buffer_stream_init(&calld->read_stream,
&calld->read_slice_buffer, 0);
return NULL;
} else {
return md;
}
@ -189,6 +218,36 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
GRPC_ERROR_UNREF(err);
}
static void hs_on_complete(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_error *err) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
/* Call recv_message_ready if we got the payload via the header field */
if (calld->seen_payload_bin && calld->recv_message_ready != NULL) {
*calld->pp_recv_message = calld->payload_bin_delivered
? NULL
: (grpc_byte_stream *)&calld->read_stream;
calld->recv_message_ready->cb(exec_ctx, calld->recv_message_ready->cb_arg,
err);
calld->recv_message_ready = NULL;
calld->payload_bin_delivered = true;
}
calld->on_complete->cb(exec_ctx, calld->on_complete->cb_arg, err);
}
static void hs_recv_message_ready(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_error *err) {
grpc_call_element *elem = user_data;
call_data *calld = elem->call_data;
if (calld->seen_payload_bin) {
/* do nothing. This is probably a GET request, and payload will be returned
in hs_on_complete callback. */
} else {
calld->recv_message_ready->cb(exec_ctx, calld->recv_message_ready->cb_arg,
err);
}
}
static void hs_mutate_op(grpc_call_element *elem,
grpc_transport_stream_op *op) {
/* grab pointers to our data from the call element */
@ -206,11 +265,25 @@ static void hs_mutate_op(grpc_call_element *elem,
if (op->recv_initial_metadata) {
/* substitute our callback for the higher callback */
GPR_ASSERT(op->recv_idempotent_request != NULL);
GPR_ASSERT(op->recv_cacheable_request != NULL);
calld->recv_initial_metadata = op->recv_initial_metadata;
calld->recv_idempotent_request = op->recv_idempotent_request;
calld->recv_cacheable_request = op->recv_cacheable_request;
calld->on_done_recv = op->recv_initial_metadata_ready;
op->recv_initial_metadata_ready = &calld->hs_on_recv;
}
if (op->recv_message) {
calld->recv_message_ready = op->recv_message_ready;
calld->pp_recv_message = op->recv_message;
if (op->recv_message_ready) {
op->recv_message_ready = &calld->hs_recv_message_ready;
}
if (op->on_complete) {
calld->on_complete = op->on_complete;
op->on_complete = &calld->hs_on_complete;
}
}
}
static void hs_start_transport_op(grpc_exec_ctx *exec_ctx,
@ -232,6 +305,8 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx,
/* initialize members */
memset(calld, 0, sizeof(*calld));
grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem);
grpc_closure_init(&calld->hs_on_complete, hs_on_complete, elem);
grpc_closure_init(&calld->hs_recv_message_ready, hs_recv_message_ready, elem);
return GRPC_ERROR_NONE;
}

@ -99,6 +99,9 @@ void grpc_client_security_context_destroy(void *ctx) {
grpc_client_security_context *c = (grpc_client_security_context *)ctx;
grpc_call_credentials_unref(c->creds);
GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context");
if (c->extension.instance != NULL && c->extension.destroy != NULL) {
c->extension.destroy(c->extension.instance);
}
gpr_free(ctx);
}
@ -114,6 +117,9 @@ grpc_server_security_context *grpc_server_security_context_create(void) {
void grpc_server_security_context_destroy(void *ctx) {
grpc_server_security_context *c = (grpc_server_security_context *)ctx;
GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "server_security_context");
if (c->extension.instance != NULL && c->extension.destroy != NULL) {
c->extension.destroy(c->extension.instance);
}
gpr_free(ctx);
}

@ -84,6 +84,16 @@ void grpc_auth_context_unref(grpc_auth_context *policy);
void grpc_auth_property_reset(grpc_auth_property *property);
/* --- grpc_security_context_extension ---
Extension to the security context that may be set in a filter and accessed
later by a higher level method on a grpc_call object. */
typedef struct {
void *instance;
void (*destroy)(void *);
} grpc_security_context_extension;
/* --- grpc_client_security_context ---
Internal client-side security context. */
@ -91,6 +101,7 @@ void grpc_auth_property_reset(grpc_auth_property *property);
typedef struct {
grpc_call_credentials *creds;
grpc_auth_context *auth_context;
grpc_security_context_extension extension;
} grpc_client_security_context;
grpc_client_security_context *grpc_client_security_context_create(void);
@ -102,6 +113,7 @@ void grpc_client_security_context_destroy(void *ctx);
typedef struct {
grpc_auth_context *auth_context;
grpc_security_context_extension extension;
} grpc_server_security_context;
grpc_server_security_context *grpc_server_security_context_create(void);

@ -0,0 +1,180 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/lib/support/percent_encoding.h"
#include <grpc/support/log.h>
const uint8_t gpr_url_percent_encoding_unreserved_bytes[256 / 8] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0xfe, 0xff, 0xff,
0x87, 0xfe, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const uint8_t gpr_compatible_percent_encoding_unreserved_bytes[256 / 8] = {
0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static bool is_unreserved_character(uint8_t c,
const uint8_t *unreserved_bytes) {
return ((unreserved_bytes[c / 8] >> (c % 8)) & 1) != 0;
}
gpr_slice gpr_percent_encode_slice(gpr_slice slice,
const uint8_t *unreserved_bytes) {
static const uint8_t hex[] = "0123456789ABCDEF";
// first pass: count the number of bytes needed to output this string
size_t output_length = 0;
const uint8_t *slice_start = GPR_SLICE_START_PTR(slice);
const uint8_t *slice_end = GPR_SLICE_END_PTR(slice);
const uint8_t *p;
bool any_reserved_bytes = false;
for (p = slice_start; p < slice_end; p++) {
bool unres = is_unreserved_character(*p, unreserved_bytes);
output_length += unres ? 1 : 3;
any_reserved_bytes |= !unres;
}
// no unreserved bytes: return the string unmodified
if (!any_reserved_bytes) {
return gpr_slice_ref(slice);
}
// second pass: actually encode
gpr_slice out = gpr_slice_malloc(output_length);
uint8_t *q = GPR_SLICE_START_PTR(out);
for (p = slice_start; p < slice_end; p++) {
if (is_unreserved_character(*p, unreserved_bytes)) {
*q++ = *p;
} else {
*q++ = '%';
*q++ = hex[*p >> 4];
*q++ = hex[*p & 15];
}
}
GPR_ASSERT(q == GPR_SLICE_END_PTR(out));
return out;
}
static bool valid_hex(const uint8_t *p, const uint8_t *end) {
if (p >= end) return false;
return (*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') ||
(*p >= 'A' && *p <= 'F');
}
static uint8_t dehex(uint8_t c) {
if (c >= '0' && c <= '9') return (uint8_t)(c - '0');
if (c >= 'A' && c <= 'F') return (uint8_t)(c - 'A' + 10);
if (c >= 'a' && c <= 'f') return (uint8_t)(c - 'a' + 10);
GPR_UNREACHABLE_CODE(return 255);
}
bool gpr_strict_percent_decode_slice(gpr_slice slice_in,
const uint8_t *unreserved_bytes,
gpr_slice *slice_out) {
const uint8_t *p = GPR_SLICE_START_PTR(slice_in);
const uint8_t *in_end = GPR_SLICE_END_PTR(slice_in);
size_t out_length = 0;
bool any_percent_encoded_stuff = false;
while (p != in_end) {
if (*p == '%') {
if (!valid_hex(++p, in_end)) return false;
if (!valid_hex(++p, in_end)) return false;
p++;
out_length++;
any_percent_encoded_stuff = true;
} else if (is_unreserved_character(*p, unreserved_bytes)) {
p++;
out_length++;
} else {
return false;
}
}
if (!any_percent_encoded_stuff) {
*slice_out = gpr_slice_ref(slice_in);
return true;
}
p = GPR_SLICE_START_PTR(slice_in);
*slice_out = gpr_slice_malloc(out_length);
uint8_t *q = GPR_SLICE_START_PTR(*slice_out);
while (p != in_end) {
if (*p == '%') {
*q++ = (uint8_t)(dehex(p[1]) << 4) | (dehex(p[2]));
p += 3;
} else {
*q++ = *p++;
}
}
GPR_ASSERT(q == GPR_SLICE_END_PTR(*slice_out));
return true;
}
gpr_slice gpr_permissive_percent_decode_slice(gpr_slice slice_in) {
const uint8_t *p = GPR_SLICE_START_PTR(slice_in);
const uint8_t *in_end = GPR_SLICE_END_PTR(slice_in);
size_t out_length = 0;
bool any_percent_encoded_stuff = false;
while (p != in_end) {
if (*p == '%') {
if (!valid_hex(p + 1, in_end) || !valid_hex(p + 2, in_end)) {
p++;
out_length++;
} else {
p += 3;
out_length++;
any_percent_encoded_stuff = true;
}
} else {
p++;
out_length++;
}
}
if (!any_percent_encoded_stuff) {
return gpr_slice_ref(slice_in);
}
p = GPR_SLICE_START_PTR(slice_in);
gpr_slice out = gpr_slice_malloc(out_length);
uint8_t *q = GPR_SLICE_START_PTR(out);
while (p != in_end) {
if (*p == '%') {
if (!valid_hex(p + 1, in_end) || !valid_hex(p + 2, in_end)) {
*q++ = *p++;
} else {
*q++ = (uint8_t)(dehex(p[1]) << 4) | (dehex(p[2]));
p += 3;
}
} else {
*q++ = *p++;
}
}
GPR_ASSERT(q == GPR_SLICE_END_PTR(out));
return out;
}

@ -0,0 +1,78 @@
/*
*
* Copyright 2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H
#define GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H
/* Percent encoding and decoding of slices.
Transforms arbitrary strings into safe-for-transmission strings by using
variants of percent encoding (RFC 3986).
Two major variants are supplied: one that strictly matches URL encoding,
and another which applies percent encoding only to non-http2 header
bytes (the 'compatible' variant) */
#include <stdbool.h>
#include <grpc/support/slice.h>
/* URL percent encoding spec bitfield (usabel as 'unreserved_bytes' in
gpr_percent_encode_slice, gpr_strict_percent_decode_slice).
Flags [A-Za-z0-9-_.~] as unreserved bytes for the percent encoding routines
*/
extern const uint8_t gpr_url_percent_encoding_unreserved_bytes[256 / 8];
/* URL percent encoding spec bitfield (usabel as 'unreserved_bytes' in
gpr_percent_encode_slice, gpr_strict_percent_decode_slice).
Flags ascii7 non-control characters excluding '%' as unreserved bytes for the
percent encoding routines */
extern const uint8_t gpr_compatible_percent_encoding_unreserved_bytes[256 / 8];
/* Percent-encode a slice, returning the new slice (this cannot fail):
unreserved_bytes is a bitfield indicating which bytes are considered
unreserved and thus do not need percent encoding */
gpr_slice gpr_percent_encode_slice(gpr_slice slice,
const uint8_t *unreserved_bytes);
/* Percent-decode a slice, strictly.
If the input is legal (contains no unreserved bytes, and legal % encodings),
returns true and sets *slice_out to the decoded slice.
If the input is not legal, returns false and leaves *slice_out untouched.
unreserved_bytes is a bitfield indicating which bytes are considered
unreserved and thus do not need percent encoding */
bool gpr_strict_percent_decode_slice(gpr_slice slice_in,
const uint8_t *unreserved_bytes,
gpr_slice *slice_out);
/* Percent-decode a slice, permissively.
If a % triplet can not be decoded, pass it through verbatim.
This cannot fail. */
gpr_slice gpr_permissive_percent_decode_slice(gpr_slice slice_in);
#endif /* GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H */

@ -149,6 +149,7 @@ struct call_data {
grpc_metadata_batch *recv_initial_metadata;
bool recv_idempotent_request;
bool recv_cacheable_request;
grpc_metadata_array initial_metadata;
request_matcher *request_matcher;
@ -497,9 +498,12 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server,
&rc->data.batch.details->method_capacity, calld->path);
rc->data.batch.details->deadline = calld->deadline;
rc->data.batch.details->flags =
0 | (calld->recv_idempotent_request
? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
: 0);
(calld->recv_idempotent_request
? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST
: 0) |
(calld->recv_cacheable_request
? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST
: 0);
break;
case REGISTERED_CALL:
*rc->data.registered.deadline = calld->deadline;
@ -779,6 +783,7 @@ static void server_mutate_op(grpc_call_element *elem,
calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready;
op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata;
op->recv_idempotent_request = &calld->recv_idempotent_request;
op->recv_cacheable_request = &calld->recv_cacheable_request;
}
}

@ -51,15 +51,15 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] =
{11, 33, 10, 33, 12, 33, 12, 49, 13, 33, 14, 33, 15, 33, 16, 33, 17, 33,
{11, 33, 10, 33, 12, 33, 12, 50, 13, 33, 14, 33, 15, 33, 16, 33, 17, 33,
19, 33, 20, 33, 21, 33, 22, 33, 23, 33, 24, 33, 25, 33, 26, 33, 27, 33,
28, 18, 28, 33, 29, 33, 30, 33, 34, 33, 35, 33, 36, 33, 37, 33, 40, 31,
40, 32, 40, 48, 40, 53, 40, 54, 40, 55, 40, 56, 42, 31, 42, 48, 42, 53,
45, 0, 45, 1, 45, 2, 50, 33, 57, 33, 58, 33, 59, 33, 60, 33, 61, 33,
62, 33, 63, 33, 64, 33, 65, 33, 66, 33, 67, 33, 68, 38, 68, 70, 68, 73,
69, 81, 69, 82, 71, 33, 72, 33, 74, 33, 75, 33, 76, 33, 77, 33, 78, 39,
78, 51, 78, 52, 79, 33, 80, 33, 83, 3, 83, 4, 83, 5, 83, 6, 83, 7,
83, 8, 83, 9, 84, 33, 85, 86, 87, 33, 88, 33, 89, 33, 90, 33, 91, 33};
40, 32, 40, 49, 40, 54, 40, 55, 40, 56, 40, 57, 42, 31, 42, 49, 42, 54,
46, 0, 46, 1, 46, 2, 51, 33, 58, 33, 59, 33, 60, 33, 61, 33, 62, 33,
63, 33, 64, 33, 65, 33, 66, 33, 67, 33, 68, 33, 69, 38, 69, 71, 69, 74,
70, 82, 70, 83, 72, 33, 73, 33, 75, 33, 76, 33, 77, 33, 78, 33, 79, 39,
79, 52, 79, 53, 80, 33, 81, 33, 84, 3, 84, 4, 84, 5, 84, 6, 84, 7,
84, 8, 84, 9, 85, 33, 86, 87, 88, 33, 89, 33, 90, 33, 91, 33, 92, 33};
const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
"0",
@ -107,6 +107,7 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
"grpc-encoding",
"grpc-internal-encoding-request",
"grpc-message",
"grpc-payload-bin",
"grpc-status",
"grpc-timeout",
"grpc-tracing-bin",

@ -44,7 +44,7 @@
#include "src/core/lib/transport/metadata.h"
#define GRPC_STATIC_MDSTR_COUNT 92
#define GRPC_STATIC_MDSTR_COUNT 93
extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
/* "0" */
#define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0])
@ -136,101 +136,103 @@ extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[43])
/* "grpc-message" */
#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[44])
/* "grpc-payload-bin" */
#define GRPC_MDSTR_GRPC_PAYLOAD_BIN (&grpc_static_mdstr_table[45])
/* "grpc-status" */
#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[45])
#define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[46])
/* "grpc-timeout" */
#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[46])
#define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[47])
/* "grpc-tracing-bin" */
#define GRPC_MDSTR_GRPC_TRACING_BIN (&grpc_static_mdstr_table[47])
#define GRPC_MDSTR_GRPC_TRACING_BIN (&grpc_static_mdstr_table[48])
/* "gzip" */
#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[48])
#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[49])
/* "gzip, deflate" */
#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[49])
#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[50])
/* "host" */
#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[50])
#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[51])
/* "http" */
#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[51])
#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[52])
/* "https" */
#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[52])
#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[53])
/* "identity" */
#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[53])
#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[54])
/* "identity,deflate" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[54])
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[55])
/* "identity,deflate,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
(&grpc_static_mdstr_table[55])
(&grpc_static_mdstr_table[56])
/* "identity,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[56])
#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[57])
/* "if-match" */
#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[57])
#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[58])
/* "if-modified-since" */
#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[58])
#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[59])
/* "if-none-match" */
#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[59])
#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[60])
/* "if-range" */
#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[60])
#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[61])
/* "if-unmodified-since" */
#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[61])
#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[62])
/* "last-modified" */
#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[62])
#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[63])
/* "link" */
#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[63])
#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[64])
/* "load-reporting-initial" */
#define GRPC_MDSTR_LOAD_REPORTING_INITIAL (&grpc_static_mdstr_table[64])
#define GRPC_MDSTR_LOAD_REPORTING_INITIAL (&grpc_static_mdstr_table[65])
/* "load-reporting-trailing" */
#define GRPC_MDSTR_LOAD_REPORTING_TRAILING (&grpc_static_mdstr_table[65])
#define GRPC_MDSTR_LOAD_REPORTING_TRAILING (&grpc_static_mdstr_table[66])
/* "location" */
#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[66])
#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[67])
/* "max-forwards" */
#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[67])
#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[68])
/* ":method" */
#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[68])
#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[69])
/* ":path" */
#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[69])
#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[70])
/* "POST" */
#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[70])
#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[71])
/* "proxy-authenticate" */
#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[71])
#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[72])
/* "proxy-authorization" */
#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[72])
#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[73])
/* "PUT" */
#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[73])
#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[74])
/* "range" */
#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[74])
#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[75])
/* "referer" */
#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[75])
#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[76])
/* "refresh" */
#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[76])
#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[77])
/* "retry-after" */
#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[77])
#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[78])
/* ":scheme" */
#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[78])
#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[79])
/* "server" */
#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[79])
#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[80])
/* "set-cookie" */
#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[80])
#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[81])
/* "/" */
#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[81])
#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[82])
/* "/index.html" */
#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[82])
#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[83])
/* ":status" */
#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[83])
#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[84])
/* "strict-transport-security" */
#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[84])
#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[85])
/* "te" */
#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[85])
#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[86])
/* "trailers" */
#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[86])
#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[87])
/* "transfer-encoding" */
#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[87])
#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[88])
/* "user-agent" */
#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[88])
#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[89])
/* "vary" */
#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[89])
#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[90])
/* "via" */
#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[90])
#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[91])
/* "www-authenticate" */
#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[91])
#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[92])
#define GRPC_STATIC_MDELEM_COUNT 81
extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];

@ -124,6 +124,7 @@ typedef struct grpc_transport_stream_op {
/** Receive initial metadata from the stream, into provided metadata batch. */
grpc_metadata_batch *recv_initial_metadata;
bool *recv_idempotent_request;
bool *recv_cacheable_request;
/** Should be enqueued when initial metadata is ready to be processed. */
grpc_closure *recv_initial_metadata_ready;

@ -60,6 +60,7 @@ ClientContext::ClientContext()
: initial_metadata_received_(false),
fail_fast_(true),
idempotent_(false),
cacheable_(false),
call_(nullptr),
call_canceled_(false),
deadline_(gpr_inf_future(GPR_CLOCK_REALTIME)),

@ -35,10 +35,9 @@
#include <grpc++/impl/service_type.h>
#include <grpc++/server.h>
#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
#include "include/grpc/support/useful.h"
#include "src/cpp/server/thread_pool_interface.h"
namespace grpc {
@ -154,14 +153,12 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
(*option)->UpdateArguments(&args);
(*option)->UpdatePlugins(&plugins_);
}
if (!thread_pool) {
for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
if ((*plugin)->has_sync_methods()) {
thread_pool.reset(CreateDefaultThreadPool());
has_sync_methods = true;
break;
}
for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) {
if (!thread_pool && (*plugin)->has_sync_methods()) {
thread_pool.reset(CreateDefaultThreadPool());
has_sync_methods = true;
}
(*plugin)->UpdateChannelArguments(&args);
}
if (max_message_size_ > 0) {
args.SetInt(GRPC_ARG_MAX_MESSAGE_LENGTH, max_message_size_);

@ -49,14 +49,26 @@
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Google.Apis.Core">
<HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
<HintPath>..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll</HintPath>
</Reference>
<Reference Include="Zlib.Portable">
<HintPath>..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
</Reference>
<Reference Include="Google.Apis">
<HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll</HintPath>
</Reference>
<Reference Include="Google.Apis.PlatformServices">
<HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll</HintPath>
</Reference>
<Reference Include="Google.Apis.Auth">
<HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
<HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll</HintPath>
</Reference>
<Reference Include="Google.Apis.Auth.PlatformServices">
<HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
<HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
<package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
<package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
<package id="Google.Apis" version="1.16.0" targetFramework="net45" />
<package id="Google.Apis.Auth" version="1.16.0" targetFramework="net45" />
<package id="Google.Apis.Core" version="1.16.0" targetFramework="net45" />
<package id="log4net" version="2.0.3" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="Zlib.Portable.Signed" version="1.11.0" targetFramework="net45" />
</packages>

@ -23,18 +23,13 @@
},
"dependencies": {
"Grpc.Core": "1.1.0-dev",
"Google.Apis.Auth": "1.15.0"
"Google.Apis.Auth": "1.16.0"
},
"frameworks": {
"net45": { },
"netstandard1.5": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"NETStandard.Library": "1.6.0",
"System.Threading.Tasks": "4.0.11"
"NETStandard.Library": "1.6.0"
}
}
}

@ -42,11 +42,6 @@
}
}
},
"runtimes": {
"win7-x64": { },
"debian.8-x64": { },
"osx.10.11-x64": { }
},
"dependencies": {
"Grpc.Core": {
@ -66,8 +61,10 @@
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": "1.0.0",
"NETStandard.Library": "1.6.0"
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
}
}
},

@ -351,11 +351,11 @@ namespace Grpc.Core
{
if (!hooksRegistered)
{
// TODO(jtattermusch): register shutdownhooks for CoreCLR as well
#if !NETSTANDARD1_5
AppDomain.CurrentDomain.ProcessExit += ShutdownHookHandler;
AppDomain.CurrentDomain.DomainUnload += ShutdownHookHandler;
#if NETSTANDARD1_5
System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += (assemblyLoadContext) => { HandleShutdown(); };
#else
AppDomain.CurrentDomain.ProcessExit += (sender, eventArgs) => { HandleShutdown(); };
AppDomain.CurrentDomain.DomainUnload += (sender, eventArgs) => { HandleShutdown(); };
#endif
}
hooksRegistered = true;
@ -363,9 +363,9 @@ namespace Grpc.Core
}
/// <summary>
/// Handler for AppDomain.DomainUnload and AppDomain.ProcessExit hooks.
/// Handler for AppDomain.DomainUnload, AppDomain.ProcessExit and AssemblyLoadContext.Unloading hooks.
/// </summary>
private static void ShutdownHookHandler(object sender, EventArgs e)
private static void HandleShutdown()
{
Task.WaitAll(GrpcEnvironment.ShutdownChannelsAsync(), GrpcEnvironment.KillServersAsync());
}

@ -100,19 +100,19 @@ namespace Grpc.Core.Internal
// With old-style VS projects, the native libraries get copied using a .targets rule to the build output folder
// alongside the compiled assembly.
// With dotnet cli projects, the native libraries (just the required ones) are similarly copied to the built output folder,
// through the magic of Microsoft.NETCore.Platforms.
// With dotnet cli projects targeting net45 framework, the native libraries (just the required ones)
// are similarly copied to the built output folder, through the magic of Microsoft.NETCore.Platforms.
var classicPath = Path.Combine(assemblyDirectory, GetNativeLibraryFilename());
// DNX-style project.json projects will use Grpc.Core assembly directly in the location where it got restored
// With dotnet cli project targeting netcoreapp1.0, projects will use Grpc.Core assembly directly in the location where it got restored
// by nuget. We locate the native libraries based on known structure of Grpc.Core nuget package.
// When "dotnet publish" is used, the runtimes directory is copied next to the published assemblies.
string runtimesDirectory = string.Format("runtimes/{0}/native", GetPlatformString());
var netCorePublishedAppStylePath = Path.Combine(assemblyDirectory, runtimesDirectory, GetNativeLibraryFilename());
var netCoreAppStylePath = Path.Combine(assemblyDirectory, "../..", runtimesDirectory, GetNativeLibraryFilename());
// TODO: Support .NET Core applications, which act slightly differently. We may be okay if "dotnet publish"
// is used, but "dotnet run" leaves the native libraries in-package, while copying assemblies.
string platform = GetPlatformString();
string relativeDirectory = string.Format("../../runtimes/{0}/native", platform);
var dnxStylePath = Path.Combine(assemblyDirectory, relativeDirectory, GetNativeLibraryFilename());
string[] paths = new[] { classicPath, dnxStylePath };
// Look for all native library in all possible locations in given order.
string[] paths = new[] { classicPath, netCorePublishedAppStylePath, netCoreAppStylePath};
return new UnmanagedLibrary(paths);
}

@ -36,11 +36,9 @@
"frameworks": {
"net45": { },
"netstandard1.5": {
"imports": [
"portable-net45"
],
"dependencies": {
"NETStandard.Library": "1.6.0",
"System.Runtime.Loader": "4.0.0",
"System.Threading.Thread": "4.0.0"
}
}

@ -42,11 +42,6 @@
}
}
},
"runtimes": {
"win7-x64": { },
"debian.8-x64": { },
"osx.10.11-x64": { }
},
"dependencies": {
"Grpc.Examples": {
@ -56,12 +51,11 @@
"frameworks": {
"net45": { },
"netcoreapp1.0": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": "1.0.0",
"NETStandard.Library": "1.6.0"
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
}
}
}

@ -42,11 +42,6 @@
}
}
},
"runtimes": {
"win7-x64": { },
"debian.8-x64": { },
"osx.10.11-x64": { }
},
"dependencies": {
"Grpc.Examples": {
@ -56,12 +51,11 @@
"frameworks": {
"net45": { },
"netcoreapp1.0": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": "1.0.0",
"NETStandard.Library": "1.6.0"
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
}
}
}

@ -36,9 +36,6 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Google.Protobuf">
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
</Reference>
@ -48,6 +45,9 @@
<Reference Include="nunitlite">
<HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf">
<HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\Grpc.Core\Version.cs">

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
<package id="NUnit" version="3.2.0" targetFramework="net45" />
<package id="NUnitLite" version="3.2.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
</packages>

@ -42,11 +42,6 @@
}
}
},
"runtimes": {
"win7-x64": { },
"debian.8-x64": { },
"osx.10.11-x64": { }
},
"dependencies": {
"Grpc.Examples": {
@ -62,8 +57,10 @@
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": "1.0.0",
"NETStandard.Library": "1.6.0"
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
}
}
}

@ -37,10 +37,6 @@
<AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
</Reference>
@ -50,6 +46,9 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf">
<HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\Grpc.Core\Version.cs">

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
<package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
<package id="NUnit" version="3.2.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
</packages>

@ -1,17 +1,12 @@
{
"buildOptions": {
},
"runtimes": {
"win7-x64": { },
"debian.8-x64": { },
"osx.10.11-x64": { }
},
"dependencies": {
"Grpc.Core": {
"target": "project"
},
"Google.Protobuf": "3.0.0-beta3"
"Google.Protobuf": "3.0.0"
},
"frameworks": {
"net45": {
@ -21,12 +16,11 @@
}
},
"netcoreapp1.0": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": "1.0.0",
"NETStandard.Library": "1.6.0"
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
}
}
}

@ -44,15 +44,15 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Google.Protobuf">
<HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="nunitlite">
<HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
</Reference>
<Reference Include="Google.Protobuf">
<HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\Grpc.Core\Version.cs">

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save