Imported Upstream version 4.6.0.125

Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-08-03 10:59:49 +00:00
parent a569aebcfd
commit e79aa3c0ed
17047 changed files with 3137615 additions and 392334 deletions

View File

@ -0,0 +1,378 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Channels
{
using System;
using System.Runtime;
using System.ServiceModel.Routing;
using System.Collections.Generic;
using System.Security.Principal;
using SR2 = System.ServiceModel.SR;
class SynchronousSendBindingElement : BindingElement
{
public override BindingElement Clone()
{
return new SynchronousSendBindingElement();
}
public override T GetProperty<T>(BindingContext context)
{
if (context == null)
{
throw FxTrace.Exception.ArgumentNull("context");
}
return context.GetInnerProperty<T>();
}
public override bool CanBuildChannelFactory<TChannel>(BindingContext context)
{
if (context == null)
{
throw FxTrace.Exception.ArgumentNull("context");
}
Type typeofTChannel = typeof(TChannel);
if (typeofTChannel == typeof(IDuplexChannel) ||
typeofTChannel == typeof(IDuplexSessionChannel) ||
typeofTChannel == typeof(IRequestChannel) ||
typeofTChannel == typeof(IRequestSessionChannel) ||
typeofTChannel == typeof(IOutputChannel) ||
typeofTChannel == typeof(IOutputSessionChannel))
{
return context.CanBuildInnerChannelFactory<TChannel>();
}
return false;
}
public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
{
if (context == null)
{
throw FxTrace.Exception.ArgumentNull("context");
}
if (!this.CanBuildChannelFactory<TChannel>(context.Clone()))
{
throw FxTrace.Exception.Argument("TChannel", SR2.GetString(SR2.ChannelTypeNotSupported, typeof(TChannel)));
}
IChannelFactory<TChannel> innerFactory = context.BuildInnerChannelFactory<TChannel>();
if (innerFactory != null)
{
return new SynchronousChannelFactory<TChannel>(context.Binding, innerFactory);
}
return null;
}
class SynchronousChannelFactory<TChannel> : LayeredChannelFactory<TChannel>
{
public SynchronousChannelFactory(IDefaultCommunicationTimeouts timeouts, IChannelFactory<TChannel> innerFactory)
: base(timeouts, innerFactory)
{
}
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
{
this.InnerChannelFactory.Open(timeout);
return new CompletedAsyncResult(callback, state);
}
protected override void OnEndOpen(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
protected override TChannel OnCreateChannel(EndpointAddress address, Uri via)
{
IChannelFactory<TChannel> factory = (IChannelFactory<TChannel>)this.InnerChannelFactory;
TChannel channel = factory.CreateChannel(address, via);
if (channel != null)
{
Type channelType = typeof(TChannel);
if (channelType == typeof(IDuplexSessionChannel))
{
channel = (TChannel)(object)new SynchronousDuplexSessionChannel(this, (IDuplexSessionChannel)channel);
}
else if (channelType == typeof(IRequestChannel))
{
channel = (TChannel)(object)new SynchronousRequestChannel(this, (IRequestChannel)channel);
}
else if (channelType == typeof(IRequestSessionChannel))
{
channel = (TChannel)(object)new SynchronousRequestSessionChannel(this, (IRequestSessionChannel)channel);
}
else if (channelType == typeof(IOutputChannel))
{
channel = (TChannel)(object)new SynchronousOutputChannel(this, (IOutputChannel)channel);
}
else if (channelType == typeof(IOutputSessionChannel))
{
channel = (TChannel)(object)new SynchronousOutputSessionChannel(this, (IOutputSessionChannel)channel);
}
else if (channelType == typeof(IDuplexChannel))
{
channel = (TChannel)(object)new SynchronousDuplexChannel(this, (IDuplexChannel)channel);
}
else
{
throw FxTrace.Exception.AsError(base.CreateChannelTypeNotSupportedException(typeof(TChannel)));
}
}
return channel;
}
}
abstract class SynchronousChannelBase<TChannel> : LayeredChannel<TChannel>
where TChannel : class, IChannel
{
protected SynchronousChannelBase(ChannelManagerBase manager, TChannel innerChannel)
: base(manager, innerChannel)
{
}
protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
{
this.InnerChannel.Open(timeout);
return new CompletedAsyncResult(callback, state);
}
protected override void OnEndOpen(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
}
class SynchronousDuplexChannelBase<TChannel> : SynchronousOutputChannelBase<TChannel>
where TChannel : class, IDuplexChannel
{
public SynchronousDuplexChannelBase(ChannelManagerBase manager, TChannel innerChannel)
: base(manager, innerChannel)
{
}
public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state)
{
return this.InnerChannel.BeginReceive(timeout, callback, state);
}
public IAsyncResult BeginReceive(AsyncCallback callback, object state)
{
return this.InnerChannel.BeginReceive(callback, state);
}
public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state)
{
return this.InnerChannel.BeginTryReceive(timeout, callback, state);
}
public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state)
{
return this.InnerChannel.BeginWaitForMessage(timeout, callback, state);
}
public Message EndReceive(IAsyncResult result)
{
return this.InnerChannel.EndReceive(result);
}
public bool EndTryReceive(IAsyncResult result, out Message message)
{
return this.InnerChannel.EndTryReceive(result, out message);
}
public bool EndWaitForMessage(IAsyncResult result)
{
return this.InnerChannel.EndWaitForMessage(result);
}
public EndpointAddress LocalAddress
{
get { return this.InnerChannel.LocalAddress; }
}
public Message Receive(TimeSpan timeout)
{
return this.InnerChannel.Receive(timeout);
}
public Message Receive()
{
return this.InnerChannel.Receive();
}
public bool TryReceive(TimeSpan timeout, out Message message)
{
return this.InnerChannel.TryReceive(timeout, out message);
}
public bool WaitForMessage(TimeSpan timeout)
{
return this.InnerChannel.WaitForMessage(timeout);
}
}
class SynchronousDuplexChannel : SynchronousDuplexChannelBase<IDuplexChannel>, IDuplexChannel
{
public SynchronousDuplexChannel(ChannelManagerBase manager, IDuplexChannel innerChannel)
: base(manager, innerChannel)
{
}
}
class SynchronousDuplexSessionChannel : SynchronousDuplexChannelBase<IDuplexSessionChannel>, IDuplexSessionChannel
{
public SynchronousDuplexSessionChannel(ChannelManagerBase manager, IDuplexSessionChannel innerChannel)
: base(manager, innerChannel)
{
}
IDuplexSession ISessionChannel<IDuplexSession>.Session
{
get { return this.InnerChannel.Session; }
}
}
abstract class SynchronousOutputChannelBase<TChannel> : SynchronousChannelBase<TChannel>
where TChannel : class, IOutputChannel
{
public SynchronousOutputChannelBase(ChannelManagerBase manager, TChannel innerChannel)
: base(manager, innerChannel)
{
}
public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
this.InnerChannel.Send(message, timeout);
return new CompletedAsyncResult(callback, state);
}
public IAsyncResult BeginSend(Message message, AsyncCallback callback, object state)
{
this.InnerChannel.Send(message);
return new CompletedAsyncResult(callback, state);
}
public void EndSend(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
public EndpointAddress RemoteAddress
{
get { return this.InnerChannel.RemoteAddress; }
}
public void Send(Message message, TimeSpan timeout)
{
this.InnerChannel.Send(message, timeout);
}
public void Send(Message message)
{
this.InnerChannel.Send(message);
}
public Uri Via
{
get { return this.InnerChannel.Via; }
}
}
class SynchronousOutputChannel : SynchronousOutputChannelBase<IOutputChannel>, IOutputChannel
{
public SynchronousOutputChannel(ChannelManagerBase manager, IOutputChannel innerChannel)
: base(manager, innerChannel)
{
}
}
class SynchronousOutputSessionChannel : SynchronousOutputChannelBase<IOutputSessionChannel>, IOutputSessionChannel
{
public SynchronousOutputSessionChannel(ChannelManagerBase manager, IOutputSessionChannel innerChannel)
: base(manager, innerChannel)
{
}
IOutputSession ISessionChannel<IOutputSession>.Session
{
get { return this.InnerChannel.Session; }
}
}
abstract class SynchronousRequestChannelBase<TChannel> : SynchronousChannelBase<TChannel>
where TChannel : class, IRequestChannel
{
public SynchronousRequestChannelBase(ChannelManagerBase manager, TChannel innerChannel)
: base(manager, innerChannel)
{
}
public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
{
Message reply = this.InnerChannel.Request(message, timeout);
return new CompletedAsyncResult<Message>(reply, callback, state);
}
public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
{
Message reply = this.InnerChannel.Request(message);
return new CompletedAsyncResult<Message>(reply, callback, state);
}
public Message EndRequest(IAsyncResult result)
{
return CompletedAsyncResult<Message>.End(result);
}
public EndpointAddress RemoteAddress
{
get { return this.InnerChannel.RemoteAddress; }
}
public Message Request(Message message, TimeSpan timeout)
{
return this.InnerChannel.Request(message, timeout);
}
public Message Request(Message message)
{
return this.InnerChannel.Request(message);
}
public Uri Via
{
get { return this.InnerChannel.Via; }
}
}
class SynchronousRequestChannel : SynchronousRequestChannelBase<IRequestChannel>, IRequestChannel
{
public SynchronousRequestChannel(ChannelManagerBase manager, IRequestChannel innerChannel)
: base(manager, innerChannel)
{
}
}
class SynchronousRequestSessionChannel : SynchronousRequestChannelBase<IRequestSessionChannel>, IRequestSessionChannel
{
public SynchronousRequestSessionChannel(ChannelManagerBase manager, IRequestSessionChannel innerChannel)
: base(manager, innerChannel)
{
}
public IOutputSession Session
{
get
{
return this.InnerChannel.Session;
}
}
}
}
}

