You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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";
|
||||
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user