You've already forked linux-packaging-mono
							
							
		
			
	
	
		
			343 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			343 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|   | //---------------------------------------------------------------------------- | ||
|  | // Copyright (c) Microsoft Corporation.  All rights reserved. | ||
|  | //---------------------------------------------------------------------------- | ||
|  | namespace System.ServiceModel.Channels | ||
|  | { | ||
|  |     using System.Collections.Generic; | ||
|  |     using System.Runtime; | ||
|  |     using System.ServiceModel; | ||
|  |     using System.ServiceModel.Description; | ||
|  |     using System.ServiceModel.Security; | ||
|  |     using SR = System.ServiceModel.SR; | ||
|  | 
 | ||
|  |     sealed class TransactionChannelFactory<TChannel> : LayeredChannelFactory<TChannel>, ITransactionChannelManager | ||
|  |     { | ||
|  |         TransactionFlowOption flowIssuedTokens; | ||
|  |         SecurityStandardsManager standardsManager; | ||
|  |         Dictionary<DirectionalAction, TransactionFlowOption> dictionary; | ||
|  |         TransactionProtocol transactionProtocol; | ||
|  |         bool allowWildcardAction; | ||
|  | 
 | ||
|  |         public TransactionChannelFactory( | ||
|  |             TransactionProtocol transactionProtocol, | ||
|  |             BindingContext context, | ||
|  |             Dictionary<DirectionalAction, TransactionFlowOption> dictionary, | ||
|  |             bool allowWildcardAction) | ||
|  |             : base(context.Binding, context.BuildInnerChannelFactory<TChannel>()) | ||
|  |         { | ||
|  |             this.dictionary = dictionary; | ||
|  |             this.TransactionProtocol = transactionProtocol; | ||
|  |             this.allowWildcardAction = allowWildcardAction; | ||
|  |             this.standardsManager = SecurityStandardsHelper.CreateStandardsManager(this.TransactionProtocol); | ||
|  |         } | ||
|  | 
 | ||
|  |         public TransactionProtocol TransactionProtocol | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return this.transactionProtocol; | ||
|  |             } | ||
|  |             set | ||
|  |             { | ||
|  |                 if (!TransactionProtocol.IsDefined(value)) | ||
|  |                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( | ||
|  |                         new ArgumentException(SR.GetString(SR.SFxBadTransactionProtocols))); | ||
|  |                 this.transactionProtocol = value; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public TransactionFlowOption FlowIssuedTokens | ||
|  |         { | ||
|  |             get { return this.flowIssuedTokens; } | ||
|  |             set { this.flowIssuedTokens = value; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public SecurityStandardsManager StandardsManager | ||
|  |         { | ||
|  |             get { return this.standardsManager; } | ||
|  |             set | ||
|  |             { | ||
|  |                 this.standardsManager = (value != null ? value : SecurityStandardsHelper.CreateStandardsManager(this.transactionProtocol)); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public IDictionary<DirectionalAction, TransactionFlowOption> Dictionary | ||
|  |         { | ||
|  |             get { return this.dictionary; } | ||
|  |         } | ||
|  | 
 | ||
|  |         public TransactionFlowOption GetTransaction(MessageDirection direction, string action) | ||
|  |         { | ||
|  |             TransactionFlowOption txOption; | ||
|  |             if (!dictionary.TryGetValue(new DirectionalAction(direction, action), out txOption)) | ||
|  |             { | ||
|  |                 //Fixinng this for clients that opted in for lesser validation before flowing out a transaction | ||
|  |                 if (this.allowWildcardAction && dictionary.TryGetValue(new DirectionalAction(direction, MessageHeaders.WildcardAction), out txOption)) | ||
|  |                 { | ||
|  |                     return txOption; | ||
|  |                 } | ||
|  |                 else | ||
|  |                     return TransactionFlowOption.NotAllowed; | ||
|  |             } | ||
|  | 
 | ||
|  |             else | ||
|  |                 return txOption; | ||
|  |         } | ||
|  | 
 | ||
|  |         protected override TChannel OnCreateChannel(EndpointAddress remoteAddress, Uri via) | ||
|  |         { | ||
|  |             TChannel innerChannel = ((IChannelFactory<TChannel>)InnerChannelFactory).CreateChannel(remoteAddress, via); | ||
|  |             return CreateTransactionChannel(innerChannel); | ||
|  |         } | ||
|  | 
 | ||
|  |         TChannel CreateTransactionChannel(TChannel innerChannel) | ||
|  |         { | ||
|  |             if (typeof(TChannel) == typeof(IDuplexSessionChannel)) | ||
|  |             { | ||
|  |                 return (TChannel)(object)new TransactionDuplexSessionChannel(this, (IDuplexSessionChannel)(object)innerChannel); | ||
|  |             } | ||
|  |             else if (typeof(TChannel) == typeof(IRequestSessionChannel)) | ||
|  |             { | ||
|  |                 return (TChannel)(object)new TransactionRequestSessionChannel(this, (IRequestSessionChannel)(object)innerChannel); | ||
|  |             } | ||
|  |             else if (typeof(TChannel) == typeof(IOutputSessionChannel)) | ||
|  |             { | ||
|  |                 return (TChannel)(object)new TransactionOutputSessionChannel(this, (IOutputSessionChannel)(object)innerChannel); | ||
|  |             } | ||
|  |             else if (typeof(TChannel) == typeof(IOutputChannel)) | ||
|  |             { | ||
|  |                 return (TChannel)(object)new TransactionOutputChannel(this, (IOutputChannel)(object)innerChannel); | ||
|  |             } | ||
|  |             else if (typeof(TChannel) == typeof(IRequestChannel)) | ||
|  |             { | ||
|  |                 return (TChannel)(object)new TransactionRequestChannel(this, (IRequestChannel)(object)innerChannel); | ||
|  |             } | ||
|  |             else if (typeof(TChannel) == typeof(IDuplexChannel)) | ||
|  |             { | ||
|  |                 return (TChannel)(object)new TransactionDuplexChannel(this, (IDuplexChannel)(object)innerChannel); | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateChannelTypeNotSupportedException(typeof(TChannel))); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         //=========================================================== | ||
|  |         //                Transaction Output Channel classes | ||
|  |         //=========================================================== | ||
|  | 
 | ||
|  |         sealed class TransactionOutputChannel : TransactionOutputChannelGeneric<IOutputChannel> | ||
|  |         { | ||
|  |             public TransactionOutputChannel(ChannelManagerBase channelManager, IOutputChannel innerChannel) | ||
|  |                 : base(channelManager, innerChannel) | ||
|  |             { | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         sealed class TransactionRequestChannel : TransactionRequestChannelGeneric<IRequestChannel> | ||
|  |         { | ||
|  |             public TransactionRequestChannel(ChannelManagerBase channelManager, IRequestChannel innerChannel) | ||
|  |                 : base(channelManager, innerChannel) | ||
|  |             { | ||
|  |             } | ||
|  | 
 | ||
|  |         } | ||
|  | 
 | ||
|  |         sealed class TransactionDuplexChannel : TransactionOutputDuplexChannelGeneric<IDuplexChannel> | ||
|  |         { | ||
|  |             public TransactionDuplexChannel(ChannelManagerBase channelManager, IDuplexChannel innerChannel) | ||
|  |                 : base(channelManager, innerChannel) | ||
|  |             { | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         sealed class TransactionOutputSessionChannel : TransactionOutputChannelGeneric<IOutputSessionChannel>, IOutputSessionChannel | ||
|  |         { | ||
|  |             public TransactionOutputSessionChannel(ChannelManagerBase channelManager, IOutputSessionChannel innerChannel) | ||
|  |                 : base(channelManager, innerChannel) | ||
|  |             { | ||
|  |             } | ||
|  | 
 | ||
|  |             public IOutputSession Session { get { return InnerChannel.Session; } } | ||
|  | 
 | ||
|  |         } | ||
|  | 
 | ||
|  |         sealed class TransactionRequestSessionChannel : TransactionRequestChannelGeneric<IRequestSessionChannel>, IRequestSessionChannel | ||
|  |         { | ||
|  |             public TransactionRequestSessionChannel(ChannelManagerBase channelManager, IRequestSessionChannel innerChannel) | ||
|  |                 : base(channelManager, innerChannel) | ||
|  |             { | ||
|  |             } | ||
|  | 
 | ||
|  |             public IOutputSession Session { get { return InnerChannel.Session; } } | ||
|  | 
 | ||
|  |         } | ||
|  | 
 | ||
|  |         sealed class TransactionDuplexSessionChannel : TransactionOutputDuplexChannelGeneric<IDuplexSessionChannel>, IDuplexSessionChannel | ||
|  |         { | ||
|  |             public TransactionDuplexSessionChannel(ChannelManagerBase channelManager, IDuplexSessionChannel innerChannel) | ||
|  |                 : base(channelManager, innerChannel) | ||
|  |             { | ||
|  |             } | ||
|  | 
 | ||
|  |             public IDuplexSession Session { get { return InnerChannel.Session; } } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     static class SecurityStandardsHelper | ||
|  |     { | ||
|  |         static SecurityStandardsManager SecurityStandardsManager2007 = | ||
|  |             CreateStandardsManager(MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12); | ||
|  | 
 | ||
|  |         static SecurityStandardsManager CreateStandardsManager(MessageSecurityVersion securityVersion) | ||
|  |         { | ||
|  |             return new SecurityStandardsManager( | ||
|  |                 securityVersion, | ||
|  |                 new WSSecurityTokenSerializer(securityVersion.SecurityVersion, securityVersion.TrustVersion, securityVersion.SecureConversationVersion, false, null, null, null)); | ||
|  |         } | ||
|  | 
 | ||
|  |         public static SecurityStandardsManager CreateStandardsManager(TransactionProtocol transactionProtocol) | ||
|  |         { | ||
|  |             if (transactionProtocol == TransactionProtocol.WSAtomicTransactionOctober2004 || | ||
|  |                 transactionProtocol == TransactionProtocol.OleTransactions) | ||
|  |             { | ||
|  |                 return SecurityStandardsManager.DefaultInstance; | ||
|  |             } | ||
|  |             else | ||
|  |             { | ||
|  |                 return SecurityStandardsHelper.SecurityStandardsManager2007; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     //============================================================== | ||
|  |     //                Transaction channel base generic classes | ||
|  |     //============================================================== | ||
|  | 
 | ||
|  |     class TransactionOutputChannelGeneric<TChannel> : TransactionChannel<TChannel>, IOutputChannel | ||
|  |         where TChannel : class, IOutputChannel | ||
|  |     { | ||
|  |         public TransactionOutputChannelGeneric(ChannelManagerBase channelManager, TChannel innerChannel) | ||
|  |             : base(channelManager, innerChannel) | ||
|  |         { | ||
|  |         } | ||
|  | 
 | ||
|  |         public EndpointAddress RemoteAddress | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return InnerChannel.RemoteAddress; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public Uri Via | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return InnerChannel.Via; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state) | ||
|  |         { | ||
|  |             return this.BeginSend(message, this.DefaultSendTimeout, callback, state); | ||
|  |         } | ||
|  | 
 | ||
|  |         public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback asyncCallback, object state) | ||
|  |         { | ||
|  |             TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); | ||
|  |             WriteTransactionDataToMessage(message, MessageDirection.Input); | ||
|  |             return InnerChannel.BeginSend(message, timeoutHelper.RemainingTime(), asyncCallback, state); | ||
|  | 
 | ||
|  |         } | ||
|  | 
 | ||
|  |         public void EndSend(IAsyncResult result) | ||
|  |         { | ||
|  |             InnerChannel.EndSend(result); | ||
|  |         } | ||
|  | 
 | ||
|  |         public void Send(Message message) | ||
|  |         { | ||
|  |             this.Send(message, this.DefaultSendTimeout); | ||
|  |         } | ||
|  | 
 | ||
|  |         public void Send(Message message, TimeSpan timeout) | ||
|  |         { | ||
|  |             TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); | ||
|  |             WriteTransactionDataToMessage(message, MessageDirection.Input); | ||
|  |             InnerChannel.Send(message, timeoutHelper.RemainingTime()); | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  |     class TransactionRequestChannelGeneric<TChannel> : TransactionChannel<TChannel>, IRequestChannel | ||
|  |         where TChannel : class, IRequestChannel | ||
|  |     { | ||
|  |         public TransactionRequestChannelGeneric(ChannelManagerBase channelManager, TChannel innerChannel) | ||
|  |             : base(channelManager, innerChannel) | ||
|  |         { | ||
|  |         } | ||
|  | 
 | ||
|  |         public EndpointAddress RemoteAddress | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return InnerChannel.RemoteAddress; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public Uri Via | ||
|  |         { | ||
|  |             get | ||
|  |             { | ||
|  |                 return InnerChannel.Via; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state) | ||
|  |         { | ||
|  |             return this.BeginRequest(message, this.DefaultSendTimeout, callback, state); | ||
|  |         } | ||
|  | 
 | ||
|  |         public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback asyncCallback, object state) | ||
|  |         { | ||
|  |             TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); | ||
|  |             WriteTransactionDataToMessage(message, MessageDirection.Input); | ||
|  |             return InnerChannel.BeginRequest(message, timeoutHelper.RemainingTime(), asyncCallback, state); | ||
|  |         } | ||
|  | 
 | ||
|  |         public Message EndRequest(IAsyncResult result) | ||
|  |         { | ||
|  |             Message reply = InnerChannel.EndRequest(result); | ||
|  |             if (reply != null) | ||
|  |                 this.ReadIssuedTokens(reply, MessageDirection.Output); | ||
|  |             return reply; | ||
|  |         } | ||
|  | 
 | ||
|  |         public Message Request(Message message) | ||
|  |         { | ||
|  |             return this.Request(message, this.DefaultSendTimeout); | ||
|  |         } | ||
|  | 
 | ||
|  |         public Message Request(Message message, TimeSpan timeout) | ||
|  |         { | ||
|  |             TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); | ||
|  |             WriteTransactionDataToMessage(message, MessageDirection.Input); | ||
|  |             Message reply = InnerChannel.Request(message, timeoutHelper.RemainingTime()); | ||
|  |             if (reply != null) | ||
|  |                 this.ReadIssuedTokens(reply, MessageDirection.Output); | ||
|  |             return reply; | ||
|  |         } | ||
|  |     } | ||
|  | 
 | ||
|  |     class TransactionOutputDuplexChannelGeneric<TChannel> : TransactionDuplexChannelGeneric<TChannel> | ||
|  |         where TChannel : class, IDuplexChannel | ||
|  |     { | ||
|  |         public TransactionOutputDuplexChannelGeneric(ChannelManagerBase channelManager, TChannel innerChannel) | ||
|  |             : base(channelManager, innerChannel, MessageDirection.Output) | ||
|  |         { | ||
|  |         } | ||
|  |     } | ||
|  | } |