View File

@ -0,0 +1,90 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.Collections.Generic;
using System.Configuration;
using System.ServiceModel.Routing;
[SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesMustHaveXamlCallableConstructors)]
[SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesShouldHavePublicParameterlessConstructors)]
public class EndpointNameMessageFilter : MessageFilter
{
const string EndpointNameKey = "System.ServiceModel.Routing.EndpointNameMessageFilter.Name";
string endpointName;
public EndpointNameMessageFilter(string endpointName)
{
if (string.IsNullOrEmpty(endpointName))
{
throw FxTrace.Exception.ArgumentNullOrEmpty("endpointName");
}
this.endpointName = endpointName;
}
public override bool Match(Message message)
{
if (message == null)
{
throw FxTrace.Exception.ArgumentNull("message");
}
return MatchInternal(message.Properties);
}
public override bool Match(MessageBuffer buffer)
{
if (buffer == null)
{
throw FxTrace.Exception.ArgumentNull("buffer");
}
using (Message tempMessage = buffer.CreateMessage())
{
return MatchInternal(tempMessage.Properties);
}
}
bool MatchInternal(MessageProperties messageProperties)
{
object value;
if (messageProperties.TryGetValue(EndpointNameKey, out value))
{
string messageEndpoint = value.ToString();
return string.Equals(messageEndpoint, this.endpointName, StringComparison.Ordinal);
}
return false;
}
internal static void Set(MessageProperties properties, string endpointName)
{
properties[EndpointNameKey] = endpointName;
}
internal static void Validate(ICollection<MessageFilter> messageFilters, HashSet<string> endpoints)
{
foreach (MessageFilter filter in messageFilters)
{
EndpointNameMessageFilter endpointFilter = filter as EndpointNameMessageFilter;
if (endpointFilter != null)
{
endpointFilter.Validate(endpoints);
}
}
}
void Validate(HashSet<string> endpoints)
{
if (!endpoints.Contains(this.endpointName))
{
throw FxTrace.Exception.AsError(new ConfigurationErrorsException(SR.EndpointNameNotFound(this.endpointName)));
}
}
}
}

View File

