SecurityChannel.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. //----------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Security
  5. {
  6. using System.Runtime;
  7. using System.ServiceModel.Channels;
  8. abstract class SecurityChannel<TChannel> :
  9. LayeredChannel<TChannel>
  10. where TChannel : class, IChannel
  11. {
  12. SecurityProtocol securityProtocol;
  13. protected SecurityChannel(ChannelManagerBase channelManager, TChannel innerChannel)
  14. : this(channelManager, innerChannel, null)
  15. {
  16. }
  17. protected SecurityChannel(ChannelManagerBase channelManager, TChannel innerChannel, SecurityProtocol securityProtocol)
  18. : base(channelManager, innerChannel)
  19. {
  20. this.securityProtocol = securityProtocol;
  21. }
  22. public override T GetProperty<T>()
  23. {
  24. if (typeof(T) == typeof(FaultConverter))
  25. {
  26. return new SecurityChannelFaultConverter(this.InnerChannel) as T;
  27. }
  28. return base.GetProperty<T>();
  29. }
  30. public SecurityProtocol SecurityProtocol
  31. {
  32. get
  33. {
  34. return this.securityProtocol;
  35. }
  36. protected set
  37. {
  38. if (value == null)
  39. {
  40. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
  41. }
  42. this.securityProtocol = value;
  43. }
  44. }
  45. protected override void OnAbort()
  46. {
  47. if (this.securityProtocol != null)
  48. {
  49. this.securityProtocol.Close(true, TimeSpan.Zero);
  50. }
  51. base.OnAbort();
  52. }
  53. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  54. {
  55. return new ChainedAsyncResult(timeout, callback, state, this.BeginCloseSecurityProtocol, this.EndCloseSecurityProtocol,
  56. base.OnBeginClose, base.OnEndClose);
  57. }
  58. protected override void OnEndClose(IAsyncResult result)
  59. {
  60. ChainedAsyncResult.End(result);
  61. }
  62. IAsyncResult BeginCloseSecurityProtocol(TimeSpan timeout, AsyncCallback callback, object state)
  63. {
  64. if (this.securityProtocol != null)
  65. {
  66. return this.securityProtocol.BeginClose(timeout, callback, state);
  67. }
  68. else
  69. {
  70. return new NullSecurityProtocolCloseAsyncResult(callback, state);
  71. }
  72. }
  73. void EndCloseSecurityProtocol(IAsyncResult result)
  74. {
  75. if (result is NullSecurityProtocolCloseAsyncResult)
  76. {
  77. NullSecurityProtocolCloseAsyncResult.End(result);
  78. }
  79. else
  80. {
  81. this.securityProtocol.EndClose(result);
  82. }
  83. }
  84. protected override void OnClose(TimeSpan timeout)
  85. {
  86. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  87. if (this.securityProtocol != null)
  88. {
  89. this.securityProtocol.Close(false, timeoutHelper.RemainingTime());
  90. }
  91. base.OnClose(timeoutHelper.RemainingTime());
  92. }
  93. protected void ThrowIfDisposedOrNotOpen(Message message)
  94. {
  95. ThrowIfDisposedOrNotOpen();
  96. if (message == null)
  97. {
  98. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
  99. }
  100. }
  101. class NullSecurityProtocolCloseAsyncResult : CompletedAsyncResult
  102. {
  103. public NullSecurityProtocolCloseAsyncResult(AsyncCallback callback, object state)
  104. : base(callback, state)
  105. {
  106. }
  107. new public static void End(IAsyncResult result)
  108. {
  109. AsyncResult.End<NullSecurityProtocolCloseAsyncResult>(result);
  110. }
  111. }
  112. protected sealed class OutputChannelSendAsyncResult : ApplySecurityAndSendAsyncResult<IOutputChannel>
  113. {
  114. public OutputChannelSendAsyncResult(Message message, SecurityProtocol binding, IOutputChannel channel, TimeSpan timeout,
  115. AsyncCallback callback, object state)
  116. : base(binding, channel, timeout, callback, state)
  117. {
  118. this.Begin(message, null);
  119. }
  120. protected override IAsyncResult BeginSendCore(IOutputChannel channel, Message message, TimeSpan timeout, AsyncCallback callback, object state)
  121. {
  122. return channel.BeginSend(message, timeout, callback, state);
  123. }
  124. internal static void End(IAsyncResult result)
  125. {
  126. OutputChannelSendAsyncResult self = result as OutputChannelSendAsyncResult;
  127. OnEnd(self);
  128. }
  129. protected override void EndSendCore(IOutputChannel channel, IAsyncResult result)
  130. {
  131. channel.EndSend(result);
  132. }
  133. protected override void OnSendCompleteCore(TimeSpan timeout)
  134. {
  135. }
  136. }
  137. }
  138. }