Merge pull request #6450 from nicolasnoble/gopro
Continuation of #6280.
diff --git a/BUILD b/BUILD
index b4b10b5..fae3596 100644
--- a/BUILD
+++ b/BUILD
@@ -285,6 +285,42 @@
"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",
+ "include/grpc/byte_buffer.h",
+ "include/grpc/grpc.h",
+ "include/grpc/impl/codegen/alloc.h",
+ "include/grpc/impl/codegen/atm.h",
+ "include/grpc/impl/codegen/atm_gcc_atomic.h",
+ "include/grpc/impl/codegen/atm_gcc_sync.h",
+ "include/grpc/impl/codegen/atm_win32.h",
+ "include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/compression_types.h",
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/grpc_types.h",
+ "include/grpc/impl/codegen/log.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/propagation_bits.h",
+ "include/grpc/impl/codegen/slice.h",
+ "include/grpc/impl/codegen/slice_buffer.h",
+ "include/grpc/impl/codegen/status.h",
+ "include/grpc/impl/codegen/sync.h",
+ "include/grpc/impl/codegen/sync_generic.h",
+ "include/grpc/impl/codegen/sync_posix.h",
+ "include/grpc/impl/codegen/sync_win32.h",
+ "include/grpc/impl/codegen/time.h",
+ "include/grpc/status.h",
+ "include/grpc/support/alloc.h",
+ "include/grpc/support/atm.h",
+ "include/grpc/support/host_port.h",
+ "include/grpc/support/log.h",
+ "include/grpc/support/port_platform.h",
+ "include/grpc/support/slice.h",
+ "include/grpc/support/slice_buffer.h",
+ "include/grpc/support/string_util.h",
+ "include/grpc/support/sync.h",
+ "include/grpc/support/time.h",
+ "include/grpc/support/useful.h",
+ "src/core/lib/support/string.h",
+ "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h",
"src/core/ext/census/aggregation.h",
@@ -439,6 +475,9 @@
"src/core/ext/client_config/uri_parser.c",
"src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
"src/core/ext/transport/chttp2/client/insecure/channel_create.c",
+ "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
+ "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
+ "src/core/ext/transport/cronet/transport/cronet_transport.c",
"src/core/ext/lb_policy/grpclb/load_balancer_api.c",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c",
"src/core/ext/lb_policy/pick_first/pick_first.c",
@@ -463,6 +502,7 @@
"include/grpc/grpc.h",
"include/grpc/status.h",
"include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/byte_buffer_reader.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
@@ -482,6 +522,7 @@
"include/grpc/impl/codegen/sync_posix.h",
"include/grpc/impl/codegen/sync_win32.h",
"include/grpc/impl/codegen/time.h",
+ "include/grpc/grpc_cronet.h",
"include/grpc/grpc_security.h",
"include/grpc/grpc_security_constants.h",
"include/grpc/census.h",
@@ -774,6 +815,7 @@
"include/grpc/grpc.h",
"include/grpc/status.h",
"include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/byte_buffer_reader.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
@@ -946,6 +988,7 @@
"include/grpc++/impl/codegen/sync_stream.h",
"include/grpc++/impl/codegen/time.h",
"include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/byte_buffer_reader.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
@@ -1091,6 +1134,7 @@
"include/grpc++/impl/codegen/sync_stream.h",
"include/grpc++/impl/codegen/time.h",
"include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/byte_buffer_reader.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
@@ -1456,6 +1500,9 @@
"src/core/ext/client_config/uri_parser.c",
"src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
"src/core/ext/transport/chttp2/client/insecure/channel_create.c",
+ "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
+ "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
+ "src/core/ext/transport/cronet/transport/cronet_transport.c",
"src/core/ext/lb_policy/grpclb/load_balancer_api.c",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c",
"src/core/ext/lb_policy/pick_first/pick_first.c",
@@ -1480,6 +1527,7 @@
"include/grpc/grpc.h",
"include/grpc/status.h",
"include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/byte_buffer_reader.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
@@ -1499,6 +1547,7 @@
"include/grpc/impl/codegen/sync_posix.h",
"include/grpc/impl/codegen/sync_win32.h",
"include/grpc/impl/codegen/time.h",
+ "include/grpc/grpc_cronet.h",
"include/grpc/grpc_security.h",
"include/grpc/grpc_security_constants.h",
"include/grpc/census.h",
@@ -1626,6 +1675,42 @@
"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",
+ "include/grpc/byte_buffer.h",
+ "include/grpc/grpc.h",
+ "include/grpc/impl/codegen/alloc.h",
+ "include/grpc/impl/codegen/atm.h",
+ "include/grpc/impl/codegen/atm_gcc_atomic.h",
+ "include/grpc/impl/codegen/atm_gcc_sync.h",
+ "include/grpc/impl/codegen/atm_win32.h",
+ "include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/compression_types.h",
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/grpc_types.h",
+ "include/grpc/impl/codegen/log.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/propagation_bits.h",
+ "include/grpc/impl/codegen/slice.h",
+ "include/grpc/impl/codegen/slice_buffer.h",
+ "include/grpc/impl/codegen/status.h",
+ "include/grpc/impl/codegen/sync.h",
+ "include/grpc/impl/codegen/sync_generic.h",
+ "include/grpc/impl/codegen/sync_posix.h",
+ "include/grpc/impl/codegen/sync_win32.h",
+ "include/grpc/impl/codegen/time.h",
+ "include/grpc/status.h",
+ "include/grpc/support/alloc.h",
+ "include/grpc/support/atm.h",
+ "include/grpc/support/host_port.h",
+ "include/grpc/support/log.h",
+ "include/grpc/support/port_platform.h",
+ "include/grpc/support/slice.h",
+ "include/grpc/support/slice_buffer.h",
+ "include/grpc/support/string_util.h",
+ "include/grpc/support/sync.h",
+ "include/grpc/support/time.h",
+ "include/grpc/support/useful.h",
+ "src/core/lib/support/string.h",
+ "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
"src/core/ext/lb_policy/grpclb/load_balancer_api.h",
"src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h",
"src/core/ext/census/aggregation.h",
diff --git a/Makefile b/Makefile
index 922e0b0..e77aa2d 100644
--- a/Makefile
+++ b/Makefile
@@ -2623,6 +2623,9 @@
src/core/ext/client_config/uri_parser.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
+ src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \
+ src/core/ext/transport/cronet/transport/cronet_api_dummy.c \
+ src/core/ext/transport/cronet/transport/cronet_transport.c \
src/core/ext/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c \
third_party/nanopb/pb_common.c \
@@ -2650,6 +2653,7 @@
include/grpc/grpc.h \
include/grpc/status.h \
include/grpc/impl/codegen/byte_buffer.h \
+ include/grpc/impl/codegen/byte_buffer_reader.h \
include/grpc/impl/codegen/compression_types.h \
include/grpc/impl/codegen/connectivity_state.h \
include/grpc/impl/codegen/grpc_types.h \
@@ -2669,6 +2673,7 @@
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_win32.h \
include/grpc/impl/codegen/time.h \
+ include/grpc/grpc_cronet.h \
include/grpc/grpc_security.h \
include/grpc/grpc_security_constants.h \
include/grpc/census.h \
@@ -2970,6 +2975,7 @@
include/grpc/grpc.h \
include/grpc/status.h \
include/grpc/impl/codegen/byte_buffer.h \
+ include/grpc/impl/codegen/byte_buffer_reader.h \
include/grpc/impl/codegen/compression_types.h \
include/grpc/impl/codegen/connectivity_state.h \
include/grpc/impl/codegen/grpc_types.h \
@@ -3256,6 +3262,7 @@
include/grpc++/impl/codegen/sync_stream.h \
include/grpc++/impl/codegen/time.h \
include/grpc/impl/codegen/byte_buffer.h \
+ include/grpc/impl/codegen/byte_buffer_reader.h \
include/grpc/impl/codegen/compression_types.h \
include/grpc/impl/codegen/connectivity_state.h \
include/grpc/impl/codegen/grpc_types.h \
@@ -3559,6 +3566,7 @@
include/grpc++/impl/codegen/sync_stream.h \
include/grpc++/impl/codegen/time.h \
include/grpc/impl/codegen/byte_buffer.h \
+ include/grpc/impl/codegen/byte_buffer_reader.h \
include/grpc/impl/codegen/compression_types.h \
include/grpc/impl/codegen/connectivity_state.h \
include/grpc/impl/codegen/grpc_types.h \
@@ -14313,6 +14321,9 @@
# otherwise parallel compilation will fail if a source is compiled first.
src/core/ext/transport/chttp2/client/secure/secure_channel_create.c: $(OPENSSL_DEP)
src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c: $(OPENSSL_DEP)
+src/core/ext/transport/cronet/client/secure/cronet_channel_create.c: $(OPENSSL_DEP)
+src/core/ext/transport/cronet/transport/cronet_api_dummy.c: $(OPENSSL_DEP)
+src/core/ext/transport/cronet/transport/cronet_transport.c: $(OPENSSL_DEP)
src/core/lib/http/httpcli_security_connector.c: $(OPENSSL_DEP)
src/core/lib/security/b64.c: $(OPENSSL_DEP)
src/core/lib/security/client_auth_filter.c: $(OPENSSL_DEP)
diff --git a/binding.gyp b/binding.gyp
index 4314ab7..12a745f 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -709,6 +709,9 @@
'src/core/ext/client_config/uri_parser.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
+ 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
+ 'src/core/ext/transport/cronet/transport/cronet_api_dummy.c',
+ 'src/core/ext/transport/cronet/transport/cronet_transport.c',
'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c',
'third_party/nanopb/pb_common.c',
diff --git a/build.yaml b/build.yaml
index 441752d..1a0888b 100644
--- a/build.yaml
+++ b/build.yaml
@@ -351,6 +351,7 @@
- name: grpc_codegen
public_headers:
- include/grpc/impl/codegen/byte_buffer.h
+ - include/grpc/impl/codegen/byte_buffer_reader.h
- include/grpc/impl/codegen/compression_types.h
- include/grpc/impl/codegen/connectivity_state.h
- include/grpc/impl/codegen/grpc_types.h
@@ -399,6 +400,7 @@
- grpc_client_config
- name: grpc_secure
public_headers:
+ - include/grpc/grpc_cronet.h
- include/grpc/grpc_security.h
- include/grpc/grpc_security_constants.h
headers:
@@ -546,6 +548,63 @@
- grpc_transport_chttp2
- grpc_base
- grpc_secure
+- name: grpc_transport_cronet_client_secure
+ headers:
+ - include/grpc/byte_buffer.h
+ - include/grpc/grpc.h
+ - include/grpc/impl/codegen/alloc.h
+ - include/grpc/impl/codegen/atm.h
+ - include/grpc/impl/codegen/atm_gcc_atomic.h
+ - include/grpc/impl/codegen/atm_gcc_sync.h
+ - include/grpc/impl/codegen/atm_win32.h
+ - include/grpc/impl/codegen/byte_buffer.h
+ - include/grpc/impl/codegen/compression_types.h
+ - include/grpc/impl/codegen/connectivity_state.h
+ - include/grpc/impl/codegen/grpc_types.h
+ - include/grpc/impl/codegen/log.h
+ - include/grpc/impl/codegen/port_platform.h
+ - include/grpc/impl/codegen/propagation_bits.h
+ - include/grpc/impl/codegen/slice.h
+ - include/grpc/impl/codegen/slice_buffer.h
+ - include/grpc/impl/codegen/status.h
+ - include/grpc/impl/codegen/sync.h
+ - include/grpc/impl/codegen/sync_generic.h
+ - include/grpc/impl/codegen/sync_posix.h
+ - include/grpc/impl/codegen/sync_win32.h
+ - include/grpc/impl/codegen/time.h
+ - include/grpc/status.h
+ - include/grpc/support/alloc.h
+ - include/grpc/support/atm.h
+ - include/grpc/support/host_port.h
+ - include/grpc/support/log.h
+ - include/grpc/support/port_platform.h
+ - include/grpc/support/slice.h
+ - include/grpc/support/slice_buffer.h
+ - include/grpc/support/string_util.h
+ - include/grpc/support/sync.h
+ - include/grpc/support/time.h
+ - include/grpc/support/useful.h
+ - src/core/ext/transport/chttp2/transport/incoming_metadata.h
+ - src/core/lib/channel/channel_stack.h
+ - src/core/lib/channel/context.h
+ - src/core/lib/debug/trace.h
+ - src/core/lib/iomgr/closure.h
+ - src/core/lib/iomgr/exec_ctx.h
+ - src/core/lib/iomgr/pollset.h
+ - src/core/lib/iomgr/pollset_set.h
+ - src/core/lib/support/string.h
+ - src/core/lib/surface/channel.h
+ - src/core/lib/surface/channel_stack_type.h
+ - src/core/lib/transport/byte_stream.h
+ - src/core/lib/transport/metadata.h
+ - src/core/lib/transport/metadata_batch.h
+ - src/core/lib/transport/transport.h
+ - src/core/lib/transport/transport_impl.h
+ - third_party/objective_c/Cronet/cronet_c_for_grpc.h
+ src:
+ - src/core/ext/transport/cronet/client/secure/cronet_channel_create.c
+ - src/core/ext/transport/cronet/transport/cronet_api_dummy.c
+ - src/core/ext/transport/cronet/transport/cronet_transport.c
- name: nanopb
headers:
- third_party/nanopb/pb.h
@@ -733,6 +792,7 @@
- grpc_transport_chttp2_client_secure
- grpc_transport_chttp2_server_insecure
- grpc_transport_chttp2_client_insecure
+ - grpc_transport_cronet_client_secure
- grpc_lb_policy_grpclb
- grpc_lb_policy_pick_first
- grpc_lb_policy_round_robin
diff --git a/config.m4 b/config.m4
index 74f9ad2..5259e67 100644
--- a/config.m4
+++ b/config.m4
@@ -228,6 +228,9 @@
src/core/ext/client_config/uri_parser.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
+ src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \
+ src/core/ext/transport/cronet/transport/cronet_api_dummy.c \
+ src/core/ext/transport/cronet/transport/cronet_transport.c \
src/core/ext/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c \
third_party/nanopb/pb_common.c \
@@ -566,6 +569,8 @@
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server/insecure)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server/secure)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/transport)
+ PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/cronet/client/secure)
+ PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/cronet/transport)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/channel)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/compression)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/debug)
diff --git a/examples/cpp/helloworld/Makefile b/examples/cpp/helloworld/Makefile
index 470b835..58a82db 100644
--- a/examples/cpp/helloworld/Makefile
+++ b/examples/cpp/helloworld/Makefile
@@ -41,7 +41,7 @@
vpath %.proto $(PROTOS_PATH)
-all: system-check greeter_client greeter_server greeter_async_client greeter_async_server
+all: system-check greeter_client greeter_server greeter_async_client greeter_async_client2 greeter_async_server
greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o
$(CXX) $^ $(LDFLAGS) -o $@
@@ -52,6 +52,9 @@
greeter_async_client: helloworld.pb.o helloworld.grpc.pb.o greeter_async_client.o
$(CXX) $^ $(LDFLAGS) -o $@
+greeter_async_client2: helloworld.pb.o helloworld.grpc.pb.o greeter_async_client2.o
+ $(CXX) $^ $(LDFLAGS) -o $@
+
greeter_async_server: helloworld.pb.o helloworld.grpc.pb.o greeter_async_server.o
$(CXX) $^ $(LDFLAGS) -o $@
@@ -64,7 +67,7 @@
$(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<
clean:
- rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server greeter_async_client greeter_async_server
+ rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server greeter_async_client greeter_async_client2 greeter_async_server
# The following is to test your system and ensure a smoother experience.
diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc
index 3501426..c1f5eb5 100644
--- a/examples/cpp/helloworld/greeter_async_client.cc
+++ b/examples/cpp/helloworld/greeter_async_client.cc
@@ -53,7 +53,7 @@
explicit GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
- // Assambles the client's payload, sends it and presents the response back
+ // Assembles the client's payload, sends it and presents the response back
// from the server.
std::string SayHello(const std::string& user) {
// Data we are sending to the server.
@@ -74,9 +74,9 @@
// Storage for the status of the RPC upon completion.
Status status;
- // stub_->AsyncSayHello() perform the RPC call, returning an instance we
- // store in "rpc". Because we are using the asynchronous API, we need the
- // hold on to the "rpc" instance in order to get updates on the ongoig RPC.
+ // stub_->AsyncSayHello() performs the RPC call, returning an instance we
+ // store in "rpc". Because we are using the asynchronous API, we need to
+ // hold on to the "rpc" instance in order to get updates on the ongoing RPC.
std::unique_ptr<ClientAsyncResponseReader<HelloReply> > rpc(
stub_->AsyncSayHello(&context, request, &cq));
diff --git a/examples/cpp/helloworld/greeter_async_client2.cc b/examples/cpp/helloworld/greeter_async_client2.cc
new file mode 100644
index 0000000..0902376
--- /dev/null
+++ b/examples/cpp/helloworld/greeter_async_client2.cc
@@ -0,0 +1,153 @@
+/*
+ *
+ * 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 <iostream>
+#include <memory>
+#include <string>
+
+#include <grpc++/grpc++.h>
+#include <thread>
+
+#include "helloworld.grpc.pb.h"
+
+using grpc::Channel;
+using grpc::ClientAsyncResponseReader;
+using grpc::ClientContext;
+using grpc::CompletionQueue;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+class GreeterClient {
+ public:
+ explicit GreeterClient(std::shared_ptr<Channel> channel)
+ : stub_(Greeter::NewStub(channel)) {}
+
+ // Assembles the client's payload and sends it to the server.
+ void SayHello(const std::string& user) {
+ // Data we are sending to the server.
+ HelloRequest request;
+ request.set_name(user);
+
+ // Call object to store rpc data
+ AsyncClientCall* call = new AsyncClientCall;
+
+ // stub_->AsyncSayHello() performs the RPC call, returning an instance to
+ // store in "call". Because we are using the asynchronous API, we need to
+ // hold on to the "call" instance in order to get updates on the ongoing RPC.
+ call->response_reader = stub_->AsyncSayHello(&call->context, request, &cq_);
+
+
+ // Request that, upon completion of the RPC, "reply" be updated with the
+ // server's response; "status" with the indication of whether the operation
+ // was successful. Tag the request with the memory address of the call object.
+ call->response_reader->Finish(&call->reply, &call->status, (void*)call);
+
+ }
+
+ // Loop while listening for completed responses.
+ // Prints out the response from the server.
+ void AsyncCompleteRpc() {
+ void* got_tag;
+ bool ok = false;
+
+ // Block until the next result is available in the completion queue "cq".
+ while (cq_.Next(&got_tag, &ok)) {
+ // The tag in this example is the memory location of the call object
+ AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag);
+
+ // Verify that the request was completed successfully. Note that "ok"
+ // corresponds solely to the request for updates introduced by Finish().
+ GPR_ASSERT(ok);
+
+ if (call->status.ok())
+ std::cout << "Greeter received: " << call->reply.message() << std::endl;
+ else
+ std::cout << "RPC failed" << std::endl;
+
+ // Once we're complete, deallocate the call object.
+ delete call;
+ }
+ }
+
+ private:
+
+ // struct for keeping state and data information
+ struct AsyncClientCall {
+ // Container for the data we expect from the server.
+ HelloReply reply;
+
+ // Context for the client. It could be used to convey extra information to
+ // the server and/or tweak certain RPC behaviors.
+ ClientContext context;
+
+ // Storage for the status of the RPC upon completion.
+ Status status;
+
+
+ std::unique_ptr<ClientAsyncResponseReader<HelloReply>> response_reader;
+ };
+
+ // Out of the passed in Channel comes the stub, stored here, our view of the
+ // server's exposed services.
+ std::unique_ptr<Greeter::Stub> stub_;
+
+ // The producer-consumer queue we use to communicate asynchronously with the
+ // gRPC runtime.
+ CompletionQueue cq_;
+};
+
+int main(int argc, char** argv) {
+
+
+ // Instantiate the client. It requires a channel, out of which the actual RPCs
+ // are created. This channel models a connection to an endpoint (in this case,
+ // localhost at port 50051). We indicate that the channel isn't authenticated
+ // (use of InsecureChannelCredentials()).
+ GreeterClient greeter(grpc::CreateChannel(
+ "localhost:50051", grpc::InsecureChannelCredentials()));
+
+ // Spawn reader thread that loops indefinitely
+ std::thread thread_ = std::thread(&GreeterClient::AsyncCompleteRpc, &greeter);
+
+ for (int i = 0; i < 100; i++) {
+ std::string user("world " + std::to_string(i));
+ greeter.SayHello(user); // The actual RPC call!
+ }
+
+ std::cout << "Press control-c to quit" << std::endl << std::endl;
+ thread_.join(); //blocks forever
+
+ return 0;
+}
diff --git a/examples/python/helloworld/helloworld_pb2.py b/examples/python/helloworld/helloworld_pb2.py
index 1b2674e..1ee80e4 100644
--- a/examples/python/helloworld/helloworld_pb2.py
+++ b/examples/python/helloworld/helloworld_pb2.py
@@ -1,6 +1,8 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
@@ -17,7 +19,7 @@
name='helloworld.proto',
package='helloworld',
syntax='proto3',
- serialized_pb=b'\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x18\n\x10io.grpc.examples\xa2\x02\x03HLWb\x06proto3'
+ serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3')
)
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
@@ -34,7 +36,7 @@
_descriptor.FieldDescriptor(
name='name', full_name='helloworld.HelloRequest.name', index=0,
number=1, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=b"".decode('utf-8'),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
@@ -65,7 +67,7 @@
_descriptor.FieldDescriptor(
name='message', full_name='helloworld.HelloReply.message', index=0,
number=1, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=b"".decode('utf-8'),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
@@ -104,69 +106,28 @@
DESCRIPTOR.has_options = True
-DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), b'\n\020io.grpc.examples\242\002\003HLW')
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW'))
import abc
+import six
from grpc.beta import implementations as beta_implementations
-from grpc.early_adopter import implementations as early_adopter_implementations
-from grpc.framework.alpha import utilities as alpha_utilities
+from grpc.beta import interfaces as beta_interfaces
from grpc.framework.common import cardinality
from grpc.framework.interfaces.face import utilities as face_utilities
-class EarlyAdopterGreeterServicer(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
- def SayHello(self, request, context):
- raise NotImplementedError()
-class EarlyAdopterGreeterServer(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
- def start(self):
- raise NotImplementedError()
- @abc.abstractmethod
- def stop(self):
- raise NotImplementedError()
-class EarlyAdopterGreeterStub(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
- def SayHello(self, request):
- raise NotImplementedError()
- SayHello.async = None
-def early_adopter_create_Greeter_server(servicer, port, private_key=None, certificate_chain=None):
- import helloworld_pb2
- import helloworld_pb2
- method_service_descriptions = {
- "SayHello": alpha_utilities.unary_unary_service_description(
- servicer.SayHello,
- helloworld_pb2.HelloRequest.FromString,
- helloworld_pb2.HelloReply.SerializeToString,
- ),
- }
- return early_adopter_implementations.server("helloworld.Greeter", method_service_descriptions, port, private_key=private_key, certificate_chain=certificate_chain)
-def early_adopter_create_Greeter_stub(host, port, metadata_transformer=None, secure=False, root_certificates=None, private_key=None, certificate_chain=None, server_host_override=None):
- import helloworld_pb2
- import helloworld_pb2
- method_invocation_descriptions = {
- "SayHello": alpha_utilities.unary_unary_invocation_description(
- helloworld_pb2.HelloRequest.SerializeToString,
- helloworld_pb2.HelloReply.FromString,
- ),
- }
- return early_adopter_implementations.stub("helloworld.Greeter", method_invocation_descriptions, host, port, metadata_transformer=metadata_transformer, secure=secure, root_certificates=root_certificates, private_key=private_key, certificate_chain=certificate_chain, server_host_override=server_host_override)
class BetaGreeterServicer(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
+ """The greeting service definition.
+ """
def SayHello(self, request, context):
- raise NotImplementedError()
+ """Sends a greeting
+ """
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
class BetaGreeterStub(object):
- """The interface to which stubs will conform."""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
+ """The greeting service definition.
+ """
def SayHello(self, request, timeout):
+ """Sends a greeting
+ """
raise NotImplementedError()
SayHello.future = None
diff --git a/examples/python/route_guide/route_guide_pb2.py b/examples/python/route_guide/route_guide_pb2.py
index d4d9f8d..81d5d07 100644
--- a/examples/python/route_guide/route_guide_pb2.py
+++ b/examples/python/route_guide/route_guide_pb2.py
@@ -1,6 +1,8 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: route_guide.proto
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
@@ -17,7 +19,7 @@
name='route_guide.proto',
package='routeguide',
syntax='proto3',
- serialized_pb=b'\n\x11route_guide.proto\x12\nrouteguide\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"I\n\tRectangle\x12\x1d\n\x02lo\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x1d\n\x02hi\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"<\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12#\n\x08location\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"A\n\tRouteNote\x12#\n\x08location\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\x85\x02\n\nRouteGuide\x12\x36\n\nGetFeature\x12\x11.routeguide.Point\x1a\x13.routeguide.Feature\"\x00\x12>\n\x0cListFeatures\x12\x15.routeguide.Rectangle\x1a\x13.routeguide.Feature\"\x00\x30\x01\x12>\n\x0bRecordRoute\x12\x11.routeguide.Point\x1a\x18.routeguide.RouteSummary\"\x00(\x01\x12?\n\tRouteChat\x12\x15.routeguide.RouteNote\x1a\x15.routeguide.RouteNote\"\x00(\x01\x30\x01\x42\x0f\n\x07\x65x.grpc\xa2\x02\x03RTGb\x06proto3'
+ serialized_pb=_b('\n\x11route_guide.proto\x12\nrouteguide\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"I\n\tRectangle\x12\x1d\n\x02lo\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x1d\n\x02hi\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"<\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12#\n\x08location\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"A\n\tRouteNote\x12#\n\x08location\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\x85\x02\n\nRouteGuide\x12\x36\n\nGetFeature\x12\x11.routeguide.Point\x1a\x13.routeguide.Feature\"\x00\x12>\n\x0cListFeatures\x12\x15.routeguide.Rectangle\x1a\x13.routeguide.Feature\"\x00\x30\x01\x12>\n\x0bRecordRoute\x12\x11.routeguide.Point\x1a\x18.routeguide.RouteSummary\"\x00(\x01\x12?\n\tRouteChat\x12\x15.routeguide.RouteNote\x1a\x15.routeguide.RouteNote\"\x00(\x01\x30\x01\x42\x36\n\x1bio.grpc.examples.routeguideB\x0fRouteGuideProtoP\x01\xa2\x02\x03RTGb\x06proto3')
)
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
@@ -110,7 +112,7 @@
_descriptor.FieldDescriptor(
name='name', full_name='routeguide.Feature.name', index=0,
number=1, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=b"".decode('utf-8'),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
@@ -155,7 +157,7 @@
_descriptor.FieldDescriptor(
name='message', full_name='routeguide.RouteNote.message', index=1,
number=2, type=9, cpp_type=9, label=1,
- has_default_value=False, default_value=b"".decode('utf-8'),
+ has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
@@ -274,149 +276,86 @@
DESCRIPTOR.has_options = True
-DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), b'\n\007ex.grpc\242\002\003RTG')
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.routeguideB\017RouteGuideProtoP\001\242\002\003RTG'))
import abc
+import six
from grpc.beta import implementations as beta_implementations
-from grpc.early_adopter import implementations as early_adopter_implementations
-from grpc.framework.alpha import utilities as alpha_utilities
+from grpc.beta import interfaces as beta_interfaces
from grpc.framework.common import cardinality
from grpc.framework.interfaces.face import utilities as face_utilities
-class EarlyAdopterRouteGuideServicer(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
- def GetFeature(self, request, context):
- raise NotImplementedError()
- @abc.abstractmethod
- def ListFeatures(self, request, context):
- raise NotImplementedError()
- @abc.abstractmethod
- def RecordRoute(self, request_iterator, context):
- raise NotImplementedError()
- @abc.abstractmethod
- def RouteChat(self, request_iterator, context):
- raise NotImplementedError()
-class EarlyAdopterRouteGuideServer(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
- def start(self):
- raise NotImplementedError()
- @abc.abstractmethod
- def stop(self):
- raise NotImplementedError()
-class EarlyAdopterRouteGuideStub(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
- def GetFeature(self, request):
- raise NotImplementedError()
- GetFeature.async = None
- @abc.abstractmethod
- def ListFeatures(self, request):
- raise NotImplementedError()
- ListFeatures.async = None
- @abc.abstractmethod
- def RecordRoute(self, request_iterator):
- raise NotImplementedError()
- RecordRoute.async = None
- @abc.abstractmethod
- def RouteChat(self, request_iterator):
- raise NotImplementedError()
- RouteChat.async = None
-def early_adopter_create_RouteGuide_server(servicer, port, private_key=None, certificate_chain=None):
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- method_service_descriptions = {
- "GetFeature": alpha_utilities.unary_unary_service_description(
- servicer.GetFeature,
- route_guide_pb2.Point.FromString,
- route_guide_pb2.Feature.SerializeToString,
- ),
- "ListFeatures": alpha_utilities.unary_stream_service_description(
- servicer.ListFeatures,
- route_guide_pb2.Rectangle.FromString,
- route_guide_pb2.Feature.SerializeToString,
- ),
- "RecordRoute": alpha_utilities.stream_unary_service_description(
- servicer.RecordRoute,
- route_guide_pb2.Point.FromString,
- route_guide_pb2.RouteSummary.SerializeToString,
- ),
- "RouteChat": alpha_utilities.stream_stream_service_description(
- servicer.RouteChat,
- route_guide_pb2.RouteNote.FromString,
- route_guide_pb2.RouteNote.SerializeToString,
- ),
- }
- return early_adopter_implementations.server("routeguide.RouteGuide", method_service_descriptions, port, private_key=private_key, certificate_chain=certificate_chain)
-def early_adopter_create_RouteGuide_stub(host, port, metadata_transformer=None, secure=False, root_certificates=None, private_key=None, certificate_chain=None, server_host_override=None):
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- import route_guide_pb2
- method_invocation_descriptions = {
- "GetFeature": alpha_utilities.unary_unary_invocation_description(
- route_guide_pb2.Point.SerializeToString,
- route_guide_pb2.Feature.FromString,
- ),
- "ListFeatures": alpha_utilities.unary_stream_invocation_description(
- route_guide_pb2.Rectangle.SerializeToString,
- route_guide_pb2.Feature.FromString,
- ),
- "RecordRoute": alpha_utilities.stream_unary_invocation_description(
- route_guide_pb2.Point.SerializeToString,
- route_guide_pb2.RouteSummary.FromString,
- ),
- "RouteChat": alpha_utilities.stream_stream_invocation_description(
- route_guide_pb2.RouteNote.SerializeToString,
- route_guide_pb2.RouteNote.FromString,
- ),
- }
- return early_adopter_implementations.stub("routeguide.RouteGuide", method_invocation_descriptions, host, port, metadata_transformer=metadata_transformer, secure=secure, root_certificates=root_certificates, private_key=private_key, certificate_chain=certificate_chain, server_host_override=server_host_override)
class BetaRouteGuideServicer(object):
- """<fill me in later!>"""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
+ """Interface exported by the server.
+ """
def GetFeature(self, request, context):
- raise NotImplementedError()
- @abc.abstractmethod
+ """A simple RPC.
+
+ Obtains the feature at a given position.
+
+ A feature with an empty name is returned if there's no feature at the given
+ position.
+ """
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def ListFeatures(self, request, context):
- raise NotImplementedError()
- @abc.abstractmethod
+ """A server-to-client streaming RPC.
+
+ Obtains the Features available within the given Rectangle. Results are
+ streamed rather than returned at once (e.g. in a response message with a
+ repeated field), as the rectangle may cover a large area and contain a
+ huge number of features.
+ """
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def RecordRoute(self, request_iterator, context):
- raise NotImplementedError()
- @abc.abstractmethod
+ """A client-to-server streaming RPC.
+
+ Accepts a stream of Points on a route being traversed, returning a
+ RouteSummary when traversal is completed.
+ """
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def RouteChat(self, request_iterator, context):
- raise NotImplementedError()
+ """A Bidirectional streaming RPC.
+
+ Accepts a stream of RouteNotes sent while a route is being traversed,
+ while receiving other RouteNotes (e.g. from other users).
+ """
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
class BetaRouteGuideStub(object):
- """The interface to which stubs will conform."""
- __metaclass__ = abc.ABCMeta
- @abc.abstractmethod
+ """Interface exported by the server.
+ """
def GetFeature(self, request, timeout):
+ """A simple RPC.
+
+ Obtains the feature at a given position.
+
+ A feature with an empty name is returned if there's no feature at the given
+ position.
+ """
raise NotImplementedError()
GetFeature.future = None
- @abc.abstractmethod
def ListFeatures(self, request, timeout):
+ """A server-to-client streaming RPC.
+
+ Obtains the Features available within the given Rectangle. Results are
+ streamed rather than returned at once (e.g. in a response message with a
+ repeated field), as the rectangle may cover a large area and contain a
+ huge number of features.
+ """
raise NotImplementedError()
- @abc.abstractmethod
def RecordRoute(self, request_iterator, timeout):
+ """A client-to-server streaming RPC.
+
+ Accepts a stream of Points on a route being traversed, returning a
+ RouteSummary when traversal is completed.
+ """
raise NotImplementedError()
RecordRoute.future = None
- @abc.abstractmethod
def RouteChat(self, request_iterator, timeout):
+ """A Bidirectional streaming RPC.
+
+ Accepts a stream of RouteNotes sent while a route is being traversed,
+ while receiving other RouteNotes (e.g. from other users).
+ """
raise NotImplementedError()
def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
diff --git a/gRPC.podspec b/gRPC.podspec
index 77d35bd..018306c 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -287,6 +287,42 @@
'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',
+ 'include/grpc/byte_buffer.h',
+ 'include/grpc/grpc.h',
+ 'include/grpc/impl/codegen/alloc.h',
+ 'include/grpc/impl/codegen/atm.h',
+ 'include/grpc/impl/codegen/atm_gcc_atomic.h',
+ 'include/grpc/impl/codegen/atm_gcc_sync.h',
+ 'include/grpc/impl/codegen/atm_win32.h',
+ 'include/grpc/impl/codegen/byte_buffer.h',
+ 'include/grpc/impl/codegen/compression_types.h',
+ 'include/grpc/impl/codegen/connectivity_state.h',
+ 'include/grpc/impl/codegen/grpc_types.h',
+ 'include/grpc/impl/codegen/log.h',
+ 'include/grpc/impl/codegen/port_platform.h',
+ 'include/grpc/impl/codegen/propagation_bits.h',
+ 'include/grpc/impl/codegen/slice.h',
+ 'include/grpc/impl/codegen/slice_buffer.h',
+ 'include/grpc/impl/codegen/status.h',
+ 'include/grpc/impl/codegen/sync.h',
+ 'include/grpc/impl/codegen/sync_generic.h',
+ 'include/grpc/impl/codegen/sync_posix.h',
+ 'include/grpc/impl/codegen/sync_win32.h',
+ 'include/grpc/impl/codegen/time.h',
+ 'include/grpc/status.h',
+ 'include/grpc/support/alloc.h',
+ 'include/grpc/support/atm.h',
+ 'include/grpc/support/host_port.h',
+ 'include/grpc/support/log.h',
+ 'include/grpc/support/port_platform.h',
+ 'include/grpc/support/slice.h',
+ 'include/grpc/support/slice_buffer.h',
+ 'include/grpc/support/string_util.h',
+ 'include/grpc/support/sync.h',
+ 'include/grpc/support/time.h',
+ 'include/grpc/support/useful.h',
+ 'src/core/lib/support/string.h',
+ 'third_party/objective_c/Cronet/cronet_c_for_grpc.h',
'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h',
'third_party/nanopb/pb.h',
@@ -305,6 +341,7 @@
'include/grpc/grpc.h',
'include/grpc/status.h',
'include/grpc/impl/codegen/byte_buffer.h',
+ 'include/grpc/impl/codegen/byte_buffer_reader.h',
'include/grpc/impl/codegen/compression_types.h',
'include/grpc/impl/codegen/connectivity_state.h',
'include/grpc/impl/codegen/grpc_types.h',
@@ -324,6 +361,7 @@
'include/grpc/impl/codegen/sync_posix.h',
'include/grpc/impl/codegen/sync_win32.h',
'include/grpc/impl/codegen/time.h',
+ 'include/grpc/grpc_cronet.h',
'include/grpc/grpc_security.h',
'include/grpc/grpc_security_constants.h',
'include/grpc/census.h',
@@ -473,6 +511,9 @@
'src/core/ext/client_config/uri_parser.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
+ 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
+ 'src/core/ext/transport/cronet/transport/cronet_api_dummy.c',
+ 'src/core/ext/transport/cronet/transport/cronet_transport.c',
'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c',
'third_party/nanopb/pb_common.c',
@@ -629,6 +670,42 @@
'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',
+ 'include/grpc/byte_buffer.h',
+ 'include/grpc/grpc.h',
+ 'include/grpc/impl/codegen/alloc.h',
+ 'include/grpc/impl/codegen/atm.h',
+ 'include/grpc/impl/codegen/atm_gcc_atomic.h',
+ 'include/grpc/impl/codegen/atm_gcc_sync.h',
+ 'include/grpc/impl/codegen/atm_win32.h',
+ 'include/grpc/impl/codegen/byte_buffer.h',
+ 'include/grpc/impl/codegen/compression_types.h',
+ 'include/grpc/impl/codegen/connectivity_state.h',
+ 'include/grpc/impl/codegen/grpc_types.h',
+ 'include/grpc/impl/codegen/log.h',
+ 'include/grpc/impl/codegen/port_platform.h',
+ 'include/grpc/impl/codegen/propagation_bits.h',
+ 'include/grpc/impl/codegen/slice.h',
+ 'include/grpc/impl/codegen/slice_buffer.h',
+ 'include/grpc/impl/codegen/status.h',
+ 'include/grpc/impl/codegen/sync.h',
+ 'include/grpc/impl/codegen/sync_generic.h',
+ 'include/grpc/impl/codegen/sync_posix.h',
+ 'include/grpc/impl/codegen/sync_win32.h',
+ 'include/grpc/impl/codegen/time.h',
+ 'include/grpc/status.h',
+ 'include/grpc/support/alloc.h',
+ 'include/grpc/support/atm.h',
+ 'include/grpc/support/host_port.h',
+ 'include/grpc/support/log.h',
+ 'include/grpc/support/port_platform.h',
+ 'include/grpc/support/slice.h',
+ 'include/grpc/support/slice_buffer.h',
+ 'include/grpc/support/string_util.h',
+ 'include/grpc/support/sync.h',
+ 'include/grpc/support/time.h',
+ 'include/grpc/support/useful.h',
+ 'src/core/lib/support/string.h',
+ 'third_party/objective_c/Cronet/cronet_c_for_grpc.h',
'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h',
'third_party/nanopb/pb.h',
diff --git a/grpc.def b/grpc.def
index 61948ed..09a94a6 100644
--- a/grpc.def
+++ b/grpc.def
@@ -87,6 +87,7 @@
grpc_header_nonbin_value_is_legal
grpc_is_binary_header
grpc_call_error_to_string
+ grpc_cronet_secure_channel_create
grpc_auth_property_iterator_next
grpc_auth_context_property_iterator
grpc_auth_context_peer_identity
diff --git a/grpc.gemspec b/grpc.gemspec
index e68cd81..ace2871 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -149,6 +149,7 @@
s.files += %w( include/grpc/grpc.h )
s.files += %w( include/grpc/status.h )
s.files += %w( include/grpc/impl/codegen/byte_buffer.h )
+ s.files += %w( include/grpc/impl/codegen/byte_buffer_reader.h )
s.files += %w( include/grpc/impl/codegen/compression_types.h )
s.files += %w( include/grpc/impl/codegen/connectivity_state.h )
s.files += %w( include/grpc/impl/codegen/grpc_types.h )
@@ -168,6 +169,7 @@
s.files += %w( include/grpc/impl/codegen/sync_posix.h )
s.files += %w( include/grpc/impl/codegen/sync_win32.h )
s.files += %w( include/grpc/impl/codegen/time.h )
+ s.files += %w( include/grpc/grpc_cronet.h )
s.files += %w( include/grpc/grpc_security.h )
s.files += %w( include/grpc/grpc_security_constants.h )
s.files += %w( include/grpc/census.h )
@@ -295,6 +297,42 @@
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( include/grpc/byte_buffer.h )
+ s.files += %w( include/grpc/grpc.h )
+ s.files += %w( include/grpc/impl/codegen/alloc.h )
+ s.files += %w( include/grpc/impl/codegen/atm.h )
+ s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
+ s.files += %w( include/grpc/impl/codegen/atm_gcc_sync.h )
+ s.files += %w( include/grpc/impl/codegen/atm_win32.h )
+ s.files += %w( include/grpc/impl/codegen/byte_buffer.h )
+ s.files += %w( include/grpc/impl/codegen/compression_types.h )
+ s.files += %w( include/grpc/impl/codegen/connectivity_state.h )
+ s.files += %w( include/grpc/impl/codegen/grpc_types.h )
+ s.files += %w( include/grpc/impl/codegen/log.h )
+ s.files += %w( include/grpc/impl/codegen/port_platform.h )
+ s.files += %w( include/grpc/impl/codegen/propagation_bits.h )
+ s.files += %w( include/grpc/impl/codegen/slice.h )
+ s.files += %w( include/grpc/impl/codegen/slice_buffer.h )
+ s.files += %w( include/grpc/impl/codegen/status.h )
+ s.files += %w( include/grpc/impl/codegen/sync.h )
+ s.files += %w( include/grpc/impl/codegen/sync_generic.h )
+ s.files += %w( include/grpc/impl/codegen/sync_posix.h )
+ s.files += %w( include/grpc/impl/codegen/sync_win32.h )
+ s.files += %w( include/grpc/impl/codegen/time.h )
+ s.files += %w( include/grpc/status.h )
+ s.files += %w( include/grpc/support/alloc.h )
+ s.files += %w( include/grpc/support/atm.h )
+ s.files += %w( include/grpc/support/host_port.h )
+ s.files += %w( include/grpc/support/log.h )
+ s.files += %w( include/grpc/support/port_platform.h )
+ s.files += %w( include/grpc/support/slice.h )
+ s.files += %w( include/grpc/support/slice_buffer.h )
+ s.files += %w( include/grpc/support/string_util.h )
+ s.files += %w( include/grpc/support/sync.h )
+ s.files += %w( include/grpc/support/time.h )
+ s.files += %w( include/grpc/support/useful.h )
+ s.files += %w( src/core/lib/support/string.h )
+ s.files += %w( third_party/objective_c/Cronet/cronet_c_for_grpc.h )
s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.h )
s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h )
s.files += %w( third_party/nanopb/pb.h )
@@ -453,6 +491,9 @@
s.files += %w( src/core/ext/client_config/uri_parser.c )
s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2.c )
s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c )
+ s.files += %w( src/core/ext/transport/cronet/client/secure/cronet_channel_create.c )
+ s.files += %w( src/core/ext/transport/cronet/transport/cronet_api_dummy.c )
+ s.files += %w( src/core/ext/transport/cronet/transport/cronet_transport.c )
s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.c )
s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c )
s.files += %w( third_party/nanopb/pb_common.c )
diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h
index 16424ba..aa9013c 100644
--- a/include/grpc++/impl/codegen/core_codegen_interface.h
+++ b/include/grpc++/impl/codegen/core_codegen_interface.h
@@ -49,18 +49,6 @@
/// \warning This interface should be considered internal and private.
class CoreCodegenInterface {
public:
- // Serialize the msg into a buffer created inside the function. The caller
- // should destroy the returned buffer when done with it. If serialization
- // fails,
- // false is returned and buffer is left unchanged.
- virtual Status SerializeProto(const grpc::protobuf::Message& msg,
- grpc_byte_buffer** buffer) = 0;
-
- // The caller keeps ownership of buffer and msg.
- virtual Status DeserializeProto(grpc_byte_buffer* buffer,
- grpc::protobuf::Message* msg,
- int max_message_size) = 0;
-
/// Upon a failed assertion, log the error.
virtual void assert_fail(const char* failed_assertion) = 0;
@@ -76,9 +64,29 @@
virtual void gpr_free(void* p) = 0;
virtual void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) = 0;
+
+ virtual void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
+ grpc_byte_buffer* buffer) = 0;
+ virtual void grpc_byte_buffer_reader_destroy(
+ grpc_byte_buffer_reader* reader) = 0;
+ virtual int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
+ gpr_slice* slice) = 0;
+
+ virtual grpc_byte_buffer* grpc_raw_byte_buffer_create(gpr_slice* slice,
+ size_t nslices) = 0;
+
+ virtual gpr_slice gpr_slice_malloc(size_t length) = 0;
+ virtual void gpr_slice_unref(gpr_slice slice) = 0;
+ virtual gpr_slice gpr_slice_split_tail(gpr_slice* s, size_t split) = 0;
+ virtual void gpr_slice_buffer_add(gpr_slice_buffer* sb, gpr_slice slice) = 0;
+ virtual void gpr_slice_buffer_pop(gpr_slice_buffer* sb) = 0;
+
virtual void grpc_metadata_array_init(grpc_metadata_array* array) = 0;
virtual void grpc_metadata_array_destroy(grpc_metadata_array* array) = 0;
+ virtual const Status& ok() = 0;
+ virtual const Status& cancelled() = 0;
+
virtual gpr_timespec gpr_inf_future(gpr_clock_type type) = 0;
};
diff --git a/include/grpc++/impl/codegen/proto_utils.h b/include/grpc++/impl/codegen/proto_utils.h
index 2aaa3c3..d044ddc 100644
--- a/include/grpc++/impl/codegen/proto_utils.h
+++ b/include/grpc++/impl/codegen/proto_utils.h
@@ -41,26 +41,179 @@
#include <grpc++/impl/codegen/serialization_traits.h>
#include <grpc++/impl/codegen/status.h>
#include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/byte_buffer_reader.h>
#include <grpc/impl/codegen/log.h>
+#include <grpc/impl/codegen/slice.h>
namespace grpc {
extern CoreCodegenInterface* g_core_codegen_interface;
+namespace {
+
+const int kGrpcBufferWriterMaxBufferLength = 8192;
+
+class GrpcBufferWriter GRPC_FINAL
+ : public ::grpc::protobuf::io::ZeroCopyOutputStream {
+ public:
+ explicit GrpcBufferWriter(grpc_byte_buffer** bp, int block_size)
+ : block_size_(block_size), byte_count_(0), have_backup_(false) {
+ *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(NULL, 0);
+ slice_buffer_ = &(*bp)->data.raw.slice_buffer;
+ }
+
+ ~GrpcBufferWriter() GRPC_OVERRIDE {
+ if (have_backup_) {
+ g_core_codegen_interface->gpr_slice_unref(backup_slice_);
+ }
+ }
+
+ bool Next(void** data, int* size) GRPC_OVERRIDE {
+ if (have_backup_) {
+ slice_ = backup_slice_;
+ have_backup_ = false;
+ } else {
+ slice_ = g_core_codegen_interface->gpr_slice_malloc(block_size_);
+ }
+ *data = GPR_SLICE_START_PTR(slice_);
+ // On win x64, int is only 32bit
+ GPR_CODEGEN_ASSERT(GPR_SLICE_LENGTH(slice_) <= INT_MAX);
+ byte_count_ += * size = (int)GPR_SLICE_LENGTH(slice_);
+ g_core_codegen_interface->gpr_slice_buffer_add(slice_buffer_, slice_);
+ return true;
+ }
+
+ void BackUp(int count) GRPC_OVERRIDE {
+ g_core_codegen_interface->gpr_slice_buffer_pop(slice_buffer_);
+ if (count == block_size_) {
+ backup_slice_ = slice_;
+ } else {
+ backup_slice_ = g_core_codegen_interface->gpr_slice_split_tail(
+ &slice_, GPR_SLICE_LENGTH(slice_) - count);
+ g_core_codegen_interface->gpr_slice_buffer_add(slice_buffer_, slice_);
+ }
+ have_backup_ = true;
+ byte_count_ -= count;
+ }
+
+ grpc::protobuf::int64 ByteCount() const GRPC_OVERRIDE { return byte_count_; }
+
+ private:
+ const int block_size_;
+ int64_t byte_count_;
+ gpr_slice_buffer* slice_buffer_;
+ bool have_backup_;
+ gpr_slice backup_slice_;
+ gpr_slice slice_;
+};
+
+class GrpcBufferReader GRPC_FINAL
+ : public ::grpc::protobuf::io::ZeroCopyInputStream {
+ public:
+ explicit GrpcBufferReader(grpc_byte_buffer* buffer)
+ : byte_count_(0), backup_count_(0) {
+ g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader_, buffer);
+ }
+ ~GrpcBufferReader() GRPC_OVERRIDE {
+ g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader_);
+ }
+
+ bool Next(const void** data, int* size) GRPC_OVERRIDE {
+ if (backup_count_ > 0) {
+ *data = GPR_SLICE_START_PTR(slice_) + GPR_SLICE_LENGTH(slice_) -
+ backup_count_;
+ GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX);
+ *size = (int)backup_count_;
+ backup_count_ = 0;
+ return true;
+ }
+ if (!g_core_codegen_interface->grpc_byte_buffer_reader_next(&reader_,
+ &slice_)) {
+ return false;
+ }
+ g_core_codegen_interface->gpr_slice_unref(slice_);
+ *data = GPR_SLICE_START_PTR(slice_);
+ // On win x64, int is only 32bit
+ GPR_CODEGEN_ASSERT(GPR_SLICE_LENGTH(slice_) <= INT_MAX);
+ byte_count_ += * size = (int)GPR_SLICE_LENGTH(slice_);
+ return true;
+ }
+
+ void BackUp(int count) GRPC_OVERRIDE { backup_count_ = count; }
+
+ bool Skip(int count) GRPC_OVERRIDE {
+ const void* data;
+ int size;
+ while (Next(&data, &size)) {
+ if (size >= count) {
+ BackUp(size - count);
+ return true;
+ }
+ // size < count;
+ count -= size;
+ }
+ // error or we have too large count;
+ return false;
+ }
+
+ grpc::protobuf::int64 ByteCount() const GRPC_OVERRIDE {
+ return byte_count_ - backup_count_;
+ }
+
+ private:
+ int64_t byte_count_;
+ int64_t backup_count_;
+ grpc_byte_buffer_reader reader_;
+ gpr_slice slice_;
+};
+} // namespace
+
template <class T>
class SerializationTraits<T, typename std::enable_if<std::is_base_of<
grpc::protobuf::Message, T>::value>::type> {
public:
static Status Serialize(const grpc::protobuf::Message& msg,
- grpc_byte_buffer** buffer, bool* own_buffer) {
+ grpc_byte_buffer** bp, bool* own_buffer) {
*own_buffer = true;
- return g_core_codegen_interface->SerializeProto(msg, buffer);
+ int byte_size = msg.ByteSize();
+ if (byte_size <= kGrpcBufferWriterMaxBufferLength) {
+ gpr_slice slice = g_core_codegen_interface->gpr_slice_malloc(byte_size);
+ GPR_CODEGEN_ASSERT(
+ GPR_SLICE_END_PTR(slice) ==
+ msg.SerializeWithCachedSizesToArray(GPR_SLICE_START_PTR(slice)));
+ *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(&slice, 1);
+ g_core_codegen_interface->gpr_slice_unref(slice);
+ return g_core_codegen_interface->ok();
+ } else {
+ GrpcBufferWriter writer(bp, kGrpcBufferWriterMaxBufferLength);
+ return msg.SerializeToZeroCopyStream(&writer)
+ ? g_core_codegen_interface->ok()
+ : Status(StatusCode::INTERNAL, "Failed to serialize message");
+ }
}
+
static Status Deserialize(grpc_byte_buffer* buffer,
grpc::protobuf::Message* msg,
int max_message_size) {
- return g_core_codegen_interface->DeserializeProto(buffer, msg,
- max_message_size);
+ if (buffer == nullptr) {
+ return Status(StatusCode::INTERNAL, "No payload");
+ }
+ Status result = g_core_codegen_interface->ok();
+ {
+ GrpcBufferReader reader(buffer);
+ ::grpc::protobuf::io::CodedInputStream decoder(&reader);
+ if (max_message_size > 0) {
+ decoder.SetTotalBytesLimit(max_message_size, max_message_size);
+ }
+ if (!msg->ParseFromCodedStream(&decoder)) {
+ result = Status(StatusCode::INTERNAL, msg->InitializationErrorString());
+ }
+ if (!decoder.ConsumedEntireMessage()) {
+ result = Status(StatusCode::INTERNAL, "Did not read entire message");
+ }
+ }
+ g_core_codegen_interface->grpc_byte_buffer_destroy(buffer);
+ return result;
}
};
diff --git a/include/grpc/byte_buffer_reader.h b/include/grpc/byte_buffer_reader.h
index 9a1c617..e95bf2f 100644
--- a/include/grpc/byte_buffer_reader.h
+++ b/include/grpc/byte_buffer_reader.h
@@ -34,25 +34,6 @@
#ifndef GRPC_BYTE_BUFFER_READER_H
#define GRPC_BYTE_BUFFER_READER_H
-#include <grpc/byte_buffer.h>
-#include <grpc/grpc.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct grpc_byte_buffer_reader {
- grpc_byte_buffer *buffer_in;
- grpc_byte_buffer *buffer_out;
- /* Different current objects correspond to different types of byte buffers */
- union {
- /* Index into a slice buffer's array of slices */
- unsigned index;
- } current;
-};
-
-#ifdef __cplusplus
-}
-#endif
+#include <grpc/impl/codegen/byte_buffer_reader.h>
#endif /* GRPC_BYTE_BUFFER_READER_H */
diff --git a/include/grpc/grpc_cronet.h b/include/grpc/grpc_cronet.h
new file mode 100644
index 0000000..295e0f5
--- /dev/null
+++ b/include/grpc/grpc_cronet.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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_GRPC_CRONET_H
+#define GRPC_GRPC_CRONET_H
+
+#include <grpc/grpc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GRPCAPI grpc_channel *grpc_cronet_secure_channel_create(
+ void *engine, const char *target, const grpc_channel_args *args,
+ void *reserved);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_GRPC_CRONET_H */
diff --git a/include/grpc/impl/codegen/byte_buffer_reader.h b/include/grpc/impl/codegen/byte_buffer_reader.h
new file mode 100644
index 0000000..10c3829
--- /dev/null
+++ b/include/grpc/impl/codegen/byte_buffer_reader.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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_IMPL_CODEGEN_BYTE_BUFFER_READER_H
+#define GRPC_IMPL_CODEGEN_BYTE_BUFFER_READER_H
+
+#include <grpc/impl/codegen/byte_buffer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct grpc_byte_buffer_reader {
+ grpc_byte_buffer *buffer_in;
+ grpc_byte_buffer *buffer_out;
+ /* Different current objects correspond to different types of byte buffers */
+ union {
+ /* Index into a slice buffer's array of slices */
+ unsigned index;
+ } current;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_BYTE_BUFFER_READER_H */
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 4c73730..7b20cc1 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -307,7 +307,9 @@
GRPC_OP_RECV_STATUS_ON_CLIENT,
/** Receive close on the server: one and only one must be made on the
server.
- This op completes after the close has been received by the server. */
+ This op completes after the close has been received by the server.
+ This operation always succeeds, meaning ops paired with this operation
+ will also appear to succeed, even though they may not have. */
GRPC_OP_RECV_CLOSE_ON_SERVER
} grpc_op_type;
diff --git a/package.xml b/package.xml
index ffb1c56..716d6ed 100644
--- a/package.xml
+++ b/package.xml
@@ -156,6 +156,7 @@
<file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
<file baseinstalldir="/" name="include/grpc/status.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer_reader.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/compression_types.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/connectivity_state.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/grpc_types.h" role="src" />
@@ -175,6 +176,7 @@
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/sync_win32.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/time.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/grpc_cronet.h" role="src" />
<file baseinstalldir="/" name="include/grpc/grpc_security.h" role="src" />
<file baseinstalldir="/" name="include/grpc/grpc_security_constants.h" role="src" />
<file baseinstalldir="/" name="include/grpc/census.h" role="src" />
@@ -302,6 +304,42 @@
<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="include/grpc/byte_buffer.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/alloc.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/atm.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_sync.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_win32.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/compression_types.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/connectivity_state.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/grpc_types.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/log.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/propagation_bits.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/slice_buffer.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/status.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/sync.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_generic.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_win32.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/impl/codegen/time.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/status.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/alloc.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/atm.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/host_port.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/log.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/port_platform.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/slice.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/slice_buffer.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/string_util.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/sync.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/time.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/useful.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/support/string.h" role="src" />
+ <file baseinstalldir="/" name="third_party/objective_c/Cronet/cronet_c_for_grpc.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" />
@@ -460,6 +498,9 @@
<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" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.c" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/cronet/client/secure/cronet_channel_create.c" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/cronet/transport/cronet_api_dummy.c" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/cronet/transport/cronet_transport.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c" role="src" />
<file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" />
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index 59137e1..8e76e6d 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -182,18 +182,40 @@
return true;
}
+// Get all comments (leading, leading_detached, trailing) and print them as a
+// docstring. Any leading space of a line will be removed, but the line wrapping
+// will not be changed.
+template <typename DescriptorType>
+static void PrintAllComments(const DescriptorType* desc, Printer* printer) {
+ std::vector<grpc::string> comments;
+ grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED,
+ &comments);
+ grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING,
+ &comments);
+ grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_TRAILING,
+ &comments);
+ if (comments.empty()) {
+ return;
+ }
+ printer->Print("\"\"\"");
+ for (auto it = comments.begin(); it != comments.end(); ++it) {
+ size_t start_pos = it->find_first_not_of(' ');
+ if (start_pos != grpc::string::npos) {
+ printer->Print(it->c_str() + start_pos);
+ }
+ printer->Print("\n");
+ }
+ printer->Print("\"\"\"\n");
+}
+
bool PrintBetaServicer(const ServiceDescriptor* service,
Printer* out) {
- grpc::string doc = "<fill me in later!>";
- map<grpc::string, grpc::string> dict = ListToDict({
- "Service", service->name(),
- "Documentation", doc,
- });
out->Print("\n");
- out->Print(dict, "class Beta$Service$Servicer(object):\n");
+ out->Print("class Beta$Service$Servicer(object):\n", "Service",
+ service->name());
{
IndentScope raii_class_indent(out);
- out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
+ PrintAllComments(service, out);
for (int i = 0; i < service->method_count(); ++i) {
auto meth = service->method(i);
grpc::string arg_name = meth->client_streaming() ?
@@ -202,6 +224,7 @@
"Method", meth->name(), "ArgName", arg_name);
{
IndentScope raii_method_indent(out);
+ PrintAllComments(meth, out);
out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
}
}
@@ -211,16 +234,11 @@
bool PrintBetaStub(const ServiceDescriptor* service,
Printer* out) {
- grpc::string doc = "The interface to which stubs will conform.";
- map<grpc::string, grpc::string> dict = ListToDict({
- "Service", service->name(),
- "Documentation", doc,
- });
out->Print("\n");
- out->Print(dict, "class Beta$Service$Stub(object):\n");
+ out->Print("class Beta$Service$Stub(object):\n", "Service", service->name());
{
IndentScope raii_class_indent(out);
- out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
+ PrintAllComments(service, out);
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* meth = service->method(i);
grpc::string arg_name = meth->client_streaming() ?
@@ -229,6 +247,7 @@
out->Print(methdict, "def $Method$(self, $ArgName$, timeout):\n");
{
IndentScope raii_method_indent(out);
+ PrintAllComments(meth, out);
out->Print("raise NotImplementedError()\n");
}
if (!meth->server_streaming()) {
diff --git a/src/core/ext/client_config/resolver_registry.c b/src/core/ext/client_config/resolver_registry.c
index 07f29bc..e7a4abd 100644
--- a/src/core/ext/client_config/resolver_registry.c
+++ b/src/core/ext/client_config/resolver_registry.c
@@ -47,7 +47,6 @@
static char *g_default_resolver_prefix;
void grpc_resolver_registry_init(const char *default_resolver_prefix) {
- g_number_of_resolvers = 0;
g_default_resolver_prefix = gpr_strdup(default_resolver_prefix);
}
@@ -57,6 +56,13 @@
grpc_resolver_factory_unref(g_all_of_the_resolvers[i]);
}
gpr_free(g_default_resolver_prefix);
+ // FIXME(ctiller): this should live in grpc_resolver_registry_init,
+ // however that would have the client_config plugin call this AFTER we start
+ // registering resolvers from third party plugins, and so they'd never show
+ // up.
+ // We likely need some kind of dependency system for plugins.... what form
+ // that takes is TBD.
+ g_number_of_resolvers = 0;
}
void grpc_register_resolver_type(grpc_resolver_factory *factory) {
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index 3f6051b..dcdc0c6 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -306,8 +306,10 @@
size_t i;
p->started_picking = 1;
- gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%d", p,
- p->num_subchannels);
+ if (grpc_lb_round_robin_trace) {
+ gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%d", p,
+ p->num_subchannels);
+ }
for (i = 0; i < p->num_subchannels; i++) {
subchannel_data *sd = p->subchannels[i];
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 8c85937..5363322 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -783,7 +783,8 @@
grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
uint32_t goaway_error, gpr_slice goaway_text) {
char *msg = gpr_dump_slice(goaway_text, GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg);
+ GRPC_CHTTP2_IF_TRACING(
+ gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg));
gpr_free(msg);
gpr_slice_unref(goaway_text);
transport_global->seen_goaway = 1;
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
index 555027c..ebeee37 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
@@ -63,6 +63,8 @@
/* don't consider adding anything bigger than this to the hpack table */
#define MAX_DECODER_SPACE_USAGE 512
+extern int grpc_http_trace;
+
typedef struct {
int is_first_frame;
/* number of bytes in 'output' when we started the frame - used to calculate
@@ -532,7 +534,9 @@
}
}
c->advertise_table_size_change = 1;
- gpr_log(GPR_DEBUG, "set max table size from encoder to %d", max_table_size);
+ if (grpc_http_trace) {
+ gpr_log(GPR_DEBUG, "set max table size from encoder to %d", max_table_size);
+ }
}
void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.c b/src/core/ext/transport/chttp2/transport/hpack_table.c
index 4d64506..295f31c 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.c
@@ -253,7 +253,9 @@
if (tbl->max_bytes == max_bytes) {
return;
}
- gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes);
+ if (grpc_http_trace) {
+ gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes);
+ }
while (tbl->mem_used > max_bytes) {
evict1(tbl);
}
diff --git a/src/core/ext/transport/cronet/client/secure/cronet_channel_create.c b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.c
new file mode 100644
index 0000000..df1acdd
--- /dev/null
+++ b/src/core/ext/transport/cronet/client/secure/cronet_channel_create.c
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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 <grpc/impl/codegen/port_platform.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/transport/transport_impl.h"
+
+// Cronet transport object
+typedef struct cronet_transport {
+ grpc_transport base; // must be first element in this structure
+ void *engine;
+ char *host;
+} cronet_transport;
+
+extern grpc_transport_vtable grpc_cronet_vtable;
+
+GRPCAPI grpc_channel *grpc_cronet_secure_channel_create(
+ void *engine, const char *target, const grpc_channel_args *args,
+ void *reserved) {
+ cronet_transport *ct = gpr_malloc(sizeof(cronet_transport));
+ ct->base.vtable = &grpc_cronet_vtable;
+ ct->engine = engine;
+ ct->host = gpr_malloc(strlen(target) + 1);
+ strcpy(ct->host, target);
+ gpr_log(GPR_DEBUG,
+ "grpc_create_cronet_transport: cronet_engine = %p, target=%s", engine,
+ ct->host);
+
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ return grpc_channel_create(&exec_ctx, target, args,
+ GRPC_CLIENT_DIRECT_CHANNEL, (grpc_transport *)ct);
+}
diff --git a/src/core/ext/transport/cronet/transport/cronet_api_dummy.c b/src/core/ext/transport/cronet/transport/cronet_api_dummy.c
new file mode 100644
index 0000000..687026c
--- /dev/null
+++ b/src/core/ext/transport/cronet/transport/cronet_api_dummy.c
@@ -0,0 +1,85 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* This file has empty implementation of all the functions exposed by the cronet
+library, so we can build it in all environments */
+
+#include <stdbool.h>
+
+#include <grpc/support/log.h>
+
+#include "third_party/objective_c/Cronet/cronet_c_for_grpc.h"
+
+#ifdef GRPC_COMPILE_WITH_CRONET
+/* link with the real CRONET library in the build system */
+#else
+/* Dummy implementation of cronet API just to test for build-ability */
+cronet_bidirectional_stream* cronet_bidirectional_stream_create(
+ cronet_engine* engine, void* annotation,
+ cronet_bidirectional_stream_callback* callback) {
+ GPR_ASSERT(0);
+ return NULL;
+}
+
+int cronet_bidirectional_stream_destroy(cronet_bidirectional_stream* stream) {
+ GPR_ASSERT(0);
+ return 0;
+}
+
+int cronet_bidirectional_stream_start(
+ cronet_bidirectional_stream* stream, const char* url, int priority,
+ const char* method, const cronet_bidirectional_stream_header_array* headers,
+ bool end_of_stream) {
+ GPR_ASSERT(0);
+ return 0;
+}
+
+int cronet_bidirectional_stream_read(cronet_bidirectional_stream* stream,
+ char* buffer, int capacity) {
+ GPR_ASSERT(0);
+ return 0;
+}
+
+int cronet_bidirectional_stream_write(cronet_bidirectional_stream* stream,
+ const char* buffer, int count,
+ bool end_of_stream) {
+ GPR_ASSERT(0);
+ return 0;
+}
+
+int cronet_bidirectional_stream_cancel(cronet_bidirectional_stream* stream) {
+ GPR_ASSERT(0);
+ return 0;
+}
+
+#endif /* GRPC_COMPILE_WITH_CRONET */
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
new file mode 100644
index 0000000..5bb0851
--- /dev/null
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -0,0 +1,640 @@
+/*
+ *
+ * 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 <string.h>
+
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/slice_buffer.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/support/string.h"
+#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/transport/metadata_batch.h"
+#include "src/core/lib/transport/transport_impl.h"
+#include "third_party/objective_c/Cronet/cronet_c_for_grpc.h"
+
+#define GRPC_HEADER_SIZE_IN_BYTES 5
+
+// Global flag that gets set with GRPC_TRACE env variable
+int grpc_cronet_trace = 1;
+
+// Cronet transport object
+struct grpc_cronet_transport {
+ grpc_transport base; /* must be first element in this structure */
+ cronet_engine *engine;
+ char *host;
+};
+
+typedef struct grpc_cronet_transport grpc_cronet_transport;
+
+enum send_state {
+ CRONET_SEND_IDLE = 0,
+ CRONET_REQ_STARTED,
+ CRONET_SEND_HEADER,
+ CRONET_WRITE,
+ CRONET_WRITE_COMPLETED,
+};
+
+enum recv_state {
+ CRONET_RECV_IDLE = 0,
+ CRONET_RECV_READ_LENGTH,
+ CRONET_RECV_READ_DATA,
+ CRONET_RECV_CLOSED,
+};
+
+static const char *recv_state_name[] = {
+ "CRONET_RECV_IDLE", "CRONET_RECV_READ_LENGTH", "CRONET_RECV_READ_DATA,",
+ "CRONET_RECV_CLOSED"};
+
+// Enum that identifies calling function.
+enum e_caller {
+ PERFORM_STREAM_OP,
+ ON_READ_COMPLETE,
+ ON_RESPONSE_HEADERS_RECEIVED,
+ ON_RESPONSE_TRAILERS_RECEIVED
+};
+
+enum callback_id {
+ CB_SEND_INITIAL_METADATA = 0,
+ CB_SEND_MESSAGE,
+ CB_SEND_TRAILING_METADATA,
+ CB_RECV_MESSAGE,
+ CB_RECV_INITIAL_METADATA,
+ CB_RECV_TRAILING_METADATA,
+ CB_NUM_CALLBACKS
+};
+
+struct stream_obj {
+ // we store received bytes here as they trickle in.
+ gpr_slice_buffer write_slice_buffer;
+ cronet_bidirectional_stream *cbs;
+ gpr_slice slice;
+ gpr_slice_buffer read_slice_buffer;
+ struct grpc_slice_buffer_stream sbs;
+ char *read_buffer;
+ int remaining_read_bytes;
+ int total_read_bytes;
+
+ char *write_buffer;
+ size_t write_buffer_size;
+
+ // Hold the URL
+ char *url;
+
+ bool response_headers_received;
+ bool read_requested;
+ bool response_trailers_received;
+ bool read_closed;
+
+ // Recv message stuff
+ grpc_byte_buffer **recv_message;
+ // Initial metadata stuff
+ grpc_metadata_batch *recv_initial_metadata;
+ // Trailing metadata stuff
+ grpc_metadata_batch *recv_trailing_metadata;
+ grpc_chttp2_incoming_metadata_buffer imb;
+
+ // This mutex protects receive state machine execution
+ gpr_mu recv_mu;
+ // we can queue up up to 2 callbacks for each OP
+ grpc_closure *callback_list[CB_NUM_CALLBACKS][2];
+
+ // storage for header
+ cronet_bidirectional_stream_header *headers;
+ uint32_t num_headers;
+ cronet_bidirectional_stream_header_array header_array;
+ // state tracking
+ enum recv_state cronet_recv_state;
+ enum send_state cronet_send_state;
+};
+
+typedef struct stream_obj stream_obj;
+
+static void next_send_step(stream_obj *s);
+static void next_recv_step(stream_obj *s, enum e_caller caller);
+
+static void set_pollset_do_nothing(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
+ grpc_stream *gs, grpc_pollset *pollset) {}
+
+static void enqueue_callbacks(grpc_closure *callback_list[]) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ if (callback_list[0]) {
+ grpc_exec_ctx_enqueue(&exec_ctx, callback_list[0], true, NULL);
+ callback_list[0] = NULL;
+ }
+ if (callback_list[1]) {
+ grpc_exec_ctx_enqueue(&exec_ctx, callback_list[1], true, NULL);
+ callback_list[1] = NULL;
+ }
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void on_canceled(cronet_bidirectional_stream *stream) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "on_canceled %p", stream);
+ }
+}
+
+static void on_failed(cronet_bidirectional_stream *stream, int net_error) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "on_failed %p, error = %d", stream, net_error);
+ }
+}
+
+static void on_succeeded(cronet_bidirectional_stream *stream) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "on_succeeded %p", stream);
+ }
+}
+
+static void on_response_trailers_received(
+ cronet_bidirectional_stream *stream,
+ const cronet_bidirectional_stream_header_array *trailers) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "R: on_response_trailers_received");
+ }
+ stream_obj *s = (stream_obj *)stream->annotation;
+
+ memset(&s->imb, 0, sizeof(s->imb));
+ grpc_chttp2_incoming_metadata_buffer_init(&s->imb);
+ unsigned int i = 0;
+ for (i = 0; i < trailers->count; i++) {
+ grpc_chttp2_incoming_metadata_buffer_add(
+ &s->imb, grpc_mdelem_from_metadata_strings(
+ grpc_mdstr_from_string(trailers->headers[i].key),
+ grpc_mdstr_from_string(trailers->headers[i].value)));
+ }
+ s->response_trailers_received = true;
+ next_recv_step(s, ON_RESPONSE_TRAILERS_RECEIVED);
+}
+
+static void on_write_completed(cronet_bidirectional_stream *stream,
+ const char *data) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "W: on_write_completed");
+ }
+ stream_obj *s = (stream_obj *)stream->annotation;
+ enqueue_callbacks(s->callback_list[CB_SEND_MESSAGE]);
+ s->cronet_send_state = CRONET_WRITE_COMPLETED;
+ next_send_step(s);
+}
+
+static void process_recv_message(stream_obj *s, const uint8_t *recv_data) {
+ gpr_slice read_data_slice = gpr_slice_malloc((uint32_t)s->total_read_bytes);
+ uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice);
+ memcpy(dst_p, recv_data, (size_t)s->total_read_bytes);
+ gpr_slice_buffer_add(&s->read_slice_buffer, read_data_slice);
+ grpc_slice_buffer_stream_init(&s->sbs, &s->read_slice_buffer, 0);
+ *s->recv_message = (grpc_byte_buffer *)&s->sbs;
+}
+
+static int parse_grpc_header(const uint8_t *data) {
+ const uint8_t *p = data + 1;
+ int length = 0;
+ length |= ((uint8_t)*p++) << 24;
+ length |= ((uint8_t)*p++) << 16;
+ length |= ((uint8_t)*p++) << 8;
+ length |= ((uint8_t)*p++);
+ return length;
+}
+
+static void on_read_completed(cronet_bidirectional_stream *stream, char *data,
+ int count) {
+ stream_obj *s = (stream_obj *)stream->annotation;
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "R: on_read_completed count=%d, total=%d, remaining=%d",
+ count, s->total_read_bytes, s->remaining_read_bytes);
+ }
+ if (count > 0) {
+ GPR_ASSERT(s->recv_message);
+ s->remaining_read_bytes -= count;
+ next_recv_step(s, ON_READ_COMPLETE);
+ } else {
+ s->read_closed = true;
+ next_recv_step(s, ON_READ_COMPLETE);
+ }
+}
+
+static void on_response_headers_received(
+ cronet_bidirectional_stream *stream,
+ const cronet_bidirectional_stream_header_array *headers,
+ const char *negotiated_protocol) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "R: on_response_headers_received");
+ }
+ stream_obj *s = (stream_obj *)stream->annotation;
+ enqueue_callbacks(s->callback_list[CB_RECV_INITIAL_METADATA]);
+ s->response_headers_received = true;
+ next_recv_step(s, ON_RESPONSE_HEADERS_RECEIVED);
+}
+
+static void on_request_headers_sent(cronet_bidirectional_stream *stream) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "W: on_request_headers_sent");
+ }
+ stream_obj *s = (stream_obj *)stream->annotation;
+ enqueue_callbacks(s->callback_list[CB_SEND_INITIAL_METADATA]);
+ s->cronet_send_state = CRONET_SEND_HEADER;
+ next_send_step(s);
+}
+
+// Callback function pointers (invoked by cronet in response to events)
+static cronet_bidirectional_stream_callback callbacks = {
+ on_request_headers_sent,
+ on_response_headers_received,
+ on_read_completed,
+ on_write_completed,
+ on_response_trailers_received,
+ on_succeeded,
+ on_failed,
+ on_canceled};
+
+static void invoke_closing_callback(stream_obj *s) {
+ grpc_chttp2_incoming_metadata_buffer_publish(&s->imb,
+ s->recv_trailing_metadata);
+ if (s->callback_list[CB_RECV_TRAILING_METADATA]) {
+ enqueue_callbacks(s->callback_list[CB_RECV_TRAILING_METADATA]);
+ }
+}
+
+static void set_recv_state(stream_obj *s, enum recv_state state) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "next_state = %s", recv_state_name[state]);
+ }
+ s->cronet_recv_state = state;
+}
+
+// This is invoked from perform_stream_op, and all on_xxxx callbacks.
+static void next_recv_step(stream_obj *s, enum e_caller caller) {
+ gpr_mu_lock(&s->recv_mu);
+ switch (s->cronet_recv_state) {
+ case CRONET_RECV_IDLE:
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_IDLE");
+ }
+ if (caller == PERFORM_STREAM_OP ||
+ caller == ON_RESPONSE_HEADERS_RECEIVED) {
+ if (s->read_closed && s->response_trailers_received) {
+ invoke_closing_callback(s);
+ set_recv_state(s, CRONET_RECV_CLOSED);
+ } else if (s->response_headers_received == true &&
+ s->read_requested == true) {
+ set_recv_state(s, CRONET_RECV_READ_LENGTH);
+ s->total_read_bytes = s->remaining_read_bytes =
+ GRPC_HEADER_SIZE_IN_BYTES;
+ GPR_ASSERT(s->read_buffer);
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()");
+ }
+ cronet_bidirectional_stream_read(s->cbs, s->read_buffer,
+ s->remaining_read_bytes);
+ }
+ }
+ break;
+ case CRONET_RECV_READ_LENGTH:
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_READ_LENGTH");
+ }
+ if (caller == ON_READ_COMPLETE) {
+ if (s->read_closed) {
+ invoke_closing_callback(s);
+ enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]);
+ set_recv_state(s, CRONET_RECV_CLOSED);
+ } else {
+ GPR_ASSERT(s->remaining_read_bytes == 0);
+ set_recv_state(s, CRONET_RECV_READ_DATA);
+ s->total_read_bytes = s->remaining_read_bytes =
+ parse_grpc_header((const uint8_t *)s->read_buffer);
+ s->read_buffer =
+ gpr_realloc(s->read_buffer, (uint32_t)s->remaining_read_bytes);
+ GPR_ASSERT(s->read_buffer);
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()");
+ }
+ cronet_bidirectional_stream_read(s->cbs, (char *)s->read_buffer,
+ s->remaining_read_bytes);
+ }
+ }
+ break;
+ case CRONET_RECV_READ_DATA:
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_READ_DATA");
+ }
+ if (caller == ON_READ_COMPLETE) {
+ if (s->remaining_read_bytes > 0) {
+ int offset = s->total_read_bytes - s->remaining_read_bytes;
+ GPR_ASSERT(s->read_buffer);
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()");
+ }
+ cronet_bidirectional_stream_read(
+ s->cbs, (char *)s->read_buffer + offset, s->remaining_read_bytes);
+ } else {
+ gpr_slice_buffer_init(&s->read_slice_buffer);
+ uint8_t *p = (uint8_t *)s->read_buffer;
+ process_recv_message(s, p);
+ set_recv_state(s, CRONET_RECV_IDLE);
+ enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]);
+ }
+ }
+ break;
+ case CRONET_RECV_CLOSED:
+ break;
+ default:
+ GPR_ASSERT(0); // Should not reach here
+ break;
+ }
+ gpr_mu_unlock(&s->recv_mu);
+}
+
+// This function takes the data from s->write_slice_buffer and assembles into
+// a contiguous byte stream with 5 byte gRPC header prepended.
+static void create_grpc_frame(stream_obj *s) {
+ gpr_slice slice = gpr_slice_buffer_take_first(&s->write_slice_buffer);
+ uint8_t *raw_data = GPR_SLICE_START_PTR(slice);
+ size_t length = GPR_SLICE_LENGTH(slice);
+ s->write_buffer_size = length + GRPC_HEADER_SIZE_IN_BYTES;
+ s->write_buffer = gpr_realloc(s->write_buffer, s->write_buffer_size);
+ uint8_t *p = (uint8_t *)s->write_buffer;
+ // Append 5 byte header
+ *p++ = 0;
+ *p++ = (uint8_t)(length >> 24);
+ *p++ = (uint8_t)(length >> 16);
+ *p++ = (uint8_t)(length >> 8);
+ *p++ = (uint8_t)(length);
+ // append actual data
+ memcpy(p, raw_data, length);
+}
+
+static void do_write(stream_obj *s) {
+ gpr_slice_buffer *sb = &s->write_slice_buffer;
+ GPR_ASSERT(sb->count <= 1);
+ if (sb->count > 0) {
+ create_grpc_frame(s);
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write");
+ }
+ cronet_bidirectional_stream_write(s->cbs, s->write_buffer,
+ (int)s->write_buffer_size, false);
+ }
+}
+
+//
+static void next_send_step(stream_obj *s) {
+ switch (s->cronet_send_state) {
+ case CRONET_SEND_IDLE:
+ GPR_ASSERT(
+ s->cbs); // cronet_bidirectional_stream is not initialized yet.
+ s->cronet_send_state = CRONET_REQ_STARTED;
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_start to %s", s->url);
+ }
+ cronet_bidirectional_stream_start(s->cbs, s->url, 0, "POST",
+ &s->header_array, false);
+ // we no longer need the memory that was allocated earlier.
+ gpr_free(s->header_array.headers);
+ break;
+ case CRONET_SEND_HEADER:
+ do_write(s);
+ s->cronet_send_state = CRONET_WRITE;
+ break;
+ case CRONET_WRITE_COMPLETED:
+ do_write(s);
+ break;
+ default:
+ GPR_ASSERT(0);
+ break;
+ }
+}
+
+static void convert_metadata_to_cronet_headers(grpc_linked_mdelem *head,
+ const char *host,
+ stream_obj *s) {
+ grpc_linked_mdelem *curr = head;
+ // Walk the linked list and get number of header fields
+ uint32_t num_headers_available = 0;
+ while (curr != NULL) {
+ curr = curr->next;
+ num_headers_available++;
+ }
+ // Allocate enough memory
+ s->headers = (cronet_bidirectional_stream_header *)gpr_malloc(
+ sizeof(cronet_bidirectional_stream_header) * num_headers_available);
+
+ // Walk the linked list again, this time copying the header fields.
+ // s->num_headers
+ // can be less than num_headers_available, as some headers are not used for
+ // cronet
+ curr = head;
+ s->num_headers = 0;
+ while (s->num_headers < num_headers_available) {
+ grpc_mdelem *mdelem = curr->md;
+ curr = curr->next;
+ const char *key = grpc_mdstr_as_c_string(mdelem->key);
+ const char *value = grpc_mdstr_as_c_string(mdelem->value);
+ if (strcmp(key, ":scheme") == 0 || strcmp(key, ":method") == 0 ||
+ strcmp(key, ":authority") == 0) {
+ // Cronet populates these fields on its own.
+ continue;
+ }
+ if (strcmp(key, ":path") == 0) {
+ // Create URL by appending :path value to the hostname
+ gpr_asprintf(&s->url, "https://%s%s", host, value);
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "extracted URL = %s", s->url);
+ }
+ continue;
+ }
+ s->headers[s->num_headers].key = key;
+ s->headers[s->num_headers].value = value;
+ s->num_headers++;
+ if (curr == NULL) {
+ break;
+ }
+ }
+}
+
+static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
+ grpc_stream *gs, grpc_transport_stream_op *op) {
+ grpc_cronet_transport *ct = (grpc_cronet_transport *)gt;
+ GPR_ASSERT(ct->engine);
+ stream_obj *s = (stream_obj *)gs;
+ if (op->recv_trailing_metadata) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG,
+ "perform_stream_op - recv_trailing_metadata: on_complete=%p",
+ op->on_complete);
+ }
+ s->recv_trailing_metadata = op->recv_trailing_metadata;
+ GPR_ASSERT(!s->callback_list[CB_RECV_TRAILING_METADATA][0]);
+ s->callback_list[CB_RECV_TRAILING_METADATA][0] = op->on_complete;
+ }
+ if (op->recv_message) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "perform_stream_op - recv_message: on_complete=%p",
+ op->on_complete);
+ }
+ s->recv_message = (grpc_byte_buffer **)op->recv_message;
+ GPR_ASSERT(!s->callback_list[CB_RECV_MESSAGE][0]);
+ GPR_ASSERT(!s->callback_list[CB_RECV_MESSAGE][1]);
+ s->callback_list[CB_RECV_MESSAGE][0] = op->recv_message_ready;
+ s->callback_list[CB_RECV_MESSAGE][1] = op->on_complete;
+ s->read_requested = true;
+ next_recv_step(s, PERFORM_STREAM_OP);
+ }
+ if (op->recv_initial_metadata) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "perform_stream_op - recv_initial_metadata:=%p",
+ op->on_complete);
+ }
+ s->recv_initial_metadata = op->recv_initial_metadata;
+ GPR_ASSERT(!s->callback_list[CB_RECV_INITIAL_METADATA][0]);
+ GPR_ASSERT(!s->callback_list[CB_RECV_INITIAL_METADATA][1]);
+ s->callback_list[CB_RECV_INITIAL_METADATA][0] =
+ op->recv_initial_metadata_ready;
+ s->callback_list[CB_RECV_INITIAL_METADATA][1] = op->on_complete;
+ }
+ if (op->send_initial_metadata) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG,
+ "perform_stream_op - send_initial_metadata: on_complete=%p",
+ op->on_complete);
+ }
+ s->num_headers = 0;
+ convert_metadata_to_cronet_headers(op->send_initial_metadata->list.head,
+ ct->host, s);
+ s->header_array.count = s->num_headers;
+ s->header_array.capacity = s->num_headers;
+ s->header_array.headers = s->headers;
+ GPR_ASSERT(!s->callback_list[CB_SEND_INITIAL_METADATA][0]);
+ s->callback_list[CB_SEND_INITIAL_METADATA][0] = op->on_complete;
+ }
+ if (op->send_message) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "perform_stream_op - send_message: on_complete=%p",
+ op->on_complete);
+ }
+ grpc_byte_stream_next(exec_ctx, op->send_message, &s->slice,
+ op->send_message->length, NULL);
+ // Check that compression flag is not ON. We don't support compression yet.
+ // TODO (makdharma): add compression support
+ GPR_ASSERT(op->send_message->flags == 0);
+ gpr_slice_buffer_add(&s->write_slice_buffer, s->slice);
+ if (s->cbs == NULL) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_create");
+ }
+ s->cbs = cronet_bidirectional_stream_create(ct->engine, s, &callbacks);
+ GPR_ASSERT(s->cbs);
+ s->read_closed = false;
+ s->response_trailers_received = false;
+ s->response_headers_received = false;
+ s->cronet_send_state = CRONET_SEND_IDLE;
+ s->cronet_recv_state = CRONET_RECV_IDLE;
+ }
+ GPR_ASSERT(!s->callback_list[CB_SEND_MESSAGE][0]);
+ s->callback_list[CB_SEND_MESSAGE][0] = op->on_complete;
+ next_send_step(s);
+ }
+ if (op->send_trailing_metadata) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG,
+ "perform_stream_op - send_trailing_metadata: on_complete=%p",
+ op->on_complete);
+ }
+ GPR_ASSERT(!s->callback_list[CB_SEND_TRAILING_METADATA][0]);
+ s->callback_list[CB_SEND_TRAILING_METADATA][0] = op->on_complete;
+ if (s->cbs) {
+ // Send an "empty" write to the far end to signal that we're done.
+ // This will induce the server to send down trailers.
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write");
+ }
+ cronet_bidirectional_stream_write(s->cbs, "abc", 0, true);
+ } else {
+ // We never created a stream. This was probably an empty request.
+ invoke_closing_callback(s);
+ }
+ }
+}
+
+static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
+ grpc_stream *gs, grpc_stream_refcount *refcount,
+ const void *server_data) {
+ stream_obj *s = (stream_obj *)gs;
+ memset(s->callback_list, 0, sizeof(s->callback_list));
+ s->cbs = NULL;
+ gpr_mu_init(&s->recv_mu);
+ s->read_buffer = gpr_malloc(GRPC_HEADER_SIZE_IN_BYTES);
+ s->write_buffer = gpr_malloc(GRPC_HEADER_SIZE_IN_BYTES);
+ gpr_slice_buffer_init(&s->write_slice_buffer);
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "cronet_transport - init_stream");
+ }
+ return 0;
+}
+
+static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
+ grpc_stream *gs, void *and_free_memory) {
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "Destroy stream");
+ }
+ stream_obj *s = (stream_obj *)gs;
+ s->cbs = NULL;
+ gpr_free(s->read_buffer);
+ gpr_free(s->write_buffer);
+ gpr_free(s->url);
+ gpr_mu_destroy(&s->recv_mu);
+ if (and_free_memory) {
+ gpr_free(and_free_memory);
+ }
+}
+
+static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {
+ grpc_cronet_transport *ct = (grpc_cronet_transport *)gt;
+ gpr_free(ct->host);
+ if (grpc_cronet_trace) {
+ gpr_log(GPR_DEBUG, "Destroy transport");
+ }
+}
+
+const grpc_transport_vtable grpc_cronet_vtable = {
+ sizeof(stream_obj), "cronet_http", init_stream,
+ set_pollset_do_nothing, perform_stream_op, NULL,
+ destroy_stream, destroy_transport, NULL};
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 0a51780..23c7b7b 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -56,10 +56,6 @@
/** Destroy arguments created by \a grpc_channel_args_copy */
void grpc_channel_args_destroy(grpc_channel_args *a);
-/** Reads census_enabled settings from channel args. Returns 1 if census_enabled
- * is specified in channel args, otherwise returns 0. */
-int grpc_channel_args_is_census_enabled(const grpc_channel_args *a);
-
/** Returns the compression algorithm set in \a a. */
grpc_compression_algorithm grpc_channel_args_get_compression_algorithm(
const grpc_channel_args *a);
diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc
index 33a8f75..8e8d42e 100644
--- a/src/cpp/common/core_codegen.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -48,124 +48,6 @@
#include "src/core/lib/profiling/timers.h"
-namespace {
-
-const int kGrpcBufferWriterMaxBufferLength = 8192;
-
-class GrpcBufferWriter GRPC_FINAL
- : public ::grpc::protobuf::io::ZeroCopyOutputStream {
- public:
- explicit GrpcBufferWriter(grpc_byte_buffer** bp, int block_size)
- : block_size_(block_size), byte_count_(0), have_backup_(false) {
- *bp = grpc_raw_byte_buffer_create(NULL, 0);
- slice_buffer_ = &(*bp)->data.raw.slice_buffer;
- }
-
- ~GrpcBufferWriter() GRPC_OVERRIDE {
- if (have_backup_) {
- gpr_slice_unref(backup_slice_);
- }
- }
-
- bool Next(void** data, int* size) GRPC_OVERRIDE {
- if (have_backup_) {
- slice_ = backup_slice_;
- have_backup_ = false;
- } else {
- slice_ = gpr_slice_malloc(block_size_);
- }
- *data = GPR_SLICE_START_PTR(slice_);
- // On win x64, int is only 32bit
- GPR_ASSERT(GPR_SLICE_LENGTH(slice_) <= INT_MAX);
- byte_count_ += * size = (int)GPR_SLICE_LENGTH(slice_);
- gpr_slice_buffer_add(slice_buffer_, slice_);
- return true;
- }
-
- void BackUp(int count) GRPC_OVERRIDE {
- gpr_slice_buffer_pop(slice_buffer_);
- if (count == block_size_) {
- backup_slice_ = slice_;
- } else {
- backup_slice_ =
- gpr_slice_split_tail(&slice_, GPR_SLICE_LENGTH(slice_) - count);
- gpr_slice_buffer_add(slice_buffer_, slice_);
- }
- have_backup_ = true;
- byte_count_ -= count;
- }
-
- grpc::protobuf::int64 ByteCount() const GRPC_OVERRIDE { return byte_count_; }
-
- private:
- const int block_size_;
- int64_t byte_count_;
- gpr_slice_buffer* slice_buffer_;
- bool have_backup_;
- gpr_slice backup_slice_;
- gpr_slice slice_;
-};
-
-class GrpcBufferReader GRPC_FINAL
- : public ::grpc::protobuf::io::ZeroCopyInputStream {
- public:
- explicit GrpcBufferReader(grpc_byte_buffer* buffer)
- : byte_count_(0), backup_count_(0) {
- grpc_byte_buffer_reader_init(&reader_, buffer);
- }
- ~GrpcBufferReader() GRPC_OVERRIDE {
- grpc_byte_buffer_reader_destroy(&reader_);
- }
-
- bool Next(const void** data, int* size) GRPC_OVERRIDE {
- if (backup_count_ > 0) {
- *data = GPR_SLICE_START_PTR(slice_) + GPR_SLICE_LENGTH(slice_) -
- backup_count_;
- GPR_ASSERT(backup_count_ <= INT_MAX);
- *size = (int)backup_count_;
- backup_count_ = 0;
- return true;
- }
- if (!grpc_byte_buffer_reader_next(&reader_, &slice_)) {
- return false;
- }
- gpr_slice_unref(slice_);
- *data = GPR_SLICE_START_PTR(slice_);
- // On win x64, int is only 32bit
- GPR_ASSERT(GPR_SLICE_LENGTH(slice_) <= INT_MAX);
- byte_count_ += * size = (int)GPR_SLICE_LENGTH(slice_);
- return true;
- }
-
- void BackUp(int count) GRPC_OVERRIDE { backup_count_ = count; }
-
- bool Skip(int count) GRPC_OVERRIDE {
- const void* data;
- int size;
- while (Next(&data, &size)) {
- if (size >= count) {
- BackUp(size - count);
- return true;
- }
- // size < count;
- count -= size;
- }
- // error or we have too large count;
- return false;
- }
-
- grpc::protobuf::int64 ByteCount() const GRPC_OVERRIDE {
- return byte_count_ - backup_count_;
- }
-
- private:
- int64_t byte_count_;
- int64_t backup_count_;
- grpc_byte_buffer_reader reader_;
- gpr_slice slice_;
-};
-} // namespace
-
namespace grpc {
grpc_completion_queue* CoreCodegen::grpc_completion_queue_create(
@@ -192,6 +74,44 @@
::grpc_byte_buffer_destroy(bb);
}
+void CoreCodegen::grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
+ grpc_byte_buffer* buffer) {
+ ::grpc_byte_buffer_reader_init(reader, buffer);
+}
+
+void CoreCodegen::grpc_byte_buffer_reader_destroy(
+ grpc_byte_buffer_reader* reader) {
+ ::grpc_byte_buffer_reader_destroy(reader);
+}
+
+int CoreCodegen::grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
+ gpr_slice* slice) {
+ return ::grpc_byte_buffer_reader_next(reader, slice);
+}
+
+grpc_byte_buffer* CoreCodegen::grpc_raw_byte_buffer_create(gpr_slice* slice,
+ size_t nslices) {
+ return ::grpc_raw_byte_buffer_create(slice, nslices);
+}
+
+gpr_slice CoreCodegen::gpr_slice_malloc(size_t length) {
+ return ::gpr_slice_malloc(length);
+}
+
+void CoreCodegen::gpr_slice_unref(gpr_slice slice) { ::gpr_slice_unref(slice); }
+
+gpr_slice CoreCodegen::gpr_slice_split_tail(gpr_slice* s, size_t split) {
+ return ::gpr_slice_split_tail(s, split);
+}
+
+void CoreCodegen::gpr_slice_buffer_add(gpr_slice_buffer* sb, gpr_slice slice) {
+ ::gpr_slice_buffer_add(sb, slice);
+}
+
+void CoreCodegen::gpr_slice_buffer_pop(gpr_slice_buffer* sb) {
+ ::gpr_slice_buffer_pop(sb);
+}
+
void CoreCodegen::grpc_metadata_array_init(grpc_metadata_array* array) {
::grpc_metadata_array_init(array);
}
@@ -200,6 +120,10 @@
::grpc_metadata_array_destroy(array);
}
+const Status& CoreCodegen::ok() { return grpc::Status::OK; }
+
+const Status& CoreCodegen::cancelled() { return grpc::Status::CANCELLED; }
+
gpr_timespec CoreCodegen::gpr_inf_future(gpr_clock_type type) {
return ::gpr_inf_future(type);
}
@@ -209,48 +133,4 @@
abort();
}
-Status CoreCodegen::SerializeProto(const grpc::protobuf::Message& msg,
- grpc_byte_buffer** bp) {
- GPR_TIMER_SCOPE("SerializeProto", 0);
- int byte_size = msg.ByteSize();
- if (byte_size <= kGrpcBufferWriterMaxBufferLength) {
- gpr_slice slice = gpr_slice_malloc(byte_size);
- GPR_ASSERT(GPR_SLICE_END_PTR(slice) ==
- msg.SerializeWithCachedSizesToArray(GPR_SLICE_START_PTR(slice)));
- *bp = grpc_raw_byte_buffer_create(&slice, 1);
- gpr_slice_unref(slice);
- return Status::OK;
- } else {
- GrpcBufferWriter writer(bp, kGrpcBufferWriterMaxBufferLength);
- return msg.SerializeToZeroCopyStream(&writer)
- ? Status::OK
- : Status(StatusCode::INTERNAL, "Failed to serialize message");
- }
-}
-
-Status CoreCodegen::DeserializeProto(grpc_byte_buffer* buffer,
- grpc::protobuf::Message* msg,
- int max_message_size) {
- GPR_TIMER_SCOPE("DeserializeProto", 0);
- if (buffer == nullptr) {
- return Status(StatusCode::INTERNAL, "No payload");
- }
- Status result = Status::OK;
- {
- GrpcBufferReader reader(buffer);
- ::grpc::protobuf::io::CodedInputStream decoder(&reader);
- if (max_message_size > 0) {
- decoder.SetTotalBytesLimit(max_message_size, max_message_size);
- }
- if (!msg->ParseFromCodedStream(&decoder)) {
- result = Status(StatusCode::INTERNAL, msg->InitializationErrorString());
- }
- if (!decoder.ConsumedEntireMessage()) {
- result = Status(StatusCode::INTERNAL, "Did not read entire message");
- }
- }
- grpc_byte_buffer_destroy(buffer);
- return result;
-}
-
} // namespace grpc
diff --git a/src/cpp/common/core_codegen.h b/src/cpp/common/core_codegen.h
index e15cb4c..656b11e 100644
--- a/src/cpp/common/core_codegen.h
+++ b/src/cpp/common/core_codegen.h
@@ -42,13 +42,6 @@
/// Implementation of the core codegen interface.
class CoreCodegen : public CoreCodegenInterface {
private:
- Status SerializeProto(const grpc::protobuf::Message& msg,
- grpc_byte_buffer** bp) override;
-
- Status DeserializeProto(grpc_byte_buffer* buffer,
- grpc::protobuf::Message* msg,
- int max_message_size) override;
-
grpc_completion_queue* grpc_completion_queue_create(void* reserved) override;
void grpc_completion_queue_destroy(grpc_completion_queue* cq) override;
grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq, void* tag,
@@ -60,11 +53,30 @@
void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) override;
+ void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
+ grpc_byte_buffer* buffer) override;
+ void grpc_byte_buffer_reader_destroy(
+ grpc_byte_buffer_reader* reader) override;
+ int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
+ gpr_slice* slice) override;
+
+ grpc_byte_buffer* grpc_raw_byte_buffer_create(gpr_slice* slice,
+ size_t nslices) override;
+
+ gpr_slice gpr_slice_malloc(size_t length) override;
+ void gpr_slice_unref(gpr_slice slice) override;
+ gpr_slice gpr_slice_split_tail(gpr_slice* s, size_t split) override;
+ void gpr_slice_buffer_add(gpr_slice_buffer* sb, gpr_slice slice) override;
+ void gpr_slice_buffer_pop(gpr_slice_buffer* sb) override;
+
void grpc_metadata_array_init(grpc_metadata_array* array) override;
void grpc_metadata_array_destroy(grpc_metadata_array* array) override;
gpr_timespec gpr_inf_future(gpr_clock_type type) override;
+ virtual const Status& ok() override;
+ virtual const Status& cancelled() override;
+
void assert_fail(const char* failed_assertion) override;
};
diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
index 0583715..0e20476 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
@@ -168,7 +168,7 @@
var responseStream = new ServerResponseStream<string, string>(asyncCallServer);
var writeTask = responseStream.WriteAsync("request1");
- var writeStatusTask = asyncCallServer.SendStatusFromServerAsync(Status.DefaultSuccess, new Metadata());
+ var writeStatusTask = asyncCallServer.SendStatusFromServerAsync(Status.DefaultSuccess, new Metadata(), null);
fakeCall.SendCompletionHandler(true);
fakeCall.SendStatusFromServerHandler(true);
diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs
index 1bec258..909112a 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs
@@ -165,7 +165,8 @@
SendCompletionHandler = callback;
}
- public void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata)
+ public void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
+ byte[] optionalPayload, WriteFlags writeFlags)
{
SendStatusFromServerHandler = callback;
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index eafe2cc..b1566b4 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -139,8 +139,11 @@
/// Sends call result status, indicating we are done with writes.
/// Sending a status different from StatusCode.OK will also implicitly cancel the call.
/// </summary>
- public Task SendStatusFromServerAsync(Status status, Metadata trailers)
+ public Task SendStatusFromServerAsync(Status status, Metadata trailers, Tuple<TResponse, WriteFlags> optionalWrite)
{
+ byte[] payload = optionalWrite != null ? UnsafeSerialize(optionalWrite.Item1) : null;
+ var writeFlags = optionalWrite != null ? optionalWrite.Item2 : default(WriteFlags);
+
lock (myLock)
{
GrpcPreconditions.CheckState(started);
@@ -149,11 +152,16 @@
using (var metadataArray = MetadataArraySafeHandle.Create(trailers))
{
- call.StartSendStatusFromServer(HandleSendStatusFromServerFinished, status, metadataArray, !initialMetadataSent);
+ call.StartSendStatusFromServer(HandleSendStatusFromServerFinished, status, metadataArray, !initialMetadataSent,
+ payload, writeFlags);
}
halfcloseRequested = true;
initialMetadataSent = true;
sendStatusFromServerTcs = new TaskCompletionSource<object>();
+ if (optionalWrite != null)
+ {
+ streamingWritesCounter++;
+ }
return sendStatusFromServerTcs.Task;
}
}
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index 500653b..244b97d 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -135,13 +135,16 @@
}
}
- public void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata)
+ public void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
+ byte[] optionalPayload, WriteFlags writeFlags)
{
using (completionQueue.NewScope())
{
var ctx = BatchContextSafeHandle.Create();
+ var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero;
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
- Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, status.Detail, metadataArray, sendEmptyInitialMetadata).CheckOk();
+ Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, status.Detail, metadataArray, sendEmptyInitialMetadata,
+ optionalPayload, optionalPayloadLength, writeFlags).CheckOk();
}
}
diff --git a/src/csharp/Grpc.Core/Internal/INativeCall.cs b/src/csharp/Grpc.Core/Internal/INativeCall.cs
index cbef599..cd3719c 100644
--- a/src/csharp/Grpc.Core/Internal/INativeCall.cs
+++ b/src/csharp/Grpc.Core/Internal/INativeCall.cs
@@ -78,7 +78,7 @@
void StartSendCloseFromClient(SendCompletionHandler callback);
- void StartSendStatusFromServer(SendCompletionHandler callback, Grpc.Core.Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata);
+ void StartSendStatusFromServer(SendCompletionHandler callback, Grpc.Core.Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, Grpc.Core.WriteFlags writeFlags);
void StartServerSide(ReceivedCloseOnServerHandler callback);
}
diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
index 9ee0ba3..c277c73 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
@@ -421,20 +421,21 @@
public delegate GRPCCallError grpcsharp_call_cancel_delegate(CallSafeHandle call);
public delegate GRPCCallError grpcsharp_call_cancel_with_status_delegate(CallSafeHandle call, StatusCode status, string description);
public delegate GRPCCallError grpcsharp_call_start_unary_delegate(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
+ BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
public delegate GRPCCallError grpcsharp_call_start_client_streaming_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
public delegate GRPCCallError grpcsharp_call_start_server_streaming_delegate(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len,
+ BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen,
MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
public delegate GRPCCallError grpcsharp_call_start_duplex_streaming_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
public delegate GRPCCallError grpcsharp_call_send_message_delegate(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
+ BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
public delegate GRPCCallError grpcsharp_call_send_close_from_client_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx);
public delegate GRPCCallError grpcsharp_call_send_status_from_server_delegate(CallSafeHandle call,
- BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata);
+ BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
+ byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags);
public delegate GRPCCallError grpcsharp_call_recv_message_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx);
public delegate GRPCCallError grpcsharp_call_recv_initial_metadata_delegate(CallSafeHandle call,
@@ -593,7 +594,7 @@
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_start_unary(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
+ BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_start_client_streaming(CallSafeHandle call,
@@ -601,7 +602,7 @@
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_start_server_streaming(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len,
+ BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen,
MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
[DllImport("grpc_csharp_ext.dll")]
@@ -610,7 +611,7 @@
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_send_message(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
+ BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_send_close_from_client(CallSafeHandle call,
@@ -618,7 +619,8 @@
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_send_status_from_server(CallSafeHandle call,
- BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata);
+ BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
+ byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags);
[DllImport("grpc_csharp_ext.dll")]
public static extern GRPCCallError grpcsharp_call_recv_message(CallSafeHandle call,
diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index 00d82d5..85b7a4b 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -75,27 +75,32 @@
var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
Status status;
+ Tuple<TResponse,WriteFlags> responseTuple = null;
var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, responseStream, asyncCall.CancellationToken);
try
{
GrpcPreconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false));
var request = requestStream.Current;
- var result = await handler(request, context).ConfigureAwait(false);
+ var response = await handler(request, context).ConfigureAwait(false);
status = context.Status;
- await responseStream.WriteAsync(result).ConfigureAwait(false);
+ responseTuple = Tuple.Create(response, HandlerUtils.GetWriteFlags(context.WriteOptions));
}
catch (Exception e)
{
- Logger.Error(e, "Exception occured in handler.");
+ if (!(e is RpcException))
+ {
+ Logger.Warning(e, "Exception occured in handler.");
+ }
status = HandlerUtils.StatusFromException(e);
}
try
{
- await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers).ConfigureAwait(false);
+ await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseTuple).ConfigureAwait(false);
}
- catch (OperationCanceledException)
+ catch (Exception)
{
- // Call has been already cancelled.
+ asyncCall.Cancel();
+ throw;
}
await finishedTask.ConfigureAwait(false);
}
@@ -139,17 +144,21 @@
}
catch (Exception e)
{
- Logger.Error(e, "Exception occured in handler.");
+ if (!(e is RpcException))
+ {
+ Logger.Warning(e, "Exception occured in handler.");
+ }
status = HandlerUtils.StatusFromException(e);
}
try
{
- await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers).ConfigureAwait(false);
+ await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, null).ConfigureAwait(false);
}
- catch (OperationCanceledException)
+ catch (Exception)
{
- // Call has been already cancelled.
+ asyncCall.Cancel();
+ throw;
}
await finishedTask.ConfigureAwait(false);
}
@@ -183,33 +192,31 @@
var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
Status status;
+ Tuple<TResponse,WriteFlags> responseTuple = null;
var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, responseStream, asyncCall.CancellationToken);
try
{
- var result = await handler(requestStream, context).ConfigureAwait(false);
+ var response = await handler(requestStream, context).ConfigureAwait(false);
status = context.Status;
- try
- {
- await responseStream.WriteAsync(result).ConfigureAwait(false);
- }
- catch (OperationCanceledException)
- {
- status = Status.DefaultCancelled;
- }
+ responseTuple = Tuple.Create(response, HandlerUtils.GetWriteFlags(context.WriteOptions));
}
catch (Exception e)
{
- Logger.Error(e, "Exception occured in handler.");
+ if (!(e is RpcException))
+ {
+ Logger.Warning(e, "Exception occured in handler.");
+ }
status = HandlerUtils.StatusFromException(e);
}
try
{
- await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers).ConfigureAwait(false);
+ await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseTuple).ConfigureAwait(false);
}
- catch (OperationCanceledException)
+ catch (Exception)
{
- // Call has been already cancelled.
+ asyncCall.Cancel();
+ throw;
}
await finishedTask.ConfigureAwait(false);
}
@@ -251,16 +258,20 @@
}
catch (Exception e)
{
- Logger.Error(e, "Exception occured in handler.");
+ if (!(e is RpcException))
+ {
+ Logger.Warning(e, "Exception occured in handler.");
+ }
status = HandlerUtils.StatusFromException(e);
}
try
{
- await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers).ConfigureAwait(false);
+ await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, null).ConfigureAwait(false);
}
- catch (OperationCanceledException)
+ catch (Exception)
{
- // Call has been already cancelled.
+ asyncCall.Cancel();
+ throw;
}
await finishedTask.ConfigureAwait(false);
}
@@ -278,7 +289,7 @@
asyncCall.Initialize(newRpc.Call);
var finishedTask = asyncCall.ServerSideCallAsync();
- await asyncCall.SendStatusFromServerAsync(new Status(StatusCode.Unimplemented, ""), Metadata.Empty).ConfigureAwait(false);
+ await asyncCall.SendStatusFromServerAsync(new Status(StatusCode.Unimplemented, ""), Metadata.Empty, null).ConfigureAwait(false);
await finishedTask.ConfigureAwait(false);
}
}
@@ -297,6 +308,11 @@
return new Status(StatusCode.Unknown, "Exception was thrown by handler.");
}
+ public static WriteFlags GetWriteFlags(WriteOptions writeOptions)
+ {
+ return writeOptions != null ? writeOptions.Flags : default(WriteFlags);
+ }
+
public static ServerCallContext NewContext<TRequest, TResponse>(ServerRpcNew newRpc, string peer, ServerResponseStream<TRequest, TResponse> serverResponseStream, CancellationToken cancellationToken)
where TRequest : class
where TResponse : class
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index aeef8a7..5b8ff9b 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -715,10 +715,11 @@
GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server(
grpc_call *call, grpcsharp_batch_context *ctx, grpc_status_code status_code,
const char *status_details, grpc_metadata_array *trailing_metadata,
- int32_t send_empty_initial_metadata) {
+ int32_t send_empty_initial_metadata, const char* optional_send_buffer,
+ size_t optional_send_buffer_len, uint32_t write_flags) {
/* TODO: don't use magic number */
- grpc_op ops[2];
- size_t nops = send_empty_initial_metadata ? 2 : 1;
+ grpc_op ops[3];
+ size_t nops = 1;
ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
ops[0].data.send_status_from_server.status = status_code;
ops[0].data.send_status_from_server.status_details =
@@ -731,12 +732,23 @@
ctx->send_status_from_server.trailing_metadata.metadata;
ops[0].flags = 0;
ops[0].reserved = NULL;
- ops[1].op = GRPC_OP_SEND_INITIAL_METADATA;
- ops[1].data.send_initial_metadata.count = 0;
- ops[1].data.send_initial_metadata.metadata = NULL;
- ops[1].flags = 0;
- ops[1].reserved = NULL;
-
+ if (optional_send_buffer) {
+ ops[nops].op = GRPC_OP_SEND_MESSAGE;
+ ctx->send_message = string_to_byte_buffer(optional_send_buffer,
+ optional_send_buffer_len);
+ ops[nops].data.send_message = ctx->send_message;
+ ops[nops].flags = write_flags;
+ ops[nops].reserved = NULL;
+ nops ++;
+ }
+ if (send_empty_initial_metadata) {
+ ops[nops].op = GRPC_OP_SEND_INITIAL_METADATA;
+ ops[nops].data.send_initial_metadata.count = 0;
+ ops[nops].data.send_initial_metadata.metadata = NULL;
+ ops[nops].flags = 0;
+ ops[nops].reserved = NULL;
+ nops++;
+ }
return grpc_call_start_batch(call, ops, nops, ctx, NULL);
}
diff --git a/src/proto/grpc/testing/echo.proto b/src/proto/grpc/testing/echo.proto
index 0eef53a..c596aab 100644
--- a/src/proto/grpc/testing/echo.proto
+++ b/src/proto/grpc/testing/echo.proto
@@ -45,3 +45,7 @@
service UnimplementedService {
rpc Unimplemented(EchoRequest) returns (EchoResponse);
}
+
+// A service without any rpc defined to test coverage.
+service NoRpcService {
+}
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.c b/src/python/grpcio/grpc/_cython/imports.generated.c
index f0a40db..0955147 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.c
+++ b/src/python/grpcio/grpc/_cython/imports.generated.c
@@ -125,6 +125,7 @@
grpc_header_nonbin_value_is_legal_type grpc_header_nonbin_value_is_legal_import;
grpc_is_binary_header_type grpc_is_binary_header_import;
grpc_call_error_to_string_type grpc_call_error_to_string_import;
+grpc_cronet_secure_channel_create_type grpc_cronet_secure_channel_create_import;
grpc_auth_property_iterator_next_type grpc_auth_property_iterator_next_import;
grpc_auth_context_property_iterator_type grpc_auth_context_property_iterator_import;
grpc_auth_context_peer_identity_type grpc_auth_context_peer_identity_import;
@@ -395,6 +396,7 @@
grpc_header_nonbin_value_is_legal_import = (grpc_header_nonbin_value_is_legal_type) GetProcAddress(library, "grpc_header_nonbin_value_is_legal");
grpc_is_binary_header_import = (grpc_is_binary_header_type) GetProcAddress(library, "grpc_is_binary_header");
grpc_call_error_to_string_import = (grpc_call_error_to_string_type) GetProcAddress(library, "grpc_call_error_to_string");
+ grpc_cronet_secure_channel_create_import = (grpc_cronet_secure_channel_create_type) GetProcAddress(library, "grpc_cronet_secure_channel_create");
grpc_auth_property_iterator_next_import = (grpc_auth_property_iterator_next_type) GetProcAddress(library, "grpc_auth_property_iterator_next");
grpc_auth_context_property_iterator_import = (grpc_auth_context_property_iterator_type) GetProcAddress(library, "grpc_auth_context_property_iterator");
grpc_auth_context_peer_identity_import = (grpc_auth_context_peer_identity_type) GetProcAddress(library, "grpc_auth_context_peer_identity");
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h
index d5e810b..54c8aaa 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.h
+++ b/src/python/grpcio/grpc/_cython/imports.generated.h
@@ -43,6 +43,7 @@
#include <grpc/census.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
+#include <grpc/grpc_cronet.h>
#include <grpc/grpc_security.h>
#include <grpc/impl/codegen/alloc.h>
#include <grpc/impl/codegen/byte_buffer.h>
@@ -325,6 +326,9 @@
typedef const char *(*grpc_call_error_to_string_type)(grpc_call_error error);
extern grpc_call_error_to_string_type grpc_call_error_to_string_import;
#define grpc_call_error_to_string grpc_call_error_to_string_import
+typedef grpc_channel *(*grpc_cronet_secure_channel_create_type)(void *engine, const char *target, const grpc_channel_args *args, void *reserved);
+extern grpc_cronet_secure_channel_create_type grpc_cronet_secure_channel_create_import;
+#define grpc_cronet_secure_channel_create grpc_cronet_secure_channel_create_import
typedef const grpc_auth_property *(*grpc_auth_property_iterator_next_type)(grpc_auth_property_iterator *it);
extern grpc_auth_property_iterator_next_type grpc_auth_property_iterator_next_import;
#define grpc_auth_property_iterator_next grpc_auth_property_iterator_next_import
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index dab6253..5314329 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -222,6 +222,9 @@
'src/core/ext/client_config/uri_parser.c',
'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
+ 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
+ 'src/core/ext/transport/cronet/transport/cronet_api_dummy.c',
+ 'src/core/ext/transport/cronet/transport/cronet_transport.c',
'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c',
'third_party/nanopb/pb_common.c',
diff --git a/src/ruby/.rubocop.yml b/src/ruby/.rubocop.yml
index d13ce42..34bb477 100644
--- a/src/ruby/.rubocop.yml
+++ b/src/ruby/.rubocop.yml
@@ -11,10 +11,10 @@
- 'pb/test/**/*'
Metrics/CyclomaticComplexity:
- Max: 8
+ Max: 9
Metrics/PerceivedComplexity:
- Max: 8
+ Max: 9
Metrics/ClassLength:
Max: 250
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index bc43f9d..cebbe8c 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -125,6 +125,7 @@
grpc_header_nonbin_value_is_legal_type grpc_header_nonbin_value_is_legal_import;
grpc_is_binary_header_type grpc_is_binary_header_import;
grpc_call_error_to_string_type grpc_call_error_to_string_import;
+grpc_cronet_secure_channel_create_type grpc_cronet_secure_channel_create_import;
grpc_auth_property_iterator_next_type grpc_auth_property_iterator_next_import;
grpc_auth_context_property_iterator_type grpc_auth_context_property_iterator_import;
grpc_auth_context_peer_identity_type grpc_auth_context_peer_identity_import;
@@ -391,6 +392,7 @@
grpc_header_nonbin_value_is_legal_import = (grpc_header_nonbin_value_is_legal_type) GetProcAddress(library, "grpc_header_nonbin_value_is_legal");
grpc_is_binary_header_import = (grpc_is_binary_header_type) GetProcAddress(library, "grpc_is_binary_header");
grpc_call_error_to_string_import = (grpc_call_error_to_string_type) GetProcAddress(library, "grpc_call_error_to_string");
+ grpc_cronet_secure_channel_create_import = (grpc_cronet_secure_channel_create_type) GetProcAddress(library, "grpc_cronet_secure_channel_create");
grpc_auth_property_iterator_next_import = (grpc_auth_property_iterator_next_type) GetProcAddress(library, "grpc_auth_property_iterator_next");
grpc_auth_context_property_iterator_import = (grpc_auth_context_property_iterator_type) GetProcAddress(library, "grpc_auth_context_property_iterator");
grpc_auth_context_peer_identity_import = (grpc_auth_context_peer_identity_type) GetProcAddress(library, "grpc_auth_context_peer_identity");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index b67361c..d7ea6c5 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -43,6 +43,7 @@
#include <grpc/census.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
+#include <grpc/grpc_cronet.h>
#include <grpc/grpc_security.h>
#include <grpc/impl/codegen/alloc.h>
#include <grpc/impl/codegen/byte_buffer.h>
@@ -325,6 +326,9 @@
typedef const char *(*grpc_call_error_to_string_type)(grpc_call_error error);
extern grpc_call_error_to_string_type grpc_call_error_to_string_import;
#define grpc_call_error_to_string grpc_call_error_to_string_import
+typedef grpc_channel *(*grpc_cronet_secure_channel_create_type)(void *engine, const char *target, const grpc_channel_args *args, void *reserved);
+extern grpc_cronet_secure_channel_create_type grpc_cronet_secure_channel_create_import;
+#define grpc_cronet_secure_channel_create grpc_cronet_secure_channel_create_import
typedef const grpc_auth_property *(*grpc_auth_property_iterator_next_type)(grpc_auth_property_iterator *it);
extern grpc_auth_property_iterator_next_type grpc_auth_property_iterator_next_import;
#define grpc_auth_property_iterator_next grpc_auth_property_iterator_next_import
diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb
index 7f3a38a..a0f4071 100644
--- a/src/ruby/lib/grpc/generic/rpc_server.rb
+++ b/src/ruby/lib/grpc/generic/rpc_server.rb
@@ -332,15 +332,13 @@
# the current thread to terminate it.
def run_till_terminated
GRPC.trap_signals
- stopped = false
t = Thread.new do
run
- stopped = true
end
+ t.abort_on_exception = true
wait_till_running
- loop do
+ until running_state == :stopped
sleep SIGNAL_CHECK_PERIOD
- break if stopped
break unless GRPC.handle_signals
end
stop
@@ -416,7 +414,7 @@
GRPC.logger.warn("NOT AVAILABLE: too many jobs_waiting: #{an_rpc}")
noop = proc { |x| x }
c = ActiveCall.new(an_rpc.call, @cq, noop, noop, an_rpc.deadline)
- c.send_status(StatusCodes::RESOURCE_EXHAUSTED, '')
+ c.send_status(GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED, '')
nil
end
@@ -427,7 +425,7 @@
GRPC.logger.warn("UNIMPLEMENTED: #{an_rpc}")
noop = proc { |x| x }
c = ActiveCall.new(an_rpc.call, @cq, noop, noop, an_rpc.deadline)
- c.send_status(StatusCodes::UNIMPLEMENTED, '')
+ c.send_status(GRPC::Core::StatusCodes::UNIMPLEMENTED, '')
nil
end
@@ -443,7 +441,12 @@
unless active_call.nil?
@pool.schedule(active_call) do |ac|
c, mth = ac
- rpc_descs[mth].run_server_method(c, rpc_handlers[mth])
+ begin
+ rpc_descs[mth].run_server_method(c, rpc_handlers[mth])
+ rescue StandardError
+ c.send_status(GRPC::Core::StatusCodes::INTERNAL,
+ 'Server handler failed')
+ end
end
end
rescue Core::CallError, RuntimeError => e
diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c
index ff2f028..e46b39e 100644
--- a/test/core/end2end/fixtures/h2_census.c
+++ b/test/core/end2end/fixtures/h2_census.c
@@ -111,7 +111,7 @@
/* All test configurations */
static grpc_end2end_test_config configs[] = {
- {"chttp2/fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
+ {"chttp2/fullstack+census", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
};
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index 0eede6c..fd6ff2c 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -36,11 +36,13 @@
#include <grpc/census.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
+#include <grpc/grpc_cronet.h>
#include <grpc/grpc_security.h>
#include <grpc/grpc_security_constants.h>
#include <grpc/impl/codegen/alloc.h>
#include <grpc/impl/codegen/atm.h>
#include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/byte_buffer_reader.h>
#include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/connectivity_state.h>
#include <grpc/impl/codegen/grpc_types.h>
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 7e4d604..0232a9f 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -51,6 +51,7 @@
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/cpp/util/string_ref_helper.h"
+#include "test/cpp/util/test_credentials_provider.h"
#ifdef GPR_POSIX_SOCKET
#include "src/core/lib/iomgr/ev_posix.h"
@@ -58,6 +59,7 @@
using grpc::testing::EchoRequest;
using grpc::testing::EchoResponse;
+using grpc::testing::kTlsCredentialsType;
using std::chrono::system_clock;
GPR_TLS_DECL(g_is_async_end2end_test);
@@ -197,20 +199,37 @@
bool spin_;
};
-class AsyncEnd2endTest : public ::testing::TestWithParam<bool> {
+class TestScenario {
+ public:
+ TestScenario(bool non_block, const grpc::string& creds_type,
+ const grpc::string& content)
+ : disable_blocking(non_block),
+ credentials_type(creds_type),
+ message_content(content) {}
+ void Log() const {
+ gpr_log(GPR_INFO,
+ "Scenario: disable_blocking %d, credentials %s, message size %d",
+ disable_blocking, credentials_type.c_str(), message_content.size());
+ }
+ bool disable_blocking;
+ const grpc::string credentials_type;
+ const grpc::string message_content;
+};
+
+class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> {
protected:
- AsyncEnd2endTest() {}
+ AsyncEnd2endTest() { GetParam().Log(); }
void SetUp() GRPC_OVERRIDE {
- poll_overrider_.reset(new PollingOverrider(!GetParam()));
+ poll_overrider_.reset(new PollingOverrider(!GetParam().disable_blocking));
int port = grpc_pick_unused_port_or_die();
server_address_ << "localhost:" << port;
// Setup server
ServerBuilder builder;
- builder.AddListeningPort(server_address_.str(),
- grpc::InsecureServerCredentials());
+ auto server_creds = GetServerCredentials(GetParam().credentials_type);
+ builder.AddListeningPort(server_address_.str(), server_creds);
builder.RegisterService(&service_);
cq_ = builder.AddCompletionQueue();
server_ = builder.BuildAndStart();
@@ -230,8 +249,11 @@
}
void ResetStub() {
+ ChannelArguments args;
+ auto channel_creds =
+ GetChannelCredentials(GetParam().credentials_type, &args);
std::shared_ptr<Channel> channel =
- CreateChannel(server_address_.str(), InsecureChannelCredentials());
+ CreateCustomChannel(server_address_.str(), channel_creds, args);
stub_ = grpc::testing::EchoTestService::NewStub(channel);
}
@@ -247,22 +269,23 @@
ServerContext srv_ctx;
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
cq_.get(), tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
send_response.set_message(recv_request.message());
response_writer.Finish(send_response, Status::OK, tag(3));
- Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
-
response_reader->Finish(&recv_response, &recv_status, tag(4));
- Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_response.message(), recv_response.message());
EXPECT_TRUE(recv_status.ok());
@@ -302,7 +325,7 @@
ServerContext srv_ctx;
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
@@ -310,23 +333,22 @@
std::chrono::system_clock::now());
std::chrono::system_clock::time_point time_limit(
std::chrono::system_clock::now() + std::chrono::seconds(10));
- Verifier(GetParam()).Verify(cq_.get(), time_now);
- Verifier(GetParam()).Verify(cq_.get(), time_now);
+ Verifier(GetParam().disable_blocking).Verify(cq_.get(), time_now);
+ Verifier(GetParam().disable_blocking).Verify(cq_.get(), time_now);
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
cq_.get(), tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get(), time_limit);
+ Verifier(GetParam().disable_blocking)
+ .Expect(2, true)
+ .Verify(cq_.get(), time_limit);
EXPECT_EQ(send_request.message(), recv_request.message());
send_response.set_message(recv_request.message());
response_writer.Finish(send_response, Status::OK, tag(3));
- Verifier(GetParam())
- .Expect(3, true)
- .Verify(cq_.get(), std::chrono::system_clock::time_point::max());
-
response_reader->Finish(&recv_response, &recv_status, tag(4));
- Verifier(GetParam())
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
.Expect(4, true)
.Verify(cq_.get(), std::chrono::system_clock::time_point::max());
@@ -347,41 +369,48 @@
ServerContext srv_ctx;
ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::unique_ptr<ClientAsyncWriter<EchoRequest>> cli_stream(
stub_->AsyncRequestStream(&cli_ctx, &recv_response, cq_.get(), tag(1)));
service_.RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
tag(2));
- Verifier(GetParam()).Expect(2, true).Expect(1, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(2, true)
+ .Expect(1, true)
+ .Verify(cq_.get());
cli_stream->Write(send_request, tag(3));
- Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
-
srv_stream.Read(&recv_request, tag(4));
- Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
cli_stream->Write(send_request, tag(5));
- Verifier(GetParam()).Expect(5, true).Verify(cq_.get());
-
srv_stream.Read(&recv_request, tag(6));
- Verifier(GetParam()).Expect(6, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(5, true)
+ .Expect(6, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
cli_stream->WritesDone(tag(7));
- Verifier(GetParam()).Expect(7, true).Verify(cq_.get());
-
srv_stream.Read(&recv_request, tag(8));
- Verifier(GetParam()).Expect(8, false).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(7, true)
+ .Expect(8, false)
+ .Verify(cq_.get());
send_response.set_message(recv_request.message());
srv_stream.Finish(send_response, Status::OK, tag(9));
- Verifier(GetParam()).Expect(9, true).Verify(cq_.get());
-
cli_stream->Finish(&recv_status, tag(10));
- Verifier(GetParam()).Expect(10, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(9, true)
+ .Expect(10, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_response.message(), recv_response.message());
EXPECT_TRUE(recv_status.ok());
@@ -400,39 +429,45 @@
ServerContext srv_ctx;
ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream(
stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1)));
service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream,
cq_.get(), cq_.get(), tag(2));
- Verifier(GetParam()).Expect(1, true).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(1, true)
+ .Expect(2, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
send_response.set_message(recv_request.message());
srv_stream.Write(send_response, tag(3));
- Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
-
cli_stream->Read(&recv_response, tag(4));
- Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_response.message(), recv_response.message());
srv_stream.Write(send_response, tag(5));
- Verifier(GetParam()).Expect(5, true).Verify(cq_.get());
-
cli_stream->Read(&recv_response, tag(6));
- Verifier(GetParam()).Expect(6, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(5, true)
+ .Expect(6, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_response.message(), recv_response.message());
srv_stream.Finish(Status::OK, tag(7));
- Verifier(GetParam()).Expect(7, true).Verify(cq_.get());
-
cli_stream->Read(&recv_response, tag(8));
- Verifier(GetParam()).Expect(8, false).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(7, true)
+ .Expect(8, false)
+ .Verify(cq_.get());
cli_stream->Finish(&recv_status, tag(9));
- Verifier(GetParam()).Expect(9, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(9, true).Verify(cq_.get());
EXPECT_TRUE(recv_status.ok());
}
@@ -450,41 +485,48 @@
ServerContext srv_ctx;
ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>>
cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1)));
service_.RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
tag(2));
- Verifier(GetParam()).Expect(1, true).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(1, true)
+ .Expect(2, true)
+ .Verify(cq_.get());
cli_stream->Write(send_request, tag(3));
- Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
-
srv_stream.Read(&recv_request, tag(4));
- Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
send_response.set_message(recv_request.message());
srv_stream.Write(send_response, tag(5));
- Verifier(GetParam()).Expect(5, true).Verify(cq_.get());
-
cli_stream->Read(&recv_response, tag(6));
- Verifier(GetParam()).Expect(6, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(5, true)
+ .Expect(6, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_response.message(), recv_response.message());
cli_stream->WritesDone(tag(7));
- Verifier(GetParam()).Expect(7, true).Verify(cq_.get());
-
srv_stream.Read(&recv_request, tag(8));
- Verifier(GetParam()).Expect(8, false).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(7, true)
+ .Expect(8, false)
+ .Verify(cq_.get());
srv_stream.Finish(Status::OK, tag(9));
- Verifier(GetParam()).Expect(9, true).Verify(cq_.get());
-
cli_stream->Finish(&recv_status, tag(10));
- Verifier(GetParam()).Expect(10, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(9, true)
+ .Expect(10, true)
+ .Verify(cq_.get());
EXPECT_TRUE(recv_status.ok());
}
@@ -503,7 +545,7 @@
ServerContext srv_ctx;
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::pair<grpc::string, grpc::string> meta1("key1", "val1");
std::pair<grpc::string, grpc::string> meta2("key2", "val2");
std::pair<grpc::string, grpc::string> meta3("g.r.d-bin", "xyz");
@@ -516,7 +558,7 @@
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
cq_.get(), tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
auto client_initial_metadata = srv_ctx.client_metadata();
EXPECT_EQ(meta1.second,
@@ -529,11 +571,11 @@
send_response.set_message(recv_request.message());
response_writer.Finish(send_response, Status::OK, tag(3));
-
- Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
-
response_reader->Finish(&recv_response, &recv_status, tag(4));
- Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_response.message(), recv_response.message());
EXPECT_TRUE(recv_status.ok());
@@ -552,7 +594,7 @@
ServerContext srv_ctx;
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::pair<grpc::string, grpc::string> meta1("key1", "val1");
std::pair<grpc::string, grpc::string> meta2("key2", "val2");
@@ -561,15 +603,15 @@
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
cq_.get(), tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
srv_ctx.AddInitialMetadata(meta1.first, meta1.second);
srv_ctx.AddInitialMetadata(meta2.first, meta2.second);
response_writer.SendInitialMetadata(tag(3));
- Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(3, true).Verify(cq_.get());
response_reader->ReadInitialMetadata(tag(4));
- Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get());
auto server_initial_metadata = cli_ctx.GetServerInitialMetadata();
EXPECT_EQ(meta1.second,
ToString(server_initial_metadata.find(meta1.first)->second));
@@ -579,10 +621,11 @@
send_response.set_message(recv_request.message());
response_writer.Finish(send_response, Status::OK, tag(5));
- Verifier(GetParam()).Expect(5, true).Verify(cq_.get());
-
response_reader->Finish(&recv_response, &recv_status, tag(6));
- Verifier(GetParam()).Expect(6, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(5, true)
+ .Expect(6, true)
+ .Verify(cq_.get());
EXPECT_EQ(send_response.message(), recv_response.message());
EXPECT_TRUE(recv_status.ok());
@@ -601,7 +644,7 @@
ServerContext srv_ctx;
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::pair<grpc::string, grpc::string> meta1("key1", "val1");
std::pair<grpc::string, grpc::string> meta2("key2", "val2");
@@ -610,20 +653,22 @@
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
cq_.get(), tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
response_writer.SendInitialMetadata(tag(3));
- Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(3, true).Verify(cq_.get());
send_response.set_message(recv_request.message());
srv_ctx.AddTrailingMetadata(meta1.first, meta1.second);
srv_ctx.AddTrailingMetadata(meta2.first, meta2.second);
response_writer.Finish(send_response, Status::OK, tag(4));
-
- Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
-
response_reader->Finish(&recv_response, &recv_status, tag(5));
- Verifier(GetParam()).Expect(5, true).Verify(cq_.get());
+
+ Verifier(GetParam().disable_blocking)
+ .Expect(4, true)
+ .Expect(5, true)
+ .Verify(cq_.get());
+
EXPECT_EQ(send_response.message(), recv_response.message());
EXPECT_TRUE(recv_status.ok());
auto server_trailing_metadata = cli_ctx.GetServerTrailingMetadata();
@@ -647,7 +692,7 @@
ServerContext srv_ctx;
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::pair<grpc::string, grpc::string> meta1("key1", "val1");
std::pair<grpc::string, grpc::string> meta2(
"key2-bin",
@@ -671,7 +716,7 @@
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
cq_.get(), tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
auto client_initial_metadata = srv_ctx.client_metadata();
EXPECT_EQ(meta1.second,
@@ -683,9 +728,9 @@
srv_ctx.AddInitialMetadata(meta3.first, meta3.second);
srv_ctx.AddInitialMetadata(meta4.first, meta4.second);
response_writer.SendInitialMetadata(tag(3));
- Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(3, true).Verify(cq_.get());
response_reader->ReadInitialMetadata(tag(4));
- Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get());
auto server_initial_metadata = cli_ctx.GetServerInitialMetadata();
EXPECT_EQ(meta3.second,
ToString(server_initial_metadata.find(meta3.first)->second));
@@ -697,11 +742,13 @@
srv_ctx.AddTrailingMetadata(meta5.first, meta5.second);
srv_ctx.AddTrailingMetadata(meta6.first, meta6.second);
response_writer.Finish(send_response, Status::OK, tag(5));
-
- Verifier(GetParam()).Expect(5, true).Verify(cq_.get());
-
response_reader->Finish(&recv_response, &recv_status, tag(6));
- Verifier(GetParam()).Expect(6, true).Verify(cq_.get());
+
+ Verifier(GetParam().disable_blocking)
+ .Expect(5, true)
+ .Expect(6, true)
+ .Verify(cq_.get());
+
EXPECT_EQ(send_response.message(), recv_response.message());
EXPECT_TRUE(recv_status.ok());
auto server_trailing_metadata = cli_ctx.GetServerTrailingMetadata();
@@ -726,7 +773,7 @@
ServerContext srv_ctx;
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
@@ -734,15 +781,15 @@
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
cq_.get(), tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
cli_ctx.TryCancel();
- Verifier(GetParam()).Expect(5, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(5, true).Verify(cq_.get());
EXPECT_TRUE(srv_ctx.IsCancelled());
response_reader->Finish(&recv_response, &recv_status, tag(4));
- Verifier(GetParam()).Expect(4, false).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(4, false).Verify(cq_.get());
EXPECT_EQ(StatusCode::CANCELLED, recv_status.error_code());
}
@@ -761,7 +808,7 @@
ServerContext srv_ctx;
grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
@@ -769,25 +816,29 @@
service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
cq_.get(), tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
send_response.set_message(recv_request.message());
response_writer.Finish(send_response, Status::OK, tag(3));
- Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
- Verifier(GetParam()).Expect(5, true).Verify(cq_.get());
- EXPECT_FALSE(srv_ctx.IsCancelled());
-
response_reader->Finish(&recv_response, &recv_status, tag(4));
- Verifier(GetParam()).Expect(4, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Expect(5, true)
+ .Verify(cq_.get());
+ EXPECT_FALSE(srv_ctx.IsCancelled());
EXPECT_EQ(send_response.message(), recv_response.message());
EXPECT_TRUE(recv_status.ok());
}
TEST_P(AsyncEnd2endTest, UnimplementedRpc) {
+ ChannelArguments args;
+ auto channel_creds =
+ GetChannelCredentials(GetParam().credentials_type, &args);
std::shared_ptr<Channel> channel =
- CreateChannel(server_address_.str(), InsecureChannelCredentials());
+ CreateCustomChannel(server_address_.str(), channel_creds, args);
std::unique_ptr<grpc::testing::UnimplementedService::Stub> stub;
stub = grpc::testing::UnimplementedService::NewStub(channel);
EchoRequest send_request;
@@ -795,12 +846,12 @@
Status recv_status;
ClientContext cli_ctx;
- send_request.set_message("Hello");
+ send_request.set_message(GetParam().message_content);
std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader(
stub->AsyncUnimplemented(&cli_ctx, send_request, cq_.get()));
response_reader->Finish(&recv_response, &recv_status, tag(4));
- Verifier(GetParam()).Expect(4, false).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(4, false).Verify(cq_.get());
EXPECT_EQ(StatusCode::UNIMPLEMENTED, recv_status.error_code());
EXPECT_EQ("", recv_status.error_message());
@@ -847,23 +898,25 @@
// Initiate the 'RequestStream' call on client
std::unique_ptr<ClientAsyncWriter<EchoRequest>> cli_stream(
stub_->AsyncRequestStream(&cli_ctx, &recv_response, cq_.get(), tag(1)));
- Verifier(GetParam()).Expect(1, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(1, true).Verify(cq_.get());
// On the server, request to be notified of 'RequestStream' calls
// and receive the 'RequestStream' call just made by the client
srv_ctx.AsyncNotifyWhenDone(tag(11));
service_.RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
// Client sends 3 messages (tags 3, 4 and 5)
for (int tag_idx = 3; tag_idx <= 5; tag_idx++) {
send_request.set_message("Ping " + std::to_string(tag_idx));
cli_stream->Write(send_request, tag(tag_idx));
- Verifier(GetParam()).Expect(tag_idx, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking)
+ .Expect(tag_idx, true)
+ .Verify(cq_.get());
}
cli_stream->WritesDone(tag(6));
- Verifier(GetParam()).Expect(6, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(6, true).Verify(cq_.get());
bool expected_server_cq_result = true;
bool ignore_cq_result = false;
@@ -871,7 +924,7 @@
if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
srv_ctx.TryCancel();
- Verifier(GetParam()).Expect(11, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(11, true).Verify(cq_.get());
EXPECT_TRUE(srv_ctx.IsCancelled());
// Since cancellation is done before server reads any results, we know
@@ -881,7 +934,7 @@
std::thread* server_try_cancel_thd = NULL;
- auto verif = Verifier(GetParam());
+ auto verif = Verifier(GetParam().disable_blocking);
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd =
@@ -939,13 +992,13 @@
// Server sends the final message and cancelled status (but the RPC is
// already cancelled at this point. So we expect the operation to fail)
srv_stream.Finish(send_response, Status::CANCELLED, tag(9));
- Verifier(GetParam()).Expect(9, false).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(9, false).Verify(cq_.get());
// Client will see the cancellation
cli_stream->Finish(&recv_status, tag(10));
// TODO(sreek): The expectation here should be true. This is a bug (github
// issue #4972)
- Verifier(GetParam()).Expect(10, false).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(10, false).Verify(cq_.get());
EXPECT_FALSE(recv_status.ok());
EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code());
}
@@ -979,13 +1032,13 @@
// Initiate the 'ResponseStream' call on the client
std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream(
stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1)));
- Verifier(GetParam()).Expect(1, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(1, true).Verify(cq_.get());
// On the server, request to be notified of 'ResponseStream' calls and
// receive the call just made by the client
srv_ctx.AsyncNotifyWhenDone(tag(11));
service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream,
cq_.get(), cq_.get(), tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
EXPECT_EQ(send_request.message(), recv_request.message());
bool expected_cq_result = true;
@@ -994,7 +1047,7 @@
if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
srv_ctx.TryCancel();
- Verifier(GetParam()).Expect(11, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(11, true).Verify(cq_.get());
EXPECT_TRUE(srv_ctx.IsCancelled());
// We know for sure that all cq results will be false from this point
@@ -1004,7 +1057,7 @@
std::thread* server_try_cancel_thd = NULL;
- auto verif = Verifier(GetParam());
+ auto verif = Verifier(GetParam().disable_blocking);
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd =
@@ -1064,7 +1117,7 @@
// Client attemts to read the three messages from the server
for (int tag_idx = 6; tag_idx <= 8; tag_idx++) {
cli_stream->Read(&recv_response, tag(tag_idx));
- Verifier(GetParam())
+ Verifier(GetParam().disable_blocking)
.Expect(tag_idx, expected_cq_result)
.Verify(cq_.get(), ignore_cq_result);
}
@@ -1075,11 +1128,11 @@
// Server finishes the stream (but the RPC is already cancelled)
srv_stream.Finish(Status::CANCELLED, tag(9));
- Verifier(GetParam()).Expect(9, false).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(9, false).Verify(cq_.get());
// Client will see the cancellation
cli_stream->Finish(&recv_status, tag(10));
- Verifier(GetParam()).Expect(10, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(10, true).Verify(cq_.get());
EXPECT_FALSE(recv_status.ok());
EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code());
}
@@ -1114,19 +1167,19 @@
// Initiate the call from the client side
std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>>
cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1)));
- Verifier(GetParam()).Expect(1, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(1, true).Verify(cq_.get());
// On the server, request to be notified of the 'BidiStream' call and
// receive the call just made by the client
srv_ctx.AsyncNotifyWhenDone(tag(11));
service_.RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
tag(2));
- Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
// Client sends the first and the only message
send_request.set_message("Ping");
cli_stream->Write(send_request, tag(3));
- Verifier(GetParam()).Expect(3, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(3, true).Verify(cq_.get());
bool expected_cq_result = true;
bool ignore_cq_result = false;
@@ -1134,7 +1187,7 @@
if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
srv_ctx.TryCancel();
- Verifier(GetParam()).Expect(11, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(11, true).Verify(cq_.get());
EXPECT_TRUE(srv_ctx.IsCancelled());
// We know for sure that all cq results will be false from this point
@@ -1144,7 +1197,7 @@
std::thread* server_try_cancel_thd = NULL;
- auto verif = Verifier(GetParam());
+ auto verif = Verifier(GetParam().disable_blocking);
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd =
@@ -1244,10 +1297,10 @@
// know that cq results are supposed to return false on server.
srv_stream.Finish(Status::CANCELLED, tag(9));
- Verifier(GetParam()).Expect(9, false).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(9, false).Verify(cq_.get());
cli_stream->Finish(&recv_status, tag(10));
- Verifier(GetParam()).Expect(10, true).Verify(cq_.get());
+ Verifier(GetParam().disable_blocking).Expect(10, true).Verify(cq_.get());
EXPECT_FALSE(recv_status.ok());
EXPECT_EQ(grpc::StatusCode::CANCELLED, recv_status.error_code());
}
@@ -1289,11 +1342,48 @@
TestBidiStreamingServerCancel(CANCEL_AFTER_PROCESSING);
}
+std::vector<TestScenario> CreateTestScenarios(bool test_disable_blocking,
+ bool test_secure,
+ int test_big_limit) {
+ std::vector<TestScenario> scenarios;
+ std::vector<grpc::string> credentials_types;
+ std::vector<grpc::string> messages;
+
+ credentials_types.push_back(kInsecureCredentialsType);
+ auto sec_list = GetSecureCredentialsTypeList();
+ for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) {
+ credentials_types.push_back(*sec);
+ }
+
+ messages.push_back("Hello");
+ for (int sz = 1; sz < test_big_limit; sz *= 2) {
+ grpc::string big_msg;
+ for (int i = 0; i < sz * 1024; i++) {
+ char c = 'a' + (i % 26);
+ big_msg += c;
+ }
+ messages.push_back(big_msg);
+ }
+
+ for (auto cred = credentials_types.begin(); cred != credentials_types.end();
+ ++cred) {
+ for (auto msg = messages.begin(); msg != messages.end(); msg++) {
+ scenarios.push_back(TestScenario(false, *cred, *msg));
+ if (test_disable_blocking) {
+ scenarios.push_back(TestScenario(true, *cred, *msg));
+ }
+ }
+ }
+ return scenarios;
+}
+
INSTANTIATE_TEST_CASE_P(AsyncEnd2end, AsyncEnd2endTest,
- ::testing::Values(false, true));
+ ::testing::ValuesIn(CreateTestScenarios(true, true,
+ 1024)));
INSTANTIATE_TEST_CASE_P(AsyncEnd2endServerTryCancel,
AsyncEnd2endServerTryCancelTest,
- ::testing::Values(false));
+ ::testing::ValuesIn(CreateTestScenarios(false, false,
+ 0)));
} // namespace
} // namespace testing
diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj
index 7605495..1acb34d 100644
--- a/test/distrib/csharp/DistribTest/DistribTest.csproj
+++ b/test/distrib/csharp/DistribTest/DistribTest.csproj
@@ -113,12 +113,12 @@
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="..\packages\grpc.native.csharp.__GRPC_NUGET_VERSION__\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets" Condition="Exists('..\packages\grpc.native.csharp.__GRPC_NUGET_VERSION__\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" />
+ <Import Project="..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\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.native.csharp.__GRPC_NUGET_VERSION__\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\grpc.native.csharp.__GRPC_NUGET_VERSION__\build\portable-net45+netcore45+wpa81+wp8\grpc.native.csharp.targets'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\build\net45\Grpc.Core.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
<Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
@@ -129,4 +129,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project>
\ No newline at end of file
+</Project>
diff --git a/test/distrib/csharp/DistribTest/packages.config b/test/distrib/csharp/DistribTest/packages.config
index aca09f6..6963019 100644
--- a/test/distrib/csharp/DistribTest/packages.config
+++ b/test/distrib/csharp/DistribTest/packages.config
@@ -6,11 +6,10 @@
<package id="Grpc" version="__GRPC_NUGET_VERSION__" targetFramework="net45" />
<package id="Grpc.Auth" version="__GRPC_NUGET_VERSION__" targetFramework="net45" />
<package id="Grpc.Core" version="__GRPC_NUGET_VERSION__" targetFramework="net45" />
- <package id="grpc.native.csharp" version="__GRPC_NUGET_VERSION__" targetFramework="net45" />
<package id="Ix-Async" version="1.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
+</packages>
diff --git a/third_party/objective_c/Cronet/cronet_c_for_grpc.h b/third_party/objective_c/Cronet/cronet_c_for_grpc.h
new file mode 100644
index 0000000..15a511a
--- /dev/null
+++ b/third_party/objective_c/Cronet/cronet_c_for_grpc.h
@@ -0,0 +1,202 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_CRONET_IOS_CRONET_C_FOR_GRPC_H_
+#define COMPONENTS_CRONET_IOS_CRONET_C_FOR_GRPC_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+/* Cronet Engine API. */
+
+/* Opaque object representing Cronet Engine. Created and configured outside
+ * of this API to facilitate sharing with other components */
+typedef struct cronet_engine { void* obj; } cronet_engine;
+
+void cronet_engine_add_quic_hint(cronet_engine* engine,
+ const char* host,
+ int port,
+ int alternate_port);
+
+/* Cronet Bidirectional Stream API */
+
+/* Opaque object representing Cronet Bidirectional Stream. */
+typedef struct cronet_bidirectional_stream {
+ void* obj;
+ void* annotation;
+} cronet_bidirectional_stream;
+
+/* A single request or response header element. */
+typedef struct cronet_bidirectional_stream_header {
+ const char* key;
+ const char* value;
+} cronet_bidirectional_stream_header;
+
+/* Array of request or response headers or trailers. */
+typedef struct cronet_bidirectional_stream_header_array {
+ size_t count;
+ size_t capacity;
+ cronet_bidirectional_stream_header* headers;
+} cronet_bidirectional_stream_header_array;
+
+/* Set of callbacks used to receive callbacks from bidirectional stream. */
+typedef struct cronet_bidirectional_stream_callback {
+ /* Invoked when request headers are sent. Indicates that stream has initiated
+ * the request. Consumer may call cronet_bidirectional_stream_write() to start
+ * writing data.
+ */
+ void (*on_request_headers_sent)(cronet_bidirectional_stream* stream);
+
+ /* Invoked when initial response headers are received.
+ * Consumer must call cronet_bidirectional_stream_read() to start reading.
+ * Consumer may call cronet_bidirectional_stream_write() to start writing or
+ * close the stream. Contents of |headers| is valid for duration of the call.
+ */
+ void (*on_response_headers_received)(
+ cronet_bidirectional_stream* stream,
+ const cronet_bidirectional_stream_header_array* headers,
+ const char* negotiated_protocol);
+
+ /* Invoked when data is read into the buffer passed to
+ * cronet_bidirectional_stream_read(). Only part of the buffer may be
+ * populated. To continue reading, call cronet_bidirectional_stream_read().
+ * It may be invoked after on_response_trailers_received()}, if there was
+ * pending read data before trailers were received.
+ *
+ * If count is 0, it means the remote side has signaled that it will send no
+ * more data; future calls to cronet_bidirectional_stream_read() will result
+ * in the on_data_read() callback or on_succeded() callback if
+ * cronet_bidirectional_stream_write() was invoked with end_of_stream set to
+ * true.
+ */
+ void (*on_read_completed)(cronet_bidirectional_stream* stream,
+ char* data,
+ int count);
+
+ /**
+ * Invoked when all data passed to cronet_bidirectional_stream_write() is
+ * sent.
+ * To continue writing, call cronet_bidirectional_stream_write().
+ */
+ void (*on_write_completed)(cronet_bidirectional_stream* stream,
+ const char* data);
+
+ /* Invoked when trailers are received before closing the stream. Only invoked
+ * when server sends trailers, which it may not. May be invoked while there is
+ * read data remaining in local buffer. Contents of |trailers| is valid for
+ * duration of the call.
+ */
+ void (*on_response_trailers_received)(
+ cronet_bidirectional_stream* stream,
+ const cronet_bidirectional_stream_header_array* trailers);
+
+ /**
+ * Invoked when there is no data to be read or written and the stream is
+ * closed successfully remotely and locally. Once invoked, no further callback
+ * methods will be invoked.
+ */
+ void (*on_succeded)(cronet_bidirectional_stream* stream);
+
+ /**
+ * Invoked if the stream failed for any reason after
+ * cronet_bidirectional_stream_start(). HTTP/2 error codes are
+ * mapped to chrome net error codes. Once invoked, no further callback methods
+ * will be invoked.
+ */
+ void (*on_failed)(cronet_bidirectional_stream* stream, int net_error);
+
+ /**
+ * Invoked if the stream was canceled via
+ * cronet_bidirectional_stream_cancel(). Once invoked, no further callback
+ * methods will be invoked.
+ */
+ void (*on_canceled)(cronet_bidirectional_stream* stream);
+} cronet_bidirectional_stream_callback;
+
+/* Create a new stream object that uses |engine| and |callback|. All stream
+ * tasks are performed asynchronously on the |engine| network thread. |callback|
+ * methods are invoked synchronously on the |engine| network thread, but must
+ * not run tasks on the current thread to prevent blocking networking operations
+ * and causing exceptions during shutdown. The |annotation| is stored in
+ * bidirectional stream for arbitrary use by application.
+ *
+ * Returned |cronet_bidirectional_stream*| is owned by the caller, and must be
+ * destroyed using |cronet_bidirectional_stream_destroy|.
+ *
+ * Both |calback| and |engine| must remain valid until stream is destroyed.
+ */
+cronet_bidirectional_stream* cronet_bidirectional_stream_create(
+ cronet_engine* engine,
+ void* annotation,
+ cronet_bidirectional_stream_callback* callback);
+
+/* TBD: The following methods return int. Should it be a custom type? */
+
+/* Destroy stream object. Destroy could be called from any thread, including
+ * network thread, but is posted, so |stream| is valid until calling task is
+ * complete.
+ */
+int cronet_bidirectional_stream_destroy(cronet_bidirectional_stream* stream);
+
+/* Start the stream by sending request to |url| using |method| and |headers|. If
+ * |end_of_stream| is true, then no data is expected to be written.
+ */
+int cronet_bidirectional_stream_start(
+ cronet_bidirectional_stream* stream,
+ const char* url,
+ int priority,
+ const char* method,
+ const cronet_bidirectional_stream_header_array* headers,
+ bool end_of_stream);
+
+/* Read response data into |buffer| of |capacity| length. Must only be called at
+ * most once in response to each invocation of the
+ * on_response_headers_received() and on_read_completed() methods of the
+ * cronet_bidirectional_stream_callback.
+ * Each call will result in an invocation of one of the callback's
+ * on_read_completed method if data is read, its on_succeeded() method if
+ * the stream is closed, or its on_failed() method if there's an error.
+ */
+int cronet_bidirectional_stream_read(cronet_bidirectional_stream* stream,
+ char* buffer,
+ int capacity);
+
+/* Read response data into |buffer| of |capacity| length. Must only be called at
+ * most once in response to each invocation of the
+ * on_response_headers_received() and on_read_completed() methods of the
+ * cronet_bidirectional_stream_callback.
+ * Each call will result in an invocation of one of the callback's
+ * on_read_completed method if data is read, its on_succeeded() method if
+ * the stream is closed, or its on_failed() method if there's an error.
+ */
+int cronet_bidirectional_stream_write(cronet_bidirectional_stream* stream,
+ const char* buffer,
+ int count,
+ bool end_of_stream);
+
+/* Cancels the stream. Can be called at any time after
+ * cronet_bidirectional_stream_start(). The on_canceled() method of
+ * cronet_bidirectional_stream_callback will be invoked when cancelation
+ * is complete and no further callback methods will be invoked. If the
+ * stream has completed or has not started, calling
+ * cronet_bidirectional_stream_cancel() has no effect and on_canceled() will not
+ * be invoked. At most one callback method may be invoked after
+ * cronet_bidirectional_stream_cancel() has completed.
+ */
+int cronet_bidirectional_stream_cancel(cronet_bidirectional_stream* stream);
+
+/* Returns true if the |stream| was successfully started and is now done
+ * (succeeded, canceled, or failed).
+ * Returns false if the |stream| stream is not yet started or is in progress.
+ */
+bool cronet_bidirectional_stream_is_done(cronet_bidirectional_stream* stream);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COMPONENTS_CRONET_IOS_CRONET_C_FOR_GRPC_H_
diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py
index 897a899..6c160c6 100755
--- a/tools/distrib/check_include_guards.py
+++ b/tools/distrib/check_include_guards.py
@@ -31,6 +31,7 @@
import argparse
import os
+import os.path
import re
import sys
import subprocess
@@ -187,6 +188,8 @@
try:
filename_list = subprocess.check_output(FILE_LIST_COMMAND,
shell=True).splitlines()
+ # Filter out non-existent files (ie, file removed or renamed)
+ filename_list = (f for f in filename_list if os.path.isfile(f))
except subprocess.CalledProcessError:
sys.exit(0)
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 7dc0496..664ca03 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -833,6 +833,7 @@
include/grpc++/impl/codegen/sync_stream.h \
include/grpc++/impl/codegen/time.h \
include/grpc/impl/codegen/byte_buffer.h \
+include/grpc/impl/codegen/byte_buffer_reader.h \
include/grpc/impl/codegen/compression_types.h \
include/grpc/impl/codegen/connectivity_state.h \
include/grpc/impl/codegen/grpc_types.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 312fd17..5188ef1 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -833,6 +833,7 @@
include/grpc++/impl/codegen/sync_stream.h \
include/grpc++/impl/codegen/time.h \
include/grpc/impl/codegen/byte_buffer.h \
+include/grpc/impl/codegen/byte_buffer_reader.h \
include/grpc/impl/codegen/compression_types.h \
include/grpc/impl/codegen/connectivity_state.h \
include/grpc/impl/codegen/grpc_types.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 034d9c6..84b5c2a 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -766,6 +766,7 @@
include/grpc/grpc.h \
include/grpc/status.h \
include/grpc/impl/codegen/byte_buffer.h \
+include/grpc/impl/codegen/byte_buffer_reader.h \
include/grpc/impl/codegen/compression_types.h \
include/grpc/impl/codegen/connectivity_state.h \
include/grpc/impl/codegen/grpc_types.h \
@@ -785,6 +786,7 @@
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_win32.h \
include/grpc/impl/codegen/time.h \
+include/grpc/grpc_cronet.h \
include/grpc/grpc_security.h \
include/grpc/grpc_security_constants.h \
include/grpc/census.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 1b1453f..228c1d9 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -766,6 +766,7 @@
include/grpc/grpc.h \
include/grpc/status.h \
include/grpc/impl/codegen/byte_buffer.h \
+include/grpc/impl/codegen/byte_buffer_reader.h \
include/grpc/impl/codegen/compression_types.h \
include/grpc/impl/codegen/connectivity_state.h \
include/grpc/impl/codegen/grpc_types.h \
@@ -785,6 +786,7 @@
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_win32.h \
include/grpc/impl/codegen/time.h \
+include/grpc/grpc_cronet.h \
include/grpc/grpc_security.h \
include/grpc/grpc_security_constants.h \
include/grpc/census.h \
@@ -912,6 +914,42 @@
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 \
+include/grpc/byte_buffer.h \
+include/grpc/grpc.h \
+include/grpc/impl/codegen/alloc.h \
+include/grpc/impl/codegen/atm.h \
+include/grpc/impl/codegen/atm_gcc_atomic.h \
+include/grpc/impl/codegen/atm_gcc_sync.h \
+include/grpc/impl/codegen/atm_win32.h \
+include/grpc/impl/codegen/byte_buffer.h \
+include/grpc/impl/codegen/compression_types.h \
+include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/grpc_types.h \
+include/grpc/impl/codegen/log.h \
+include/grpc/impl/codegen/port_platform.h \
+include/grpc/impl/codegen/propagation_bits.h \
+include/grpc/impl/codegen/slice.h \
+include/grpc/impl/codegen/slice_buffer.h \
+include/grpc/impl/codegen/status.h \
+include/grpc/impl/codegen/sync.h \
+include/grpc/impl/codegen/sync_generic.h \
+include/grpc/impl/codegen/sync_posix.h \
+include/grpc/impl/codegen/sync_win32.h \
+include/grpc/impl/codegen/time.h \
+include/grpc/status.h \
+include/grpc/support/alloc.h \
+include/grpc/support/atm.h \
+include/grpc/support/host_port.h \
+include/grpc/support/log.h \
+include/grpc/support/port_platform.h \
+include/grpc/support/slice.h \
+include/grpc/support/slice_buffer.h \
+include/grpc/support/string_util.h \
+include/grpc/support/sync.h \
+include/grpc/support/time.h \
+include/grpc/support/useful.h \
+src/core/lib/support/string.h \
+third_party/objective_c/Cronet/cronet_c_for_grpc.h \
src/core/ext/lb_policy/grpclb/load_balancer_api.h \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.h \
third_party/nanopb/pb.h \
@@ -1070,6 +1108,9 @@
src/core/ext/client_config/uri_parser.c \
src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
src/core/ext/transport/chttp2/client/insecure/channel_create.c \
+src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \
+src/core/ext/transport/cronet/transport/cronet_api_dummy.c \
+src/core/ext/transport/cronet/transport/cronet_transport.c \
src/core/ext/lb_policy/grpclb/load_balancer_api.c \
src/core/ext/lb_policy/grpclb/proto/grpc/lb/v0/load_balancer.pb.c \
third_party/nanopb/pb_common.c \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index f546f3b..8c67d2f 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -4140,7 +4140,8 @@
"grpc_transport_chttp2_client_insecure",
"grpc_transport_chttp2_client_secure",
"grpc_transport_chttp2_server_insecure",
- "grpc_transport_chttp2_server_secure"
+ "grpc_transport_chttp2_server_secure",
+ "grpc_transport_cronet_client_secure"
],
"headers": [],
"language": "c",
@@ -5903,6 +5904,7 @@
],
"headers": [
"include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/byte_buffer_reader.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
@@ -5913,6 +5915,7 @@
"name": "grpc_codegen",
"src": [
"include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/byte_buffer_reader.h",
"include/grpc/impl/codegen/compression_types.h",
"include/grpc/impl/codegen/connectivity_state.h",
"include/grpc/impl/codegen/grpc_types.h",
@@ -6012,6 +6015,7 @@
"tsi"
],
"headers": [
+ "include/grpc/grpc_cronet.h",
"include/grpc/grpc_security.h",
"include/grpc/grpc_security_constants.h",
"src/core/lib/security/auth_filters.h",
@@ -6027,6 +6031,7 @@
"language": "c",
"name": "grpc_secure",
"src": [
+ "include/grpc/grpc_cronet.h",
"include/grpc/grpc_security.h",
"include/grpc/grpc_security_constants.h",
"src/core/lib/http/httpcli_security_connector.c",
@@ -6265,6 +6270,121 @@
{
"deps": [],
"headers": [
+ "include/grpc/byte_buffer.h",
+ "include/grpc/grpc.h",
+ "include/grpc/impl/codegen/alloc.h",
+ "include/grpc/impl/codegen/atm.h",
+ "include/grpc/impl/codegen/atm_gcc_atomic.h",
+ "include/grpc/impl/codegen/atm_gcc_sync.h",
+ "include/grpc/impl/codegen/atm_win32.h",
+ "include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/compression_types.h",
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/grpc_types.h",
+ "include/grpc/impl/codegen/log.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/propagation_bits.h",
+ "include/grpc/impl/codegen/slice.h",
+ "include/grpc/impl/codegen/slice_buffer.h",
+ "include/grpc/impl/codegen/status.h",
+ "include/grpc/impl/codegen/sync.h",
+ "include/grpc/impl/codegen/sync_generic.h",
+ "include/grpc/impl/codegen/sync_posix.h",
+ "include/grpc/impl/codegen/sync_win32.h",
+ "include/grpc/impl/codegen/time.h",
+ "include/grpc/status.h",
+ "include/grpc/support/alloc.h",
+ "include/grpc/support/atm.h",
+ "include/grpc/support/host_port.h",
+ "include/grpc/support/log.h",
+ "include/grpc/support/port_platform.h",
+ "include/grpc/support/slice.h",
+ "include/grpc/support/slice_buffer.h",
+ "include/grpc/support/string_util.h",
+ "include/grpc/support/sync.h",
+ "include/grpc/support/time.h",
+ "include/grpc/support/useful.h",
+ "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
+ "src/core/lib/channel/channel_stack.h",
+ "src/core/lib/channel/context.h",
+ "src/core/lib/debug/trace.h",
+ "src/core/lib/iomgr/closure.h",
+ "src/core/lib/iomgr/exec_ctx.h",
+ "src/core/lib/iomgr/pollset.h",
+ "src/core/lib/iomgr/pollset_set.h",
+ "src/core/lib/support/string.h",
+ "src/core/lib/surface/channel.h",
+ "src/core/lib/surface/channel_stack_type.h",
+ "src/core/lib/transport/byte_stream.h",
+ "src/core/lib/transport/metadata.h",
+ "src/core/lib/transport/metadata_batch.h",
+ "src/core/lib/transport/transport.h",
+ "src/core/lib/transport/transport_impl.h",
+ "third_party/objective_c/Cronet/cronet_c_for_grpc.h"
+ ],
+ "language": "c",
+ "name": "grpc_transport_cronet_client_secure",
+ "src": [
+ "include/grpc/byte_buffer.h",
+ "include/grpc/grpc.h",
+ "include/grpc/impl/codegen/alloc.h",
+ "include/grpc/impl/codegen/atm.h",
+ "include/grpc/impl/codegen/atm_gcc_atomic.h",
+ "include/grpc/impl/codegen/atm_gcc_sync.h",
+ "include/grpc/impl/codegen/atm_win32.h",
+ "include/grpc/impl/codegen/byte_buffer.h",
+ "include/grpc/impl/codegen/compression_types.h",
+ "include/grpc/impl/codegen/connectivity_state.h",
+ "include/grpc/impl/codegen/grpc_types.h",
+ "include/grpc/impl/codegen/log.h",
+ "include/grpc/impl/codegen/port_platform.h",
+ "include/grpc/impl/codegen/propagation_bits.h",
+ "include/grpc/impl/codegen/slice.h",
+ "include/grpc/impl/codegen/slice_buffer.h",
+ "include/grpc/impl/codegen/status.h",
+ "include/grpc/impl/codegen/sync.h",
+ "include/grpc/impl/codegen/sync_generic.h",
+ "include/grpc/impl/codegen/sync_posix.h",
+ "include/grpc/impl/codegen/sync_win32.h",
+ "include/grpc/impl/codegen/time.h",
+ "include/grpc/status.h",
+ "include/grpc/support/alloc.h",
+ "include/grpc/support/atm.h",
+ "include/grpc/support/host_port.h",
+ "include/grpc/support/log.h",
+ "include/grpc/support/port_platform.h",
+ "include/grpc/support/slice.h",
+ "include/grpc/support/slice_buffer.h",
+ "include/grpc/support/string_util.h",
+ "include/grpc/support/sync.h",
+ "include/grpc/support/time.h",
+ "include/grpc/support/useful.h",
+ "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
+ "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
+ "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
+ "src/core/ext/transport/cronet/transport/cronet_transport.c",
+ "src/core/lib/channel/channel_stack.h",
+ "src/core/lib/channel/context.h",
+ "src/core/lib/debug/trace.h",
+ "src/core/lib/iomgr/closure.h",
+ "src/core/lib/iomgr/exec_ctx.h",
+ "src/core/lib/iomgr/pollset.h",
+ "src/core/lib/iomgr/pollset_set.h",
+ "src/core/lib/support/string.h",
+ "src/core/lib/surface/channel.h",
+ "src/core/lib/surface/channel_stack_type.h",
+ "src/core/lib/transport/byte_stream.h",
+ "src/core/lib/transport/metadata.h",
+ "src/core/lib/transport/metadata_batch.h",
+ "src/core/lib/transport/transport.h",
+ "src/core/lib/transport/transport_impl.h"
+ ],
+ "third_party": false,
+ "type": "filegroup"
+ },
+ {
+ "deps": [],
+ "headers": [
"third_party/nanopb/pb.h",
"third_party/nanopb/pb_common.h",
"third_party/nanopb/pb_decode.h",
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 29cab37..0ec53ac 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -331,6 +331,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index 15e2807..491aeae 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -315,6 +315,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index fcda361..96bee41 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -331,6 +331,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 1dc95f9..fe9eed7 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -300,6 +300,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 4eec05a..7f0e5a8 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -273,6 +273,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
@@ -292,6 +293,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_cronet.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\census.h" />
@@ -421,6 +423,42 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_call_holder.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice_buffer.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\alloc.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\atm.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\host_port.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\log.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\port_platform.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\slice.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\slice_buffer.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\string_util.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\sync.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\time.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\useful.h" />
+ <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\string.h" />
+ <ClInclude Include="$(SolutionDir)\..\third_party\objective_c\Cronet\cronet_c_for_grpc.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v0\load_balancer.pb.h" />
<ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h" />
@@ -727,6 +765,12 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create.c">
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\client\secure\cronet_channel_create.c">
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\transport\cronet_api_dummy.c">
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\transport\cronet_transport.c">
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v0\load_balancer.pb.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 17c88c4..6d1d69a 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -439,6 +439,15 @@
<ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create.c">
<Filter>src\core\ext\transport\chttp2\client\insecure</Filter>
</ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\client\secure\cronet_channel_create.c">
+ <Filter>src\core\ext\transport\cronet\client\secure</Filter>
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\transport\cronet_api_dummy.c">
+ <Filter>src\core\ext\transport\cronet\transport</Filter>
+ </ClCompile>
+ <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\transport\cronet_transport.c">
+ <Filter>src\core\ext\transport\cronet\transport</Filter>
+ </ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.c">
<Filter>src\core\ext\lb_policy\grpclb</Filter>
</ClCompile>
@@ -516,6 +525,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
@@ -573,6 +585,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_cronet.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h">
<Filter>include\grpc</Filter>
</ClInclude>
@@ -956,6 +971,114 @@
<ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h">
<Filter>src\core\ext\client_config</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice_buffer.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
+ <Filter>include\grpc</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\alloc.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\atm.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\host_port.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\log.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\port_platform.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\slice.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\slice_buffer.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\string_util.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\sync.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\time.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\support\useful.h">
+ <Filter>include\grpc\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\string.h">
+ <Filter>src\core\lib\support</Filter>
+ </ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\third_party\objective_c\Cronet\cronet_c_for_grpc.h">
+ <Filter>third_party\objective_c\Cronet</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h">
<Filter>src\core\ext\lb_policy\grpclb</Filter>
</ClInclude>
@@ -1007,6 +1130,9 @@
<Filter Include="include\grpc\impl\codegen">
<UniqueIdentifier>{def748f5-ed2a-a9bb-40d9-c31d00f0e13b}</UniqueIdentifier>
</Filter>
+ <Filter Include="include\grpc\support">
+ <UniqueIdentifier>{31de82ea-dc6c-73fb-a640-979b8a7b240c}</UniqueIdentifier>
+ </Filter>
<Filter Include="src">
<UniqueIdentifier>{d538af37-07b2-062b-fa2a-d9f882cb2737}</UniqueIdentifier>
</Filter>
@@ -1088,6 +1214,18 @@
<Filter Include="src\core\ext\transport\chttp2\transport">
<UniqueIdentifier>{6f34254e-e69f-c9b4-156d-5024bade5408}</UniqueIdentifier>
</Filter>
+ <Filter Include="src\core\ext\transport\cronet">
+ <UniqueIdentifier>{1e9c85e9-5522-7ef8-0017-7e19990a6194}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\ext\transport\cronet\client">
+ <UniqueIdentifier>{d0530883-75d9-b5f7-d594-26735a70ac7b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\ext\transport\cronet\client\secure">
+ <UniqueIdentifier>{4fa6fe90-b7a8-5c8f-d629-db1e68d89eed}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="src\core\ext\transport\cronet\transport">
+ <UniqueIdentifier>{31518af8-5860-6d0d-ff78-4059fce29ec2}</UniqueIdentifier>
+ </Filter>
<Filter Include="src\core\lib">
<UniqueIdentifier>{5b2ded3f-84a5-f6b4-2060-286c7d1dc945}</UniqueIdentifier>
</Filter>
@@ -1112,6 +1250,9 @@
<Filter Include="src\core\lib\security">
<UniqueIdentifier>{c4661d64-349f-01c1-1ba8-0602f9047595}</UniqueIdentifier>
</Filter>
+ <Filter Include="src\core\lib\support">
+ <UniqueIdentifier>{27f30339-d694-40f5-db07-4b89b9aeea73}</UniqueIdentifier>
+ </Filter>
<Filter Include="src\core\lib\surface">
<UniqueIdentifier>{a21971fb-304f-da08-b1b2-7bd8df8ac373}</UniqueIdentifier>
</Filter>
@@ -1130,6 +1271,12 @@
<Filter Include="third_party\nanopb">
<UniqueIdentifier>{93d6596d-330c-1d27-6f84-3c840e57869e}</UniqueIdentifier>
</Filter>
+ <Filter Include="third_party\objective_c">
+ <UniqueIdentifier>{3a56a516-857e-d2aa-95cc-11685baf4e8c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="third_party\objective_c\Cronet">
+ <UniqueIdentifier>{a165c6e3-0776-6f40-7351-d7865668e220}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
</Project>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 26050dc..0eb6535 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -264,6 +264,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index a4acf51..f544fe6 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -456,6 +456,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
index cd0b40c..34e939c 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
@@ -191,6 +191,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
index 029b8ef..d662365 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
@@ -120,6 +120,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
index 6d138fa..890d77d 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
@@ -191,6 +191,7 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
index dc3f0b2..4e0ba65 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
@@ -120,6 +120,9 @@
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>
+ <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
+ <Filter>include\grpc\impl\codegen</Filter>
+ </ClInclude>
<ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
<Filter>include\grpc\impl\codegen</Filter>
</ClInclude>