@ -0,0 +1,301 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.Linq;
using System.Runtime;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.Collections;
using System.ServiceModel.Routing;
[SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesMustHaveXamlCallableConstructors)]
[SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesShouldHavePublicParameterlessConstructors)]
public class StrictAndMessageFilter : MessageFilter
{
MessageFilter filter1;
MessageFilter filter2;
public StrictAndMessageFilter(MessageFilter filter1, MessageFilter filter2)
{
if (filter1 == null || filter2 == null)
{
throw FxTrace.Exception.ArgumentNull(filter1 == null ? "filter1" : "filter2");
}
this.filter1 = filter1;
this.filter2 = filter2;
}
public override bool Match(Message message)
{
throw FxTrace.Exception.AsError(new NotSupportedException());
}
public override bool Match(MessageBuffer buffer)
{
throw FxTrace.Exception.AsError(new NotSupportedException());
}
protected internal override IMessageFilterTable<TFilterData> CreateFilterTable<TFilterData>()
{
StrictAndMessageFilterTable<TFilterData> table = new StrictAndMessageFilterTable<TFilterData>();
return table;
}
class StrictAndMessageFilterTable<TFilterData> : IMessageFilterTable<TFilterData>
{
Dictionary<MessageFilter, TFilterData> andFilters;
MessageFilterTable<StrictAndMessageFilter> filterTable;
public StrictAndMessageFilterTable()
{
this.andFilters = new Dictionary<MessageFilter, TFilterData>();
this.filterTable = new MessageFilterTable<StrictAndMessageFilter>();
}
public int Count
{
get { return this.andFilters.Count; }
}
public bool IsReadOnly
{
get { return true; }
}
public ICollection<MessageFilter> Keys
{
get { return this.andFilters.Keys; }
}
public ICollection<TFilterData> Values
{
get { return this.andFilters.Values; }
}
public TFilterData this[MessageFilter key]
{
get
{
return this.andFilters[key];
}
set
{
this.andFilters[key] = value;
}
}
public bool GetMatchingFilter(MessageBuffer messageBuffer, out MessageFilter filter)
{
throw FxTrace.Exception.AsError(new NotImplementedException());
}
public bool GetMatchingFilter(Message message, out MessageFilter filter)
{
throw FxTrace.Exception.AsError(new NotImplementedException());
}
public bool GetMatchingFilters(MessageBuffer messageBuffer, ICollection<MessageFilter> results)
{
if (messageBuffer == null)
{
throw FxTrace.Exception.ArgumentNull("messageBuffer");
}
List<MessageFilter> firstPassResults = new List<MessageFilter>();
if (this.filterTable.GetMatchingFilters(messageBuffer, firstPassResults))
{
IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
foreach (StrictAndMessageFilter andFilter in matchingFilters)
{
results.Add(andFilter);
}
return (matchingFilters.Count > 0);
}
return false;
}
public bool GetMatchingFilters(Message message, ICollection<MessageFilter> results)
{
if (message == null)
{
throw FxTrace.Exception.ArgumentNull("message");
}
List<MessageFilter> firstPassResults = new List<MessageFilter>();
if (this.filterTable.GetMatchingFilters(message, firstPassResults))
{
IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
foreach (StrictAndMessageFilter andFilter in matchingFilters)
{
results.Add(andFilter);
}
return (matchingFilters.Count > 0);
}
return false;
}
public bool GetMatchingValue(MessageBuffer messageBuffer, out TFilterData value)
{
value = default(TFilterData);
List<TFilterData> results = new List<TFilterData>();
bool result = this.GetMatchingValues(messageBuffer, results);
if (results.Count == 1)
{
value = results[0];
}
if (results.Count > 1)
{
throw FxTrace.Exception.AsError(new MultipleFilterMatchesException());
}
return result;
}
public bool GetMatchingValue(Message message, out TFilterData value)
{
value = default(TFilterData);
List<TFilterData> results = new List<TFilterData>();
bool result = this.GetMatchingValues(message, results);
if (results.Count == 1)
{
value = results[0];
}
else if (results.Count > 1)
{
throw FxTrace.Exception.AsError(new MultipleFilterMatchesException());
}
return result;
}
public bool GetMatchingValues(MessageBuffer messageBuffer, ICollection<TFilterData> results)
{
if (messageBuffer == null)
{
throw FxTrace.Exception.ArgumentNull("messageBuffer");
}
List<MessageFilter> firstPassResults = new List<MessageFilter>();
if (this.filterTable.GetMatchingFilters(messageBuffer, firstPassResults))
{
IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
foreach (StrictAndMessageFilter andFilter in matchingFilters)
{
results.Add(this.andFilters[andFilter]);
}
return (matchingFilters.Count > 0);
}
return false;
}
public bool GetMatchingValues(Message message, ICollection<TFilterData> results)
{
if (message == null)
{
throw FxTrace.Exception.ArgumentNull("message");
}
List<MessageFilter> firstPassResults = new List<MessageFilter>();
if (this.filterTable.GetMatchingFilters(message, firstPassResults))
{
IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
foreach (StrictAndMessageFilter andFilter in matchingFilters)
{
results.Add(this.andFilters[andFilter]);
}
return (matchingFilters.Count > 0);
}
return false;
}
IList<StrictAndMessageFilter> FindMatchingAndFilters(List<MessageFilter> firstPassResults)
{
IList<StrictAndMessageFilter> matchingFilters = new List<StrictAndMessageFilter>();
foreach (MessageFilter filter in firstPassResults)
{
StrictAndMessageFilter andFilter = this.filterTable[filter];
// Check if this StrictAndMessageFilter is already in our result set
if (!matchingFilters.Contains(andFilter))
{
if (firstPassResults.Contains(andFilter.filter1) && firstPassResults.Contains(andFilter.filter2))
{
matchingFilters.Add(andFilter);
}
}
}
return matchingFilters;
}
public void Add(MessageFilter key, TFilterData value)
{
StrictAndMessageFilter andFilter = (StrictAndMessageFilter)key;
this.andFilters.Add(andFilter, value);
this.filterTable.Add(andFilter.filter1, andFilter);
this.filterTable.Add(andFilter.filter2, andFilter);
}
public bool ContainsKey(MessageFilter key)
{
return this.andFilters.ContainsKey(key);
}
public bool Remove(MessageFilter key)
{
StrictAndMessageFilter andFilter = (StrictAndMessageFilter)key;
if (this.andFilters.Remove(andFilter))
{
this.filterTable.Remove(andFilter.filter1);
this.filterTable.Remove(andFilter.filter2);
return true;
}
return false;
}
public bool TryGetValue(MessageFilter key, out TFilterData value)
{
return this.andFilters.TryGetValue(key, out value);
}
public void Add(KeyValuePair<MessageFilter, TFilterData> item)
{
this.Add(item.Key, item.Value);
}
public void Clear()
{
this.andFilters.Clear();
this.filterTable.Clear();
}
public bool Contains(KeyValuePair<MessageFilter, TFilterData> item)
{
return this.andFilters.Contains(item);
}
public void CopyTo(KeyValuePair<MessageFilter, TFilterData>[] array, int arrayIndex)
{
throw FxTrace.Exception.AsError(new NotImplementedException());
}
public bool Remove(KeyValuePair<MessageFilter, TFilterData> item)
{
return this.andFilters.Remove(item.Key);
}
public IEnumerator<KeyValuePair<MessageFilter, TFilterData>> GetEnumerator()
{
throw FxTrace.Exception.AsError(new NotImplementedException());
}
IEnumerator IEnumerable.GetEnumerator()
{
throw FxTrace.Exception.AsError(new NotImplementedException());
}
}
}
}

