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,379 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Runtime;
|
||||
using System.Runtime.Serialization;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Dispatcher;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
public abstract class AddressHeader
|
||||
{
|
||||
ParameterHeader header;
|
||||
|
||||
protected AddressHeader()
|
||||
{
|
||||
}
|
||||
|
||||
internal bool IsReferenceProperty
|
||||
{
|
||||
get
|
||||
{
|
||||
BufferedAddressHeader bah = this as BufferedAddressHeader;
|
||||
return bah != null && bah.IsReferencePropertyHeader;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract string Name { get; }
|
||||
public abstract string Namespace { get; }
|
||||
|
||||
public static AddressHeader CreateAddressHeader(object value)
|
||||
{
|
||||
Type type = GetObjectType(value);
|
||||
return CreateAddressHeader(value, DataContractSerializerDefaults.CreateSerializer(type, int.MaxValue/*maxItems*/));
|
||||
}
|
||||
|
||||
public static AddressHeader CreateAddressHeader(object value, XmlObjectSerializer serializer)
|
||||
{
|
||||
if (serializer == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serializer"));
|
||||
return new XmlObjectSerializerAddressHeader(value, serializer);
|
||||
}
|
||||
|
||||
public static AddressHeader CreateAddressHeader(string name, string ns, object value)
|
||||
{
|
||||
return CreateAddressHeader(name, ns, value, DataContractSerializerDefaults.CreateSerializer(GetObjectType(value), name, ns, int.MaxValue/*maxItems*/));
|
||||
}
|
||||
|
||||
internal static AddressHeader CreateAddressHeader(XmlDictionaryString name, XmlDictionaryString ns, object value)
|
||||
{
|
||||
return new DictionaryAddressHeader(name, ns, value);
|
||||
}
|
||||
|
||||
public static AddressHeader CreateAddressHeader(string name, string ns, object value, XmlObjectSerializer serializer)
|
||||
{
|
||||
if (serializer == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serializer"));
|
||||
return new XmlObjectSerializerAddressHeader(name, ns, value, serializer);
|
||||
}
|
||||
|
||||
static Type GetObjectType(object value)
|
||||
{
|
||||
return (value == null) ? typeof(object) : value.GetType();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
AddressHeader hdr = obj as AddressHeader;
|
||||
if (hdr == null)
|
||||
return false;
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
string hdr1 = GetComparableForm(builder);
|
||||
|
||||
builder.Remove(0, builder.Length);
|
||||
string hdr2 = hdr.GetComparableForm(builder);
|
||||
|
||||
if (hdr1.Length != hdr2.Length)
|
||||
return false;
|
||||
|
||||
if (string.CompareOrdinal(hdr1, hdr2) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal string GetComparableForm()
|
||||
{
|
||||
return GetComparableForm(new StringBuilder());
|
||||
}
|
||||
|
||||
internal string GetComparableForm(StringBuilder builder)
|
||||
{
|
||||
return EndpointAddressProcessor.GetComparableForm(builder, GetComparableReader());
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return GetComparableForm().GetHashCode();
|
||||
}
|
||||
|
||||
public T GetValue<T>()
|
||||
{
|
||||
return GetValue<T>(DataContractSerializerDefaults.CreateSerializer(typeof(T), this.Name, this.Namespace, int.MaxValue/*maxItems*/));
|
||||
}
|
||||
|
||||
public T GetValue<T>(XmlObjectSerializer serializer)
|
||||
{
|
||||
if (serializer == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serializer"));
|
||||
using (XmlDictionaryReader reader = GetAddressHeaderReader())
|
||||
{
|
||||
if (serializer.IsStartObject(reader))
|
||||
return (T)serializer.ReadObject(reader);
|
||||
else
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.GetString(SR.ExpectedElementMissing, Name, Namespace)));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual XmlDictionaryReader GetAddressHeaderReader()
|
||||
{
|
||||
XmlBuffer buffer = new XmlBuffer(int.MaxValue);
|
||||
XmlDictionaryWriter writer = buffer.OpenSection(XmlDictionaryReaderQuotas.Max);
|
||||
WriteAddressHeader(writer);
|
||||
buffer.CloseSection();
|
||||
buffer.Close();
|
||||
return buffer.GetReader(0);
|
||||
}
|
||||
|
||||
XmlDictionaryReader GetComparableReader()
|
||||
{
|
||||
XmlBuffer buffer = new XmlBuffer(int.MaxValue);
|
||||
XmlDictionaryWriter writer = buffer.OpenSection(XmlDictionaryReaderQuotas.Max);
|
||||
// WSAddressingAugust2004 does not write the IsReferenceParameter attribute,
|
||||
// and that's good for a consistent comparable form
|
||||
ParameterHeader.WriteStartHeader(writer, this, AddressingVersion.WSAddressingAugust2004);
|
||||
ParameterHeader.WriteHeaderContents(writer, this);
|
||||
writer.WriteEndElement();
|
||||
buffer.CloseSection();
|
||||
buffer.Close();
|
||||
return buffer.GetReader(0);
|
||||
}
|
||||
|
||||
protected virtual void OnWriteStartAddressHeader(XmlDictionaryWriter writer)
|
||||
{
|
||||
writer.WriteStartElement(Name, Namespace);
|
||||
}
|
||||
|
||||
protected abstract void OnWriteAddressHeaderContents(XmlDictionaryWriter writer);
|
||||
|
||||
public MessageHeader ToMessageHeader()
|
||||
{
|
||||
if (header == null)
|
||||
header = new ParameterHeader(this);
|
||||
return header;
|
||||
}
|
||||
|
||||
public void WriteAddressHeader(XmlWriter writer)
|
||||
{
|
||||
WriteAddressHeader(XmlDictionaryWriter.CreateDictionaryWriter(writer));
|
||||
}
|
||||
|
||||
public void WriteAddressHeader(XmlDictionaryWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
|
||||
WriteStartAddressHeader(writer);
|
||||
WriteAddressHeaderContents(writer);
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
public void WriteStartAddressHeader(XmlDictionaryWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
|
||||
OnWriteStartAddressHeader(writer);
|
||||
}
|
||||
|
||||
public void WriteAddressHeaderContents(XmlDictionaryWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
|
||||
OnWriteAddressHeaderContents(writer);
|
||||
}
|
||||
|
||||
class ParameterHeader : MessageHeader
|
||||
{
|
||||
AddressHeader parameter;
|
||||
|
||||
public override bool IsReferenceParameter
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return parameter.Name; }
|
||||
}
|
||||
|
||||
public override string Namespace
|
||||
{
|
||||
get { return parameter.Namespace; }
|
||||
}
|
||||
|
||||
public ParameterHeader(AddressHeader parameter)
|
||||
{
|
||||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
|
||||
{
|
||||
if (messageVersion == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("messageVersion"));
|
||||
|
||||
WriteStartHeader(writer, parameter, messageVersion.Addressing);
|
||||
}
|
||||
|
||||
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
|
||||
{
|
||||
WriteHeaderContents(writer, parameter);
|
||||
}
|
||||
|
||||
internal static void WriteStartHeader(XmlDictionaryWriter writer, AddressHeader parameter, AddressingVersion addressingVersion)
|
||||
{
|
||||
parameter.WriteStartAddressHeader(writer);
|
||||
if (addressingVersion == AddressingVersion.WSAddressing10)
|
||||
{
|
||||
writer.WriteAttributeString(XD.AddressingDictionary.IsReferenceParameter, XD.Addressing10Dictionary.Namespace, "true");
|
||||
}
|
||||
}
|
||||
|
||||
internal static void WriteHeaderContents(XmlDictionaryWriter writer, AddressHeader parameter)
|
||||
{
|
||||
parameter.WriteAddressHeaderContents(writer);
|
||||
}
|
||||
}
|
||||
|
||||
class XmlObjectSerializerAddressHeader : AddressHeader
|
||||
{
|
||||
XmlObjectSerializer serializer;
|
||||
object objectToSerialize;
|
||||
string name;
|
||||
string ns;
|
||||
|
||||
public XmlObjectSerializerAddressHeader(object objectToSerialize, XmlObjectSerializer serializer)
|
||||
{
|
||||
this.serializer = serializer;
|
||||
this.objectToSerialize = objectToSerialize;
|
||||
|
||||
Type type = (objectToSerialize == null) ? typeof(object) : objectToSerialize.GetType();
|
||||
XmlQualifiedName rootName = new XsdDataContractExporter().GetRootElementName(type);
|
||||
this.name = rootName.Name;
|
||||
this.ns = rootName.Namespace;
|
||||
}
|
||||
|
||||
public XmlObjectSerializerAddressHeader(string name, string ns, object objectToSerialize, XmlObjectSerializer serializer)
|
||||
{
|
||||
if ((null == name) || (name.Length == 0))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("name"));
|
||||
}
|
||||
|
||||
this.serializer = serializer;
|
||||
this.objectToSerialize = objectToSerialize;
|
||||
this.name = name;
|
||||
this.ns = ns;
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return name; }
|
||||
}
|
||||
|
||||
public override string Namespace
|
||||
{
|
||||
get { return ns; }
|
||||
}
|
||||
|
||||
object ThisLock
|
||||
{
|
||||
get { return this; }
|
||||
}
|
||||
|
||||
protected override void OnWriteAddressHeaderContents(XmlDictionaryWriter writer)
|
||||
{
|
||||
lock (ThisLock)
|
||||
{
|
||||
serializer.WriteObjectContent(writer, objectToSerialize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [....], This will be kept internal for now. If the optimization needs to be public, we'll re-evaluate it.
|
||||
class DictionaryAddressHeader : XmlObjectSerializerAddressHeader
|
||||
{
|
||||
XmlDictionaryString name;
|
||||
XmlDictionaryString ns;
|
||||
|
||||
public DictionaryAddressHeader(XmlDictionaryString name, XmlDictionaryString ns, object value)
|
||||
: base(name.Value, ns.Value, value, DataContractSerializerDefaults.CreateSerializer(GetObjectType(value), name, ns, int.MaxValue/*maxItems*/))
|
||||
{
|
||||
this.name = name;
|
||||
this.ns = ns;
|
||||
}
|
||||
|
||||
protected override void OnWriteStartAddressHeader(XmlDictionaryWriter writer)
|
||||
{
|
||||
writer.WriteStartElement(name, ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BufferedAddressHeader : AddressHeader
|
||||
{
|
||||
string name;
|
||||
string ns;
|
||||
XmlBuffer buffer;
|
||||
bool isReferenceProperty;
|
||||
|
||||
public BufferedAddressHeader(XmlDictionaryReader reader)
|
||||
{
|
||||
buffer = new XmlBuffer(int.MaxValue);
|
||||
XmlDictionaryWriter writer = buffer.OpenSection(reader.Quotas);
|
||||
Fx.Assert(reader.NodeType == XmlNodeType.Element, "");
|
||||
name = reader.LocalName;
|
||||
ns = reader.NamespaceURI;
|
||||
Fx.Assert(name != null, "");
|
||||
Fx.Assert(ns != null, "");
|
||||
writer.WriteNode(reader, false);
|
||||
buffer.CloseSection();
|
||||
buffer.Close();
|
||||
this.isReferenceProperty = false;
|
||||
}
|
||||
|
||||
public BufferedAddressHeader(XmlDictionaryReader reader, bool isReferenceProperty)
|
||||
: this(reader)
|
||||
{
|
||||
this.isReferenceProperty = isReferenceProperty;
|
||||
}
|
||||
|
||||
public bool IsReferencePropertyHeader { get { return this.isReferenceProperty; } }
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get { return name; }
|
||||
}
|
||||
|
||||
public override string Namespace
|
||||
{
|
||||
get { return ns; }
|
||||
}
|
||||
|
||||
public override XmlDictionaryReader GetAddressHeaderReader()
|
||||
{
|
||||
return buffer.GetReader(0);
|
||||
}
|
||||
|
||||
protected override void OnWriteStartAddressHeader(XmlDictionaryWriter writer)
|
||||
{
|
||||
XmlDictionaryReader reader = GetAddressHeaderReader();
|
||||
writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
|
||||
writer.WriteAttributes(reader, false);
|
||||
reader.Close();
|
||||
}
|
||||
|
||||
protected override void OnWriteAddressHeaderContents(XmlDictionaryWriter writer)
|
||||
{
|
||||
XmlDictionaryReader reader = GetAddressHeaderReader();
|
||||
reader.ReadStartElement();
|
||||
while (reader.NodeType != XmlNodeType.EndElement)
|
||||
writer.WriteNode(reader, false);
|
||||
reader.ReadEndElement();
|
||||
reader.Close();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,239 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.ServiceModel;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
using System.ServiceModel.Security;
|
||||
using System.IdentityModel.Claims;
|
||||
using System.IdentityModel.Policy;
|
||||
|
||||
public sealed class AddressHeaderCollection : ReadOnlyCollection<AddressHeader>
|
||||
{
|
||||
static AddressHeaderCollection emptyHeaderCollection = new AddressHeaderCollection();
|
||||
|
||||
public AddressHeaderCollection()
|
||||
: base(new List<AddressHeader>())
|
||||
{
|
||||
}
|
||||
|
||||
public AddressHeaderCollection(IEnumerable<AddressHeader> addressHeaders)
|
||||
: base(new List<AddressHeader>(addressHeaders))
|
||||
{
|
||||
// avoid allocating an enumerator when possible
|
||||
IList<AddressHeader> collection = addressHeaders as IList<AddressHeader>;
|
||||
if (collection != null)
|
||||
{
|
||||
for (int i = 0; i < collection.Count; i++)
|
||||
{
|
||||
if (collection[i] == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MessageHeaderIsNull0)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (AddressHeader addressHeader in addressHeaders)
|
||||
{
|
||||
if (addressHeaders == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MessageHeaderIsNull0)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static AddressHeaderCollection EmptyHeaderCollection
|
||||
{
|
||||
get { return emptyHeaderCollection; }
|
||||
}
|
||||
|
||||
int InternalCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this == (object)emptyHeaderCollection)
|
||||
return 0;
|
||||
return Count;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddHeadersTo(Message message)
|
||||
{
|
||||
if (message == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
|
||||
|
||||
for (int i = 0; i < InternalCount; i++)
|
||||
{
|
||||
#pragma warning suppress 56506 // [....], Message.Headers can never be null
|
||||
message.Headers.Add(this[i].ToMessageHeader());
|
||||
}
|
||||
}
|
||||
|
||||
public AddressHeader[] FindAll(string name, string ns)
|
||||
{
|
||||
if (name == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("name"));
|
||||
if (ns == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("ns"));
|
||||
|
||||
List<AddressHeader> results = new List<AddressHeader>();
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
AddressHeader header = this[i];
|
||||
if (header.Name == name && header.Namespace == ns)
|
||||
{
|
||||
results.Add(header);
|
||||
}
|
||||
}
|
||||
|
||||
return results.ToArray();
|
||||
}
|
||||
|
||||
public AddressHeader FindHeader(string name, string ns)
|
||||
{
|
||||
if (name == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("name"));
|
||||
if (ns == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("ns"));
|
||||
|
||||
AddressHeader matchingHeader = null;
|
||||
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
AddressHeader header = this[i];
|
||||
if (header.Name == name && header.Namespace == ns)
|
||||
{
|
||||
if (matchingHeader != null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MultipleMessageHeaders, name, ns)));
|
||||
matchingHeader = header;
|
||||
}
|
||||
}
|
||||
|
||||
return matchingHeader;
|
||||
}
|
||||
|
||||
internal bool IsEquivalent(AddressHeaderCollection col)
|
||||
{
|
||||
if (InternalCount != col.InternalCount)
|
||||
return false;
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Dictionary<string, int> myHeaders = new Dictionary<string, int>();
|
||||
PopulateHeaderDictionary(builder, myHeaders);
|
||||
|
||||
Dictionary<string, int> otherHeaders = new Dictionary<string, int>();
|
||||
col.PopulateHeaderDictionary(builder, otherHeaders);
|
||||
|
||||
if (myHeaders.Count != otherHeaders.Count)
|
||||
return false;
|
||||
|
||||
foreach (KeyValuePair<string, int> pair in myHeaders)
|
||||
{
|
||||
int count;
|
||||
if (otherHeaders.TryGetValue(pair.Key, out count))
|
||||
{
|
||||
if (count != pair.Value)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void PopulateHeaderDictionary(StringBuilder builder, Dictionary<string, int> headers)
|
||||
{
|
||||
string key;
|
||||
for (int i = 0; i < InternalCount; ++i)
|
||||
{
|
||||
builder.Remove(0, builder.Length);
|
||||
key = this[i].GetComparableForm(builder);
|
||||
if (headers.ContainsKey(key))
|
||||
{
|
||||
headers[key] = headers[key] + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
headers.Add(key, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static AddressHeaderCollection ReadServiceParameters(XmlDictionaryReader reader)
|
||||
{
|
||||
return ReadServiceParameters(reader, false);
|
||||
}
|
||||
|
||||
internal static AddressHeaderCollection ReadServiceParameters(XmlDictionaryReader reader, bool isReferenceProperty)
|
||||
{
|
||||
reader.MoveToContent();
|
||||
if (reader.IsEmptyElement)
|
||||
{
|
||||
reader.Skip();
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.ReadStartElement();
|
||||
List<AddressHeader> headerList = new List<AddressHeader>();
|
||||
while (reader.IsStartElement())
|
||||
{
|
||||
headerList.Add(new BufferedAddressHeader(reader, isReferenceProperty));
|
||||
}
|
||||
reader.ReadEndElement();
|
||||
return new AddressHeaderCollection(headerList);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasReferenceProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < InternalCount; i++)
|
||||
if (this[i].IsReferenceProperty)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasNonReferenceProperties
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < InternalCount; i++)
|
||||
if (!this[i].IsReferenceProperty)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteReferencePropertyContentsTo(XmlDictionaryWriter writer)
|
||||
{
|
||||
for (int i = 0; i < InternalCount; i++)
|
||||
if (this[i].IsReferenceProperty)
|
||||
this[i].WriteAddressHeader(writer);
|
||||
}
|
||||
|
||||
internal void WriteNonReferencePropertyContentsTo(XmlDictionaryWriter writer)
|
||||
{
|
||||
for (int i = 0; i < InternalCount; i++)
|
||||
if (!this[i].IsReferenceProperty)
|
||||
this[i].WriteAddressHeader(writer);
|
||||
}
|
||||
|
||||
internal void WriteContentsTo(XmlDictionaryWriter writer)
|
||||
{
|
||||
for (int i = 0; i < InternalCount; i++)
|
||||
this[i].WriteAddressHeader(writer);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,176 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Runtime.Serialization;
|
||||
using System.Xml;
|
||||
using System.ServiceModel.Security;
|
||||
|
||||
public sealed class AddressingVersion
|
||||
{
|
||||
string ns;
|
||||
XmlDictionaryString dictionaryNs;
|
||||
MessagePartSpecification signedMessageParts;
|
||||
string toStringFormat;
|
||||
string anonymous;
|
||||
XmlDictionaryString dictionaryAnonymous;
|
||||
Uri anonymousUri;
|
||||
Uri noneUri;
|
||||
string faultAction;
|
||||
string defaultFaultAction;
|
||||
|
||||
static AddressingVersion none = new AddressingVersion(AddressingNoneStrings.Namespace, XD.AddressingNoneDictionary.Namespace,
|
||||
SR.AddressingNoneToStringFormat, new MessagePartSpecification(), null, null, null, null, null);
|
||||
|
||||
static AddressingVersion addressing10 = new AddressingVersion(Addressing10Strings.Namespace,
|
||||
XD.Addressing10Dictionary.Namespace, SR.Addressing10ToStringFormat, Addressing10SignedMessageParts,
|
||||
Addressing10Strings.Anonymous, XD.Addressing10Dictionary.Anonymous, Addressing10Strings.NoneAddress,
|
||||
Addressing10Strings.FaultAction, Addressing10Strings.DefaultFaultAction);
|
||||
static MessagePartSpecification addressing10SignedMessageParts;
|
||||
|
||||
static AddressingVersion addressing200408 = new AddressingVersion(Addressing200408Strings.Namespace,
|
||||
XD.Addressing200408Dictionary.Namespace, SR.Addressing200408ToStringFormat, Addressing200408SignedMessageParts,
|
||||
Addressing200408Strings.Anonymous, XD.Addressing200408Dictionary.Anonymous, null,
|
||||
Addressing200408Strings.FaultAction, Addressing200408Strings.DefaultFaultAction);
|
||||
static MessagePartSpecification addressing200408SignedMessageParts;
|
||||
|
||||
AddressingVersion(string ns, XmlDictionaryString dictionaryNs, string toStringFormat,
|
||||
MessagePartSpecification signedMessageParts, string anonymous, XmlDictionaryString dictionaryAnonymous, string none, string faultAction, string defaultFaultAction)
|
||||
{
|
||||
this.ns = ns;
|
||||
this.dictionaryNs = dictionaryNs;
|
||||
this.toStringFormat = toStringFormat;
|
||||
this.signedMessageParts = signedMessageParts;
|
||||
this.anonymous = anonymous;
|
||||
this.dictionaryAnonymous = dictionaryAnonymous;
|
||||
|
||||
if (anonymous != null)
|
||||
{
|
||||
this.anonymousUri = new Uri(anonymous);
|
||||
}
|
||||
|
||||
if (none != null)
|
||||
{
|
||||
this.noneUri = new Uri(none);
|
||||
}
|
||||
|
||||
this.faultAction = faultAction;
|
||||
this.defaultFaultAction = defaultFaultAction;
|
||||
}
|
||||
|
||||
public static AddressingVersion WSAddressingAugust2004
|
||||
{
|
||||
get { return addressing200408; }
|
||||
}
|
||||
|
||||
public static AddressingVersion WSAddressing10
|
||||
{
|
||||
get { return addressing10; }
|
||||
}
|
||||
|
||||
public static AddressingVersion None
|
||||
{
|
||||
get { return none; }
|
||||
}
|
||||
|
||||
internal string Namespace
|
||||
{
|
||||
get { return ns; }
|
||||
}
|
||||
|
||||
static MessagePartSpecification Addressing10SignedMessageParts
|
||||
{
|
||||
get
|
||||
{
|
||||
if (addressing10SignedMessageParts == null)
|
||||
{
|
||||
MessagePartSpecification s = new MessagePartSpecification(
|
||||
new XmlQualifiedName(AddressingStrings.To, Addressing10Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.From, Addressing10Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.FaultTo, Addressing10Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.ReplyTo, Addressing10Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.MessageId, Addressing10Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.RelatesTo, Addressing10Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.Action, Addressing10Strings.Namespace)
|
||||
);
|
||||
s.MakeReadOnly();
|
||||
addressing10SignedMessageParts = s;
|
||||
}
|
||||
|
||||
return addressing10SignedMessageParts;
|
||||
}
|
||||
}
|
||||
|
||||
static MessagePartSpecification Addressing200408SignedMessageParts
|
||||
{
|
||||
get
|
||||
{
|
||||
if (addressing200408SignedMessageParts == null)
|
||||
{
|
||||
MessagePartSpecification s = new MessagePartSpecification(
|
||||
new XmlQualifiedName(AddressingStrings.To, Addressing200408Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.From, Addressing200408Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.FaultTo, Addressing200408Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.ReplyTo, Addressing200408Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.MessageId, Addressing200408Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.RelatesTo, Addressing200408Strings.Namespace),
|
||||
new XmlQualifiedName(AddressingStrings.Action, Addressing200408Strings.Namespace)
|
||||
);
|
||||
s.MakeReadOnly();
|
||||
addressing200408SignedMessageParts = s;
|
||||
}
|
||||
|
||||
return addressing200408SignedMessageParts;
|
||||
}
|
||||
}
|
||||
|
||||
internal XmlDictionaryString DictionaryNamespace
|
||||
{
|
||||
get { return dictionaryNs; }
|
||||
}
|
||||
|
||||
internal string Anonymous
|
||||
{
|
||||
get { return anonymous; }
|
||||
}
|
||||
|
||||
internal XmlDictionaryString DictionaryAnonymous
|
||||
{
|
||||
get { return dictionaryAnonymous; }
|
||||
}
|
||||
|
||||
internal Uri AnonymousUri
|
||||
{
|
||||
get { return anonymousUri; }
|
||||
}
|
||||
|
||||
internal Uri NoneUri
|
||||
{
|
||||
get { return noneUri; }
|
||||
}
|
||||
|
||||
internal string FaultAction // the action for addressing faults
|
||||
{
|
||||
get { return faultAction; }
|
||||
}
|
||||
|
||||
internal string DefaultFaultAction // a default string that can be used for non-addressing faults
|
||||
{
|
||||
get { return defaultFaultAction; }
|
||||
}
|
||||
|
||||
internal MessagePartSpecification SignedMessageParts
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.signedMessageParts;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return SR.GetString(toStringFormat, Namespace);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,262 @@
|
||||
// <copyright>
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using System.Runtime;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
|
||||
using SafeCloseHandle = System.ServiceModel.Activation.SafeCloseHandle;
|
||||
|
||||
/// <summary>
|
||||
/// This class provides the entry points into Application Container related functionality.
|
||||
/// Callers are expected to check if the application is running in an AppContainer before
|
||||
/// invoking any of the methods in this class.
|
||||
/// </summary>
|
||||
class AppContainerInfo
|
||||
{
|
||||
static object thisLock = new object();
|
||||
static bool isAppContainerSupported;
|
||||
static bool isRunningInAppContainer;
|
||||
static volatile bool isRunningInAppContainerSet;
|
||||
static object isRunningInAppContainerLock = new object();
|
||||
static int? currentSessionId;
|
||||
static volatile SecurityIdentifier currentAppContainerSid;
|
||||
|
||||
static AppContainerInfo()
|
||||
{
|
||||
// AppContainers are supported starting in Win8
|
||||
isAppContainerSupported = OSEnvironmentHelper.IsAtLeast(OSVersion.Win8);
|
||||
|
||||
if (!isAppContainerSupported)
|
||||
{
|
||||
isRunningInAppContainerSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
AppContainerInfo(int sessionId, string namedObjectPath)
|
||||
{
|
||||
this.SessionId = sessionId;
|
||||
this.NamedObjectPath = namedObjectPath;
|
||||
}
|
||||
|
||||
internal static bool IsAppContainerSupported
|
||||
{
|
||||
get
|
||||
{
|
||||
return isAppContainerSupported;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool IsRunningInAppContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
// The AppContainerInfo.RunningInAppContainer() API may throw security exceptions,
|
||||
// so cannot be used inside the static constructor of the class.
|
||||
if (!isRunningInAppContainerSet)
|
||||
{
|
||||
lock (isRunningInAppContainerLock)
|
||||
{
|
||||
if (!isRunningInAppContainerSet)
|
||||
{
|
||||
isRunningInAppContainer = AppContainerInfo.RunningInAppContainer();
|
||||
isRunningInAppContainerSet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isRunningInAppContainer;
|
||||
}
|
||||
}
|
||||
|
||||
internal int SessionId { get; private set; }
|
||||
|
||||
internal string NamedObjectPath { get; private set; }
|
||||
|
||||
internal static AppContainerInfo CreateAppContainerInfo(string fullName, int sessionId)
|
||||
{
|
||||
Fx.Assert(IsAppContainerSupported, "AppContainers are not supported.");
|
||||
Fx.Assert(!string.IsNullOrEmpty(fullName), "fullName should be provided to initialize an AppContainerInfo.");
|
||||
|
||||
int appSession = sessionId;
|
||||
if (appSession == ApplicationContainerSettings.CurrentSession)
|
||||
{
|
||||
lock (thisLock)
|
||||
{
|
||||
if (currentSessionId == null)
|
||||
{
|
||||
currentSessionId = AppContainerInfo.GetCurrentSessionId();
|
||||
}
|
||||
}
|
||||
|
||||
appSession = currentSessionId.Value;
|
||||
}
|
||||
|
||||
string namedObjectPath = AppContainerInfo.GetAppContainerNamedObjectPath(fullName);
|
||||
return new AppContainerInfo(appSession, namedObjectPath);
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
[Fx.Tag.SecurityNote(Critical = "This calls into the SecurityCritical method GetCurrentProcessToken and unsafe GetAppContainerSid.",
|
||||
Safe = "All critical token access and dispose is ensured. " +
|
||||
" The Sid is a non protected resource and can be obtained only if we have the appropriate process token permissions.")]
|
||||
internal static SecurityIdentifier GetCurrentAppContainerSid()
|
||||
{
|
||||
Fx.Assert(AppContainerInfo.IsAppContainerSupported, "AppContainers are not supported.");
|
||||
if (currentAppContainerSid == null)
|
||||
{
|
||||
lock (thisLock)
|
||||
{
|
||||
if (currentAppContainerSid == null)
|
||||
{
|
||||
SafeCloseHandle tokenHandle = null;
|
||||
try
|
||||
{
|
||||
tokenHandle = AppContainerInfo.GetCurrentProcessToken();
|
||||
currentAppContainerSid = UnsafeNativeMethods.GetAppContainerSid(tokenHandle);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tokenHandle != null)
|
||||
{
|
||||
tokenHandle.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentAppContainerSid;
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
[Fx.Tag.SecurityNote(Safe = "Process token handle access and dispose is ensured here and we only return a non-critical flag.")]
|
||||
static bool RunningInAppContainer()
|
||||
{
|
||||
Fx.Assert(AppContainerInfo.IsAppContainerSupported, "AppContainers are not supported.");
|
||||
SafeCloseHandle tokenHandle = null;
|
||||
try
|
||||
{
|
||||
tokenHandle = AppContainerInfo.GetCurrentProcessToken();
|
||||
return UnsafeNativeMethods.RunningInAppContainer(tokenHandle);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tokenHandle != null)
|
||||
{
|
||||
tokenHandle.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
[Fx.Tag.SecurityNote(Critical = "Calls into unsafe native AppContainer package resolution methods.",
|
||||
Safe = "Wraps all access and disposal of securityDescriptors and returns a NamedObjectPath, " +
|
||||
"which is a non protected resource.")]
|
||||
static string GetAppContainerNamedObjectPath(string name)
|
||||
{
|
||||
// 1. Derive the PackageFamilyName(PFN) from the PackageFullName
|
||||
// 2. Get the AppContainerSID from the PFN
|
||||
// 3. Get the NamedObjectPath from the AppContainerSID
|
||||
Fx.Assert(AppContainerInfo.IsAppContainerSupported, "AppContainers are not supported.");
|
||||
IntPtr appContainerSid = IntPtr.Zero;
|
||||
|
||||
// Package Full Name => Package family name
|
||||
uint packageFamilyNameLength = UnsafeNativeMethods.MAX_PATH;
|
||||
StringBuilder packageFamilyNameBuilder = new StringBuilder((int)UnsafeNativeMethods.MAX_PATH);
|
||||
string packageFamilyName;
|
||||
int errorCode = UnsafeNativeMethods.PackageFamilyNameFromFullName(name, ref packageFamilyNameLength, packageFamilyNameBuilder);
|
||||
if (errorCode != UnsafeNativeMethods.ERROR_SUCCESS)
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new Win32Exception(errorCode, SR.GetString(SR.PackageFullNameInvalid, name)));
|
||||
}
|
||||
|
||||
packageFamilyName = packageFamilyNameBuilder.ToString();
|
||||
|
||||
try
|
||||
{
|
||||
// PackageFamilyName => AppContainerSID
|
||||
int hresult = UnsafeNativeMethods.DeriveAppContainerSidFromAppContainerName(
|
||||
packageFamilyName,
|
||||
out appContainerSid);
|
||||
if (hresult != 0)
|
||||
{
|
||||
errorCode = Marshal.GetLastWin32Error();
|
||||
throw FxTrace.Exception.AsError(new Win32Exception(errorCode));
|
||||
}
|
||||
|
||||
// AppContainerSID => NamedObjectPath
|
||||
StringBuilder namedObjectPath = new StringBuilder((int)UnsafeNativeMethods.MAX_PATH);
|
||||
uint returnLength = 0;
|
||||
if (!UnsafeNativeMethods.GetAppContainerNamedObjectPath(
|
||||
IntPtr.Zero,
|
||||
appContainerSid,
|
||||
UnsafeNativeMethods.MAX_PATH,
|
||||
namedObjectPath,
|
||||
ref returnLength))
|
||||
{
|
||||
errorCode = Marshal.GetLastWin32Error();
|
||||
throw FxTrace.Exception.AsError(new Win32Exception(errorCode));
|
||||
}
|
||||
|
||||
return namedObjectPath.ToString();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (appContainerSid != IntPtr.Zero)
|
||||
{
|
||||
UnsafeNativeMethods.FreeSid(appContainerSid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SecuritySafeCritical]
|
||||
[Fx.Tag.SecurityNote(Critical = "Accesses the native current process token.",
|
||||
Safe = "The session id returned is a non-critical resource and " +
|
||||
" we ensure that the current process token handle created is disposed here.")]
|
||||
static int GetCurrentSessionId()
|
||||
{
|
||||
Fx.Assert(AppContainerInfo.IsAppContainerSupported, "AppContainers are not supported.");
|
||||
SafeCloseHandle tokenHandle = null;
|
||||
try
|
||||
{
|
||||
tokenHandle = AppContainerInfo.GetCurrentProcessToken();
|
||||
return UnsafeNativeMethods.GetSessionId(tokenHandle);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (tokenHandle != null)
|
||||
{
|
||||
tokenHandle.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the process token using TokenAccessLevels.Query
|
||||
/// </summary>
|
||||
/// <returns>ProcessToken as a SafeCloseHandle.</returns>
|
||||
[SecurityCritical]
|
||||
[Fx.Tag.SecurityNote(Critical = "Returns a process token. The caller is responsible for disposing the SafeCloseHandle.")]
|
||||
static SafeCloseHandle GetCurrentProcessToken()
|
||||
{
|
||||
SafeCloseHandle tokenHandle = null;
|
||||
if (!UnsafeNativeMethods.OpenProcessToken(
|
||||
UnsafeNativeMethods.GetCurrentProcess(),
|
||||
TokenAccessLevels.Query,
|
||||
out tokenHandle))
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
throw FxTrace.Exception.AsError(new Win32Exception(error));
|
||||
}
|
||||
|
||||
return tokenHandle;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,100 @@
|
||||
// <copyright>
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Runtime;
|
||||
|
||||
public sealed class ApplicationContainerSettings
|
||||
{
|
||||
public const int CurrentSession = ApplicationContainerSettingsDefaults.CurrentSession;
|
||||
public const int ServiceSession = ApplicationContainerSettingsDefaults.ServiceSession;
|
||||
const string GroupNameSuffixFormat = ";SessionId={0};PackageFullName={1}";
|
||||
|
||||
int sessionId;
|
||||
|
||||
internal ApplicationContainerSettings()
|
||||
{
|
||||
this.PackageFullName = ApplicationContainerSettingsDefaults.PackageFullNameDefaultString;
|
||||
this.sessionId = ApplicationContainerSettingsDefaults.CurrentSession;
|
||||
}
|
||||
|
||||
ApplicationContainerSettings(ApplicationContainerSettings source)
|
||||
{
|
||||
this.PackageFullName = source.PackageFullName;
|
||||
this.sessionId = source.sessionId;
|
||||
}
|
||||
|
||||
public string PackageFullName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public int SessionId
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.sessionId;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
// CurrentSession default is -1 and expect the user to set
|
||||
// non-negative windows session Id.
|
||||
if (value < ApplicationContainerSettingsDefaults.CurrentSession)
|
||||
{
|
||||
throw FxTrace.Exception.Argument("value", SR.GetString(SR.SessionValueInvalid, value));
|
||||
}
|
||||
|
||||
this.sessionId = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool TargetingAppContainer
|
||||
{
|
||||
get
|
||||
{
|
||||
return !string.IsNullOrEmpty(this.PackageFullName);
|
||||
}
|
||||
}
|
||||
|
||||
internal ApplicationContainerSettings Clone()
|
||||
{
|
||||
return new ApplicationContainerSettings(this);
|
||||
}
|
||||
|
||||
internal string GetConnectionGroupSuffix()
|
||||
{
|
||||
string suffix = string.Empty;
|
||||
if (AppContainerInfo.IsAppContainerSupported && this.TargetingAppContainer)
|
||||
{
|
||||
suffix = string.Format(CultureInfo.InvariantCulture, GroupNameSuffixFormat, this.SessionId, this.PackageFullName);
|
||||
}
|
||||
|
||||
return suffix;
|
||||
}
|
||||
|
||||
internal bool IsMatch(ApplicationContainerSettings applicationContainerSettings)
|
||||
{
|
||||
if (applicationContainerSettings == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.PackageFullName != applicationContainerSettings.PackageFullName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.sessionId != applicationContainerSettings.sessionId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,474 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System;
|
||||
using System.ServiceModel.Description;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Security;
|
||||
using System.ServiceModel.Security.Tokens;
|
||||
|
||||
using System.Net.Security;
|
||||
using System.Text;
|
||||
|
||||
public sealed class AsymmetricSecurityBindingElement : SecurityBindingElement, IPolicyExportExtension
|
||||
{
|
||||
internal const bool defaultAllowSerializedSigningTokenOnReply = false;
|
||||
|
||||
bool allowSerializedSigningTokenOnReply;
|
||||
SecurityTokenParameters initiatorTokenParameters;
|
||||
MessageProtectionOrder messageProtectionOrder;
|
||||
SecurityTokenParameters recipientTokenParameters;
|
||||
bool requireSignatureConfirmation;
|
||||
bool isCertificateSignatureBinding;
|
||||
|
||||
AsymmetricSecurityBindingElement(AsymmetricSecurityBindingElement elementToBeCloned)
|
||||
: base(elementToBeCloned)
|
||||
{
|
||||
if (elementToBeCloned.initiatorTokenParameters != null)
|
||||
this.initiatorTokenParameters = (SecurityTokenParameters)elementToBeCloned.initiatorTokenParameters.Clone();
|
||||
this.messageProtectionOrder = elementToBeCloned.messageProtectionOrder;
|
||||
if (elementToBeCloned.recipientTokenParameters != null)
|
||||
this.recipientTokenParameters = (SecurityTokenParameters)elementToBeCloned.recipientTokenParameters.Clone();
|
||||
this.requireSignatureConfirmation = elementToBeCloned.requireSignatureConfirmation;
|
||||
this.allowSerializedSigningTokenOnReply = elementToBeCloned.allowSerializedSigningTokenOnReply;
|
||||
this.isCertificateSignatureBinding = elementToBeCloned.isCertificateSignatureBinding;
|
||||
}
|
||||
|
||||
public AsymmetricSecurityBindingElement()
|
||||
: this(null, null)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
public AsymmetricSecurityBindingElement(SecurityTokenParameters recipientTokenParameters)
|
||||
: this(recipientTokenParameters, null)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
public AsymmetricSecurityBindingElement(SecurityTokenParameters recipientTokenParameters, SecurityTokenParameters initiatorTokenParameters)
|
||||
: this(recipientTokenParameters, initiatorTokenParameters, AsymmetricSecurityBindingElement.defaultAllowSerializedSigningTokenOnReply)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
internal AsymmetricSecurityBindingElement(
|
||||
SecurityTokenParameters recipientTokenParameters,
|
||||
SecurityTokenParameters initiatorTokenParameters,
|
||||
bool allowSerializedSigningTokenOnReply)
|
||||
: base()
|
||||
{
|
||||
this.messageProtectionOrder = SecurityBindingElement.defaultMessageProtectionOrder;
|
||||
this.requireSignatureConfirmation = SecurityBindingElement.defaultRequireSignatureConfirmation;
|
||||
this.initiatorTokenParameters = initiatorTokenParameters;
|
||||
this.recipientTokenParameters = recipientTokenParameters;
|
||||
this.allowSerializedSigningTokenOnReply = allowSerializedSigningTokenOnReply;
|
||||
this.isCertificateSignatureBinding = false;
|
||||
}
|
||||
|
||||
public bool AllowSerializedSigningTokenOnReply
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.allowSerializedSigningTokenOnReply;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.allowSerializedSigningTokenOnReply = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SecurityTokenParameters InitiatorTokenParameters
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.initiatorTokenParameters;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.initiatorTokenParameters = value;
|
||||
}
|
||||
}
|
||||
|
||||
public MessageProtectionOrder MessageProtectionOrder
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.messageProtectionOrder;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!MessageProtectionOrderHelper.IsDefined(value))
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
|
||||
this.messageProtectionOrder = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SecurityTokenParameters RecipientTokenParameters
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.recipientTokenParameters;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.recipientTokenParameters = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool RequireSignatureConfirmation
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.requireSignatureConfirmation;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.requireSignatureConfirmation = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal override ISecurityCapabilities GetIndividualISecurityCapabilities()
|
||||
{
|
||||
ProtectionLevel requestProtectionLevel = ProtectionLevel.EncryptAndSign;
|
||||
ProtectionLevel responseProtectionLevel = ProtectionLevel.EncryptAndSign;
|
||||
bool supportsServerAuthentication = false;
|
||||
|
||||
if (IsCertificateSignatureBinding)
|
||||
{
|
||||
requestProtectionLevel = ProtectionLevel.Sign;
|
||||
responseProtectionLevel = ProtectionLevel.None;
|
||||
}
|
||||
else if (RecipientTokenParameters != null)
|
||||
{
|
||||
supportsServerAuthentication = RecipientTokenParameters.SupportsServerAuthentication;
|
||||
}
|
||||
|
||||
bool supportsClientAuthentication;
|
||||
bool supportsClientWindowsIdentity;
|
||||
GetSupportingTokensCapabilities(out supportsClientAuthentication, out supportsClientWindowsIdentity);
|
||||
if (InitiatorTokenParameters != null)
|
||||
{
|
||||
supportsClientAuthentication = supportsClientAuthentication || InitiatorTokenParameters.SupportsClientAuthentication;
|
||||
supportsClientWindowsIdentity = supportsClientWindowsIdentity || InitiatorTokenParameters.SupportsClientWindowsIdentity;
|
||||
}
|
||||
|
||||
return new SecurityCapabilities(supportsClientAuthentication, supportsServerAuthentication, supportsClientWindowsIdentity,
|
||||
requestProtectionLevel, responseProtectionLevel);
|
||||
}
|
||||
|
||||
internal override bool SupportsDuplex
|
||||
{
|
||||
get { return !this.isCertificateSignatureBinding; }
|
||||
}
|
||||
|
||||
internal override bool SupportsRequestReply
|
||||
{
|
||||
get
|
||||
{
|
||||
return !this.isCertificateSignatureBinding;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsCertificateSignatureBinding
|
||||
{
|
||||
get { return this.isCertificateSignatureBinding; }
|
||||
set { this.isCertificateSignatureBinding = value; }
|
||||
}
|
||||
|
||||
public override void SetKeyDerivation(bool requireDerivedKeys)
|
||||
{
|
||||
base.SetKeyDerivation(requireDerivedKeys);
|
||||
if (this.initiatorTokenParameters != null)
|
||||
this.initiatorTokenParameters.RequireDerivedKeys = requireDerivedKeys;
|
||||
if (this.recipientTokenParameters != null)
|
||||
this.recipientTokenParameters.RequireDerivedKeys = requireDerivedKeys;
|
||||
}
|
||||
|
||||
internal override bool IsSetKeyDerivation(bool requireDerivedKeys)
|
||||
{
|
||||
if (!base.IsSetKeyDerivation(requireDerivedKeys))
|
||||
return false;
|
||||
if (this.initiatorTokenParameters != null && this.initiatorTokenParameters.RequireDerivedKeys != requireDerivedKeys)
|
||||
return false;
|
||||
if (this.recipientTokenParameters != null && this.recipientTokenParameters.RequireDerivedKeys != requireDerivedKeys)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasProtectionRequirements(ScopedMessagePartSpecification scopedParts)
|
||||
{
|
||||
foreach (string action in scopedParts.Actions)
|
||||
{
|
||||
MessagePartSpecification parts;
|
||||
if (scopedParts.TryGetParts(action, out parts))
|
||||
{
|
||||
if (!parts.IsEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal override SecurityProtocolFactory CreateSecurityProtocolFactory<TChannel>(BindingContext context, SecurityCredentialsManager credentialsManager, bool isForService, BindingContext issuerBindingContext)
|
||||
{
|
||||
if (context == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
if (credentialsManager == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("credentialsManager");
|
||||
|
||||
if (this.InitiatorTokenParameters == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.AsymmetricSecurityBindingElementNeedsInitiatorTokenParameters, this.ToString())));
|
||||
if (this.RecipientTokenParameters == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.AsymmetricSecurityBindingElementNeedsRecipientTokenParameters, this.ToString())));
|
||||
|
||||
bool isDuplexSecurity = !this.isCertificateSignatureBinding && (typeof(IDuplexChannel) == typeof(TChannel) || typeof(IDuplexSessionChannel) == typeof(TChannel));
|
||||
|
||||
SecurityProtocolFactory protocolFactory;
|
||||
|
||||
AsymmetricSecurityProtocolFactory forward = new AsymmetricSecurityProtocolFactory();
|
||||
forward.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, isForService));
|
||||
forward.RequireConfidentiality = this.HasProtectionRequirements(forward.ProtectionRequirements.IncomingEncryptionParts);
|
||||
forward.RequireIntegrity = this.HasProtectionRequirements(forward.ProtectionRequirements.IncomingSignatureParts);
|
||||
if (this.isCertificateSignatureBinding)
|
||||
{
|
||||
if (isForService)
|
||||
{
|
||||
forward.ApplyIntegrity = forward.ApplyConfidentiality = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
forward.ApplyConfidentiality = forward.RequireIntegrity = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
forward.ApplyIntegrity = this.HasProtectionRequirements(forward.ProtectionRequirements.OutgoingSignatureParts);
|
||||
forward.ApplyConfidentiality = this.HasProtectionRequirements(forward.ProtectionRequirements.OutgoingEncryptionParts);
|
||||
}
|
||||
if (isForService)
|
||||
{
|
||||
base.ApplyAuditBehaviorSettings(context, forward);
|
||||
if (forward.RequireConfidentiality || (!this.isCertificateSignatureBinding && forward.ApplyIntegrity))
|
||||
{
|
||||
forward.AsymmetricTokenParameters = (SecurityTokenParameters)this.RecipientTokenParameters.Clone();
|
||||
}
|
||||
else
|
||||
{
|
||||
forward.AsymmetricTokenParameters = null;
|
||||
}
|
||||
forward.CryptoTokenParameters = this.InitiatorTokenParameters.Clone();
|
||||
SetIssuerBindingContextIfRequired(forward.CryptoTokenParameters, issuerBindingContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (forward.ApplyConfidentiality || (!this.isCertificateSignatureBinding && forward.RequireIntegrity))
|
||||
{
|
||||
forward.AsymmetricTokenParameters = (SecurityTokenParameters)this.RecipientTokenParameters.Clone();
|
||||
}
|
||||
else
|
||||
{
|
||||
forward.AsymmetricTokenParameters = null;
|
||||
}
|
||||
forward.CryptoTokenParameters = this.InitiatorTokenParameters.Clone();
|
||||
SetIssuerBindingContextIfRequired(forward.CryptoTokenParameters, issuerBindingContext);
|
||||
}
|
||||
if (isDuplexSecurity)
|
||||
{
|
||||
if (isForService)
|
||||
{
|
||||
forward.ApplyConfidentiality = forward.ApplyIntegrity = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
forward.RequireIntegrity = forward.RequireConfidentiality = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isForService)
|
||||
{
|
||||
forward.AllowSerializedSigningTokenOnReply = this.AllowSerializedSigningTokenOnReply;
|
||||
}
|
||||
}
|
||||
|
||||
forward.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
|
||||
forward.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
|
||||
forward.MessageProtectionOrder = this.MessageProtectionOrder;
|
||||
base.ConfigureProtocolFactory(forward, credentialsManager, isForService, issuerBindingContext, context.Binding);
|
||||
if (!forward.RequireIntegrity)
|
||||
forward.DetectReplays = false;
|
||||
|
||||
if (isDuplexSecurity)
|
||||
{
|
||||
AsymmetricSecurityProtocolFactory reverse = new AsymmetricSecurityProtocolFactory();
|
||||
if (isForService)
|
||||
{
|
||||
reverse.AsymmetricTokenParameters = this.InitiatorTokenParameters.Clone();
|
||||
reverse.AsymmetricTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.External;
|
||||
reverse.AsymmetricTokenParameters.InclusionMode = SecurityTokenInclusionMode.Never;
|
||||
reverse.CryptoTokenParameters = (SecurityTokenParameters)this.RecipientTokenParameters.Clone();
|
||||
reverse.CryptoTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
|
||||
reverse.CryptoTokenParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
|
||||
reverse.IdentityVerifier = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
reverse.AsymmetricTokenParameters = this.InitiatorTokenParameters.Clone();
|
||||
reverse.AsymmetricTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.External;
|
||||
reverse.AsymmetricTokenParameters.InclusionMode = SecurityTokenInclusionMode.Never;
|
||||
reverse.CryptoTokenParameters = (SecurityTokenParameters)this.RecipientTokenParameters.Clone();
|
||||
reverse.CryptoTokenParameters.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
|
||||
reverse.CryptoTokenParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
|
||||
reverse.IdentityVerifier = this.LocalClientSettings.IdentityVerifier;
|
||||
}
|
||||
reverse.DoRequestSignatureConfirmation = this.RequireSignatureConfirmation;
|
||||
reverse.MessageProtectionOrder = this.MessageProtectionOrder;
|
||||
reverse.ProtectionRequirements.Add(SecurityBindingElement.ComputeProtectionRequirements(this, context.BindingParameters, context.Binding.Elements, isForService));
|
||||
if (isForService)
|
||||
{
|
||||
reverse.ApplyConfidentiality = this.HasProtectionRequirements(reverse.ProtectionRequirements.OutgoingEncryptionParts);
|
||||
reverse.ApplyIntegrity = true;
|
||||
reverse.RequireIntegrity = reverse.RequireConfidentiality = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
reverse.RequireConfidentiality = this.HasProtectionRequirements(reverse.ProtectionRequirements.IncomingEncryptionParts);
|
||||
reverse.RequireIntegrity = true;
|
||||
reverse.ApplyIntegrity = reverse.ApplyConfidentiality = false;
|
||||
}
|
||||
base.ConfigureProtocolFactory(reverse, credentialsManager, !isForService, issuerBindingContext, context.Binding);
|
||||
if (!reverse.RequireIntegrity)
|
||||
reverse.DetectReplays = false;
|
||||
|
||||
// setup reverse here
|
||||
reverse.IsDuplexReply = true;
|
||||
|
||||
DuplexSecurityProtocolFactory duplex = new DuplexSecurityProtocolFactory();
|
||||
duplex.ForwardProtocolFactory = forward;
|
||||
duplex.ReverseProtocolFactory = reverse;
|
||||
protocolFactory = duplex;
|
||||
}
|
||||
else
|
||||
{
|
||||
protocolFactory = forward;
|
||||
}
|
||||
|
||||
return protocolFactory;
|
||||
}
|
||||
|
||||
internal override bool RequiresChannelDemuxer()
|
||||
{
|
||||
return (base.RequiresChannelDemuxer() || RequiresChannelDemuxer(this.InitiatorTokenParameters));
|
||||
}
|
||||
|
||||
protected override IChannelFactory<TChannel> BuildChannelFactoryCore<TChannel>(BindingContext context)
|
||||
{
|
||||
ISecurityCapabilities securityCapabilities = this.GetProperty<ISecurityCapabilities>(context);
|
||||
bool requireDemuxer = RequiresChannelDemuxer();
|
||||
ChannelBuilder channelBuilder = new ChannelBuilder(context, requireDemuxer);
|
||||
if (requireDemuxer)
|
||||
{
|
||||
ApplyPropertiesOnDemuxer(channelBuilder, context);
|
||||
}
|
||||
|
||||
BindingContext issuerBindingContext = context.Clone();
|
||||
SecurityCredentialsManager credentialsManager = context.BindingParameters.Find<SecurityCredentialsManager>();
|
||||
if (credentialsManager == null)
|
||||
{
|
||||
credentialsManager = ClientCredentials.CreateDefaultCredentials();
|
||||
}
|
||||
|
||||
SecurityProtocolFactory protocolFactory =
|
||||
this.CreateSecurityProtocolFactory<TChannel>(context, credentialsManager, false, issuerBindingContext);
|
||||
|
||||
return new SecurityChannelFactory<TChannel>(securityCapabilities, context, channelBuilder, protocolFactory);
|
||||
}
|
||||
|
||||
protected override IChannelListener<TChannel> BuildChannelListenerCore<TChannel>(BindingContext context)
|
||||
{
|
||||
bool requireDemuxer = RequiresChannelDemuxer();
|
||||
ChannelBuilder channelBuilder = new ChannelBuilder(context, requireDemuxer);
|
||||
if (requireDemuxer)
|
||||
{
|
||||
ApplyPropertiesOnDemuxer(channelBuilder, context);
|
||||
}
|
||||
BindingContext issuerBindingContext = context.Clone();
|
||||
|
||||
SecurityChannelListener<TChannel> channelListener = new SecurityChannelListener<TChannel>(this, context);
|
||||
SecurityCredentialsManager credentialsManager = context.BindingParameters.Find<SecurityCredentialsManager>();
|
||||
if (credentialsManager == null)
|
||||
credentialsManager = ServiceCredentials.CreateDefaultCredentials();
|
||||
|
||||
SecurityProtocolFactory protocolFactory = this.CreateSecurityProtocolFactory<TChannel>(context, credentialsManager, true, issuerBindingContext);
|
||||
channelListener.SecurityProtocolFactory = protocolFactory;
|
||||
channelListener.InitializeListener(channelBuilder);
|
||||
|
||||
return channelListener;
|
||||
}
|
||||
|
||||
public override T GetProperty<T>(BindingContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
|
||||
if (typeof(T) == typeof(ChannelProtectionRequirements))
|
||||
{
|
||||
AddressingVersion addressing = MessageVersion.Default.Addressing;
|
||||
#pragma warning suppress 56506
|
||||
MessageEncodingBindingElement encoding = context.Binding.Elements.Find<MessageEncodingBindingElement>();
|
||||
if (encoding != null)
|
||||
{
|
||||
addressing = encoding.MessageVersion.Addressing;
|
||||
}
|
||||
|
||||
ChannelProtectionRequirements myRequirements = base.GetProtectionRequirements(addressing, this.GetIndividualProperty<ISecurityCapabilities>().SupportedRequestProtectionLevel);
|
||||
myRequirements.Add(context.GetInnerProperty<ChannelProtectionRequirements>() ?? new ChannelProtectionRequirements());
|
||||
return (T)(object)myRequirements;
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.GetProperty<T>(context);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine(base.ToString());
|
||||
|
||||
sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "MessageProtectionOrder: {0}", this.messageProtectionOrder.ToString()));
|
||||
sb.AppendLine(String.Format(CultureInfo.InvariantCulture, "RequireSignatureConfirmation: {0}", this.requireSignatureConfirmation.ToString()));
|
||||
sb.Append("InitiatorTokenParameters: ");
|
||||
if (this.initiatorTokenParameters != null)
|
||||
sb.AppendLine(this.initiatorTokenParameters.ToString().Trim().Replace("\n", "\n "));
|
||||
else
|
||||
sb.AppendLine("null");
|
||||
sb.Append("RecipientTokenParameters: ");
|
||||
if (this.recipientTokenParameters != null)
|
||||
sb.AppendLine(this.recipientTokenParameters.ToString().Trim().Replace("\n", "\n "));
|
||||
else
|
||||
sb.AppendLine("null");
|
||||
|
||||
return sb.ToString().Trim();
|
||||
}
|
||||
|
||||
public override BindingElement Clone()
|
||||
{
|
||||
return new AsymmetricSecurityBindingElement(this);
|
||||
}
|
||||
|
||||
void IPolicyExportExtension.ExportPolicy(MetadataExporter exporter, PolicyConversionContext context)
|
||||
{
|
||||
SecurityBindingElement.ExportPolicy(exporter, context);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Net;
|
||||
using System.Runtime;
|
||||
|
||||
class AuthenticationSchemesBindingParameter
|
||||
{
|
||||
AuthenticationSchemes authenticationSchemes = AuthenticationSchemes.None;
|
||||
|
||||
public AuthenticationSchemesBindingParameter(AuthenticationSchemes authenticationSchemes)
|
||||
{
|
||||
Fx.Assert(authenticationSchemes != AuthenticationSchemes.None, "AuthenticationSchemesBindingParameter should not be added for AuthenticationSchemes.None.");
|
||||
|
||||
this.authenticationSchemes = authenticationSchemes;
|
||||
}
|
||||
|
||||
public AuthenticationSchemes AuthenticationSchemes
|
||||
{
|
||||
get { return this.authenticationSchemes; }
|
||||
}
|
||||
|
||||
public static bool TryExtract(BindingParameterCollection collection, out AuthenticationSchemes authenticationSchemes)
|
||||
{
|
||||
Fx.Assert(collection != null, "collection != null");
|
||||
authenticationSchemes = AuthenticationSchemes.None;
|
||||
AuthenticationSchemesBindingParameter instance = collection.Find<AuthenticationSchemesBindingParameter>();
|
||||
if (instance != null)
|
||||
{
|
||||
authenticationSchemes = instance.AuthenticationSchemes;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.ComponentModel;
|
||||
using System.Net;
|
||||
using System.Runtime;
|
||||
using System.Text;
|
||||
|
||||
static class AuthenticationSchemesHelper
|
||||
{
|
||||
public static bool DoesAuthTypeMatch(AuthenticationSchemes authScheme, string authType)
|
||||
{
|
||||
if ((authType == null) || (authType.Length == 0))
|
||||
{
|
||||
return authScheme.IsSet(AuthenticationSchemes.Anonymous);
|
||||
}
|
||||
|
||||
if (authType.Equals("kerberos", StringComparison.OrdinalIgnoreCase) ||
|
||||
authType.Equals("negotiate", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return authScheme.IsSet(AuthenticationSchemes.Negotiate);
|
||||
}
|
||||
else if (authType.Equals("ntlm", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return authScheme.IsSet(AuthenticationSchemes.Negotiate) ||
|
||||
authScheme.IsSet(AuthenticationSchemes.Ntlm);
|
||||
}
|
||||
|
||||
AuthenticationSchemes authTypeScheme;
|
||||
if (!Enum.TryParse<AuthenticationSchemes>(authType, true, out authTypeScheme))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return authScheme.IsSet(authTypeScheme);
|
||||
}
|
||||
|
||||
public static bool IsSingleton(this AuthenticationSchemes v)
|
||||
{
|
||||
bool result;
|
||||
switch (v)
|
||||
{
|
||||
case AuthenticationSchemes.Digest:
|
||||
case AuthenticationSchemes.Negotiate:
|
||||
case AuthenticationSchemes.Ntlm:
|
||||
case AuthenticationSchemes.Basic:
|
||||
case AuthenticationSchemes.Anonymous:
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool IsSet(this AuthenticationSchemes thisPtr, AuthenticationSchemes authenticationSchemes)
|
||||
{
|
||||
return (thisPtr & authenticationSchemes) == authenticationSchemes;
|
||||
}
|
||||
|
||||
public static bool IsNotSet(this AuthenticationSchemes thisPtr, AuthenticationSchemes authenticationSchemes)
|
||||
{
|
||||
return (thisPtr & authenticationSchemes) == 0;
|
||||
}
|
||||
|
||||
internal static string ToString(AuthenticationSchemes authScheme)
|
||||
{
|
||||
return authScheme.ToString().ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,342 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime;
|
||||
using System.Runtime.Serialization;
|
||||
using System.ServiceModel;
|
||||
|
||||
[DataContract]
|
||||
sealed class BaseUriWithWildcard
|
||||
{
|
||||
[DataMember]
|
||||
Uri baseAddress;
|
||||
|
||||
const char segmentDelimiter = '/';
|
||||
|
||||
[DataMember]
|
||||
HostNameComparisonMode hostNameComparisonMode;
|
||||
const string plus = "+";
|
||||
const string star = "*";
|
||||
const int HttpUriDefaultPort = 80;
|
||||
const int HttpsUriDefaultPort = 443;
|
||||
|
||||
// Derived from [DataMember] fields
|
||||
Comparand comparand;
|
||||
int hashCode;
|
||||
|
||||
public BaseUriWithWildcard(Uri baseAddress, HostNameComparisonMode hostNameComparisonMode)
|
||||
{
|
||||
this.baseAddress = baseAddress;
|
||||
this.hostNameComparisonMode = hostNameComparisonMode;
|
||||
this.SetComparisonAddressAndHashCode();
|
||||
|
||||
// Note the Uri may contain query string for WSDL purpose.
|
||||
// So do not check IsValid().
|
||||
}
|
||||
|
||||
BaseUriWithWildcard(string protocol, int defaultPort, string binding, int segmentCount, string path, string sampleBinding)
|
||||
{
|
||||
string[] urlParameters = SplitBinding(binding);
|
||||
|
||||
if (urlParameters.Length != segmentCount)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
||||
new UriFormatException(SR.GetString(SR.Hosting_MisformattedBinding, binding, protocol, sampleBinding)));
|
||||
}
|
||||
|
||||
int currentIndex = segmentCount - 1;
|
||||
string host = ParseHostAndHostNameComparisonMode(urlParameters[currentIndex]);
|
||||
|
||||
int port = -1;
|
||||
|
||||
if (--currentIndex >= 0)
|
||||
{
|
||||
string portString = urlParameters[currentIndex].Trim();
|
||||
|
||||
if (!string.IsNullOrEmpty(portString) &&
|
||||
!int.TryParse(portString, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out port))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new UriFormatException(SR.GetString(SR.Hosting_MisformattedPort, protocol, binding, portString)));
|
||||
}
|
||||
|
||||
if (port == defaultPort)
|
||||
{
|
||||
// Set to -1 so that Uri does not show it in the string.
|
||||
port = -1;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
Fx.Assert(path != null, "path should never be null here");
|
||||
this.baseAddress = new UriBuilder(protocol, host, port, path).Uri;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
if (Fx.IsFatal(exception))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
DiagnosticUtility.TraceHandledException(exception, TraceEventType.Error);
|
||||
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new UriFormatException(SR.GetString(SR.Hosting_MisformattedBindingData, binding,
|
||||
protocol)));
|
||||
}
|
||||
SetComparisonAddressAndHashCode();
|
||||
}
|
||||
|
||||
internal Uri BaseAddress
|
||||
{
|
||||
get { return this.baseAddress; }
|
||||
}
|
||||
|
||||
internal HostNameComparisonMode HostNameComparisonMode
|
||||
{
|
||||
get { return this.hostNameComparisonMode; }
|
||||
}
|
||||
|
||||
static string[] SplitBinding(string binding)
|
||||
{
|
||||
bool parsingIPv6Address = false;
|
||||
string[] tokens = null;
|
||||
const char splitChar = ':', startIPv6Address = '[', endIPv6Address = ']';
|
||||
|
||||
List<int> splitLocations = null;
|
||||
|
||||
for (int i = 0; i < binding.Length; i++)
|
||||
{
|
||||
if (parsingIPv6Address && binding[i] == endIPv6Address)
|
||||
{
|
||||
parsingIPv6Address = false;
|
||||
}
|
||||
else if (binding[i] == startIPv6Address)
|
||||
{
|
||||
parsingIPv6Address = true;
|
||||
}
|
||||
else if (!parsingIPv6Address && binding[i] == splitChar)
|
||||
{
|
||||
if (splitLocations == null)
|
||||
{
|
||||
splitLocations = new List<int>();
|
||||
}
|
||||
splitLocations.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (splitLocations == null)
|
||||
{
|
||||
tokens = new string[] { binding };
|
||||
}
|
||||
else
|
||||
{
|
||||
tokens = new string[splitLocations.Count + 1];
|
||||
int startIndex = 0;
|
||||
for (int i = 0; i < tokens.Length; i++)
|
||||
{
|
||||
if (i < splitLocations.Count)
|
||||
{
|
||||
int nextSplitIndex = splitLocations[i];
|
||||
tokens[i] = binding.Substring(startIndex, nextSplitIndex - startIndex);
|
||||
startIndex = nextSplitIndex + 1;
|
||||
}
|
||||
else //splitting the last segment
|
||||
{
|
||||
if (startIndex < binding.Length)
|
||||
{
|
||||
tokens[i] = binding.Substring(startIndex, binding.Length - startIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
//splitChar was the last character in the string
|
||||
tokens[i] = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
internal static BaseUriWithWildcard CreateHostedUri(string protocol, string binding, string path)
|
||||
{
|
||||
Fx.Assert(protocol != null, "caller must verify");
|
||||
|
||||
if (binding == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("binding");
|
||||
}
|
||||
|
||||
if (path == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("path");
|
||||
}
|
||||
|
||||
if (protocol.Equals(Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// For http, binding format is: "<ipAddress>:<port>:<hostName>"
|
||||
// as specified in http://www.microsoft.com/resources/documentation/WindowsServ/2003/standard/proddocs/en-us/Default.asp?url=/resources/documentation/WindowsServ/2003/standard/proddocs/en-us/ref_mb_serverbindings.asp
|
||||
return new BaseUriWithWildcard(Uri.UriSchemeHttp, HttpUriDefaultPort, binding, 3, path, ":80:");
|
||||
}
|
||||
else if (protocol.Equals(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// For https, binding format is the same as http
|
||||
return new BaseUriWithWildcard(Uri.UriSchemeHttps, HttpsUriDefaultPort, binding, 3, path, ":443:");
|
||||
}
|
||||
else if (protocol.Equals(Uri.UriSchemeNetTcp, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// For net.tcp, binding format is: "<port>:<hostName>"
|
||||
return new BaseUriWithWildcard(Uri.UriSchemeNetTcp, TcpUri.DefaultPort, binding, 2, path, "808:*");
|
||||
}
|
||||
else if (protocol.Equals(Uri.UriSchemeNetPipe, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return CreateHostedPipeUri(binding, path);
|
||||
}
|
||||
else if (protocol.Equals(MsmqUri.NetMsmqAddressTranslator.Scheme, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new BaseUriWithWildcard(MsmqUri.NetMsmqAddressTranslator.Scheme, -1, binding, 1, path, "*");
|
||||
}
|
||||
else if (protocol.Equals(MsmqUri.FormatNameAddressTranslator.Scheme, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new BaseUriWithWildcard(MsmqUri.FormatNameAddressTranslator.Scheme, -1, binding, 1, path, "*");
|
||||
}
|
||||
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new UriFormatException(SR.GetString(SR.Hosting_NotSupportedProtocol, binding)));
|
||||
}
|
||||
|
||||
internal static BaseUriWithWildcard CreateHostedPipeUri(string binding, string path)
|
||||
{
|
||||
// For net.pipe, binding format is: "<hostName>"
|
||||
return new BaseUriWithWildcard(Uri.UriSchemeNetPipe, -1, binding, 1, path, "*");
|
||||
}
|
||||
|
||||
public override bool Equals(object o)
|
||||
{
|
||||
BaseUriWithWildcard other = o as BaseUriWithWildcard;
|
||||
|
||||
if (other == null || other.hashCode != this.hashCode || other.hostNameComparisonMode != this.hostNameComparisonMode ||
|
||||
other.comparand.Port != this.comparand.Port)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!object.ReferenceEquals(other.comparand.Scheme, this.comparand.Scheme))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.comparand.Address.Equals(other.comparand.Address);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return this.hashCode;
|
||||
}
|
||||
|
||||
internal bool IsBaseOf(Uri fullAddress)
|
||||
{
|
||||
if ((object)baseAddress.Scheme != (object)fullAddress.Scheme)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (baseAddress.Port != fullAddress.Port)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.HostNameComparisonMode == HostNameComparisonMode.Exact)
|
||||
{
|
||||
if (string.Compare(baseAddress.Host, fullAddress.Host, StringComparison.OrdinalIgnoreCase) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
string s1 = baseAddress.GetComponents(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.Unescaped);
|
||||
string s2 = fullAddress.GetComponents(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.Unescaped);
|
||||
|
||||
if (s1.Length > s2.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s1.Length < s2.Length &&
|
||||
s1[s1.Length - 1] != segmentDelimiter &&
|
||||
s2[s1.Length] != segmentDelimiter)
|
||||
{
|
||||
// Matching over segments
|
||||
return false;
|
||||
}
|
||||
return string.Compare(s2, 0, s1, 0, s1.Length, StringComparison.OrdinalIgnoreCase) == 0;
|
||||
}
|
||||
|
||||
[OnDeserialized]
|
||||
internal void OnDeserialized(StreamingContext context)
|
||||
{
|
||||
UriSchemeKeyedCollection.ValidateBaseAddress(baseAddress, "context");
|
||||
|
||||
if (!HostNameComparisonModeHelper.IsDefined(this.HostNameComparisonMode))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("context", SR.GetString(SR.Hosting_BaseUriDeserializedNotValid));
|
||||
}
|
||||
this.SetComparisonAddressAndHashCode();
|
||||
}
|
||||
|
||||
string ParseHostAndHostNameComparisonMode(string host)
|
||||
{
|
||||
if (string.IsNullOrEmpty(host) || host.Equals(star))
|
||||
{
|
||||
hostNameComparisonMode = HostNameComparisonMode.WeakWildcard;
|
||||
host = DnsCache.MachineName;
|
||||
}
|
||||
else if (host.Equals(plus))
|
||||
{
|
||||
hostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
|
||||
host = DnsCache.MachineName;
|
||||
}
|
||||
else
|
||||
{
|
||||
hostNameComparisonMode = HostNameComparisonMode.Exact;
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
void SetComparisonAddressAndHashCode()
|
||||
{
|
||||
if (this.HostNameComparisonMode == HostNameComparisonMode.Exact)
|
||||
{
|
||||
// Use canonical string representation of the full base address for comparison
|
||||
this.comparand.Address = this.baseAddress.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use canonical string representation of the absolute path for comparison
|
||||
this.comparand.Address = this.baseAddress.GetComponents(UriComponents.Path | UriComponents.KeepDelimiter, UriFormat.UriEscaped);
|
||||
}
|
||||
|
||||
this.comparand.Port = this.baseAddress.Port;
|
||||
this.comparand.Scheme = this.baseAddress.Scheme;
|
||||
|
||||
if ((this.comparand.Port == -1) && ((object)this.comparand.Scheme == (object)Uri.UriSchemeNetTcp))
|
||||
{
|
||||
// Compensate for the fact that the Uri type doesn't know about our default TCP port number
|
||||
this.comparand.Port = TcpUri.DefaultPort;
|
||||
}
|
||||
this.hashCode = this.comparand.Address.GetHashCode() ^ this.comparand.Port ^ (int)this.HostNameComparisonMode;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0}:{1}", this.HostNameComparisonMode, this.BaseAddress);
|
||||
}
|
||||
|
||||
struct Comparand
|
||||
{
|
||||
public string Address;
|
||||
public int Port;
|
||||
public string Scheme;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,319 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Reflection;
|
||||
using System.ServiceModel.Description;
|
||||
using System.Runtime.Serialization;
|
||||
using System.ServiceModel;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
public sealed class BinaryMessageEncodingBindingElement : MessageEncodingBindingElement, IWsdlExportExtension, IPolicyExportExtension
|
||||
{
|
||||
int maxReadPoolSize;
|
||||
int maxWritePoolSize;
|
||||
XmlDictionaryReaderQuotas readerQuotas;
|
||||
int maxSessionSize;
|
||||
BinaryVersion binaryVersion;
|
||||
MessageVersion messageVersion;
|
||||
CompressionFormat compressionFormat;
|
||||
long maxReceivedMessageSize;
|
||||
|
||||
public BinaryMessageEncodingBindingElement()
|
||||
{
|
||||
this.maxReadPoolSize = EncoderDefaults.MaxReadPoolSize;
|
||||
this.maxWritePoolSize = EncoderDefaults.MaxWritePoolSize;
|
||||
this.readerQuotas = new XmlDictionaryReaderQuotas();
|
||||
EncoderDefaults.ReaderQuotas.CopyTo(this.readerQuotas);
|
||||
this.maxSessionSize = BinaryEncoderDefaults.MaxSessionSize;
|
||||
this.binaryVersion = BinaryEncoderDefaults.BinaryVersion;
|
||||
this.messageVersion = MessageVersion.CreateVersion(BinaryEncoderDefaults.EnvelopeVersion);
|
||||
this.compressionFormat = EncoderDefaults.DefaultCompressionFormat;
|
||||
}
|
||||
|
||||
BinaryMessageEncodingBindingElement(BinaryMessageEncodingBindingElement elementToBeCloned)
|
||||
: base(elementToBeCloned)
|
||||
{
|
||||
this.maxReadPoolSize = elementToBeCloned.maxReadPoolSize;
|
||||
this.maxWritePoolSize = elementToBeCloned.maxWritePoolSize;
|
||||
this.readerQuotas = new XmlDictionaryReaderQuotas();
|
||||
elementToBeCloned.readerQuotas.CopyTo(this.readerQuotas);
|
||||
this.MaxSessionSize = elementToBeCloned.MaxSessionSize;
|
||||
this.BinaryVersion = elementToBeCloned.BinaryVersion;
|
||||
this.messageVersion = elementToBeCloned.messageVersion;
|
||||
this.CompressionFormat = elementToBeCloned.CompressionFormat;
|
||||
this.maxReceivedMessageSize = elementToBeCloned.maxReceivedMessageSize;
|
||||
}
|
||||
|
||||
[DefaultValue(EncoderDefaults.DefaultCompressionFormat)]
|
||||
public CompressionFormat CompressionFormat
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.compressionFormat;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.compressionFormat = value;
|
||||
}
|
||||
}
|
||||
|
||||
/* public */
|
||||
BinaryVersion BinaryVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return binaryVersion;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value"));
|
||||
}
|
||||
this.binaryVersion = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override MessageVersion MessageVersion
|
||||
{
|
||||
get { return this.messageVersion; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
|
||||
}
|
||||
if (value.Envelope != BinaryEncoderDefaults.EnvelopeVersion)
|
||||
{
|
||||
string errorMsg = SR.GetString(SR.UnsupportedEnvelopeVersion, this.GetType().FullName, BinaryEncoderDefaults.EnvelopeVersion, value.Envelope);
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(errorMsg));
|
||||
}
|
||||
|
||||
this.messageVersion = MessageVersion.CreateVersion(BinaryEncoderDefaults.EnvelopeVersion, value.Addressing);
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValue(EncoderDefaults.MaxReadPoolSize)]
|
||||
public int MaxReadPoolSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.maxReadPoolSize;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value,
|
||||
SR.GetString(SR.ValueMustBePositive)));
|
||||
}
|
||||
this.maxReadPoolSize = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValue(EncoderDefaults.MaxWritePoolSize)]
|
||||
public int MaxWritePoolSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.maxWritePoolSize;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value,
|
||||
SR.GetString(SR.ValueMustBePositive)));
|
||||
}
|
||||
this.maxWritePoolSize = value;
|
||||
}
|
||||
}
|
||||
|
||||
public XmlDictionaryReaderQuotas ReaderQuotas
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.readerQuotas;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
|
||||
value.CopyTo(this.readerQuotas);
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValue(BinaryEncoderDefaults.MaxSessionSize)]
|
||||
public int MaxSessionSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.maxSessionSize;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value,
|
||||
SR.GetString(SR.ValueMustBeNonNegative)));
|
||||
}
|
||||
|
||||
this.maxSessionSize = value;
|
||||
}
|
||||
}
|
||||
|
||||
private void VerifyCompression(BindingContext context)
|
||||
{
|
||||
if (this.compressionFormat != CompressionFormat.None)
|
||||
{
|
||||
ITransportCompressionSupport compressionSupport = context.GetInnerProperty<ITransportCompressionSupport>();
|
||||
if (compressionSupport == null || !compressionSupport.IsCompressionFormatSupported(this.compressionFormat))
|
||||
{
|
||||
throw FxTrace.Exception.AsError(new NotSupportedException(SR.GetString(
|
||||
SR.TransportDoesNotSupportCompression,
|
||||
this.compressionFormat.ToString(),
|
||||
this.GetType().Name,
|
||||
CompressionFormat.None.ToString())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetMaxReceivedMessageSizeFromTransport(BindingContext context)
|
||||
{
|
||||
TransportBindingElement transport = context.Binding.Elements.Find<TransportBindingElement>();
|
||||
if (transport != null)
|
||||
{
|
||||
// We are guaranteed that a transport exists when building a binding;
|
||||
// Allow the regular flow/checks to happen rather than throw here
|
||||
// (InternalBuildChannelListener will call into the BindingContext. Validation happens there and it will throw)
|
||||
this.maxReceivedMessageSize = transport.MaxReceivedMessageSize;
|
||||
}
|
||||
}
|
||||
|
||||
public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
|
||||
{
|
||||
VerifyCompression(context);
|
||||
SetMaxReceivedMessageSizeFromTransport(context);
|
||||
return InternalBuildChannelFactory<TChannel>(context);
|
||||
}
|
||||
|
||||
public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
|
||||
{
|
||||
VerifyCompression(context);
|
||||
SetMaxReceivedMessageSizeFromTransport(context);
|
||||
return InternalBuildChannelListener<TChannel>(context);
|
||||
}
|
||||
|
||||
public override bool CanBuildChannelListener<TChannel>(BindingContext context)
|
||||
{
|
||||
return InternalCanBuildChannelListener<TChannel>(context);
|
||||
}
|
||||
|
||||
public override BindingElement Clone()
|
||||
{
|
||||
return new BinaryMessageEncodingBindingElement(this);
|
||||
}
|
||||
|
||||
public override MessageEncoderFactory CreateMessageEncoderFactory()
|
||||
{
|
||||
return new BinaryMessageEncoderFactory(
|
||||
this.MessageVersion,
|
||||
this.MaxReadPoolSize,
|
||||
this.MaxWritePoolSize,
|
||||
this.MaxSessionSize,
|
||||
this.ReaderQuotas,
|
||||
this.maxReceivedMessageSize,
|
||||
this.BinaryVersion,
|
||||
this.CompressionFormat);
|
||||
}
|
||||
|
||||
public override T GetProperty<T>(BindingContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
}
|
||||
if (typeof(T) == typeof(XmlDictionaryReaderQuotas))
|
||||
{
|
||||
return (T)(object)this.readerQuotas;
|
||||
}
|
||||
else
|
||||
{
|
||||
return base.GetProperty<T>(context);
|
||||
}
|
||||
}
|
||||
|
||||
void IPolicyExportExtension.ExportPolicy(MetadataExporter exporter, PolicyConversionContext policyContext)
|
||||
{
|
||||
if (policyContext == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("policyContext");
|
||||
}
|
||||
XmlDocument document = new XmlDocument();
|
||||
policyContext.GetBindingAssertions().Add(document.CreateElement(
|
||||
MessageEncodingPolicyConstants.BinaryEncodingPrefix,
|
||||
MessageEncodingPolicyConstants.BinaryEncodingName,
|
||||
MessageEncodingPolicyConstants.BinaryEncodingNamespace));
|
||||
}
|
||||
|
||||
void IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context) { }
|
||||
void IWsdlExportExtension.ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
}
|
||||
|
||||
SoapHelper.SetSoapVersion(context, exporter, MessageVersion.Soap12WSAddressing10.Envelope);
|
||||
}
|
||||
|
||||
internal override bool IsMatch(BindingElement b)
|
||||
{
|
||||
if (!base.IsMatch(b))
|
||||
return false;
|
||||
|
||||
BinaryMessageEncodingBindingElement binary = b as BinaryMessageEncodingBindingElement;
|
||||
if (binary == null)
|
||||
return false;
|
||||
if (this.maxReadPoolSize != binary.MaxReadPoolSize)
|
||||
return false;
|
||||
if (this.maxWritePoolSize != binary.MaxWritePoolSize)
|
||||
return false;
|
||||
|
||||
// compare XmlDictionaryReaderQuotas
|
||||
if (this.readerQuotas.MaxStringContentLength != binary.ReaderQuotas.MaxStringContentLength)
|
||||
return false;
|
||||
if (this.readerQuotas.MaxArrayLength != binary.ReaderQuotas.MaxArrayLength)
|
||||
return false;
|
||||
if (this.readerQuotas.MaxBytesPerRead != binary.ReaderQuotas.MaxBytesPerRead)
|
||||
return false;
|
||||
if (this.readerQuotas.MaxDepth != binary.ReaderQuotas.MaxDepth)
|
||||
return false;
|
||||
if (this.readerQuotas.MaxNameTableCharCount != binary.ReaderQuotas.MaxNameTableCharCount)
|
||||
return false;
|
||||
|
||||
if (this.MaxSessionSize != binary.MaxSessionSize)
|
||||
return false;
|
||||
if (this.CompressionFormat != binary.CompressionFormat)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeReaderQuotas()
|
||||
{
|
||||
return (!EncoderDefaults.IsDefaultReaderQuotas(this.ReaderQuotas));
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeMessageVersion()
|
||||
{
|
||||
return (!this.messageVersion.IsMatch(MessageVersion.Default));
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Xml;
|
||||
|
||||
/* public */
|
||||
class BinaryVersion
|
||||
{
|
||||
static public readonly BinaryVersion Version1 = new BinaryVersion(FramingEncodingString.Binary, FramingEncodingString.BinarySession, ServiceModelDictionary.Version1);
|
||||
static public readonly BinaryVersion GZipVersion1 = new BinaryVersion(FramingEncodingString.ExtendedBinaryGZip, FramingEncodingString.ExtendedBinarySessionGZip, ServiceModelDictionary.Version1);
|
||||
static public readonly BinaryVersion DeflateVersion1 = new BinaryVersion(FramingEncodingString.ExtendedBinaryDeflate, FramingEncodingString.ExtendedBinarySessionDeflate, ServiceModelDictionary.Version1);
|
||||
|
||||
string contentType;
|
||||
string sessionContentType;
|
||||
IXmlDictionary dictionary;
|
||||
|
||||
BinaryVersion(string contentType, string sessionContentType, IXmlDictionary dictionary)
|
||||
{
|
||||
this.contentType = contentType;
|
||||
this.sessionContentType = sessionContentType;
|
||||
this.dictionary = dictionary;
|
||||
}
|
||||
|
||||
static public BinaryVersion CurrentVersion { get { return Version1; } }
|
||||
public string ContentType { get { return contentType; } }
|
||||
public string SessionContentType { get { return sessionContentType; } }
|
||||
public IXmlDictionary Dictionary { get { return dictionary; } }
|
||||
}
|
||||
}
|
@@ -0,0 +1,355 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Description;
|
||||
|
||||
public abstract class Binding : IDefaultCommunicationTimeouts
|
||||
{
|
||||
TimeSpan closeTimeout = ServiceDefaults.CloseTimeout;
|
||||
string name;
|
||||
string namespaceIdentifier;
|
||||
TimeSpan openTimeout = ServiceDefaults.OpenTimeout;
|
||||
TimeSpan receiveTimeout = ServiceDefaults.ReceiveTimeout;
|
||||
TimeSpan sendTimeout = ServiceDefaults.SendTimeout;
|
||||
internal const string DefaultNamespace = NamingHelper.DefaultNamespace;
|
||||
|
||||
protected Binding()
|
||||
{
|
||||
this.name = null;
|
||||
this.namespaceIdentifier = DefaultNamespace;
|
||||
}
|
||||
|
||||
protected Binding(string name, string ns)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("name", SR.GetString(SR.SFXBindingNameCannotBeNullOrEmpty));
|
||||
}
|
||||
if (ns == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("ns");
|
||||
}
|
||||
|
||||
if (ns.Length > 0)
|
||||
{
|
||||
NamingHelper.CheckUriParameter(ns, "ns");
|
||||
}
|
||||
|
||||
this.name = name;
|
||||
this.namespaceIdentifier = ns;
|
||||
}
|
||||
|
||||
|
||||
[DefaultValue(typeof(TimeSpan), ServiceDefaults.CloseTimeoutString)]
|
||||
public TimeSpan CloseTimeout
|
||||
{
|
||||
get { return this.closeTimeout; }
|
||||
set
|
||||
{
|
||||
if (value < TimeSpan.Zero)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRange0)));
|
||||
}
|
||||
if (TimeoutHelper.IsTooLarge(value))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRangeTooBig)));
|
||||
}
|
||||
|
||||
this.closeTimeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.name == null)
|
||||
this.name = this.GetType().Name;
|
||||
|
||||
return this.name;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrEmpty(value))
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.GetString(SR.SFXBindingNameCannotBeNullOrEmpty));
|
||||
|
||||
this.name = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string Namespace
|
||||
{
|
||||
get { return this.namespaceIdentifier; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
|
||||
}
|
||||
|
||||
if (value.Length > 0)
|
||||
{
|
||||
NamingHelper.CheckUriProperty(value, "Namespace");
|
||||
}
|
||||
this.namespaceIdentifier = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValue(typeof(TimeSpan), ServiceDefaults.OpenTimeoutString)]
|
||||
public TimeSpan OpenTimeout
|
||||
{
|
||||
get { return this.openTimeout; }
|
||||
set
|
||||
{
|
||||
if (value < TimeSpan.Zero)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRange0)));
|
||||
}
|
||||
if (TimeoutHelper.IsTooLarge(value))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRangeTooBig)));
|
||||
}
|
||||
|
||||
this.openTimeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValue(typeof(TimeSpan), ServiceDefaults.ReceiveTimeoutString)]
|
||||
public TimeSpan ReceiveTimeout
|
||||
{
|
||||
get { return this.receiveTimeout; }
|
||||
set
|
||||
{
|
||||
if (value < TimeSpan.Zero)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRange0)));
|
||||
}
|
||||
if (TimeoutHelper.IsTooLarge(value))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRangeTooBig)));
|
||||
}
|
||||
|
||||
this.receiveTimeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract string Scheme { get; }
|
||||
|
||||
public MessageVersion MessageVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.GetProperty<MessageVersion>(new BindingParameterCollection());
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValue(typeof(TimeSpan), ServiceDefaults.SendTimeoutString)]
|
||||
public TimeSpan SendTimeout
|
||||
{
|
||||
get { return this.sendTimeout; }
|
||||
set
|
||||
{
|
||||
if (value < TimeSpan.Zero)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRange0)));
|
||||
}
|
||||
if (TimeoutHelper.IsTooLarge(value))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value", value, SR.GetString(SR.SFxTimeoutOutOfRangeTooBig)));
|
||||
}
|
||||
|
||||
this.sendTimeout = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IChannelFactory<TChannel> BuildChannelFactory<TChannel>(params object[] parameters)
|
||||
{
|
||||
return this.BuildChannelFactory<TChannel>(new BindingParameterCollection(parameters));
|
||||
}
|
||||
|
||||
public virtual IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingParameterCollection parameters)
|
||||
{
|
||||
EnsureInvariants();
|
||||
BindingContext context = new BindingContext(new CustomBinding(this), parameters);
|
||||
IChannelFactory<TChannel> channelFactory = context.BuildInnerChannelFactory<TChannel>();
|
||||
context.ValidateBindingElementsConsumed();
|
||||
this.ValidateSecurityCapabilities(channelFactory.GetProperty<ISecurityCapabilities>(), parameters);
|
||||
|
||||
return channelFactory;
|
||||
}
|
||||
|
||||
void ValidateSecurityCapabilities(ISecurityCapabilities runtimeSecurityCapabilities, BindingParameterCollection parameters)
|
||||
{
|
||||
ISecurityCapabilities bindingSecurityCapabilities = this.GetProperty<ISecurityCapabilities>(parameters);
|
||||
|
||||
if (!SecurityCapabilities.IsEqual(bindingSecurityCapabilities, runtimeSecurityCapabilities))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
||||
new InvalidOperationException(SR.GetString(SR.SecurityCapabilitiesMismatched, this)));
|
||||
}
|
||||
}
|
||||
|
||||
public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(params object[] parameters)
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
return this.BuildChannelListener<TChannel>(new BindingParameterCollection(parameters));
|
||||
}
|
||||
|
||||
public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(Uri listenUriBaseAddress, params object[] parameters)
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
return this.BuildChannelListener<TChannel>(listenUriBaseAddress, new BindingParameterCollection(parameters));
|
||||
}
|
||||
|
||||
public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(Uri listenUriBaseAddress, string listenUriRelativeAddress, params object[] parameters)
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
return this.BuildChannelListener<TChannel>(listenUriBaseAddress, listenUriRelativeAddress, new BindingParameterCollection(parameters));
|
||||
}
|
||||
|
||||
public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(Uri listenUriBaseAddress, string listenUriRelativeAddress, ListenUriMode listenUriMode, params object[] parameters)
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
return this.BuildChannelListener<TChannel>(listenUriBaseAddress, listenUriRelativeAddress, listenUriMode, new BindingParameterCollection(parameters));
|
||||
}
|
||||
|
||||
public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingParameterCollection parameters)
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
UriBuilder listenUriBuilder = new UriBuilder(this.Scheme, DnsCache.MachineName);
|
||||
return this.BuildChannelListener<TChannel>(listenUriBuilder.Uri, String.Empty, ListenUriMode.Unique, parameters);
|
||||
}
|
||||
|
||||
public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(Uri listenUriBaseAddress, BindingParameterCollection parameters)
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
return this.BuildChannelListener<TChannel>(listenUriBaseAddress, String.Empty, ListenUriMode.Explicit, parameters);
|
||||
}
|
||||
|
||||
public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(Uri listenUriBaseAddress, string listenUriRelativeAddress, BindingParameterCollection parameters)
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
return this.BuildChannelListener<TChannel>(listenUriBaseAddress, listenUriRelativeAddress, ListenUriMode.Explicit, parameters);
|
||||
}
|
||||
|
||||
public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(Uri listenUriBaseAddress, string listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters)
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
EnsureInvariants();
|
||||
BindingContext context = new BindingContext(new CustomBinding(this), parameters, listenUriBaseAddress, listenUriRelativeAddress, listenUriMode);
|
||||
IChannelListener<TChannel> channelListener = context.BuildInnerChannelListener<TChannel>();
|
||||
context.ValidateBindingElementsConsumed();
|
||||
this.ValidateSecurityCapabilities(channelListener.GetProperty<ISecurityCapabilities>(), parameters);
|
||||
|
||||
return channelListener;
|
||||
}
|
||||
|
||||
public bool CanBuildChannelFactory<TChannel>(params object[] parameters)
|
||||
{
|
||||
return this.CanBuildChannelFactory<TChannel>(new BindingParameterCollection(parameters));
|
||||
}
|
||||
|
||||
public virtual bool CanBuildChannelFactory<TChannel>(BindingParameterCollection parameters)
|
||||
{
|
||||
BindingContext context = new BindingContext(new CustomBinding(this), parameters);
|
||||
return context.CanBuildInnerChannelFactory<TChannel>();
|
||||
}
|
||||
|
||||
public bool CanBuildChannelListener<TChannel>(params object[] parameters) where TChannel : class, IChannel
|
||||
{
|
||||
return this.CanBuildChannelListener<TChannel>(new BindingParameterCollection(parameters));
|
||||
}
|
||||
|
||||
public virtual bool CanBuildChannelListener<TChannel>(BindingParameterCollection parameters) where TChannel : class, IChannel
|
||||
{
|
||||
BindingContext context = new BindingContext(new CustomBinding(this), parameters);
|
||||
return context.CanBuildInnerChannelListener<TChannel>();
|
||||
}
|
||||
|
||||
// the elements should NOT reference internal elements used by the Binding
|
||||
public abstract BindingElementCollection CreateBindingElements();
|
||||
|
||||
public T GetProperty<T>(BindingParameterCollection parameters)
|
||||
where T : class
|
||||
{
|
||||
BindingContext context = new BindingContext(new CustomBinding(this), parameters);
|
||||
return context.GetInnerProperty<T>();
|
||||
}
|
||||
|
||||
void EnsureInvariants()
|
||||
{
|
||||
EnsureInvariants(null);
|
||||
}
|
||||
|
||||
internal void EnsureInvariants(string contractName)
|
||||
{
|
||||
BindingElementCollection elements = this.CreateBindingElements();
|
||||
TransportBindingElement transport = null;
|
||||
int index;
|
||||
for (index = 0; index < elements.Count; index++)
|
||||
{
|
||||
transport = elements[index] as TransportBindingElement;
|
||||
if (transport != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if (transport == null)
|
||||
{
|
||||
if (contractName == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
|
||||
SR.GetString(SR.CustomBindingRequiresTransport, this.Name)));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
|
||||
SR.GetString(SR.SFxCustomBindingNeedsTransport1, contractName)));
|
||||
}
|
||||
}
|
||||
if (index != elements.Count - 1)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
|
||||
SR.GetString(SR.TransportBindingElementMustBeLast, this.Name, transport.GetType().Name)));
|
||||
}
|
||||
if (string.IsNullOrEmpty(transport.Scheme))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
|
||||
SR.GetString(SR.InvalidBindingScheme, transport.GetType().Name)));
|
||||
}
|
||||
|
||||
if (this.MessageVersion == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
|
||||
SR.GetString(SR.MessageVersionMissingFromBinding, this.Name)));
|
||||
}
|
||||
}
|
||||
|
||||
internal void CopyTimeouts(IDefaultCommunicationTimeouts source)
|
||||
{
|
||||
this.CloseTimeout = source.CloseTimeout;
|
||||
this.OpenTimeout = source.OpenTimeout;
|
||||
this.ReceiveTimeout = source.ReceiveTimeout;
|
||||
this.SendTimeout = source.SendTimeout;
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeName()
|
||||
{
|
||||
return (this.Name != this.GetType().Name);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool ShouldSerializeNamespace()
|
||||
{
|
||||
return (this.Namespace != DefaultNamespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,176 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.ServiceModel.Description;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
public class BindingContext
|
||||
{
|
||||
CustomBinding binding;
|
||||
BindingParameterCollection bindingParameters;
|
||||
Uri listenUriBaseAddress;
|
||||
ListenUriMode listenUriMode;
|
||||
string listenUriRelativeAddress;
|
||||
BindingElementCollection remainingBindingElements; // kept to ensure each BE builds itself once
|
||||
|
||||
public BindingContext(CustomBinding binding, BindingParameterCollection parameters)
|
||||
: this(binding, parameters, null, string.Empty, ListenUriMode.Explicit)
|
||||
{
|
||||
}
|
||||
|
||||
public BindingContext(CustomBinding binding, BindingParameterCollection parameters, Uri listenUriBaseAddress, string listenUriRelativeAddress, ListenUriMode listenUriMode)
|
||||
{
|
||||
if (binding == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("binding");
|
||||
}
|
||||
if (listenUriRelativeAddress == null)
|
||||
{
|
||||
listenUriRelativeAddress = string.Empty;
|
||||
}
|
||||
if (!ListenUriModeHelper.IsDefined(listenUriMode))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("listenUriMode"));
|
||||
}
|
||||
|
||||
Initialize(binding, binding.Elements, parameters, listenUriBaseAddress, listenUriRelativeAddress, listenUriMode);
|
||||
}
|
||||
|
||||
BindingContext(CustomBinding binding,
|
||||
BindingElementCollection remainingBindingElements,
|
||||
BindingParameterCollection parameters,
|
||||
Uri listenUriBaseAddress,
|
||||
string listenUriRelativeAddress,
|
||||
ListenUriMode listenUriMode)
|
||||
{
|
||||
Initialize(binding, remainingBindingElements, parameters, listenUriBaseAddress, listenUriRelativeAddress, listenUriMode);
|
||||
}
|
||||
|
||||
void Initialize(CustomBinding binding,
|
||||
BindingElementCollection remainingBindingElements,
|
||||
BindingParameterCollection parameters,
|
||||
Uri listenUriBaseAddress,
|
||||
string listenUriRelativeAddress,
|
||||
ListenUriMode listenUriMode)
|
||||
{
|
||||
this.binding = binding;
|
||||
|
||||
this.remainingBindingElements = new BindingElementCollection(remainingBindingElements);
|
||||
this.bindingParameters = new BindingParameterCollection(parameters);
|
||||
this.listenUriBaseAddress = listenUriBaseAddress;
|
||||
this.listenUriRelativeAddress = listenUriRelativeAddress;
|
||||
this.listenUriMode = listenUriMode;
|
||||
}
|
||||
|
||||
public CustomBinding Binding
|
||||
{
|
||||
get { return this.binding; }
|
||||
}
|
||||
|
||||
public BindingParameterCollection BindingParameters
|
||||
{
|
||||
get { return this.bindingParameters; }
|
||||
}
|
||||
|
||||
public Uri ListenUriBaseAddress
|
||||
{
|
||||
get { return this.listenUriBaseAddress; }
|
||||
set { this.listenUriBaseAddress = value; }
|
||||
}
|
||||
|
||||
public ListenUriMode ListenUriMode
|
||||
{
|
||||
get { return this.listenUriMode; }
|
||||
set { this.listenUriMode = value; }
|
||||
}
|
||||
|
||||
public string ListenUriRelativeAddress
|
||||
{
|
||||
get { return this.listenUriRelativeAddress; }
|
||||
set { this.listenUriRelativeAddress = value; }
|
||||
}
|
||||
|
||||
public BindingElementCollection RemainingBindingElements
|
||||
{
|
||||
get { return this.remainingBindingElements; }
|
||||
}
|
||||
|
||||
public IChannelFactory<TChannel> BuildInnerChannelFactory<TChannel>()
|
||||
{
|
||||
return this.RemoveNextElement().BuildChannelFactory<TChannel>(this);
|
||||
}
|
||||
|
||||
public IChannelListener<TChannel> BuildInnerChannelListener<TChannel>()
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
return this.RemoveNextElement().BuildChannelListener<TChannel>(this);
|
||||
}
|
||||
|
||||
public bool CanBuildInnerChannelFactory<TChannel>()
|
||||
{
|
||||
BindingContext clone = this.Clone();
|
||||
return clone.RemoveNextElement().CanBuildChannelFactory<TChannel>(clone);
|
||||
}
|
||||
|
||||
public bool CanBuildInnerChannelListener<TChannel>()
|
||||
where TChannel : class, IChannel
|
||||
{
|
||||
BindingContext clone = this.Clone();
|
||||
return clone.RemoveNextElement().CanBuildChannelListener<TChannel>(clone);
|
||||
}
|
||||
|
||||
public T GetInnerProperty<T>()
|
||||
where T : class
|
||||
{
|
||||
if (this.remainingBindingElements.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
BindingContext clone = this.Clone();
|
||||
return clone.RemoveNextElement().GetProperty<T>(clone);
|
||||
}
|
||||
}
|
||||
|
||||
public BindingContext Clone()
|
||||
{
|
||||
return new BindingContext(this.binding, this.remainingBindingElements, this.bindingParameters,
|
||||
this.listenUriBaseAddress, this.listenUriRelativeAddress, this.listenUriMode);
|
||||
}
|
||||
|
||||
BindingElement RemoveNextElement()
|
||||
{
|
||||
BindingElement element = this.remainingBindingElements.Remove<BindingElement>();
|
||||
if (element != null)
|
||||
return element;
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(
|
||||
SR.NoChannelBuilderAvailable, this.binding.Name, this.binding.Namespace)));
|
||||
}
|
||||
|
||||
internal void ValidateBindingElementsConsumed()
|
||||
{
|
||||
if (this.RemainingBindingElements.Count != 0)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
foreach (BindingElement bindingElement in this.RemainingBindingElements)
|
||||
{
|
||||
if (builder.Length > 0)
|
||||
{
|
||||
builder.Append(CultureInfo.CurrentCulture.TextInfo.ListSeparator);
|
||||
builder.Append(" ");
|
||||
}
|
||||
string typeString = bindingElement.GetType().ToString();
|
||||
builder.Append(typeString.Substring(typeString.LastIndexOf('.') + 1));
|
||||
}
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NotAllBindingElementsBuilt, builder.ToString())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Runtime;
|
||||
using System.ServiceModel;
|
||||
|
||||
public abstract class BindingElement
|
||||
{
|
||||
protected BindingElement()
|
||||
{
|
||||
}
|
||||
|
||||
protected BindingElement(BindingElement elementToBeCloned)
|
||||
{
|
||||
}
|
||||
|
||||
public abstract BindingElement Clone();
|
||||
|
||||
public virtual IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
|
||||
return context.BuildInnerChannelFactory<TChannel>();
|
||||
}
|
||||
|
||||
public virtual IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context) where TChannel : class, IChannel
|
||||
{
|
||||
if (context == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
|
||||
return context.BuildInnerChannelListener<TChannel>();
|
||||
}
|
||||
|
||||
public virtual bool CanBuildChannelFactory<TChannel>(BindingContext context)
|
||||
{
|
||||
if (context == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
|
||||
return context.CanBuildInnerChannelFactory<TChannel>();
|
||||
}
|
||||
|
||||
public virtual bool CanBuildChannelListener<TChannel>(BindingContext context) where TChannel : class, IChannel
|
||||
{
|
||||
if (context == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("context");
|
||||
|
||||
return context.CanBuildInnerChannelListener<TChannel>();
|
||||
}
|
||||
|
||||
public abstract T GetProperty<T>(BindingContext context) where T : class;
|
||||
|
||||
internal T GetIndividualProperty<T>() where T : class
|
||||
{
|
||||
return this.GetProperty<T>(new BindingContext(new CustomBinding(), new BindingParameterCollection()));
|
||||
}
|
||||
|
||||
internal virtual bool IsMatch(BindingElement b)
|
||||
{
|
||||
Fx.Assert(true, "Should not be called unless this binding element is used in one of the standard bindings. In which case, please re-implement the IsMatch() method.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,162 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.ServiceModel;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
public class BindingElementCollection : Collection<BindingElement>
|
||||
{
|
||||
public BindingElementCollection()
|
||||
{
|
||||
}
|
||||
|
||||
public BindingElementCollection(IEnumerable<BindingElement> elements)
|
||||
{
|
||||
if (elements == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("elements");
|
||||
|
||||
foreach (BindingElement element in elements)
|
||||
{
|
||||
base.Add(element);
|
||||
}
|
||||
}
|
||||
|
||||
public BindingElementCollection(BindingElement[] elements)
|
||||
{
|
||||
if (elements == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("elements");
|
||||
|
||||
for (int i = 0; i < elements.Length; i++)
|
||||
{
|
||||
base.Add(elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
internal BindingElementCollection(BindingElementCollection elements)
|
||||
{
|
||||
if (elements == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("elements");
|
||||
|
||||
for (int i = 0; i < elements.Count; i++)
|
||||
{
|
||||
base.Add(elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// returns a new collection with clones of all the elements
|
||||
public BindingElementCollection Clone()
|
||||
{
|
||||
BindingElementCollection result = new BindingElementCollection();
|
||||
for (int i = 0; i < this.Count; i++)
|
||||
{
|
||||
result.Add(this[i].Clone());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void AddRange(params BindingElement[] elements)
|
||||
{
|
||||
if (elements == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("elements");
|
||||
|
||||
for (int i = 0; i < elements.Length; i++)
|
||||
{
|
||||
base.Add(elements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(Type bindingElementType)
|
||||
{
|
||||
if (bindingElementType == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("bindingElementType");
|
||||
|
||||
for (int i = 0; i < this.Count; i++)
|
||||
{
|
||||
if (bindingElementType.IsInstanceOfType(this[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public T Find<T>()
|
||||
{
|
||||
return Find<T>(false);
|
||||
}
|
||||
|
||||
public T Remove<T>()
|
||||
{
|
||||
return Find<T>(true);
|
||||
}
|
||||
|
||||
T Find<T>(bool remove)
|
||||
{
|
||||
for (int index = 0; index < this.Count; index++)
|
||||
{
|
||||
if (this[index] is T)
|
||||
{
|
||||
T item = (T)(object)this[index];
|
||||
if (remove)
|
||||
{
|
||||
RemoveAt(index);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public Collection<T> FindAll<T>()
|
||||
{
|
||||
return FindAll<T>(false);
|
||||
}
|
||||
|
||||
public Collection<T> RemoveAll<T>()
|
||||
{
|
||||
return FindAll<T>(true);
|
||||
}
|
||||
|
||||
Collection<T> FindAll<T>(bool remove)
|
||||
{
|
||||
Collection<T> collection = new Collection<T>();
|
||||
|
||||
for (int index = 0; index < this.Count; index++)
|
||||
{
|
||||
if (this[index] is T)
|
||||
{
|
||||
T item = (T)(object)this[index];
|
||||
if (remove)
|
||||
{
|
||||
RemoveAt(index);
|
||||
// back up the index so we inspect the new item at this location
|
||||
index--;
|
||||
}
|
||||
collection.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, BindingElement item)
|
||||
{
|
||||
if (item == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
|
||||
|
||||
base.InsertItem(index, item);
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, BindingElement item)
|
||||
{
|
||||
if (item == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("item");
|
||||
|
||||
base.SetItem(index, item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
// Some binding elements can sometimes consume extra information when building factories.
|
||||
// BindingParameterCollection is a collection of objects with this extra information.
|
||||
// See comments in SecurityBindingElement and TransactionFlowBindingElement for examples
|
||||
// of binding elements that go looking for certain data in this collection.
|
||||
public class BindingParameterCollection : KeyedByTypeCollection<object>
|
||||
{
|
||||
public BindingParameterCollection() { }
|
||||
|
||||
internal BindingParameterCollection(params object[] parameters)
|
||||
{
|
||||
if (parameters == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parameters");
|
||||
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
base.Add(parameters[i]);
|
||||
}
|
||||
}
|
||||
|
||||
internal BindingParameterCollection(BindingParameterCollection parameters)
|
||||
{
|
||||
if (parameters == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parameters");
|
||||
|
||||
for (int i = 0; i < parameters.Count; i++)
|
||||
{
|
||||
base.Add(parameters[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,176 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System.Xml;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime;
|
||||
using System.Threading;
|
||||
|
||||
public abstract class BodyWriter
|
||||
{
|
||||
bool isBuffered;
|
||||
bool canWrite;
|
||||
object thisLock;
|
||||
|
||||
protected BodyWriter(bool isBuffered)
|
||||
{
|
||||
this.isBuffered = isBuffered;
|
||||
this.canWrite = true;
|
||||
if (!this.isBuffered)
|
||||
{
|
||||
this.thisLock = new object();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsBuffered
|
||||
{
|
||||
get { return this.isBuffered; }
|
||||
}
|
||||
|
||||
internal virtual bool IsEmpty
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
internal virtual bool IsFault
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public BodyWriter CreateBufferedCopy(int maxBufferSize)
|
||||
{
|
||||
if (maxBufferSize < 0)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxBufferSize", maxBufferSize,
|
||||
SR.GetString(SR.ValueMustBeNonNegative)));
|
||||
if (this.isBuffered)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (this.thisLock)
|
||||
{
|
||||
if (!this.canWrite)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BodyWriterCanOnlyBeWrittenOnce)));
|
||||
this.canWrite = false;
|
||||
}
|
||||
BodyWriter bodyWriter = OnCreateBufferedCopy(maxBufferSize);
|
||||
if (!bodyWriter.IsBuffered)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BodyWriterReturnedIsNotBuffered)));
|
||||
return bodyWriter;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual BodyWriter OnCreateBufferedCopy(int maxBufferSize)
|
||||
{
|
||||
return OnCreateBufferedCopy(maxBufferSize, XmlDictionaryReaderQuotas.Max);
|
||||
}
|
||||
|
||||
internal BodyWriter OnCreateBufferedCopy(int maxBufferSize, XmlDictionaryReaderQuotas quotas)
|
||||
{
|
||||
XmlBuffer buffer = new XmlBuffer(maxBufferSize);
|
||||
using (XmlDictionaryWriter writer = buffer.OpenSection(quotas))
|
||||
{
|
||||
writer.WriteStartElement("a");
|
||||
OnWriteBodyContents(writer);
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
buffer.CloseSection();
|
||||
buffer.Close();
|
||||
return new BufferedBodyWriter(buffer);
|
||||
}
|
||||
|
||||
protected abstract void OnWriteBodyContents(XmlDictionaryWriter writer);
|
||||
|
||||
protected virtual IAsyncResult OnBeginWriteBodyContents(XmlDictionaryWriter writer, AsyncCallback callback, object state)
|
||||
{
|
||||
return new OnWriteBodyContentsAsyncResult(writer, this, callback, state);
|
||||
}
|
||||
|
||||
protected virtual void OnEndWriteBodyContents(IAsyncResult result)
|
||||
{
|
||||
OnWriteBodyContentsAsyncResult.End(result);
|
||||
}
|
||||
|
||||
void EnsureWriteBodyContentsState(XmlDictionaryWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
|
||||
if (!this.isBuffered)
|
||||
{
|
||||
lock (this.thisLock)
|
||||
{
|
||||
if (!this.canWrite)
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.BodyWriterCanOnlyBeWrittenOnce)));
|
||||
this.canWrite = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteBodyContents(XmlDictionaryWriter writer)
|
||||
{
|
||||
EnsureWriteBodyContentsState(writer);
|
||||
OnWriteBodyContents(writer);
|
||||
}
|
||||
|
||||
public IAsyncResult BeginWriteBodyContents(XmlDictionaryWriter writer, AsyncCallback callback, object state)
|
||||
{
|
||||
EnsureWriteBodyContentsState(writer);
|
||||
return OnBeginWriteBodyContents(writer, callback, state);
|
||||
}
|
||||
|
||||
public void EndWriteBodyContents(IAsyncResult result)
|
||||
{
|
||||
OnEndWriteBodyContents(result);
|
||||
}
|
||||
|
||||
class BufferedBodyWriter : BodyWriter
|
||||
{
|
||||
XmlBuffer buffer;
|
||||
|
||||
public BufferedBodyWriter(XmlBuffer buffer)
|
||||
: base(true)
|
||||
{
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
|
||||
{
|
||||
XmlDictionaryReader reader = this.buffer.GetReader(0);
|
||||
using (reader)
|
||||
{
|
||||
reader.ReadStartElement();
|
||||
while (reader.NodeType != XmlNodeType.EndElement)
|
||||
{
|
||||
writer.WriteNode(reader, false);
|
||||
}
|
||||
reader.ReadEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OnWriteBodyContentsAsyncResult : ScheduleActionItemAsyncResult
|
||||
{
|
||||
BodyWriter bodyWriter;
|
||||
XmlDictionaryWriter writer;
|
||||
|
||||
public OnWriteBodyContentsAsyncResult(XmlDictionaryWriter writer, BodyWriter bodyWriter, AsyncCallback callback, object state)
|
||||
: base(callback, state)
|
||||
{
|
||||
Fx.Assert(bodyWriter != null, "bodyWriter should never be null");
|
||||
|
||||
this.writer = writer;
|
||||
this.bodyWriter = bodyWriter;
|
||||
|
||||
Schedule();
|
||||
}
|
||||
|
||||
protected override void OnDoWork()
|
||||
{
|
||||
this.bodyWriter.OnWriteBodyContents(this.writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
namespace System.ServiceModel.Channels
|
||||
{
|
||||
using System;
|
||||
using System.Runtime;
|
||||
using System.ServiceModel;
|
||||
|
||||
public abstract class BufferManager
|
||||
{
|
||||
public abstract byte[] TakeBuffer(int bufferSize);
|
||||
public abstract void ReturnBuffer(byte[] buffer);
|
||||
public abstract void Clear();
|
||||
|
||||
public static BufferManager CreateBufferManager(long maxBufferPoolSize, int maxBufferSize)
|
||||
{
|
||||
if (maxBufferPoolSize < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxBufferPoolSize",
|
||||
maxBufferPoolSize, SR.GetString(SR.ValueMustBeNonNegative)));
|
||||
}
|
||||
|
||||
if (maxBufferSize < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxBufferSize",
|
||||
maxBufferSize, SR.GetString(SR.ValueMustBeNonNegative)));
|
||||
}
|
||||
|
||||
return new WrappingBufferManager(InternalBufferManager.Create(maxBufferPoolSize, maxBufferSize));
|
||||
}
|
||||
|
||||
internal static InternalBufferManager GetInternalBufferManager(BufferManager bufferManager)
|
||||
{
|
||||
if (bufferManager is WrappingBufferManager)
|
||||
{
|
||||
return ((WrappingBufferManager)bufferManager).InternalBufferManager;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new WrappingInternalBufferManager(bufferManager);
|
||||
}
|
||||
}
|
||||
|
||||
class WrappingBufferManager : BufferManager
|
||||
{
|
||||
InternalBufferManager innerBufferManager;
|
||||
|
||||
public WrappingBufferManager(InternalBufferManager innerBufferManager)
|
||||
{
|
||||
this.innerBufferManager = innerBufferManager;
|
||||
}
|
||||
|
||||
public InternalBufferManager InternalBufferManager
|
||||
{
|
||||
get { return this.innerBufferManager; }
|
||||
}
|
||||
|
||||
public override byte[] TakeBuffer(int bufferSize)
|
||||
{
|
||||
if (bufferSize < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("bufferSize", bufferSize,
|
||||
SR.GetString(SR.ValueMustBeNonNegative)));
|
||||
}
|
||||
|
||||
return this.innerBufferManager.TakeBuffer(bufferSize);
|
||||
}
|
||||
|
||||
public override void ReturnBuffer(byte[] buffer)
|
||||
{
|
||||
if (buffer == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("buffer");
|
||||
}
|
||||
|
||||
this.innerBufferManager.ReturnBuffer(buffer);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
this.innerBufferManager.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
class WrappingInternalBufferManager : InternalBufferManager
|
||||
{
|
||||
BufferManager innerBufferManager;
|
||||
|
||||
public WrappingInternalBufferManager(BufferManager innerBufferManager)
|
||||
{
|
||||
this.innerBufferManager = innerBufferManager;
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
this.innerBufferManager.Clear();
|
||||
}
|
||||
|
||||
public override void ReturnBuffer(byte[] buffer)
|
||||
{
|
||||
this.innerBufferManager.ReturnBuffer(buffer);
|
||||
}
|
||||
|
||||
public override byte[] TakeBuffer(int bufferSize)
|
||||
{
|
||||
return this.innerBufferManager.TakeBuffer(bufferSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user