1 #region Copyright notice and license 2 3 // Copyright 2017 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #endregion 18 19 using System; 20 using System.Collections.Generic; 21 using System.Runtime.InteropServices; 22 using System.Text; 23 using Grpc.Core; 24 using Grpc.Core.Utils; 25 26 namespace Grpc.Core.Internal 27 { 28 /// <summary> 29 /// grpc_auth_context 30 /// </summary> 31 internal class AuthContextSafeHandle : SafeHandleZeroIsInvalid 32 { 33 static readonly NativeMethods Native = NativeMethods.Get(); 34 AuthContextSafeHandle()35 private AuthContextSafeHandle() 36 { 37 } 38 39 /// <summary> 40 /// Copies contents of the native auth context into a new <c>AuthContext</c> instance. 41 /// </summary> ToAuthContext()42 public AuthContext ToAuthContext() 43 { 44 if (IsInvalid) 45 { 46 return new AuthContext(null, new Dictionary<string, List<AuthProperty>>()); 47 } 48 49 var peerIdentityPropertyName = Marshal.PtrToStringAnsi(Native.grpcsharp_auth_context_peer_identity_property_name(this)); 50 51 var propertiesDict = new Dictionary<string, List<AuthProperty>>(); 52 53 var it = Native.grpcsharp_auth_context_property_iterator(this); 54 IntPtr authPropertyPtr = IntPtr.Zero; 55 while ((authPropertyPtr = Native.grpcsharp_auth_property_iterator_next(ref it)) != IntPtr.Zero) 56 { 57 var authProperty = PtrToAuthProperty(authPropertyPtr); 58 59 if (!propertiesDict.ContainsKey(authProperty.Name)) 60 { 61 propertiesDict[authProperty.Name] = new List<AuthProperty>(); 62 } 63 propertiesDict[authProperty.Name].Add(authProperty); 64 } 65 66 return new AuthContext(peerIdentityPropertyName, propertiesDict); 67 } 68 ReleaseHandle()69 protected override bool ReleaseHandle() 70 { 71 Native.grpcsharp_auth_context_release(handle); 72 return true; 73 } 74 PtrToAuthProperty(IntPtr authPropertyPtr)75 private AuthProperty PtrToAuthProperty(IntPtr authPropertyPtr) 76 { 77 #pragma warning disable 0618 78 // We need to use the obsolete non-generic version of Marshal.PtrToStructure, because the generic version is not available in net45 79 var nativeAuthProperty = (NativeAuthProperty) Marshal.PtrToStructure(authPropertyPtr, typeof(NativeAuthProperty)); 80 #pragma warning restore 0618 81 var name = Marshal.PtrToStringAnsi(nativeAuthProperty.Name); 82 var valueBytes = new byte[(int) nativeAuthProperty.ValueLength]; 83 Marshal.Copy(nativeAuthProperty.Value, valueBytes, 0, (int)nativeAuthProperty.ValueLength); 84 return AuthProperty.CreateUnsafe(name, valueBytes); 85 } 86 87 /// <summary> 88 /// grpc_auth_property 89 /// </summary> 90 internal struct NativeAuthProperty 91 { 92 public IntPtr Name; 93 public IntPtr Value; 94 public UIntPtr ValueLength; 95 } 96 97 /// <summary> 98 /// grpc_auth_property_iterator 99 /// </summary> 100 internal struct NativeAuthPropertyIterator 101 { 102 public IntPtr AuthContext; 103 public UIntPtr Index; 104 public IntPtr Name; 105 } 106 } 107 } 108