View File

@ -0,0 +1,484 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing
{
using System;
using System.Collections.Generic;
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Transactions;
using System.Runtime.Diagnostics;
using System.ServiceModel.Diagnostics;
static class ClientFactory
{
public static IRoutingClient Create(RoutingEndpointTrait endpointTrait, RoutingService service, bool impersonating)
{
Type contractType = endpointTrait.RouterContract;
IRoutingClient client;
if (contractType == typeof(ISimplexDatagramRouter))
{
client = new SimplexDatagramClient(endpointTrait, service.RoutingConfig, impersonating);
}
else if (contractType == typeof(IRequestReplyRouter))
{
client = new RequestReplyClient(endpointTrait, service.RoutingConfig, impersonating);
}
else if (contractType == typeof(ISimplexSessionRouter))
{
client = new SimplexSessionClient(endpointTrait, service.RoutingConfig, impersonating);
}
else //if (contractType == typeof(IDuplexSessionRouter))
{
Fx.Assert(contractType == typeof(IDuplexSessionRouter), "Only one contract type remaining.");
client = new DuplexSessionClient(service, endpointTrait, impersonating);
}
return client;
}
abstract class RoutingClientBase<TChannel> : ClientBase<TChannel>, IRoutingClient
where TChannel : class
{
bool openCompleted;
object thisLock;
Queue<OperationAsyncResult> waiters;
protected RoutingClientBase(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, bool impersonating)
: base(endpointTrait.Endpoint.Binding, endpointTrait.Endpoint.Address)
{
Initialize(endpointTrait, routingConfig, impersonating);
}
protected RoutingClientBase(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, object callbackInstance, bool impersonating)
: base(new InstanceContext(callbackInstance), endpointTrait.Endpoint.Binding, endpointTrait.Endpoint.Address)
{
Initialize(endpointTrait, routingConfig, impersonating);
}
public RoutingEndpointTrait Key
{
get;
private set;
}
public event EventHandler Faulted;
static void ConfigureImpersonation(ServiceEndpoint endpoint, bool impersonating)
{
// Used for both impersonation and ASP.NET Compatibilty Mode. Both currently require
// everything to be synchronous.
if (impersonating)
{
CustomBinding binding = endpoint.Binding as CustomBinding;
if (binding == null)
{
binding = new CustomBinding(endpoint.Binding);
}
SynchronousSendBindingElement syncSend = binding.Elements.Find<SynchronousSendBindingElement>();
if (syncSend == null)
{
binding.Elements.Insert(0, new SynchronousSendBindingElement());
endpoint.Binding = binding;
}
}
}
static void ConfigureTransactionFlow(ServiceEndpoint endpoint)
{
CustomBinding binding = endpoint.Binding as CustomBinding;
if (binding == null)
{
binding = new CustomBinding(endpoint.Binding);
}
TransactionFlowBindingElement transactionFlow = binding.Elements.Find<TransactionFlowBindingElement>();
if (transactionFlow != null)
{
transactionFlow.AllowWildcardAction = true;
endpoint.Binding = binding;
}
}
void Initialize(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, bool impersonating)
{
this.thisLock = new object();
this.Key = endpointTrait;
if (TD.RoutingServiceCreatingClientForEndpointIsEnabled())
{
TD.RoutingServiceCreatingClientForEndpoint(this.Key.ToString());
}
ServiceEndpoint clientEndpoint = endpointTrait.Endpoint;
ServiceEndpoint endpoint = this.Endpoint;
KeyedByTypeCollection<IEndpointBehavior> behaviors = endpoint.Behaviors;
endpoint.ListenUri = clientEndpoint.ListenUri;
endpoint.ListenUriMode = clientEndpoint.ListenUriMode;
endpoint.Name = clientEndpoint.Name;
foreach (IEndpointBehavior behavior in clientEndpoint.Behaviors)
{
// Remove if present, ok to call if not there (will simply return false)
behaviors.Remove(behavior.GetType());
behaviors.Add(behavior);
}
// If the configuration doesn't explicitly add MustUnderstandBehavior (to override us)
// add it here, with mustunderstand = false.
if (behaviors.Find<MustUnderstandBehavior>() == null)
{
behaviors.Add(new MustUnderstandBehavior(false));
}
// If the configuration doesn't explicitly turn off marshaling we add it here.
if (routingConfig.SoapProcessingEnabled && behaviors.Find<SoapProcessingBehavior>() == null)
{
behaviors.Add(new SoapProcessingBehavior());
}
ConfigureTransactionFlow(endpoint);
ConfigureImpersonation(endpoint, impersonating);
}
protected override TChannel CreateChannel()
{
TChannel channel = base.CreateChannel();
((ICommunicationObject)channel).Faulted += this.InnerChannelFaulted;
return channel;
}
public IAsyncResult BeginOperation(Message message, Transaction transaction, AsyncCallback callback, object state)
{
return new OperationAsyncResult(this, message, transaction, callback, state);
}
public Message EndOperation(IAsyncResult result)
{
return OperationAsyncResult.End(result);
}
protected abstract IAsyncResult OnBeginOperation(Message message, AsyncCallback callback, object state);
protected abstract Message OnEndOperation(IAsyncResult asyncResult);
void InnerChannelFaulted(object sender, EventArgs args)
{
EventHandler handlers = this.Faulted;
if (handlers != null)
{
handlers(this, args);
}
}
class OperationAsyncResult : TransactedAsyncResult
{
static AsyncCompletion openComplete = OpenComplete;
static AsyncCompletion operationComplete = OperationComplete;
static Action<object> signalWaiter;
RoutingClientBase<TChannel> parent;
Message replyMessage;
Message requestMessage;
Transaction transaction;
public OperationAsyncResult(RoutingClientBase<TChannel> parent, Message requestMessage, Transaction transaction, AsyncCallback callback, object state)
: base(callback, state)
{
this.parent = parent;
this.requestMessage = requestMessage;
this.transaction = transaction;
bool shouldOpen = false;
if (!this.parent.openCompleted)
{
lock (this.parent.thisLock)
{
if (!this.parent.openCompleted)
{
//The first to open initializes the waiters queue others add themselves to it.
if (this.parent.waiters == null)
{
//it's our job to open the proxy
this.parent.waiters = new Queue<OperationAsyncResult>();
shouldOpen = true;
}
else
{
//Someone beat us to it, just join the list of waiters.
this.parent.waiters.Enqueue(this);
return;
}
}
}
}
if (shouldOpen)
{
//we are the first so we need to open this channel
IAsyncResult asyncResult;
using (this.PrepareTransactionalCall(this.transaction))
{
//This will use the binding's OpenTimeout.
asyncResult = ((ICommunicationObject)this.parent).BeginOpen(this.PrepareAsyncCompletion(openComplete), this);
}
if (this.SyncContinue(asyncResult))
{
this.Complete(true);
}
}
else
{
if (this.CallOperation())
{
this.Complete(true);
}
}
}
public static Message End(IAsyncResult result)
{
OperationAsyncResult thisPtr = AsyncResult.End<OperationAsyncResult>(result);
return thisPtr.replyMessage;
}
static bool OpenComplete(IAsyncResult openResult)
{
OperationAsyncResult thisPtr = (OperationAsyncResult)openResult.AsyncState;
try
{
((ICommunicationObject)thisPtr.parent).EndOpen(openResult);
}
finally
{
Queue<OperationAsyncResult> localWaiters = null;
lock (thisPtr.parent.thisLock)
{
localWaiters = thisPtr.parent.waiters;
thisPtr.parent.waiters = null;
thisPtr.parent.openCompleted = true;
}
if (localWaiters != null && localWaiters.Count > 0)
{
if (signalWaiter == null)
{
signalWaiter = new Action<object>(SignalWaiter);
}
//foreach over Queue<T> goes FIFO
foreach (OperationAsyncResult waiter in localWaiters)
{
ActionItem.Schedule(signalWaiter, waiter);
}
}
}
return thisPtr.CallOperation();
}
bool CallOperation()
{
IAsyncResult asyncResult;
using (this.PrepareTransactionalCall(this.transaction))
{
asyncResult = this.parent.OnBeginOperation(this.requestMessage, this.PrepareAsyncCompletion(operationComplete), this);
}
return this.SyncContinue(asyncResult);
}
static bool OperationComplete(IAsyncResult result)
{
OperationAsyncResult thisPtr = (OperationAsyncResult)result.AsyncState;
thisPtr.replyMessage = thisPtr.parent.OnEndOperation(result);
return true;
}
static void SignalWaiter(object state)
{
OperationAsyncResult waiter = (OperationAsyncResult)state;
try
{
if (waiter.CallOperation())
{
waiter.Complete(false);
}
}
catch (Exception exception)
{
if (Fx.IsFatal(exception))
{
throw;
}
waiter.Complete(false, exception);
}
}
}
}
class SimplexDatagramClient : RoutingClientBase<ISimplexDatagramRouter>
{
public SimplexDatagramClient(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, bool impersonating)
: base(endpointTrait, routingConfig, impersonating)
{
}
protected override IAsyncResult OnBeginOperation(Message message, AsyncCallback callback, object state)
{
return this.Channel.BeginProcessMessage(message, callback, state);
}
protected override Message OnEndOperation(IAsyncResult result)
{
this.Channel.EndProcessMessage(result);
return null;
}
}
class SimplexSessionClient : RoutingClientBase<ISimplexSessionRouter>
{
public SimplexSessionClient(RoutingEndpointTrait endointTrait, RoutingConfiguration routingConfig, bool impersonating)
: base(endointTrait, routingConfig, impersonating)
{
}
protected override IAsyncResult OnBeginOperation(Message message, AsyncCallback callback, object state)
{
return this.Channel.BeginProcessMessage(message, callback, state);
}
protected override Message OnEndOperation(IAsyncResult result)
{
this.Channel.EndProcessMessage(result);
return null;
}
}
class DuplexSessionClient : RoutingClientBase<IDuplexSessionRouter>
{
public DuplexSessionClient(RoutingService service, RoutingEndpointTrait endpointTrait, bool impersonating)
: base(endpointTrait, service.RoutingConfig, new DuplexCallbackProxy(service.ChannelExtension.ActivityID, endpointTrait.CallbackInstance), impersonating)
{
}
protected override IAsyncResult OnBeginOperation(Message message, AsyncCallback callback, object state)
{
return this.Channel.BeginProcessMessage(message, callback, state);
}
protected override Message OnEndOperation(IAsyncResult result)
{
this.Channel.EndProcessMessage(result);
return null;
}
class DuplexCallbackProxy : IDuplexRouterCallback
{
Guid activityID;
IDuplexRouterCallback callbackInstance;
EventTraceActivity eventTraceActivity;
public DuplexCallbackProxy(Guid activityID, IDuplexRouterCallback callbackInstance)
{
this.activityID = activityID;
this.callbackInstance = callbackInstance;
if (Fx.Trace.IsEtwProviderEnabled)
{
this.eventTraceActivity = new EventTraceActivity(activityID);
}
}
IAsyncResult IDuplexRouterCallback.BeginProcessMessage(Message message, AsyncCallback callback, object state)
{
FxTrace.Trace.SetAndTraceTransfer(this.activityID, true);
try
{
return new CallbackAsyncResult(this.callbackInstance, message, callback, state);
}
catch (Exception e)
{
if (TD.RoutingServiceDuplexCallbackExceptionIsEnabled())
{
TD.RoutingServiceDuplexCallbackException(this.eventTraceActivity, "DuplexCallbackProxy.BeginProcessMessage", e);
}
throw;
}
}
void IDuplexRouterCallback.EndProcessMessage(IAsyncResult result)
{
FxTrace.Trace.SetAndTraceTransfer(this.activityID, true);
try
{
CallbackAsyncResult.End(result);
}
catch (Exception e)
{
if (TD.RoutingServiceDuplexCallbackExceptionIsEnabled())
{
TD.RoutingServiceDuplexCallbackException(this.eventTraceActivity, "DuplexCallbackProxy.EndProcessMessage", e);
}
throw;
}
}
// We have to have an AsyncResult implementation here in order to handle the
// TransactionScope appropriately (use PrepareTransactionalCall, SyncContinue, etc...)
class CallbackAsyncResult : TransactedAsyncResult
{
static AsyncCompletion processCallback = ProcessCallback;
IDuplexRouterCallback callbackInstance;
public CallbackAsyncResult(IDuplexRouterCallback callbackInstance, Message message, AsyncCallback callback, object state)
: base(callback, state)
{
this.callbackInstance = callbackInstance;
IAsyncResult result;
using (this.PrepareTransactionalCall(TransactionMessageProperty.TryGetTransaction(message)))
{
result = this.callbackInstance.BeginProcessMessage(message,
this.PrepareAsyncCompletion(processCallback), this);
}
if (this.SyncContinue(result))
{
this.Complete(true);
}
}
public static void End(IAsyncResult result)
{
AsyncResult.End<CallbackAsyncResult>(result);
}
static bool ProcessCallback(IAsyncResult result)
{
CallbackAsyncResult thisPtr = (CallbackAsyncResult)result.AsyncState;
thisPtr.callbackInstance.EndProcessMessage(result);
return true;
}
}
}
}
class RequestReplyClient : RoutingClientBase<IRequestReplyRouter>
{
public RequestReplyClient(RoutingEndpointTrait endpointTrait, RoutingConfiguration routingConfig, bool impersonating)
: base(endpointTrait, routingConfig, impersonating)
{
}
protected override IAsyncResult OnBeginOperation(Message message, AsyncCallback callback, object state)
{
return this.Channel.BeginProcessRequest(message, callback, state);
}
protected override Message OnEndOperation(IAsyncResult result)
{
return this.Channel.EndProcessRequest(result);
}
}
}
}

