< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.XmlAttributeHolder
Assembly: CoreWCF.WebHttp
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.WebHttp/src/CoreWCF/Channels/Message.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 51
Coverable lines: 51
Total lines: 625
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 18
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%110%
.ctor(...)100%110%
WriteTo(...)100%110%
WriteAttributes(...)0%220%
ReadAttributes(...)100%110%
ReadAttributes(...)0%880%
Deduct(...)0%220%
GetAttribute(...)0%660%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.WebHttp/src/CoreWCF/Channels/Message.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.Collections.Generic;
 6using System.Xml;
 7using CoreWCF.Runtime;
 8
 9namespace CoreWCF.Channels
 10{
 11    internal abstract class ReceivedMessage : Message
 12    {
 13        private bool _isFault;
 14        private bool _isEmpty;
 15
 16        public override bool IsEmpty
 17        {
 18            get { return _isEmpty; }
 19        }
 20
 21        public override bool IsFault
 22        {
 23            get { return _isFault; }
 24        }
 25
 26        protected static bool HasHeaderElement(XmlDictionaryReader reader, EnvelopeVersion envelopeVersion)
 27        {
 28            return reader.IsStartElement(XD.MessageDictionary.Header, envelopeVersion.DictionaryNamespace);
 29        }
 30
 31        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
 32        {
 33            if (!_isEmpty)
 34            {
 35                using (XmlDictionaryReader bodyReader = OnGetReaderAtBodyContents())
 36                {
 37                    if (bodyReader.ReadState == ReadState.Error || bodyReader.ReadState == ReadState.Closed)
 38                    {
 39                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Forma
 40                    }
 41
 42                    while (bodyReader.NodeType != XmlNodeType.EndElement && !bodyReader.EOF)
 43                    {
 44                        writer.WriteNode(bodyReader, false);
 45                    }
 46
 47                    ReadFromBodyContentsToEnd(bodyReader, Version.Envelope);
 48                }
 49            }
 50        }
 51
 52        protected bool ReadStartBody(XmlDictionaryReader reader)
 53        {
 54            return ReadStartBody(reader, Version.Envelope, out _isFault, out _isEmpty);
 55        }
 56
 57        protected static EnvelopeVersion ReadStartEnvelope(XmlDictionaryReader reader)
 58        {
 59            EnvelopeVersion envelopeVersion;
 60
 61            if (reader.IsStartElement(XD.MessageDictionary.Envelope, XD.Message12Dictionary.Namespace))
 62            {
 63                envelopeVersion = EnvelopeVersion.Soap12;
 64            }
 65            else if (reader.IsStartElement(XD.MessageDictionary.Envelope, XD.Message11Dictionary.Namespace))
 66            {
 67                envelopeVersion = EnvelopeVersion.Soap11;
 68            }
 69            else
 70            {
 71                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.MessageVersionUn
 72            }
 73
 74            if (reader.IsEmptyElement)
 75            {
 76                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.MessageBodyMissi
 77            }
 78
 79            reader.Read();
 80            return envelopeVersion;
 81        }
 82
 83        protected static void VerifyStartBody(XmlDictionaryReader reader, EnvelopeVersion version)
 84        {
 85            if (!reader.IsStartElement(XD.MessageDictionary.Body, version.DictionaryNamespace))
 86            {
 87                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.MessageBodyMissi
 88            }
 89        }
 90
 91        private static void ReadFromBodyContentsToEnd(XmlDictionaryReader reader, EnvelopeVersion envelopeVersion)
 92        {
 93            if (envelopeVersion != EnvelopeVersion.None)
 94            {
 95                reader.ReadEndElement(); // </Body>
 96                reader.ReadEndElement(); // </Envelope>
 97            }
 98            reader.MoveToContent();
 99        }
 100
 101        internal static bool ReadStartBody(XmlDictionaryReader reader, EnvelopeVersion envelopeVersion, out bool isFault
 102        {
 103            if (reader.IsEmptyElement)
 104            {
 105                reader.Read();
 106                isEmpty = true;
 107                isFault = false;
 108                reader.ReadEndElement();
 109                return false;
 110            }
 111            else
 112            {
 113                reader.Read();
 114                if (reader.NodeType != XmlNodeType.Element)
 115                {
 116                    reader.MoveToContent();
 117                }
 118
 119                if (reader.NodeType == XmlNodeType.Element)
 120                {
 121                    isFault = IsFaultStartElement(reader, envelopeVersion);
 122                    isEmpty = false;
 123                }
 124                else if (reader.NodeType == XmlNodeType.EndElement)
 125                {
 126                    isEmpty = true;
 127                    isFault = false;
 128                    ReadFromBodyContentsToEnd(reader, envelopeVersion);
 129                    return false;
 130                }
 131                else
 132                {
 133                    isEmpty = false;
 134                    isFault = false;
 135                }
 136
 137                return true;
 138            }
 139        }
 140
 141        internal static bool IsFaultStartElement(XmlDictionaryReader reader, EnvelopeVersion version)
 142        {
 143            return reader.IsStartElement(XD.MessageDictionary.Fault, version.DictionaryNamespace);
 144        }
 145    }
 146
 147    internal sealed class BufferedMessage : ReceivedMessage
 148    {
 149        private readonly MessageHeaders _headers;
 150        private readonly MessageProperties _properties;
 151        private RecycledMessageState _recycledMessageState;
 152        private XmlDictionaryReader _reader;
 153        private readonly XmlAttributeHolder[] _bodyAttributes;
 154
 155        public BufferedMessage(IBufferedMessageData messageData, RecycledMessageState recycledMessageState)
 156            : this(messageData, recycledMessageState, null, false)
 157        {
 158        }
 159
 160        public BufferedMessage(IBufferedMessageData messageData, RecycledMessageState recycledMessageState, bool[] under
 161        {
 162            //bool throwing = true;
 163            //try
 164            //{
 165            _recycledMessageState = recycledMessageState;
 166            MessageData = messageData;
 167            _properties = recycledMessageState.TakeProperties();
 168            if (_properties == null)
 169            {
 170                _properties = new MessageProperties();
 171            }
 172
 173            XmlDictionaryReader reader = messageData.GetMessageReader();
 174            MessageVersion desiredVersion = messageData.MessageEncoder.MessageVersion;
 175
 176            if (desiredVersion.Envelope == EnvelopeVersion.None)
 177            {
 178                _reader = reader;
 179                _headers = new MessageHeaders(desiredVersion);
 180            }
 181            else
 182            {
 183                EnvelopeVersion envelopeVersion = ReadStartEnvelope(reader);
 184                if (desiredVersion.Envelope != envelopeVersion)
 185                {
 186                    Exception versionMismatchException = new ArgumentException(SR.Format(SR.EncoderEnvelopeVersionMismat
 187                    throw TraceUtility.ThrowHelperError(
 188                        new CommunicationException(versionMismatchException.Message, versionMismatchException),
 189                        this);
 190                }
 191
 192                if (HasHeaderElement(reader, envelopeVersion))
 193                {
 194                    _headers = recycledMessageState.TakeHeaders();
 195                    if (_headers == null)
 196                    {
 197                        _headers = new MessageHeaders(desiredVersion, reader, messageData, recycledMessageState, underst
 198                    }
 199                    else
 200                    {
 201                        _headers.Init(desiredVersion, reader, messageData, recycledMessageState, understoodHeaders, unde
 202                    }
 203                }
 204                else
 205                {
 206                    _headers = new MessageHeaders(desiredVersion);
 207                }
 208
 209                VerifyStartBody(reader, envelopeVersion);
 210
 211                int maxSizeOfAttributes = int.MaxValue;
 212                _bodyAttributes = XmlAttributeHolder.ReadAttributes(reader, ref maxSizeOfAttributes);
 213                if (maxSizeOfAttributes < int.MaxValue - 4096)
 214                {
 215                    _bodyAttributes = null;
 216                }
 217
 218                if (ReadStartBody(reader))
 219                {
 220                    _reader = reader;
 221                }
 222                else
 223                {
 224                    reader.Dispose();
 225                }
 226            }
 227            //throwing = false;
 228            //}
 229            //finally
 230            //{
 231            //    if (throwing && MessageLogger.LoggingEnabled)
 232            //    {
 233            //        MessageLogger.LogMessage(messageData.Buffer, MessageLoggingSource.Malformed);
 234            //    }
 235            //}
 236        }
 237
 238        public override MessageHeaders Headers
 239        {
 240            get
 241            {
 242                if (IsDisposed)
 243                {
 244                    throw TraceUtility.ThrowHelperError(this.CreateMessageDisposedException(), this);
 245                }
 246
 247                return _headers;
 248            }
 249        }
 250
 251        internal IBufferedMessageData MessageData { get; private set; }
 252
 253        public override MessageProperties Properties
 254        {
 255            get
 256            {
 257                if (IsDisposed)
 258                {
 259                    throw TraceUtility.ThrowHelperError(this.CreateMessageDisposedException(), this);
 260                }
 261
 262                return _properties;
 263            }
 264        }
 265
 266        public override RecycledMessageState RecycledMessageState
 267        {
 268            get { return _recycledMessageState; }
 269        }
 270
 271        public override MessageVersion Version
 272        {
 273            get
 274            {
 275                return _headers.MessageVersion;
 276            }
 277        }
 278
 279        protected override XmlDictionaryReader OnGetReaderAtBodyContents()
 280        {
 281            XmlDictionaryReader reader = _reader;
 282            _reader = null;
 283            return reader;
 284        }
 285
 286        public override XmlDictionaryReader GetReaderAtHeader()
 287        {
 288            if (!_headers.ContainsOnlyBufferedMessageHeaders)
 289            {
 290                return base.GetReaderAtHeader();
 291            }
 292
 293            XmlDictionaryReader reader = MessageData.GetMessageReader();
 294            if (reader.NodeType != XmlNodeType.Element)
 295            {
 296                reader.MoveToContent();
 297            }
 298
 299            reader.Read();
 300            if (HasHeaderElement(reader, _headers.MessageVersion.Envelope))
 301            {
 302                return reader;
 303            }
 304
 305            return base.GetReaderAtHeader();
 306        }
 307
 308        public XmlDictionaryReader GetBufferedReaderAtBody()
 309        {
 310            XmlDictionaryReader reader = MessageData.GetMessageReader();
 311            if (reader.NodeType != XmlNodeType.Element)
 312            {
 313                reader.MoveToContent();
 314            }
 315
 316            if (Version.Envelope != EnvelopeVersion.None)
 317            {
 318                reader.Read();
 319                if (HasHeaderElement(reader, _headers.MessageVersion.Envelope))
 320                {
 321                    reader.Skip();
 322                }
 323
 324                if (reader.NodeType != XmlNodeType.Element)
 325                {
 326                    reader.MoveToContent();
 327                }
 328            }
 329            return reader;
 330        }
 331
 332        public XmlDictionaryReader GetMessageReader()
 333        {
 334            return MessageData.GetMessageReader();
 335        }
 336
 337        protected override void OnBodyToString(XmlDictionaryWriter writer)
 338        {
 339            using (XmlDictionaryReader reader = GetBufferedReaderAtBody())
 340            {
 341                if (Version == MessageVersion.None)
 342                {
 343                    writer.WriteNode(reader, false);
 344                }
 345                else
 346                {
 347                    if (!reader.IsEmptyElement)
 348                    {
 349                        reader.ReadStartElement();
 350                        while (reader.NodeType != XmlNodeType.EndElement)
 351                        {
 352                            writer.WriteNode(reader, false);
 353                        }
 354                    }
 355                }
 356            }
 357        }
 358        protected override void OnClose()
 359        {
 360            Exception ex = null;
 361            try
 362            {
 363                base.OnClose();
 364            }
 365            catch (Exception e)
 366            {
 367                if (Fx.IsFatal(e))
 368                {
 369                    throw;
 370                }
 371
 372                ex = e;
 373            }
 374
 375            try
 376            {
 377                _properties.Dispose();
 378            }
 379            catch (Exception e)
 380            {
 381                if (Fx.IsFatal(e))
 382                {
 383                    throw;
 384                }
 385
 386                if (ex == null)
 387                {
 388                    ex = e;
 389                }
 390            }
 391
 392            try
 393            {
 394                if (_reader != null)
 395                {
 396                    _reader.Dispose();
 397                }
 398            }
 399            catch (Exception e)
 400            {
 401                if (Fx.IsFatal(e))
 402                {
 403                    throw;
 404                }
 405
 406                if (ex == null)
 407                {
 408                    ex = e;
 409                }
 410            }
 411
 412            try
 413            {
 414                _recycledMessageState.ReturnHeaders(_headers);
 415                _recycledMessageState.ReturnProperties(_properties);
 416                MessageData.ReturnMessageState(_recycledMessageState);
 417                _recycledMessageState = null;
 418                MessageData.Close();
 419                MessageData = null;
 420            }
 421            catch (Exception e)
 422            {
 423                if (Fx.IsFatal(e))
 424                {
 425                    throw;
 426                }
 427
 428                if (ex == null)
 429                {
 430                    ex = e;
 431                }
 432            }
 433
 434            if (ex != null)
 435            {
 436                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ex);
 437            }
 438        }
 439
 440        protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
 441        {
 442            using (XmlDictionaryReader reader = GetMessageReader())
 443            {
 444                reader.MoveToContent();
 445                EnvelopeVersion envelopeVersion = Version.Envelope;
 446                writer.WriteStartElement(reader.Prefix, MessageStrings.Envelope, envelopeVersion.Namespace);
 447                writer.WriteAttributes(reader, false);
 448            }
 449        }
 450
 451        protected override void OnWriteStartHeaders(XmlDictionaryWriter writer)
 452        {
 453            using (XmlDictionaryReader reader = GetMessageReader())
 454            {
 455                reader.MoveToContent();
 456                EnvelopeVersion envelopeVersion = Version.Envelope;
 457                reader.Read();
 458                if (HasHeaderElement(reader, envelopeVersion))
 459                {
 460                    writer.WriteStartElement(reader.Prefix, MessageStrings.Header, envelopeVersion.Namespace);
 461                    writer.WriteAttributes(reader, false);
 462                }
 463                else
 464                {
 465                    writer.WriteStartElement(MessageStrings.Prefix, MessageStrings.Header, envelopeVersion.Namespace);
 466                }
 467            }
 468        }
 469
 470        protected override void OnWriteStartBody(XmlDictionaryWriter writer)
 471        {
 472            using (XmlDictionaryReader reader = GetBufferedReaderAtBody())
 473            {
 474                writer.WriteStartElement(reader.Prefix, MessageStrings.Body, Version.Envelope.Namespace);
 475                writer.WriteAttributes(reader, false);
 476            }
 477        }
 478
 479        protected override MessageBuffer OnCreateBufferedCopy(int maxBufferSize)
 480        {
 481            if (_headers.ContainsOnlyBufferedMessageHeaders)
 482            {
 483                KeyValuePair<string, object>[] properties = new KeyValuePair<string, object>[Properties.Count];
 484                ((ICollection<KeyValuePair<string, object>>)Properties).CopyTo(properties, 0);
 485                MessageData.EnableMultipleUsers();
 486                bool[] understoodHeaders = null;
 487                if (_headers.UnderstoodHeaders.Modified)
 488                {
 489                    understoodHeaders = new bool[_headers.Count];
 490                    for (int i = 0; i < _headers.Count; i++)
 491                    {
 492                        understoodHeaders[i] = _headers.IsUnderstood(i);
 493                    }
 494                }
 495                return new BufferedMessageBuffer(MessageData, properties, understoodHeaders, _headers.UnderstoodHeaders.
 496            }
 497            else
 498            {
 499                if (_reader != null)
 500                {
 501                    return OnCreateBufferedCopy(maxBufferSize, _reader.Quotas);
 502                }
 503
 504                return OnCreateBufferedCopy(maxBufferSize, XmlDictionaryReaderQuotas.Max);
 505            }
 506        }
 507
 508        protected override string OnGetBodyAttribute(string localName, string ns)
 509        {
 510            if (_bodyAttributes != null)
 511            {
 512                return XmlAttributeHolder.GetAttribute(_bodyAttributes, localName, ns);
 513            }
 514
 515            using (XmlDictionaryReader reader = GetBufferedReaderAtBody())
 516            {
 517                return reader.GetAttribute(localName, ns);
 518            }
 519        }
 520    }
 521
 522    internal struct XmlAttributeHolder
 523    {
 0524        public static XmlAttributeHolder[] emptyArray = Array.Empty<XmlAttributeHolder>();
 525
 526        public XmlAttributeHolder(string prefix, string localName, string ns, string value)
 527        {
 0528            Prefix = prefix;
 0529            LocalName = localName;
 0530            NamespaceUri = ns;
 0531            Value = value;
 0532        }
 533
 0534        public string Prefix { get; }
 535
 0536        public string NamespaceUri { get; }
 537
 0538        public string LocalName { get; }
 539
 0540        public string Value { get; }
 541
 542        public void WriteTo(XmlWriter writer)
 543        {
 0544            writer.WriteStartAttribute(Prefix, LocalName, NamespaceUri);
 0545            writer.WriteString(Value);
 0546            writer.WriteEndAttribute();
 0547        }
 548
 549        public static void WriteAttributes(XmlAttributeHolder[] attributes, XmlWriter writer)
 550        {
 0551            for (int i = 0; i < attributes.Length; i++)
 552            {
 0553                attributes[i].WriteTo(writer);
 554            }
 0555        }
 556
 557        public static XmlAttributeHolder[] ReadAttributes(XmlDictionaryReader reader)
 558        {
 0559            int maxSizeOfHeaders = int.MaxValue;
 0560            return ReadAttributes(reader, ref maxSizeOfHeaders);
 561        }
 562
 563        public static XmlAttributeHolder[] ReadAttributes(XmlDictionaryReader reader, ref int maxSizeOfHeaders)
 564        {
 0565            if (reader.AttributeCount == 0)
 566            {
 0567                return emptyArray;
 568            }
 569
 0570            XmlAttributeHolder[] attributes = new XmlAttributeHolder[reader.AttributeCount];
 0571            reader.MoveToFirstAttribute();
 0572            for (int i = 0; i < attributes.Length; i++)
 573            {
 0574                string ns = reader.NamespaceURI;
 0575                string localName = reader.LocalName;
 0576                string prefix = reader.Prefix;
 0577                string value = string.Empty;
 0578                while (reader.ReadAttributeValue())
 579                {
 0580                    if (value.Length == 0)
 581                    {
 0582                        value = reader.Value;
 583                    }
 584                    else
 585                    {
 0586                        value += reader.Value;
 587                    }
 588                }
 0589                Deduct(prefix, ref maxSizeOfHeaders);
 0590                Deduct(localName, ref maxSizeOfHeaders);
 0591                Deduct(ns, ref maxSizeOfHeaders);
 0592                Deduct(value, ref maxSizeOfHeaders);
 0593                attributes[i] = new XmlAttributeHolder(prefix, localName, ns, value);
 0594                reader.MoveToNextAttribute();
 595            }
 0596            reader.MoveToElement();
 0597            return attributes;
 598        }
 599
 600        private static void Deduct(string s, ref int maxSizeOfHeaders)
 601        {
 0602            int byteCount = s.Length * sizeof(char);
 0603            if (byteCount > maxSizeOfHeaders)
 604            {
 0605                string message = SRCommon.XmlBufferQuotaExceeded;
 0606                Exception inner = new QuotaExceededException(message);
 0607                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(message, inner));
 608            }
 0609            maxSizeOfHeaders -= byteCount;
 0610        }
 611
 612        public static string GetAttribute(XmlAttributeHolder[] attributes, string localName, string ns)
 613        {
 0614            for (int i = 0; i < attributes.Length; i++)
 615            {
 0616                if (attributes[i].LocalName == localName && attributes[i].NamespaceUri == ns)
 617                {
 0618                    return attributes[i].Value;
 619                }
 620            }
 621
 0622            return null;
 623        }
 624    }
 625}