| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel.Channels
- {
- using System.Globalization;
- using System.IO;
- using System.Runtime;
- using System.Runtime.Serialization;
- using System.ServiceModel;
- using System.ServiceModel.Description;
- using System.ServiceModel.Dispatcher;
- using System.Xml;
- public abstract class MessageHeader : MessageHeaderInfo
- {
- const bool DefaultRelayValue = false;
- const bool DefaultMustUnderstandValue = false;
- const string DefaultActorValue = "";
- public override string Actor
- {
- get { return ""; }
- }
- public override bool IsReferenceParameter
- {
- get { return false; }
- }
- public override bool MustUnderstand
- {
- get { return DefaultMustUnderstandValue; }
- }
- public override bool Relay
- {
- get { return DefaultRelayValue; }
- }
- public virtual bool IsMessageVersionSupported(MessageVersion messageVersion)
- {
- if (messageVersion == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageVersion");
- }
- return true;
- }
- public override string ToString()
- {
- StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
- XmlTextWriter textWriter = new XmlTextWriter(stringWriter);
- textWriter.Formatting = Formatting.Indented;
- XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(textWriter);
- if (IsMessageVersionSupported(MessageVersion.Soap12WSAddressing10))
- {
- WriteHeader(writer, MessageVersion.Soap12WSAddressing10);
- }
- else if (IsMessageVersionSupported(MessageVersion.Soap12WSAddressingAugust2004))
- {
- WriteHeader(writer, MessageVersion.Soap12WSAddressingAugust2004);
- }
- else if (IsMessageVersionSupported(MessageVersion.Soap11WSAddressing10))
- {
- WriteHeader(writer, MessageVersion.Soap11WSAddressing10);
- }
- else if (IsMessageVersionSupported(MessageVersion.Soap11WSAddressingAugust2004))
- {
- WriteHeader(writer, MessageVersion.Soap11WSAddressingAugust2004);
- }
- else if (IsMessageVersionSupported(MessageVersion.Soap12))
- {
- WriteHeader(writer, MessageVersion.Soap12);
- }
- else if (IsMessageVersionSupported(MessageVersion.Soap11))
- {
- WriteHeader(writer, MessageVersion.Soap11);
- }
- else
- {
- WriteHeader(writer, MessageVersion.None);
- }
- writer.Flush();
- return stringWriter.ToString();
- }
- public void WriteHeader(XmlWriter writer, MessageVersion messageVersion)
- {
- WriteHeader(XmlDictionaryWriter.CreateDictionaryWriter(writer), messageVersion);
- }
- public void WriteHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- if (writer == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
- if (messageVersion == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("messageVersion"));
- OnWriteStartHeader(writer, messageVersion);
- OnWriteHeaderContents(writer, messageVersion);
- writer.WriteEndElement();
- }
- public void WriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- if (writer == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
- if (messageVersion == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("messageVersion"));
- OnWriteStartHeader(writer, messageVersion);
- }
- protected virtual void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- writer.WriteStartElement(this.Name, this.Namespace);
- WriteHeaderAttributes(writer, messageVersion);
- }
- public void WriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- if (writer == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("writer"));
- if (messageVersion == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("messageVersion"));
- OnWriteHeaderContents(writer, messageVersion);
- }
- protected abstract void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion);
- protected void WriteHeaderAttributes(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- string actor = this.Actor;
- if (actor.Length > 0)
- writer.WriteAttributeString(messageVersion.Envelope.DictionaryActor, messageVersion.Envelope.DictionaryNamespace, actor);
- if (this.MustUnderstand)
- writer.WriteAttributeString(XD.MessageDictionary.MustUnderstand, messageVersion.Envelope.DictionaryNamespace, "1");
- if (this.Relay && messageVersion.Envelope == EnvelopeVersion.Soap12)
- writer.WriteAttributeString(XD.Message12Dictionary.Relay, XD.Message12Dictionary.Namespace, "1");
- }
- public static MessageHeader CreateHeader(string name, string ns, object value)
- {
- return CreateHeader(name, ns, value, DefaultMustUnderstandValue, DefaultActorValue, DefaultRelayValue);
- }
- public static MessageHeader CreateHeader(string name, string ns, object value, bool mustUnderstand)
- {
- return CreateHeader(name, ns, value, mustUnderstand, DefaultActorValue, DefaultRelayValue);
- }
- public static MessageHeader CreateHeader(string name, string ns, object value, bool mustUnderstand, string actor)
- {
- return CreateHeader(name, ns, value, mustUnderstand, actor, DefaultRelayValue);
- }
- public static MessageHeader CreateHeader(string name, string ns, object value, bool mustUnderstand, string actor, bool relay)
- {
- return new XmlObjectSerializerHeader(name, ns, value, null, mustUnderstand, actor, relay);
- }
- public static MessageHeader CreateHeader(string name, string ns, object value, XmlObjectSerializer serializer)
- {
- return CreateHeader(name, ns, value, serializer, DefaultMustUnderstandValue, DefaultActorValue, DefaultRelayValue);
- }
- public static MessageHeader CreateHeader(string name, string ns, object value, XmlObjectSerializer serializer, bool mustUnderstand)
- {
- return CreateHeader(name, ns, value, serializer, mustUnderstand, DefaultActorValue, DefaultRelayValue);
- }
- public static MessageHeader CreateHeader(string name, string ns, object value, XmlObjectSerializer serializer, bool mustUnderstand, string actor)
- {
- return CreateHeader(name, ns, value, serializer, mustUnderstand, actor, DefaultRelayValue);
- }
- public static MessageHeader CreateHeader(string name, string ns, object value, XmlObjectSerializer serializer, bool mustUnderstand, string actor, bool relay)
- {
- if (serializer == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serializer"));
- return new XmlObjectSerializerHeader(name, ns, value, serializer, mustUnderstand, actor, relay);
- }
- internal static void GetHeaderAttributes(XmlDictionaryReader reader, MessageVersion version,
- out string actor, out bool mustUnderstand, out bool relay, out bool isReferenceParameter)
- {
- int attributeCount = reader.AttributeCount;
- if (attributeCount == 0)
- {
- mustUnderstand = false;
- actor = string.Empty;
- relay = false;
- isReferenceParameter = false;
- }
- else
- {
- string mustUnderstandString = reader.GetAttribute(XD.MessageDictionary.MustUnderstand, version.Envelope.DictionaryNamespace);
- if (mustUnderstandString != null && ToBoolean(mustUnderstandString))
- mustUnderstand = true;
- else
- mustUnderstand = false;
- if (mustUnderstand && attributeCount == 1)
- {
- actor = string.Empty;
- relay = false;
- }
- else
- {
- actor = reader.GetAttribute(version.Envelope.DictionaryActor, version.Envelope.DictionaryNamespace);
- if (actor == null)
- actor = "";
- if (version.Envelope == EnvelopeVersion.Soap12)
- {
- string relayString = reader.GetAttribute(XD.Message12Dictionary.Relay, version.Envelope.DictionaryNamespace);
- if (relayString != null && ToBoolean(relayString))
- relay = true;
- else
- relay = false;
- }
- else
- {
- relay = false;
- }
- }
- isReferenceParameter = false;
- if (version.Addressing == AddressingVersion.WSAddressing10)
- {
- string refParam = reader.GetAttribute(XD.AddressingDictionary.IsReferenceParameter, version.Addressing.DictionaryNamespace);
- if (refParam != null)
- isReferenceParameter = ToBoolean(refParam);
- }
- }
- }
- static bool ToBoolean(string value)
- {
- if (value.Length == 1)
- {
- char ch = value[0];
- if (ch == '1')
- {
- return true;
- }
- if (ch == '0')
- {
- return false;
- }
- }
- else
- {
- if (value == "true")
- {
- return true;
- }
- else if (value == "false")
- {
- return false;
- }
- }
- try
- {
- return XmlConvert.ToBoolean(value);
- }
- catch (FormatException exception)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(exception.Message, null));
- }
- }
- }
- abstract class DictionaryHeader : MessageHeader
- {
- public override string Name
- {
- get { return DictionaryName.Value; }
- }
- public override string Namespace
- {
- get { return DictionaryNamespace.Value; }
- }
- public abstract XmlDictionaryString DictionaryName { get; }
- public abstract XmlDictionaryString DictionaryNamespace { get; }
- protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- writer.WriteStartElement(DictionaryName, DictionaryNamespace);
- WriteHeaderAttributes(writer, messageVersion);
- }
- }
- class XmlObjectSerializerHeader : MessageHeader
- {
- XmlObjectSerializer serializer;
- bool mustUnderstand;
- bool relay;
- bool isOneTwoSupported;
- bool isOneOneSupported;
- bool isNoneSupported;
- object objectToSerialize;
- string name;
- string ns;
- string actor;
- object syncRoot = new object();
- XmlObjectSerializerHeader(XmlObjectSerializer serializer, bool mustUnderstand, string actor, bool relay)
- {
- if (actor == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("actor");
- }
- this.mustUnderstand = mustUnderstand;
- this.relay = relay;
- this.serializer = serializer;
- this.actor = actor;
- if (actor == EnvelopeVersion.Soap12.UltimateDestinationActor)
- {
- this.isOneOneSupported = false;
- this.isOneTwoSupported = true;
- }
- else if (actor == EnvelopeVersion.Soap12.NextDestinationActorValue)
- {
- this.isOneOneSupported = false;
- this.isOneTwoSupported = true;
- }
- else if (actor == EnvelopeVersion.Soap11.NextDestinationActorValue)
- {
- this.isOneOneSupported = true;
- this.isOneTwoSupported = false;
- }
- else
- {
- this.isOneOneSupported = true;
- this.isOneTwoSupported = true;
- this.isNoneSupported = true;
- }
- }
- public XmlObjectSerializerHeader(string name, string ns, object objectToSerialize, XmlObjectSerializer serializer, bool mustUnderstand, string actor, bool relay)
- : this(serializer, mustUnderstand, actor, relay)
- {
- if (null == name)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("name"));
- }
- if (name.Length == 0)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SFXHeaderNameCannotBeNullOrEmpty), "name"));
- }
- if (ns == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("ns");
- }
- if (ns.Length > 0)
- {
- NamingHelper.CheckUriParameter(ns, "ns");
- }
- this.objectToSerialize = objectToSerialize;
- this.name = name;
- this.ns = ns;
- }
- public override bool IsMessageVersionSupported(MessageVersion messageVersion)
- {
- if (messageVersion == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("messageVersion");
- }
- if (messageVersion.Envelope == EnvelopeVersion.Soap12)
- {
- return this.isOneTwoSupported;
- }
- else if (messageVersion.Envelope == EnvelopeVersion.Soap11)
- {
- return this.isOneOneSupported;
- }
- else if (messageVersion.Envelope == EnvelopeVersion.None)
- {
- return this.isNoneSupported;
- }
- else
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.EnvelopeVersionUnknown, messageVersion.Envelope.ToString())));
- }
- }
- public override string Name
- {
- get { return name; }
- }
- public override string Namespace
- {
- get { return ns; }
- }
- public override bool MustUnderstand
- {
- get { return mustUnderstand; }
- }
- public override bool Relay
- {
- get { return relay; }
- }
- public override string Actor
- {
- get { return actor; }
- }
- protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- lock (syncRoot)
- {
- if (serializer == null)
- {
- serializer = DataContractSerializerDefaults.CreateSerializer(
- (objectToSerialize == null ? typeof(object) : objectToSerialize.GetType()), this.Name, this.Namespace, int.MaxValue/*maxItems*/);
- }
- serializer.WriteObjectContent(writer, objectToSerialize);
- }
- }
- }
- abstract class ReadableMessageHeader : MessageHeader
- {
- public abstract XmlDictionaryReader GetHeaderReader();
- protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- if (!IsMessageVersionSupported(messageVersion))
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MessageHeaderVersionNotSupported, this.GetType().FullName, messageVersion.ToString()), "version"));
- XmlDictionaryReader reader = GetHeaderReader();
- writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
- writer.WriteAttributes(reader, false);
- reader.Close();
- }
- protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
- {
- XmlDictionaryReader reader = GetHeaderReader();
- reader.ReadStartElement();
- while (reader.NodeType != XmlNodeType.EndElement)
- writer.WriteNode(reader, false);
- reader.ReadEndElement();
- reader.Close();
- }
- }
- internal interface IMessageHeaderWithSharedNamespace
- {
- XmlDictionaryString SharedNamespace { get; }
- XmlDictionaryString SharedPrefix { get; }
- }
- class BufferedHeader : ReadableMessageHeader
- {
- MessageVersion version;
- XmlBuffer buffer;
- int bufferIndex;
- string actor;
- bool relay;
- bool mustUnderstand;
- string name;
- string ns;
- bool streamed;
- bool isRefParam;
- public BufferedHeader(MessageVersion version, XmlBuffer buffer, int bufferIndex, string name, string ns, bool mustUnderstand, string actor, bool relay, bool isRefParam)
- {
- this.version = version;
- this.buffer = buffer;
- this.bufferIndex = bufferIndex;
- this.name = name;
- this.ns = ns;
- this.mustUnderstand = mustUnderstand;
- this.actor = actor;
- this.relay = relay;
- this.isRefParam = isRefParam;
- }
- public BufferedHeader(MessageVersion version, XmlBuffer buffer, int bufferIndex, MessageHeaderInfo headerInfo)
- {
- this.version = version;
- this.buffer = buffer;
- this.bufferIndex = bufferIndex;
- actor = headerInfo.Actor;
- relay = headerInfo.Relay;
- name = headerInfo.Name;
- ns = headerInfo.Namespace;
- isRefParam = headerInfo.IsReferenceParameter;
- mustUnderstand = headerInfo.MustUnderstand;
- }
- public BufferedHeader(MessageVersion version, XmlBuffer buffer, XmlDictionaryReader reader, XmlAttributeHolder[] envelopeAttributes, XmlAttributeHolder[] headerAttributes)
- {
- this.streamed = true;
- this.buffer = buffer;
- this.version = version;
- GetHeaderAttributes(reader, version, out this.actor, out this.mustUnderstand, out this.relay, out this.isRefParam);
- name = reader.LocalName;
- ns = reader.NamespaceURI;
- Fx.Assert(name != null, "");
- Fx.Assert(ns != null, "");
- bufferIndex = buffer.SectionCount;
- XmlDictionaryWriter writer = buffer.OpenSection(reader.Quotas);
- // Write an enclosing Envelope tag
- writer.WriteStartElement(MessageStrings.Envelope);
- if (envelopeAttributes != null)
- XmlAttributeHolder.WriteAttributes(envelopeAttributes, writer);
- // Write and enclosing Header tag
- writer.WriteStartElement(MessageStrings.Header);
- if (headerAttributes != null)
- XmlAttributeHolder.WriteAttributes(headerAttributes, writer);
- writer.WriteNode(reader, false);
- writer.WriteEndElement();
- writer.WriteEndElement();
- buffer.CloseSection();
- }
- public override string Actor
- {
- get { return actor; }
- }
- public override bool IsReferenceParameter
- {
- get { return isRefParam; }
- }
- public override string Name
- {
- get { return name; }
- }
- public override string Namespace
- {
- get { return ns; }
- }
- public override bool MustUnderstand
- {
- get { return mustUnderstand; }
- }
- public override bool Relay
- {
- get { return relay; }
- }
- public override bool IsMessageVersionSupported(MessageVersion messageVersion)
- {
- if (messageVersion == null)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("messageVersion"));
- return messageVersion == this.version;
- }
- public override XmlDictionaryReader GetHeaderReader()
- {
- XmlDictionaryReader reader = buffer.GetReader(bufferIndex);
- // See if we need to move past the enclosing envelope/header
- if (this.streamed)
- {
- reader.MoveToContent();
- reader.Read(); // Envelope
- reader.Read(); // Header
- reader.MoveToContent();
- }
- return reader;
- }
- }
- }
|