View File

@ -0,0 +1,34 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing.Configuration
{
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
sealed class ClientEndpointLoader : ChannelFactory
{
ClientEndpointLoader(string configurationName)
{
base.InitializeEndpoint(configurationName, null);
base.Endpoint.Name = configurationName;
}
public static ServiceEndpoint LoadEndpoint(string configurationName)
{
using (ClientEndpointLoader loader = new ClientEndpointLoader(configurationName))
{
return loader.Endpoint;
}
}
protected override ServiceEndpoint CreateDescription()
{
ServiceEndpoint ep = new ServiceEndpoint(new ContractDescription("contract"));
ep.Contract.ConfigurationName = "*";
return ep;
}
}
}

View File

@ -0,0 +1,37 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing.Configuration
{
static class ConfigurationStrings
{
internal const string BackupList = "backupList";
internal const string BackupLists = "backupLists";
internal const string CustomType = "customType";
internal const string EndpointName = "endpointName";
internal const string Endpoints = "endpoints";
internal const string Entries = "entries";
internal const string Filter = "filter";
internal const string Filter1 = "filter1";
internal const string Filter2 = "filter2";
internal const string FilterData = "filterData";
internal const string FilterName = "filterName";
internal const string Filters = "filters";
internal const string FilterTable = "filterTable";
internal const string FilterTableName = "filterTableName";
internal const string FilterTables = "filterTables";
internal const string FilterType = "filterType";
//internal const string Impersonation = "impersonation";
internal const string Name = "name";
internal const string Namespace = "namespace";
internal const string NamespaceTable = "namespaceTable";
internal const string Prefix = "prefix";
internal const string Priority = "priority";
internal const string ProcessMessages = "processMessages";
internal const string RouteOnHeadersOnly = "routeOnHeadersOnly";
internal const string SoapProcessingEnabled = "soapProcessingEnabled";
internal const string EnsureOrderedDispatch = "ensureOrderedDispatch";
}
}

