allow utf8 encoded status message

pull/9390/head
Jan Tattermusch 8 years ago
parent 2e5e5f661c
commit 603249229a
  1. 11
      src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
  2. 5
      src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
  3. 2
      src/csharp/Grpc.Core/Internal/NativeMethods.cs
  4. 5
      src/csharp/ext/grpc_csharp_ext.c

@ -33,6 +33,7 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using Grpc.Core;
namespace Grpc.Core.Internal
@ -42,6 +43,7 @@ namespace Grpc.Core.Internal
/// </summary>
internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid
{
static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8;
static readonly NativeMethods Native = NativeMethods.Get();
private BatchContextSafeHandle()
@ -73,7 +75,7 @@ namespace Grpc.Core.Internal
{
UIntPtr detailsLength;
IntPtr detailsPtr = Native.grpcsharp_batch_context_recv_status_on_client_details(this, out detailsLength);
string details = Marshal.PtrToStringAnsi(detailsPtr, (int) detailsLength.ToUInt32());
string details = PtrToStringUtf8(detailsPtr, (int) detailsLength.ToUInt32());
var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details);
IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
@ -106,5 +108,12 @@ namespace Grpc.Core.Internal
Native.grpcsharp_batch_context_destroy(handle);
return true;
}
string PtrToStringUtf8(IntPtr ptr, int len)
{
var bytes = new byte[len];
Marshal.Copy(ptr, bytes, 0, len);
return EncodingUTF8.GetString(bytes);
}
}
}

@ -32,6 +32,7 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Grpc.Core;
using Grpc.Core.Utils;
using Grpc.Core.Profiling;
@ -44,6 +45,7 @@ namespace Grpc.Core.Internal
internal class CallSafeHandle : SafeHandleZeroIsInvalid, INativeCall
{
public static readonly CallSafeHandle NullInstance = new CallSafeHandle();
static readonly Encoding EncodingUTF8 = System.Text.Encoding.UTF8;
static readonly NativeMethods Native = NativeMethods.Get();
const uint GRPC_WRITE_BUFFER_HINT = 1;
@ -138,7 +140,8 @@ namespace Grpc.Core.Internal
var ctx = BatchContextSafeHandle.Create();
var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero;
completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, status.Detail, metadataArray, sendEmptyInitialMetadata,
var statusDetailBytes = EncodingUTF8.GetBytes(status.Detail);
Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, statusDetailBytes, new UIntPtr((ulong)statusDetailBytes.Length), metadataArray, sendEmptyInitialMetadata,
optionalPayload, optionalPayloadLength, writeFlags).CheckOk();
}
}

@ -336,7 +336,7 @@ namespace Grpc.Core.Internal
public delegate CallError grpcsharp_call_send_close_from_client_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx);
public delegate CallError grpcsharp_call_send_status_from_server_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
BatchContextSafeHandle ctx, StatusCode statusCode, byte[] statusMessage, UIntPtr statusMessageLen, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata,
byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags);
public delegate CallError grpcsharp_call_recv_message_delegate(CallSafeHandle call,
BatchContextSafeHandle ctx);

@ -734,14 +734,15 @@ grpcsharp_call_send_close_from_client(grpc_call *call,
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,
const char *status_details, size_t status_details_len,
grpc_metadata_array *trailing_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[3];
memset(ops, 0, sizeof(ops));
size_t nops = 1;
grpc_slice status_details_slice = grpc_slice_from_copied_string(status_details);
grpc_slice status_details_slice = grpc_slice_from_copied_buffer(status_details, status_details_len);
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 = &status_details_slice;

Loading…
Cancel
Save