< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.XmlObjectSerializerHeader
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Channels/MessageHeader.cs
Line coverage
75%
Covered lines: 40
Uncovered lines: 13
Coverable lines: 53
Total lines: 645
Line coverage: 75.4%
Branch coverage
57%
Covered branches: 16
Total branches: 28
Branch coverage: 57.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)50%8868.42%
.ctor(...)62.5%8876.92%
IsMessageVersionSupported(...)37.5%8844.44%
OnWriteHeaderContents(...)75%44100%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Channels/MessageHeader.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Globalization;
 6using System.IO;
 7using System.Runtime.Serialization;
 8using System.Xml;
 9using CoreWCF.Description;
 10using CoreWCF.Dispatcher;
 11using CoreWCF.Runtime;
 12
 13namespace CoreWCF.Channels
 14{
 15    public abstract class MessageHeader : MessageHeaderInfo
 16    {
 17        private const bool DefaultRelayValue = false;
 18        private const bool DefaultMustUnderstandValue = false;
 19        private const string DefaultActorValue = "";
 20
 21        public override string Actor
 22        {
 23            get { return ""; }
 24        }
 25
 26        public override bool IsReferenceParameter
 27        {
 28            get { return false; }
 29        }
 30
 31        public override bool MustUnderstand
 32        {
 33            get { return DefaultMustUnderstandValue; }
 34        }
 35
 36        public override bool Relay
 37        {
 38            get { return DefaultRelayValue; }
 39        }
 40
 41        public virtual bool IsMessageVersionSupported(MessageVersion messageVersion)
 42        {
 43            if (messageVersion == null)
 44            {
 45                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(messageVersion));
 46            }
 47
 48            return true;
 49        }
 50
 51        public override string ToString()
 52        {
 53            XmlWriterSettings xmlSettings = new XmlWriterSettings() { Indent = true };
 54            using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture))
 55            {
 56                using (XmlWriter textWriter = XmlWriter.Create(stringWriter, xmlSettings))
 57                {
 58                    using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateDictionaryWriter(textWriter))
 59                    {
 60                        if (IsMessageVersionSupported(MessageVersion.Soap12WSAddressing10))
 61                        {
 62                            WriteHeader(writer, MessageVersion.Soap12WSAddressing10);
 63                        }
 64                        //else if (IsMessageVersionSupported(MessageVersion.Soap12WSAddressingAugust2004))
 65                        //{
 66                        //    WriteHeader(writer, MessageVersion.Soap12WSAddressingAugust2004);
 67                        //}
 68                        //else if (IsMessageVersionSupported(MessageVersion.Soap11WSAddressing10))
 69                        //{
 70                        //    WriteHeader(writer, MessageVersion.Soap11WSAddressing10);
 71                        //}
 72                        //else if (IsMessageVersionSupported(MessageVersion.Soap11WSAddressingAugust2004))
 73                        //{
 74                        //    WriteHeader(writer, MessageVersion.Soap11WSAddressingAugust2004);
 75                        //}
 76                        //else if (IsMessageVersionSupported(MessageVersion.Soap12))
 77                        //{
 78                        //    WriteHeader(writer, MessageVersion.Soap12);
 79                        //}
 80                        else if (IsMessageVersionSupported(MessageVersion.Soap11))
 81                        {
 82                            WriteHeader(writer, MessageVersion.Soap11);
 83                        }
 84                        else
 85                        {
 86                            WriteHeader(writer, MessageVersion.None);
 87                        }
 88
 89                        writer.Flush();
 90                        return stringWriter.ToString();
 91                    }
 92                }
 93            }
 94        }
 95
 96        public void WriteHeader(XmlWriter writer, MessageVersion messageVersion)
 97        {
 98            WriteHeader(XmlDictionaryWriter.CreateDictionaryWriter(writer), messageVersion);
 99        }
 100
 101        public void WriteHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
 102        {
 103            if (writer == null)
 104            {
 105                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(writer));
 106            }
 107
 108            if (messageVersion == null)
 109            {
 110                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(messageVersion));
 111            }
 112
 113            OnWriteStartHeader(writer, messageVersion);
 114            OnWriteHeaderContents(writer, messageVersion);
 115            writer.WriteEndElement();
 116        }
 117
 118        public void WriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
 119        {
 120            if (writer == null)
 121            {
 122                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(writer));
 123            }
 124
 125            if (messageVersion == null)
 126            {
 127                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(messageVersion));
 128            }
 129
 130            OnWriteStartHeader(writer, messageVersion);
 131        }
 132
 133        protected virtual void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
 134        {
 135            writer.WriteStartElement(Name, Namespace);
 136            WriteHeaderAttributes(writer, messageVersion);
 137        }
 138
 139        public void WriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
 140        {
 141            if (writer == null)
 142            {
 143                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(writer));
 144            }
 145
 146            if (messageVersion == null)
 147            {
 148                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(messageVersion));
 149            }
 150
 151            OnWriteHeaderContents(writer, messageVersion);
 152        }
 153
 154        protected abstract void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion);
 155
 156        protected void WriteHeaderAttributes(XmlDictionaryWriter writer, MessageVersion messageVersion)
 157        {
 158            string actor = Actor;
 159            if (actor.Length > 0)
 160            {
 161                writer.WriteAttributeString(messageVersion.Envelope.DictionaryActor, messageVersion.Envelope.DictionaryN
 162            }
 163
 164            if (MustUnderstand)
 165            {
 166                writer.WriteAttributeString(XD.MessageDictionary.MustUnderstand, messageVersion.Envelope.DictionaryNames
 167            }
 168
 169            if (Relay && messageVersion.Envelope == EnvelopeVersion.Soap12)
 170            {
 171                writer.WriteAttributeString(XD.Message12Dictionary.Relay, XD.Message12Dictionary.Namespace, "1");
 172            }
 173        }
 174
 175        public static MessageHeader CreateHeader(string name, string ns, object value)
 176        {
 177            return CreateHeader(name, ns, value, DefaultMustUnderstandValue, DefaultActorValue, DefaultRelayValue);
 178        }
 179
 180        public static MessageHeader CreateHeader(string name, string ns, object value, bool mustUnderstand)
 181        {
 182            return CreateHeader(name, ns, value, mustUnderstand, DefaultActorValue, DefaultRelayValue);
 183        }
 184
 185        public static MessageHeader CreateHeader(string name, string ns, object value, bool mustUnderstand, string actor
 186        {
 187            return CreateHeader(name, ns, value, mustUnderstand, actor, DefaultRelayValue);
 188        }
 189
 190        public static MessageHeader CreateHeader(string name, string ns, object value, bool mustUnderstand, string actor
 191        {
 192            return new XmlObjectSerializerHeader(name, ns, value, null, mustUnderstand, actor, relay);
 193        }
 194
 195        public static MessageHeader CreateHeader(string name, string ns, object value, XmlObjectSerializer serializer)
 196        {
 197            return CreateHeader(name, ns, value, serializer, DefaultMustUnderstandValue, DefaultActorValue, DefaultRelay
 198        }
 199
 200        public static MessageHeader CreateHeader(string name, string ns, object value, XmlObjectSerializer serializer, b
 201        {
 202            return CreateHeader(name, ns, value, serializer, mustUnderstand, DefaultActorValue, DefaultRelayValue);
 203        }
 204
 205        public static MessageHeader CreateHeader(string name, string ns, object value, XmlObjectSerializer serializer, b
 206        {
 207            return CreateHeader(name, ns, value, serializer, mustUnderstand, actor, DefaultRelayValue);
 208        }
 209
 210        public static MessageHeader CreateHeader(string name, string ns, object value, XmlObjectSerializer serializer, b
 211        {
 212            if (serializer == null)
 213            {
 214                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(serializer));
 215            }
 216
 217            return new XmlObjectSerializerHeader(name, ns, value, serializer, mustUnderstand, actor, relay);
 218        }
 219
 220        internal static void GetHeaderAttributes(XmlDictionaryReader reader, MessageVersion version,
 221            out string actor, out bool mustUnderstand, out bool relay, out bool isReferenceParameter)
 222        {
 223            int attributeCount = reader.AttributeCount;
 224
 225            if (attributeCount == 0)
 226            {
 227                mustUnderstand = false;
 228                actor = string.Empty;
 229                relay = false;
 230                isReferenceParameter = false;
 231            }
 232            else
 233            {
 234                string mustUnderstandString = reader.GetAttribute(XD.MessageDictionary.MustUnderstand, version.Envelope.
 235                if (mustUnderstandString != null && ToBoolean(mustUnderstandString))
 236                {
 237                    mustUnderstand = true;
 238                }
 239                else
 240                {
 241                    mustUnderstand = false;
 242                }
 243
 244                if (mustUnderstand && attributeCount == 1)
 245                {
 246                    actor = string.Empty;
 247                    relay = false;
 248                }
 249                else
 250                {
 251                    actor = reader.GetAttribute(version.Envelope.DictionaryActor, version.Envelope.DictionaryNamespace);
 252                    if (actor == null)
 253                    {
 254                        actor = "";
 255                    }
 256
 257                    if (version.Envelope == EnvelopeVersion.Soap12)
 258                    {
 259                        string relayString = reader.GetAttribute(XD.Message12Dictionary.Relay, version.Envelope.Dictiona
 260                        if (relayString != null && ToBoolean(relayString))
 261                        {
 262                            relay = true;
 263                        }
 264                        else
 265                        {
 266                            relay = false;
 267                        }
 268                    }
 269                    else
 270                    {
 271                        relay = false;
 272                    }
 273                }
 274
 275                isReferenceParameter = false;
 276                if (version.Addressing == AddressingVersion.WSAddressing10)
 277                {
 278                    string refParam = reader.GetAttribute(XD.AddressingDictionary.IsReferenceParameter, version.Addressi
 279                    if (refParam != null)
 280                    {
 281                        isReferenceParameter = ToBoolean(refParam);
 282                    }
 283                }
 284            }
 285        }
 286
 287        private static bool ToBoolean(string value)
 288        {
 289            if (value.Length == 1)
 290            {
 291                char ch = value[0];
 292                if (ch == '1')
 293                {
 294                    return true;
 295                }
 296                if (ch == '0')
 297                {
 298                    return false;
 299                }
 300            }
 301            else
 302            {
 303                if (value == "true")
 304                {
 305                    return true;
 306                }
 307                else if (value == "false")
 308                {
 309                    return false;
 310                }
 311            }
 312            try
 313            {
 314                return XmlConvert.ToBoolean(value);
 315            }
 316            catch (FormatException exception)
 317            {
 318                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(exception.Message, null));
 319            }
 320        }
 321    }
 322
 323    // TODO: This needed to be made public for NetTcp, investigate making it internal again
 324    public abstract class DictionaryHeader : MessageHeader
 325    {
 326        public override string Name
 327        {
 328            get { return DictionaryName.Value; }
 329        }
 330
 331        public override string Namespace
 332        {
 333            get { return DictionaryNamespace.Value; }
 334        }
 335
 336        public abstract XmlDictionaryString DictionaryName { get; }
 337        public abstract XmlDictionaryString DictionaryNamespace { get; }
 338
 339        protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
 340        {
 341            writer.WriteStartElement(DictionaryName, DictionaryNamespace);
 342            WriteHeaderAttributes(writer, messageVersion);
 343        }
 344    }
 345
 346    internal class XmlObjectSerializerHeader : MessageHeader
 347    {
 348        private XmlObjectSerializer _serializer;
 349        private readonly bool _mustUnderstand;
 350        private readonly bool _relay;
 351        private readonly bool _isOneTwoSupported;
 352        private readonly bool _isOneOneSupported;
 353        private readonly bool _isNoneSupported;
 354        private readonly object _objectToSerialize;
 355        private readonly string _name;
 356        private readonly string _ns;
 357        private readonly string _actor;
 13358        private readonly object _syncRoot = new object();
 359
 13360        private XmlObjectSerializerHeader(XmlObjectSerializer serializer, bool mustUnderstand, string actor, bool relay)
 361        {
 13362            _mustUnderstand = mustUnderstand;
 13363            _relay = relay;
 13364            _serializer = serializer;
 13365            _actor = actor ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(actor));
 13366            if (actor == EnvelopeVersion.Soap12.UltimateDestinationActor)
 367            {
 0368                _isOneOneSupported = false;
 0369                _isOneTwoSupported = true;
 370            }
 13371            else if (actor == EnvelopeVersion.Soap12.NextDestinationActorValue)
 372            {
 0373                _isOneOneSupported = false;
 0374                _isOneTwoSupported = true;
 375            }
 13376            else if (actor == EnvelopeVersion.Soap11.NextDestinationActorValue)
 377            {
 0378                _isOneOneSupported = true;
 0379                _isOneTwoSupported = false;
 380            }
 381            else
 382            {
 13383                _isOneOneSupported = true;
 13384                _isOneTwoSupported = true;
 13385                _isNoneSupported = true;
 386            }
 13387        }
 388
 389        public XmlObjectSerializerHeader(string name, string ns, object objectToSerialize, XmlObjectSerializer serialize
 13390            : this(serializer, mustUnderstand, actor, relay)
 391        {
 13392            if (null == name)
 393            {
 0394                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(name));
 395            }
 396
 13397            if (name.Length == 0)
 398            {
 0399                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.SFXHeaderNameCannotBe
 400            }
 401
 13402            if (ns == null)
 403            {
 0404                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(ns));
 405            }
 13406            if (ns.Length > 0)
 407            {
 12408                NamingHelper.CheckUriParameter(ns, nameof(ns));
 409            }
 13410            _objectToSerialize = objectToSerialize;
 13411            _name = name;
 13412            _ns = ns;
 13413        }
 414
 415        public override bool IsMessageVersionSupported(MessageVersion messageVersion)
 416        {
 13417            if (messageVersion == null)
 418            {
 0419                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(messageVersion));
 420            }
 421
 13422            if (messageVersion.Envelope == EnvelopeVersion.Soap12)
 423            {
 3424                return _isOneTwoSupported;
 425            }
 10426            else if (messageVersion.Envelope == EnvelopeVersion.Soap11)
 427            {
 10428                return _isOneOneSupported;
 429            }
 0430            else if (messageVersion.Envelope == EnvelopeVersion.None)
 431            {
 0432                return _isNoneSupported;
 433            }
 434            else
 435            {
 0436                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Env
 437            }
 438        }
 439
 440        public override string Name
 441        {
 6442            get { return _name; }
 443        }
 444
 445        public override string Namespace
 446        {
 53447            get { return _ns; }
 448        }
 449
 450        public override bool MustUnderstand
 451        {
 28452            get { return _mustUnderstand; }
 453        }
 454
 455        public override bool Relay
 456        {
 13457            get { return _relay; }
 458        }
 459
 460        public override string Actor
 461        {
 13462            get { return _actor; }
 463        }
 464
 465        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
 466        {
 9467            lock (_syncRoot)
 468            {
 9469                if (_serializer == null)
 470                {
 1471                    _serializer = DataContractSerializerDefaults.CreateSerializer(
 1472                        (_objectToSerialize == null ? typeof(object) : _objectToSerialize.GetType()), Name, Namespace, i
 473                }
 474
 9475                _serializer.WriteObjectContent(writer, _objectToSerialize);
 9476            }
 9477        }
 478    }
 479
 480    internal abstract class ReadableMessageHeader : MessageHeader
 481    {
 482        public abstract XmlDictionaryReader GetHeaderReader();
 483
 484        protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
 485        {
 486            if (!IsMessageVersionSupported(messageVersion))
 487            {
 488                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.MessageHead
 489            }
 490
 491            XmlDictionaryReader reader = GetHeaderReader();
 492            writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
 493            writer.WriteAttributes(reader, false);
 494            reader.Dispose();
 495        }
 496
 497        protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
 498        {
 499            XmlDictionaryReader reader = GetHeaderReader();
 500            reader.ReadStartElement();
 501            while (reader.NodeType != XmlNodeType.EndElement)
 502            {
 503                writer.WriteNode(reader, false);
 504            }
 505
 506            reader.ReadEndElement();
 507            reader.Dispose();
 508        }
 509    }
 510
 511    internal interface IMessageHeaderWithSharedNamespace
 512    {
 513        XmlDictionaryString SharedNamespace { get; }
 514        XmlDictionaryString SharedPrefix { get; }
 515    }
 516
 517    internal class BufferedHeader : ReadableMessageHeader
 518    {
 519        private readonly MessageVersion _version;
 520        private readonly XmlBuffer _buffer;
 521        private readonly int _bufferIndex;
 522        private readonly string _actor;
 523        private readonly bool _relay;
 524        private readonly bool _mustUnderstand;
 525        private readonly string _name;
 526        private readonly string _ns;
 527        private readonly bool _streamed;
 528        private readonly bool _isRefParam;
 529
 530        public BufferedHeader(MessageVersion version, XmlBuffer buffer, int bufferIndex, string name, string ns, bool mu
 531        {
 532            _version = version;
 533            _buffer = buffer;
 534            _bufferIndex = bufferIndex;
 535            _name = name;
 536            _ns = ns;
 537            _mustUnderstand = mustUnderstand;
 538            _actor = actor;
 539            _relay = relay;
 540            _isRefParam = isRefParam;
 541        }
 542
 543        public BufferedHeader(MessageVersion version, XmlBuffer buffer, int bufferIndex, MessageHeaderInfo headerInfo)
 544        {
 545            _version = version;
 546            _buffer = buffer;
 547            _bufferIndex = bufferIndex;
 548            _actor = headerInfo.Actor;
 549            _relay = headerInfo.Relay;
 550            _name = headerInfo.Name;
 551            _ns = headerInfo.Namespace;
 552            _isRefParam = headerInfo.IsReferenceParameter;
 553            _mustUnderstand = headerInfo.MustUnderstand;
 554        }
 555
 556        public BufferedHeader(MessageVersion version, XmlBuffer buffer, XmlDictionaryReader reader, XmlAttributeHolder[]
 557        {
 558            _streamed = true;
 559            _buffer = buffer;
 560            _version = version;
 561            GetHeaderAttributes(reader, version, out _actor, out _mustUnderstand, out _relay, out _isRefParam);
 562            _name = reader.LocalName;
 563            _ns = reader.NamespaceURI;
 564            Fx.Assert(_name != null, "");
 565            Fx.Assert(_ns != null, "");
 566            _bufferIndex = buffer.SectionCount;
 567            XmlDictionaryWriter writer = buffer.OpenSection(reader.Quotas);
 568
 569            // Write an enclosing Envelope tag
 570            writer.WriteStartElement(MessageStrings.Envelope);
 571            if (envelopeAttributes != null)
 572            {
 573                XmlAttributeHolder.WriteAttributes(envelopeAttributes, writer);
 574            }
 575
 576            // Write and enclosing Header tag
 577            writer.WriteStartElement(MessageStrings.Header);
 578            if (headerAttributes != null)
 579            {
 580                XmlAttributeHolder.WriteAttributes(headerAttributes, writer);
 581            }
 582
 583            writer.WriteNode(reader, false);
 584
 585            writer.WriteEndElement();
 586            writer.WriteEndElement();
 587
 588            buffer.CloseSection();
 589        }
 590
 591        public override string Actor
 592        {
 593            get { return _actor; }
 594        }
 595
 596        public override bool IsReferenceParameter
 597        {
 598            get { return _isRefParam; }
 599        }
 600
 601        public override string Name
 602        {
 603            get { return _name; }
 604        }
 605
 606        public override string Namespace
 607        {
 608            get { return _ns; }
 609        }
 610
 611        public override bool MustUnderstand
 612        {
 613            get { return _mustUnderstand; }
 614        }
 615
 616        public override bool Relay
 617        {
 618            get { return _relay; }
 619        }
 620
 621        public override bool IsMessageVersionSupported(MessageVersion messageVersion)
 622        {
 623            if (messageVersion == null)
 624            {
 625                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(messageVersion));
 626            }
 627
 628            return messageVersion == _version;
 629        }
 630
 631        public override XmlDictionaryReader GetHeaderReader()
 632        {
 633            XmlDictionaryReader reader = _buffer.GetReader(_bufferIndex);
 634            // See if we need to move past the enclosing envelope/header
 635            if (_streamed)
 636            {
 637                reader.MoveToContent();
 638                reader.Read(); // Envelope
 639                reader.Read(); // Header
 640                reader.MoveToContent();
 641            }
 642            return reader;
 643        }
 644    }
 645}