View File

@ -0,0 +1,20 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing.Configuration
{
using System;
public enum FilterType
{
Action,
EndpointAddress,
PrefixEndpointAddress,
And,
Custom,
EndpointName,
MatchAll,
XPath
}
}

View File

@ -0,0 +1,102 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing.Configuration
{
using System;
using System.Linq;
using System.Configuration;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
public sealed class RoutingExtensionElement : BehaviorExtensionElement
{
public RoutingExtensionElement()
{
this.RouteOnHeadersOnly = RoutingConfiguration.DefaultRouteOnHeadersOnly;
}
[SuppressMessage(FxCop.Category.Configuration, FxCop.Rule.ConfigurationPropertyAttributeRule, Justification = "this is not a configuration property")]
public override Type BehaviorType
{
get { return typeof(RoutingBehavior); }
}
[ConfigurationProperty(ConfigurationStrings.RouteOnHeadersOnly, DefaultValue = RoutingConfiguration.DefaultRouteOnHeadersOnly, Options = ConfigurationPropertyOptions.None)]
public bool RouteOnHeadersOnly
{
get
{
return (bool)this[ConfigurationStrings.RouteOnHeadersOnly];
}
set
{
this[ConfigurationStrings.RouteOnHeadersOnly] = value;
}
}
[SuppressMessage(FxCop.Category.Configuration, FxCop.Rule.ConfigurationValidatorAttributeRule, Justification = "fxcop didn't like [StringValidator(MinLength = 0)]")]
[ConfigurationProperty(ConfigurationStrings.FilterTableName, DefaultValue = null)]
public string FilterTableName
{
get
{
return (string)this[ConfigurationStrings.FilterTableName];
}
set
{
this[ConfigurationStrings.FilterTableName] = value;
}
}
[ConfigurationProperty(ConfigurationStrings.SoapProcessingEnabled, DefaultValue = RoutingConfiguration.DefaultSoapProcessingEnabled)]
public bool SoapProcessingEnabled
{
get
{
return (bool)this[ConfigurationStrings.SoapProcessingEnabled];
}
set
{
this[ConfigurationStrings.SoapProcessingEnabled] = value;
}
}
[ConfigurationProperty(ConfigurationStrings.EnsureOrderedDispatch, DefaultValue = RoutingConfiguration.DefaultEnsureOrderedDispatch)]
public bool EnsureOrderedDispatch
{
get
{
return (bool)this[ConfigurationStrings.EnsureOrderedDispatch];
}
set
{
this[ConfigurationStrings.EnsureOrderedDispatch] = value;
}
}
protected internal override object CreateBehavior()
{
RoutingConfiguration config;
if (string.IsNullOrEmpty(this.FilterTableName))
{
config = new RoutingConfiguration();
config.RouteOnHeadersOnly = this.RouteOnHeadersOnly;
}
else
{
config = new RoutingConfiguration(RoutingSection.CreateFilterTable(this.FilterTableName), this.RouteOnHeadersOnly);
}
config.SoapProcessingEnabled = this.SoapProcessingEnabled;
config.EnsureOrderedDispatch = this.EnsureOrderedDispatch;
RoutingBehavior behavior = new RoutingBehavior(config);
//behavior.Impersonation = this.Impersonation;
return behavior;
}
}
}

View File

