diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index a73458821ec..2e250338138 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -505,13 +505,13 @@ static void cc_on_config_changed(void *arg, int iomgr_success) {
if (iomgr_success && chand->resolver) {
grpc_resolver *resolver = chand->resolver;
GRPC_RESOLVER_REF(resolver, "channel-next");
+ grpc_connectivity_state_set(&chand->state_tracker, state,
+ "new_lb+resolver");
gpr_mu_unlock(&chand->mu_config);
GRPC_CHANNEL_INTERNAL_REF(chand->master, "resolver");
grpc_resolver_next(resolver, &chand->incoming_configuration,
&chand->on_config_changed);
GRPC_RESOLVER_UNREF(resolver, "channel-next");
- grpc_connectivity_state_set(&chand->state_tracker, state,
- "new_lb+resolver");
if (lb_policy != NULL) {
watch_lb_policy(chand, lb_policy, state);
}
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index a6153b479d9..33f277da46d 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -1573,7 +1573,8 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
const grpc_op *op;
grpc_ioreq *req;
void (*finish_func)(grpc_call *, int, void *) = finish_batch;
- GPR_ASSERT(!reserved);
+
+ if (reserved != NULL) return GRPC_CALL_ERROR;
GRPC_CALL_LOG_BATCH(GPR_INFO, call, ops, nops, tag);
@@ -1588,6 +1589,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
/* rewrite batch ops into ioreq ops */
for (in = 0, out = 0; in < nops; in++) {
op = &ops[in];
+ if (op->reserved != NULL) return GRPC_CALL_ERROR;
switch (op->op) {
case GRPC_OP_SEND_INITIAL_METADATA:
/* Flag validation: currently allow no flags */
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index f399aa69f2f..4990e6583ad 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -1135,6 +1135,7 @@ grpc_call_error grpc_server_request_call(
return GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
}
grpc_cq_begin_op(cq_for_notification);
+ details->reserved = NULL;
rc->type = BATCH_CALL;
rc->server = server;
rc->tag = tag;
diff --git a/src/csharp/Grpc.Auth/AuthInterceptors.cs b/src/csharp/Grpc.Auth/AuthInterceptors.cs
new file mode 100644
index 00000000000..61338f7f0e2
--- /dev/null
+++ b/src/csharp/Grpc.Auth/AuthInterceptors.cs
@@ -0,0 +1,84 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Threading;
+
+using Google.Apis.Auth.OAuth2;
+using Grpc.Core;
+using Grpc.Core.Utils;
+
+namespace Grpc.Auth
+{
+ ///
+ /// Factory methods to create authorization interceptors.
+ ///
+ public static class AuthInterceptors
+ {
+ private const string AuthorizationHeader = "Authorization";
+ private const string Schema = "Bearer";
+
+ ///
+ /// Creates interceptor that will obtain access token from any credential type that implements
+ /// ITokenAccess. (e.g. GoogleCredential).
+ ///
+ public static HeaderInterceptor FromCredential(ITokenAccess credential)
+ {
+ return new HeaderInterceptor((method, authUri, metadata) =>
+ {
+ // TODO(jtattermusch): Rethink synchronous wait to obtain the result.
+ var accessToken = credential.GetAccessTokenForRequestAsync(authUri, CancellationToken.None)
+ .ConfigureAwait(false).GetAwaiter().GetResult();
+ metadata.Add(CreateBearerTokenHeader(accessToken));
+ });
+ }
+
+ ///
+ /// Creates OAuth2 interceptor that will use given access token as authorization.
+ ///
+ /// OAuth2 access token.
+ public static HeaderInterceptor FromAccessToken(string accessToken)
+ {
+ Preconditions.CheckNotNull(accessToken);
+ return new HeaderInterceptor((method, authUri, metadata) =>
+ {
+ metadata.Add(CreateBearerTokenHeader(accessToken));
+ });
+ }
+
+ private static Metadata.Entry CreateBearerTokenHeader(string accessToken)
+ {
+ return new Metadata.Entry(AuthorizationHeader, Schema + " " + accessToken);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
index 930a34b0c33..4fb087d4a34 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
@@ -3,8 +3,6 @@
Debug
AnyCPU
- 10.0.0
- 2.0
{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}
Library
Grpc.Auth
@@ -41,57 +39,47 @@
C:\keys\Grpc.snk
-
- False
+
+
+
+
+
..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll
-
- False
+
..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll
-
- False
+
..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll
-
- False
+
..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll
-
- False
+
..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll
-
- False
+
..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll
-
- False
+
..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll
-
- False
+
..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
-
-
-
-
- False
+
..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll
-
- False
+
..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll
-
Version.cs
-
+
diff --git a/src/csharp/Grpc.Auth/OAuth2Interceptors.cs b/src/csharp/Grpc.Auth/OAuth2Interceptors.cs
deleted file mode 100644
index d628a83246d..00000000000
--- a/src/csharp/Grpc.Auth/OAuth2Interceptors.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-#region Copyright notice and license
-
-// 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.
-
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Security.Cryptography.X509Certificates;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Threading.Tasks;
-
-using Google.Apis.Auth.OAuth2;
-using Google.Apis.Util;
-using Grpc.Core;
-using Grpc.Core.Utils;
-
-namespace Grpc.Auth
-{
- public static class OAuth2Interceptors
- {
- ///
- /// Creates OAuth2 interceptor that will obtain access token from GoogleCredentials.
- ///
- public static MetadataInterceptorDelegate FromCredential(GoogleCredential googleCredential)
- {
- var interceptor = new OAuth2Interceptor(googleCredential, SystemClock.Default);
- return new MetadataInterceptorDelegate(interceptor.InterceptHeaders);
- }
-
- ///
- /// Creates OAuth2 interceptor that will use given OAuth2 token.
- ///
- ///
- ///
- public static MetadataInterceptorDelegate FromAccessToken(string oauth2Token)
- {
- Preconditions.CheckNotNull(oauth2Token);
- return new MetadataInterceptorDelegate((authUri, metadata) =>
- {
- metadata.Add(OAuth2Interceptor.CreateBearerTokenHeader(oauth2Token));
- });
- }
-
- ///
- /// Injects OAuth2 authorization header into initial metadata (= request headers).
- ///
- private class OAuth2Interceptor
- {
- private const string AuthorizationHeader = "Authorization";
- private const string Schema = "Bearer";
-
- private ITokenAccess credential;
- private IClock clock;
-
- public OAuth2Interceptor(ITokenAccess credential, IClock clock)
- {
- this.credential = credential;
- this.clock = clock;
- }
-
- ///
- /// Gets access token and requests refreshing it if is going to expire soon.
- ///
- ///
- ///
- public string GetAccessToken(string authUri, CancellationToken cancellationToken)
- {
- // TODO(jtattermusch): Rethink synchronous wait to obtain the result.
- return credential.GetAccessTokenForRequestAsync(authUri, cancellationToken: cancellationToken).GetAwaiter().GetResult();
- }
-
- public void InterceptHeaders(string authUri, Metadata metadata)
- {
- var accessToken = GetAccessToken(authUri, CancellationToken.None);
- metadata.Add(CreateBearerTokenHeader(accessToken));
- }
-
- public static Metadata.Entry CreateBearerTokenHeader(string accessToken)
- {
- return new Metadata.Entry(AuthorizationHeader, Schema + " " + accessToken);
- }
- }
- }
-}
diff --git a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs b/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
index bf020cd6274..fb9b562c77b 100644
--- a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
@@ -88,6 +88,24 @@ namespace Grpc.Core
return responseAsync.GetAwaiter();
}
+ ///
+ /// Gets the call status if the call has already finished.
+ /// Throws InvalidOperationException otherwise.
+ ///
+ public Status GetStatus()
+ {
+ return getStatusFunc();
+ }
+
+ ///
+ /// Gets the call trailing metadata if the call has already finished.
+ /// Throws InvalidOperationException otherwise.
+ ///
+ public Metadata GetTrailers()
+ {
+ return getTrailersFunc();
+ }
+
///
/// Provides means to cleanup after the call.
/// If the call has already finished normally (request stream has been completed and call result has been received), doesn't do anything.
diff --git a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs b/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
index 0979de606f7..183c84216a0 100644
--- a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
@@ -32,8 +32,6 @@
#endregion
using System;
-using System.Runtime.CompilerServices;
-using System.Threading.Tasks;
namespace Grpc.Core
{
diff --git a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs b/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
index 380efcdb0e2..ab2049f2695 100644
--- a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
@@ -32,8 +32,6 @@
#endregion
using System;
-using System.Runtime.CompilerServices;
-using System.Threading.Tasks;
namespace Grpc.Core
{
diff --git a/src/csharp/Grpc.Core/ChannelOptions.cs b/src/csharp/Grpc.Core/ChannelOptions.cs
index 0cb2953f2c2..ad54b46ad59 100644
--- a/src/csharp/Grpc.Core/ChannelOptions.cs
+++ b/src/csharp/Grpc.Core/ChannelOptions.cs
@@ -71,7 +71,7 @@ namespace Grpc.Core
/// Creates a channel option with an integer value.
///
/// Name.
- /// String value.
+ /// Integer value.
public ChannelOption(string name, int intValue)
{
this.type = OptionType.Integer;
diff --git a/src/csharp/Grpc.Core/ClientBase.cs b/src/csharp/Grpc.Core/ClientBase.cs
index f240d777b9c..7bc100ca603 100644
--- a/src/csharp/Grpc.Core/ClientBase.cs
+++ b/src/csharp/Grpc.Core/ClientBase.cs
@@ -32,15 +32,15 @@
#endregion
using System;
-using System.Collections.Generic;
using System.Text.RegularExpressions;
-
-using Grpc.Core.Internal;
-using Grpc.Core.Utils;
+using System.Threading.Tasks;
namespace Grpc.Core
{
- public delegate void MetadataInterceptorDelegate(string authUri, Metadata metadata);
+ ///
+ /// Interceptor for call headers.
+ ///
+ public delegate void HeaderInterceptor(IMethod method, string authUri, Metadata metadata);
///
/// Base class for client-side stubs.
@@ -60,10 +60,10 @@ namespace Grpc.Core
}
///
- /// Can be used to register a custom header (initial metadata) interceptor.
- /// The delegate each time before a new call on this client is started.
+ /// Can be used to register a custom header (request metadata) interceptor.
+ /// The interceptor is invoked each time a new call on this client is started.
///
- public MetadataInterceptorDelegate HeaderInterceptor
+ public HeaderInterceptor HeaderInterceptor
{
get;
set;
@@ -107,7 +107,7 @@ namespace Grpc.Core
options = options.WithHeaders(new Metadata());
}
var authUri = authUriBase != null ? authUriBase + method.ServiceName : null;
- interceptor(authUri, options.Headers);
+ interceptor(method, authUri, options.Headers);
}
return new CallInvocationDetails(channel, method, Host, options);
}
diff --git a/src/csharp/Grpc.Core/Method.cs b/src/csharp/Grpc.Core/Method.cs
index 4c208b4a263..4c53285893e 100644
--- a/src/csharp/Grpc.Core/Method.cs
+++ b/src/csharp/Grpc.Core/Method.cs
@@ -54,10 +54,37 @@ namespace Grpc.Core
DuplexStreaming
}
+ ///
+ /// A non-generic representation of a remote method.
+ ///
+ public interface IMethod
+ {
+ ///
+ /// Gets the type of the method.
+ ///
+ MethodType Type { get; }
+
+ ///
+ /// Gets the name of the service to which this method belongs.
+ ///
+ string ServiceName { get; }
+
+ ///
+ /// Gets the unqualified name of the method.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the fully qualified name of the method. On the server side, methods are dispatched
+ /// based on this name.
+ ///
+ string FullName { get; }
+ }
+
///
/// A description of a remote method.
///
- public class Method
+ public class Method : IMethod
{
readonly MethodType type;
readonly string serviceName;
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 385ca920862..f4b0a1028f9 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -308,7 +308,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("running service_account_creds");
var credential = await GoogleCredential.GetApplicationDefaultAsync();
credential = credential.CreateScoped(new[] { AuthScope });
- client.HeaderInterceptor = OAuth2Interceptors.FromCredential(credential);
+ client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
var request = SimpleRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
@@ -332,7 +332,7 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("running compute_engine_creds");
var credential = await GoogleCredential.GetApplicationDefaultAsync();
Assert.IsFalse(credential.IsCreateScopedRequired);
- client.HeaderInterceptor = OAuth2Interceptors.FromCredential(credential);
+ client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
var request = SimpleRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
@@ -357,7 +357,7 @@ namespace Grpc.IntegrationTesting
var credential = await GoogleCredential.GetApplicationDefaultAsync();
// check this a credential with scope support, but don't add the scope.
Assert.IsTrue(credential.IsCreateScopedRequired);
- client.HeaderInterceptor = OAuth2Interceptors.FromCredential(credential);
+ client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
var request = SimpleRequest.CreateBuilder()
.SetResponseType(PayloadType.COMPRESSABLE)
@@ -381,7 +381,7 @@ namespace Grpc.IntegrationTesting
ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { AuthScope });
string oauth2Token = await credential.GetAccessTokenForRequestAsync();
- client.HeaderInterceptor = OAuth2Interceptors.FromAccessToken(oauth2Token);
+ client.HeaderInterceptor = AuthInterceptors.FromAccessToken(oauth2Token);
var request = SimpleRequest.CreateBuilder()
.SetFillUsername(true)
@@ -401,7 +401,7 @@ namespace Grpc.IntegrationTesting
ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { AuthScope });
string oauth2Token = await credential.GetAccessTokenForRequestAsync();
- var headerInterceptor = OAuth2Interceptors.FromAccessToken(oauth2Token);
+ var headerInterceptor = AuthInterceptors.FromAccessToken(oauth2Token);
var request = SimpleRequest.CreateBuilder()
.SetFillUsername(true)
@@ -409,7 +409,7 @@ namespace Grpc.IntegrationTesting
.Build();
var headers = new Metadata();
- headerInterceptor("", headers);
+ headerInterceptor(null, "", headers);
var response = client.UnaryCall(request, headers: headers);
Assert.AreEqual(AuthScopeResponse, response.OauthScope);
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index bf2bbd873b0..fc9470f93f1 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -510,22 +510,27 @@ grpcsharp_call_start_unary(grpc_call *call, grpcsharp_batch_context *ctx,
ops[0].data.send_initial_metadata.metadata =
ctx->send_initial_metadata.metadata;
ops[0].flags = 0;
+ ops[0].reserved = NULL;
ops[1].op = GRPC_OP_SEND_MESSAGE;
ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
ops[1].data.send_message = ctx->send_message;
ops[1].flags = write_flags;
+ ops[1].reserved = NULL;
ops[2].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
ops[2].flags = 0;
+ ops[2].reserved = NULL;
ops[3].op = GRPC_OP_RECV_INITIAL_METADATA;
ops[3].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
ops[3].flags = 0;
+ ops[3].reserved = NULL;
ops[4].op = GRPC_OP_RECV_MESSAGE;
ops[4].data.recv_message = &(ctx->recv_message);
ops[4].flags = 0;
+ ops[4].reserved = NULL;
ops[5].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
ops[5].data.recv_status_on_client.trailing_metadata =
@@ -538,6 +543,7 @@ grpcsharp_call_start_unary(grpc_call *call, grpcsharp_batch_context *ctx,
ops[5].data.recv_status_on_client.status_details_capacity =
&(ctx->recv_status_on_client.status_details_capacity);
ops[5].flags = 0;
+ ops[5].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
@@ -556,14 +562,17 @@ grpcsharp_call_start_client_streaming(grpc_call *call,
ops[0].data.send_initial_metadata.metadata =
ctx->send_initial_metadata.metadata;
ops[0].flags = 0;
+ ops[0].reserved = NULL;
ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
ops[1].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
ops[1].flags = 0;
+ ops[1].reserved = NULL;
ops[2].op = GRPC_OP_RECV_MESSAGE;
ops[2].data.recv_message = &(ctx->recv_message);
ops[2].flags = 0;
+ ops[2].reserved = NULL;
ops[3].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
ops[3].data.recv_status_on_client.trailing_metadata =
@@ -576,6 +585,7 @@ grpcsharp_call_start_client_streaming(grpc_call *call,
ops[3].data.recv_status_on_client.status_details_capacity =
&(ctx->recv_status_on_client.status_details_capacity);
ops[3].flags = 0;
+ ops[3].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
@@ -593,18 +603,22 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
ops[0].data.send_initial_metadata.metadata =
ctx->send_initial_metadata.metadata;
ops[0].flags = 0;
+ ops[0].reserved = NULL;
ops[1].op = GRPC_OP_SEND_MESSAGE;
ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
ops[1].data.send_message = ctx->send_message;
ops[1].flags = write_flags;
+ ops[1].reserved = NULL;
ops[2].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
ops[2].flags = 0;
+ ops[2].reserved = NULL;
ops[3].op = GRPC_OP_RECV_INITIAL_METADATA;
ops[3].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
ops[3].flags = 0;
+ ops[3].reserved = NULL;
ops[4].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
ops[4].data.recv_status_on_client.trailing_metadata =
@@ -617,6 +631,7 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
ops[4].data.recv_status_on_client.status_details_capacity =
&(ctx->recv_status_on_client.status_details_capacity);
ops[4].flags = 0;
+ ops[4].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
@@ -635,10 +650,12 @@ grpcsharp_call_start_duplex_streaming(grpc_call *call,
ops[0].data.send_initial_metadata.metadata =
ctx->send_initial_metadata.metadata;
ops[0].flags = 0;
+ ops[0].reserved = NULL;
ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
ops[1].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
ops[1].flags = 0;
+ ops[1].reserved = NULL;
ops[2].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
ops[2].data.recv_status_on_client.trailing_metadata =
@@ -651,6 +668,7 @@ grpcsharp_call_start_duplex_streaming(grpc_call *call,
ops[2].data.recv_status_on_client.status_details_capacity =
&(ctx->recv_status_on_client.status_details_capacity);
ops[2].flags = 0;
+ ops[2].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
@@ -668,10 +686,12 @@ grpcsharp_call_send_message(grpc_call *call, grpcsharp_batch_context *ctx,
ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
ops[0].data.send_message = ctx->send_message;
ops[0].flags = write_flags;
+ 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;
return grpc_call_start_batch(call, ops, nops, ctx, NULL);
}
@@ -683,6 +703,7 @@ grpcsharp_call_send_close_from_client(grpc_call *call,
grpc_op ops[1];
ops[0].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
ops[0].flags = 0;
+ ops[0].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
@@ -706,10 +727,12 @@ GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server(
ops[0].data.send_status_from_server.trailing_metadata =
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;
return grpc_call_start_batch(call, ops, nops, ctx, NULL);
}
@@ -721,6 +744,7 @@ grpcsharp_call_recv_message(grpc_call *call, grpcsharp_batch_context *ctx) {
ops[0].op = GRPC_OP_RECV_MESSAGE;
ops[0].data.recv_message = &(ctx->recv_message);
ops[0].flags = 0;
+ ops[0].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
}
@@ -733,6 +757,7 @@ grpcsharp_call_start_serverside(grpc_call *call, grpcsharp_batch_context *ctx) {
ops[0].data.recv_close_on_server.cancelled =
(&ctx->recv_close_on_server_cancelled);
ops[0].flags = 0;
+ ops[0].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
@@ -751,6 +776,7 @@ grpcsharp_call_send_initial_metadata(grpc_call *call,
ops[0].data.send_initial_metadata.metadata =
ctx->send_initial_metadata.metadata;
ops[0].flags = 0;
+ ops[0].reserved = NULL;
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
NULL);
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index 705c80ffc1d..18858fa334a 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -207,6 +207,13 @@ class SendMessageOp : public Op {
if (!::node::Buffer::HasInstance(value)) {
return false;
}
+ Handle