@ -0,0 +1,41 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing.Configuration
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime;
using System.ServiceModel.Configuration;
using System.Configuration;
public class SoapProcessingExtensionElement : BehaviorExtensionElement
{
[SuppressMessage(FxCop.Category.Configuration, FxCop.Rule.ConfigurationPropertyAttributeRule, Justification = "this is not a configuration property")]
public override Type BehaviorType
{
get { return typeof(SoapProcessingBehavior); }
}
protected internal override object CreateBehavior()
{
SoapProcessingBehavior behavior = new SoapProcessingBehavior();
behavior.ProcessMessages = this.ProcessMessages;
return behavior;
}
[ConfigurationProperty(ConfigurationStrings.ProcessMessages, DefaultValue = true, Options = ConfigurationPropertyOptions.None)]
public bool ProcessMessages
{
get
{
return (bool)this[ConfigurationStrings.ProcessMessages];
}
set
{
this[ConfigurationStrings.ProcessMessages] = value;
}
}
}
}

View File

@ -0,0 +1,84 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing
{
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Xml;
using System.Runtime;
class DelegatingHeader : MessageHeader
{
int index;
MessageHeaderInfo info;
MessageHeaders originalHeaders;
public DelegatingHeader(MessageHeaderInfo info, MessageHeaders originalHeaders)
{
Fx.Assert(info != null, "info is required");
Fx.Assert(originalHeaders != null, "originalHeaders is required");
this.info = info;
this.originalHeaders = originalHeaders;
this.index = -1;
}
void EnsureIndex()
{
if (this.index < 0)
{
this.index = this.originalHeaders.FindHeader(this.info.Name, this.info.Namespace);
if (this.index < 0)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR.SourceHeaderNotFound(this.info.Name, this.info.Namespace)));
}
}
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
this.EnsureIndex();
this.originalHeaders.WriteHeaderContents(index, writer);
this.index = -1;
}
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
this.EnsureIndex();
this.originalHeaders.WriteStartHeader(this.index, writer);
}
public override string Name
{
get { return this.info.Name; }
}
public override string Namespace
{
get { return this.info.Namespace; }
}
public override bool MustUnderstand
{
get { return this.info.MustUnderstand; }
}
public override string Actor
{
get { return this.info.Actor; }
}
public override bool IsReferenceParameter
{
get { return this.info.IsReferenceParameter; }
}
public override bool Relay
{
get { return base.Relay; }
}
}
}

View File

@ -0,0 +1,42 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing
{
using System;
using System.Collections.Generic;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
sealed class GenericTransactionFlowAttribute : Attribute, IOperationBehavior
{
TransactionFlowAttribute transactionFlowAttribute;
public GenericTransactionFlowAttribute(TransactionFlowOption flowOption)
{
this.transactionFlowAttribute = new TransactionFlowAttribute(flowOption);
}
void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
{
((IOperationBehavior)this.transactionFlowAttribute).AddBindingParameters(operationDescription, bindingParameters);
}
void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
{
((IOperationBehavior)this.transactionFlowAttribute).ApplyClientBehavior(operationDescription, clientOperation);
}
void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
((IOperationBehavior)this.transactionFlowAttribute).ApplyDispatchBehavior(operationDescription, dispatchOperation);
}
void IOperationBehavior.Validate(OperationDescription operationDescription)
{
((IOperationBehavior)this.transactionFlowAttribute).Validate(operationDescription);
}
}
}

View File

@ -0,0 +1,20 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing
{
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
[ServiceContract(Namespace = RoutingUtilities.RoutingNamespace, SessionMode = SessionMode.Allowed)]
interface IDuplexRouterCallback
{
[OperationContract(AsyncPattern = true, IsOneWay = true, Action = "*")]
[GenericTransactionFlow(TransactionFlowOption.Allowed)]
IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);
void EndProcessMessage(IAsyncResult result);
}
}

View File

@ -0,0 +1,20 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing
{
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
[ServiceContract(Namespace = RoutingUtilities.RoutingNamespace, SessionMode = SessionMode.Required, CallbackContract = typeof(IDuplexRouterCallback))]
public interface IDuplexSessionRouter
{
[OperationContract(AsyncPattern = true, IsOneWay = true, Action = "*")]
[GenericTransactionFlow(TransactionFlowOption.Allowed)]
IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);
void EndProcessMessage(IAsyncResult result);
}
}

View File

@ -0,0 +1,20 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing
{
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
[ServiceContract(Namespace = RoutingUtilities.RoutingNamespace, SessionMode = SessionMode.Allowed)]
public interface IRequestReplyRouter
{
[OperationContract(AsyncPattern = true, IsOneWay = false, Action = "*", ReplyAction = "*")]
[GenericTransactionFlow(TransactionFlowOption.Allowed)]
IAsyncResult BeginProcessRequest(Message message, AsyncCallback callback, object state);
Message EndProcessRequest(IAsyncResult result);
}
}

View File

@ -0,0 +1,20 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing
{
using System;
using System.ServiceModel.Channels;
using System.Transactions;
interface IRoutingClient
{
IAsyncResult BeginOperation(Message message, Transaction transaction, AsyncCallback callback, object state);
Message EndOperation(IAsyncResult result);
event EventHandler Faulted;
RoutingEndpointTrait Key { get; }
CommunicationState State { get; }
void Open();
}
}

View File

@ -0,0 +1,19 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing
{
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
[ServiceContract(Namespace = RoutingUtilities.RoutingNamespace, SessionMode = SessionMode.Allowed)]
public interface ISimplexDatagramRouter
{
[OperationContract(AsyncPattern = true, IsOneWay = true, Action = "*")]
IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);
void EndProcessMessage(IAsyncResult result);
}
}

View File

@ -0,0 +1,19 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing
{
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
[ServiceContract(Namespace = RoutingUtilities.RoutingNamespace, SessionMode = SessionMode.Required)]
public interface ISimplexSessionRouter
{
[OperationContract(AsyncPattern = true, IsOneWay = true, Action = "*")]
IAsyncResult BeginProcessMessage(Message message, AsyncCallback callback, object state);
void EndProcessMessage(IAsyncResult result);
}
}

View File

@ -0,0 +1,269 @@
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------
namespace System.ServiceModel.Routing
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Runtime;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
using System.Transactions;
using SR2 = System.ServiceModel.Routing.SR;
using System.Security.Principal;
using System.Runtime.Diagnostics;
using System.ServiceModel.Diagnostics;
// This class wraps a Message, MessageBuffer (if requested), and the OperationContext
// The message is not buffered if nobody calls MessageRpc.CreateBuffer. If the message
// is buffered, then we hang on to the buffer so it can be reused and Clone the message
// which became invalid when we buffered this message.
class MessageRpc
{
const int ERROR_BAD_IMPERSONATION_LEVEL = 1346;
Message originalMessage;
Message clonedMessage;
MessageBuffer messageBuffer;
string uniqueID;
Transaction transaction;
ReceiveContext receiveContext;
IList<SendOperation> operations;
WindowsIdentity windowsIdentity;
EventTraceActivity eventTraceActivity;
public MessageRpc(Message message, OperationContext operationContext, bool impersonationRequired)
{
Fx.Assert(message != null, "message cannot be null");
Fx.Assert(operationContext != null, "operationContext cannot be null");
this.originalMessage = message;
this.OperationContext = operationContext;
if (Fx.Trace.IsEtwProviderEnabled)
{
this.eventTraceActivity = EventTraceActivityHelper.TryExtractActivity(message);
}
//passing in true causes this to return null if the thread is not impersonating.
this.windowsIdentity = WindowsIdentity.GetCurrent(true);
if (impersonationRequired && !AspNetEnvironment.Current.AspNetCompatibilityEnabled)
{
if (this.windowsIdentity == null || this.windowsIdentity.ImpersonationLevel != TokenImpersonationLevel.Impersonation)
{
//Temporarily revert impersonation to process token to throw an exception
IDisposable autoRevert = null;
try
{
try { }
finally
{
autoRevert = WindowsIdentity.Impersonate(IntPtr.Zero);
}
Win32Exception errorDetail = new Win32Exception(ERROR_BAD_IMPERSONATION_LEVEL);
throw FxTrace.Exception.AsError(new SecurityNegotiationException(errorDetail.Message));
}
finally
{
if (autoRevert != null)
{
autoRevert.Dispose();
}
}
}
}
ReceiveContext.TryGet(message, out this.receiveContext);
this.transaction = Transaction.Current;
if (this.transaction == null)
{
this.transaction = TransactionMessageProperty.TryGetTransaction(message);
}
}
internal bool Impersonating
{
get { return this.windowsIdentity != null; }
}
internal EventTraceActivity EventTraceActivity
{
get
{
return this.eventTraceActivity;
}
}
public OperationContext OperationContext
{
get;
private set;
}
public string UniqueID
{
get
{
if (this.uniqueID == null)
{
if (this.Message.Version != MessageVersion.None &&
this.Message.Headers.MessageId != null)
{
this.uniqueID = this.originalMessage.Headers.MessageId.ToString();
}
else
{
this.uniqueID = this.GetHashCode().ToString(CultureInfo.InvariantCulture);
}
}
return this.uniqueID;
}
}
public Message Message
{
get
{
// If we've created a MessageBuffer then the originalMessage has already been consumed
if (this.messageBuffer != null)
{
Fx.Assert(this.clonedMessage != null, "Need to set clonedMessage if we buffered the message");
return this.clonedMessage;
}
else
{
// Haven't buffered, can use the original.
return this.originalMessage;
}
}
}
public ReceiveContext ReceiveContext
{
get { return this.receiveContext; }
}
public IList<SendOperation> Operations
{
get { return this.operations; }
}
public Transaction Transaction
{
get { return this.transaction; }
}
public MessageBuffer CreateBuffer()
{
if (this.messageBuffer == null)
{
this.messageBuffer = this.originalMessage.CreateBufferedCopy(int.MaxValue);
this.clonedMessage = this.messageBuffer.CreateMessage();
}
return this.messageBuffer;
}
public IDisposable PrepareCall()
{
return new CallState(this);
}
public void RouteToSingleEndpoint<TContract>(RoutingConfiguration routingConfig)
{
IEnumerable<ServiceEndpoint> result;
if (routingConfig.RouteOnHeadersOnly)
{
if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(this.eventTraceActivity); }
routingConfig.InternalFilterTable.GetMatchingValue(this.Message, out result);
if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(this.eventTraceActivity); }
}
else
{
MessageBuffer buffer = this.CreateBuffer();
if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(this.eventTraceActivity); }
routingConfig.InternalFilterTable.GetMatchingValue(buffer, out result);
if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(this.eventTraceActivity); }
}
if (result == null)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.NoFilterMatched));
}
if (TD.RoutingServiceMessageRoutedToEndpointsIsEnabled())
{
TD.RoutingServiceMessageRoutedToEndpoints(this.eventTraceActivity, this.UniqueID, "1");
}
this.operations = new List<SendOperation>(1);
this.operations.Add(new SendOperation(result, typeof(TContract), this.OperationContext));
}
public void RouteToEndpoints<TContract>(RoutingConfiguration routingConfig)
{
List<IEnumerable<ServiceEndpoint>> endpointLists = new List<IEnumerable<ServiceEndpoint>>();
if (routingConfig.RouteOnHeadersOnly)
{
if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(this.eventTraceActivity); }
routingConfig.InternalFilterTable.GetMatchingValues(this.Message, endpointLists);
if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(this.eventTraceActivity); }
}
else
{
MessageBuffer messageBuffer = this.CreateBuffer();
if (TD.RoutingServiceFilterTableMatchStartIsEnabled()) { TD.RoutingServiceFilterTableMatchStart(this.eventTraceActivity); }
routingConfig.InternalFilterTable.GetMatchingValues(messageBuffer, endpointLists);
if (TD.RoutingServiceFilterTableMatchStopIsEnabled()) { TD.RoutingServiceFilterTableMatchStop(this.eventTraceActivity); }
}
if (TD.RoutingServiceMessageRoutedToEndpointsIsEnabled())
{
TD.RoutingServiceMessageRoutedToEndpoints(this.eventTraceActivity, this.UniqueID, endpointLists.Count.ToString(TD.Culture));
}
if (endpointLists.Count == 0)
{
throw FxTrace.Exception.AsError(new InvalidOperationException(SR2.NoFilterMatched));
}
this.operations = new List<SendOperation>(endpointLists.Count);
foreach (IEnumerable<ServiceEndpoint> endpointList in endpointLists)
{
this.operations.Add(new SendOperation(endpointList, typeof(TContract), this.OperationContext));
}
}
class CallState : IDisposable
{
OperationContextScope nullContextScope;
WindowsImpersonationContext impersonation;
public CallState (MessageRpc messageRpc)
{
this.nullContextScope = new OperationContextScope((OperationContext)null);
if (messageRpc.windowsIdentity != null)
{
this.impersonation = messageRpc.windowsIdentity.Impersonate();
}
}
void IDisposable.Dispose()
{
if (this.impersonation != null)
{
this.impersonation.Dispose();
}
this.nullContextScope.Dispose();
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More