< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.BufferedMessage
Assembly: CoreWCF.WebHttp
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.WebHttp/src/CoreWCF/Channels/Message.cs
Line coverage
24%
Covered lines: 38
Uncovered lines: 117
Coverable lines: 155
Total lines: 625
Line coverage: 24.5%
Branch coverage
10%
Covered branches: 7
Total branches: 68
Branch coverage: 10.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
.ctor(...)21.42%141434.37%
OnGetReaderAtBodyContents()100%11100%
GetReaderAtHeader()0%660%
GetBufferedReaderAtBody()0%880%
GetMessageReader()100%110%
OnBodyToString(...)0%660%
OnClose()11.11%181840%
OnWriteStartEnvelope(...)100%110%
OnWriteStartHeaders(...)0%220%
OnWriteStartBody(...)100%110%
OnCreateBufferedCopy(...)0%880%
OnGetBodyAttribute(...)0%220%

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)
 6156            : this(messageData, recycledMessageState, null, false)
 157        {
 6158        }
 159
 6160        public BufferedMessage(IBufferedMessageData messageData, RecycledMessageState recycledMessageState, bool[] under
 161        {
 162            //bool throwing = true;
 163            //try
 164            //{
 6165            _recycledMessageState = recycledMessageState;
 6166            MessageData = messageData;
 6167            _properties = recycledMessageState.TakeProperties();
 6168            if (_properties == null)
 169            {
 6170                _properties = new MessageProperties();
 171            }
 172
 6173            XmlDictionaryReader reader = messageData.GetMessageReader();
 6174            MessageVersion desiredVersion = messageData.MessageEncoder.MessageVersion;
 175
 6176            if (desiredVersion.Envelope == EnvelopeVersion.None)
 177            {
 6178                _reader = reader;
 6179                _headers = new MessageHeaders(desiredVersion);
 180            }
 181            else
 182            {
 0183                EnvelopeVersion envelopeVersion = ReadStartEnvelope(reader);
 0184                if (desiredVersion.Envelope != envelopeVersion)
 185                {
 0186                    Exception versionMismatchException = new ArgumentException(SR.Format(SR.EncoderEnvelopeVersionMismat
 0187                    throw TraceUtility.ThrowHelperError(
 0188                        new CommunicationException(versionMismatchException.Message, versionMismatchException),
 0189                        this);
 190                }
 191
 0192                if (HasHeaderElement(reader, envelopeVersion))
 193                {
 0194                    _headers = recycledMessageState.TakeHeaders();
 0195                    if (_headers == null)
 196                    {
 0197                        _headers = new MessageHeaders(desiredVersion, reader, messageData, recycledMessageState, underst
 198                    }
 199                    else
 200                    {
 0201                        _headers.Init(desiredVersion, reader, messageData, recycledMessageState, understoodHeaders, unde
 202                    }
 203                }
 204                else
 205                {
 0206                    _headers = new MessageHeaders(desiredVersion);
 207                }
 208
 0209                VerifyStartBody(reader, envelopeVersion);
 210
 0211                int maxSizeOfAttributes = int.MaxValue;
 0212                _bodyAttributes = XmlAttributeHolder.ReadAttributes(reader, ref maxSizeOfAttributes);
 0213                if (maxSizeOfAttributes < int.MaxValue - 4096)
 214                {
 0215                    _bodyAttributes = null;
 216                }
 217
 0218                if (ReadStartBody(reader))
 219                {
 0220                    _reader = reader;
 221                }
 222                else
 223                {
 0224                    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            //}
 0236        }
 237
 238        public override MessageHeaders Headers
 239        {
 240            get
 241            {
 40242                if (IsDisposed)
 243                {
 0244                    throw TraceUtility.ThrowHelperError(this.CreateMessageDisposedException(), this);
 245                }
 246
 40247                return _headers;
 248            }
 249        }
 250
 18251        internal IBufferedMessageData MessageData { get; private set; }
 252
 253        public override MessageProperties Properties
 254        {
 255            get
 256            {
 106257                if (IsDisposed)
 258                {
 0259                    throw TraceUtility.ThrowHelperError(this.CreateMessageDisposedException(), this);
 260                }
 261
 106262                return _properties;
 263            }
 264        }
 265
 266        public override RecycledMessageState RecycledMessageState
 267        {
 0268            get { return _recycledMessageState; }
 269        }
 270
 271        public override MessageVersion Version
 272        {
 273            get
 274            {
 30275                return _headers.MessageVersion;
 276            }
 277        }
 278
 279        protected override XmlDictionaryReader OnGetReaderAtBodyContents()
 280        {
 4281            XmlDictionaryReader reader = _reader;
 4282            _reader = null;
 4283            return reader;
 284        }
 285
 286        public override XmlDictionaryReader GetReaderAtHeader()
 287        {
 0288            if (!_headers.ContainsOnlyBufferedMessageHeaders)
 289            {
 0290                return base.GetReaderAtHeader();
 291            }
 292
 0293            XmlDictionaryReader reader = MessageData.GetMessageReader();
 0294            if (reader.NodeType != XmlNodeType.Element)
 295            {
 0296                reader.MoveToContent();
 297            }
 298
 0299            reader.Read();
 0300            if (HasHeaderElement(reader, _headers.MessageVersion.Envelope))
 301            {
 0302                return reader;
 303            }
 304
 0305            return base.GetReaderAtHeader();
 306        }
 307
 308        public XmlDictionaryReader GetBufferedReaderAtBody()
 309        {
 0310            XmlDictionaryReader reader = MessageData.GetMessageReader();
 0311            if (reader.NodeType != XmlNodeType.Element)
 312            {
 0313                reader.MoveToContent();
 314            }
 315
 0316            if (Version.Envelope != EnvelopeVersion.None)
 317            {
 0318                reader.Read();
 0319                if (HasHeaderElement(reader, _headers.MessageVersion.Envelope))
 320                {
 0321                    reader.Skip();
 322                }
 323
 0324                if (reader.NodeType != XmlNodeType.Element)
 325                {
 0326                    reader.MoveToContent();
 327                }
 328            }
 0329            return reader;
 330        }
 331
 332        public XmlDictionaryReader GetMessageReader()
 333        {
 0334            return MessageData.GetMessageReader();
 335        }
 336
 337        protected override void OnBodyToString(XmlDictionaryWriter writer)
 338        {
 0339            using (XmlDictionaryReader reader = GetBufferedReaderAtBody())
 340            {
 0341                if (Version == MessageVersion.None)
 342                {
 0343                    writer.WriteNode(reader, false);
 344                }
 345                else
 346                {
 0347                    if (!reader.IsEmptyElement)
 348                    {
 0349                        reader.ReadStartElement();
 0350                        while (reader.NodeType != XmlNodeType.EndElement)
 351                        {
 0352                            writer.WriteNode(reader, false);
 353                        }
 354                    }
 355                }
 0356            }
 0357        }
 358        protected override void OnClose()
 359        {
 4360            Exception ex = null;
 361            try
 362            {
 4363                base.OnClose();
 4364            }
 365            catch (Exception e)
 366            {
 0367                if (Fx.IsFatal(e))
 368                {
 0369                    throw;
 370                }
 371
 0372                ex = e;
 0373            }
 374
 375            try
 376            {
 4377                _properties.Dispose();
 4378            }
 0379            catch (Exception e)
 380            {
 0381                if (Fx.IsFatal(e))
 382                {
 0383                    throw;
 384                }
 385
 0386                if (ex == null)
 387                {
 0388                    ex = e;
 389                }
 0390            }
 391
 392            try
 393            {
 4394                if (_reader != null)
 395                {
 0396                    _reader.Dispose();
 397                }
 4398            }
 0399            catch (Exception e)
 400            {
 0401                if (Fx.IsFatal(e))
 402                {
 0403                    throw;
 404                }
 405
 0406                if (ex == null)
 407                {
 0408                    ex = e;
 409                }
 0410            }
 411
 412            try
 413            {
 4414                _recycledMessageState.ReturnHeaders(_headers);
 4415                _recycledMessageState.ReturnProperties(_properties);
 4416                MessageData.ReturnMessageState(_recycledMessageState);
 4417                _recycledMessageState = null;
 4418                MessageData.Close();
 4419                MessageData = null;
 4420            }
 0421            catch (Exception e)
 422            {
 0423                if (Fx.IsFatal(e))
 424                {
 0425                    throw;
 426                }
 427
 0428                if (ex == null)
 429                {
 0430                    ex = e;
 431                }
 0432            }
 433
 4434            if (ex != null)
 435            {
 0436                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ex);
 437            }
 4438        }
 439
 440        protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
 441        {
 0442            using (XmlDictionaryReader reader = GetMessageReader())
 443            {
 0444                reader.MoveToContent();
 0445                EnvelopeVersion envelopeVersion = Version.Envelope;
 0446                writer.WriteStartElement(reader.Prefix, MessageStrings.Envelope, envelopeVersion.Namespace);
 0447                writer.WriteAttributes(reader, false);
 0448            }
 0449        }
 450
 451        protected override void OnWriteStartHeaders(XmlDictionaryWriter writer)
 452        {
 0453            using (XmlDictionaryReader reader = GetMessageReader())
 454            {
 0455                reader.MoveToContent();
 0456                EnvelopeVersion envelopeVersion = Version.Envelope;
 0457                reader.Read();
 0458                if (HasHeaderElement(reader, envelopeVersion))
 459                {
 0460                    writer.WriteStartElement(reader.Prefix, MessageStrings.Header, envelopeVersion.Namespace);
 0461                    writer.WriteAttributes(reader, false);
 462                }
 463                else
 464                {
 0465                    writer.WriteStartElement(MessageStrings.Prefix, MessageStrings.Header, envelopeVersion.Namespace);
 466                }
 0467            }
 0468        }
 469
 470        protected override void OnWriteStartBody(XmlDictionaryWriter writer)
 471        {
 0472            using (XmlDictionaryReader reader = GetBufferedReaderAtBody())
 473            {
 0474                writer.WriteStartElement(reader.Prefix, MessageStrings.Body, Version.Envelope.Namespace);
 0475                writer.WriteAttributes(reader, false);
 0476            }
 0477        }
 478
 479        protected override MessageBuffer OnCreateBufferedCopy(int maxBufferSize)
 480        {
 0481            if (_headers.ContainsOnlyBufferedMessageHeaders)
 482            {
 0483                KeyValuePair<string, object>[] properties = new KeyValuePair<string, object>[Properties.Count];
 0484                ((ICollection<KeyValuePair<string, object>>)Properties).CopyTo(properties, 0);
 0485                MessageData.EnableMultipleUsers();
 0486                bool[] understoodHeaders = null;
 0487                if (_headers.UnderstoodHeaders.Modified)
 488                {
 0489                    understoodHeaders = new bool[_headers.Count];
 0490                    for (int i = 0; i < _headers.Count; i++)
 491                    {
 0492                        understoodHeaders[i] = _headers.IsUnderstood(i);
 493                    }
 494                }
 0495                return new BufferedMessageBuffer(MessageData, properties, understoodHeaders, _headers.UnderstoodHeaders.
 496            }
 497            else
 498            {
 0499                if (_reader != null)
 500                {
 0501                    return OnCreateBufferedCopy(maxBufferSize, _reader.Quotas);
 502                }
 503
 0504                return OnCreateBufferedCopy(maxBufferSize, XmlDictionaryReaderQuotas.Max);
 505            }
 506        }
 507
 508        protected override string OnGetBodyAttribute(string localName, string ns)
 509        {
 0510            if (_bodyAttributes != null)
 511            {
 0512                return XmlAttributeHolder.GetAttribute(_bodyAttributes, localName, ns);
 513            }
 514
 0515            using (XmlDictionaryReader reader = GetBufferedReaderAtBody())
 516            {
 0517                return reader.GetAttribute(localName, ns);
 518            }
 0519        }
 520    }
 521
 522    internal struct XmlAttributeHolder
 523    {
 524        public static XmlAttributeHolder[] emptyArray = Array.Empty<XmlAttributeHolder>();
 525
 526        public XmlAttributeHolder(string prefix, string localName, string ns, string value)
 527        {
 528            Prefix = prefix;
 529            LocalName = localName;
 530            NamespaceUri = ns;
 531            Value = value;
 532        }
 533
 534        public string Prefix { get; }
 535
 536        public string NamespaceUri { get; }
 537
 538        public string LocalName { get; }
 539
 540        public string Value { get; }
 541
 542        public void WriteTo(XmlWriter writer)
 543        {
 544            writer.WriteStartAttribute(Prefix, LocalName, NamespaceUri);
 545            writer.WriteString(Value);
 546            writer.WriteEndAttribute();
 547        }
 548
 549        public static void WriteAttributes(XmlAttributeHolder[] attributes, XmlWriter writer)
 550        {
 551            for (int i = 0; i < attributes.Length; i++)
 552            {
 553                attributes[i].WriteTo(writer);
 554            }
 555        }
 556
 557        public static XmlAttributeHolder[] ReadAttributes(XmlDictionaryReader reader)
 558        {
 559            int maxSizeOfHeaders = int.MaxValue;
 560            return ReadAttributes(reader, ref maxSizeOfHeaders);
 561        }
 562
 563        public static XmlAttributeHolder[] ReadAttributes(XmlDictionaryReader reader, ref int maxSizeOfHeaders)
 564        {
 565            if (reader.AttributeCount == 0)
 566            {
 567                return emptyArray;
 568            }
 569
 570            XmlAttributeHolder[] attributes = new XmlAttributeHolder[reader.AttributeCount];
 571            reader.MoveToFirstAttribute();
 572            for (int i = 0; i < attributes.Length; i++)
 573            {
 574                string ns = reader.NamespaceURI;
 575                string localName = reader.LocalName;
 576                string prefix = reader.Prefix;
 577                string value = string.Empty;
 578                while (reader.ReadAttributeValue())
 579                {
 580                    if (value.Length == 0)
 581                    {
 582                        value = reader.Value;
 583                    }
 584                    else
 585                    {
 586                        value += reader.Value;
 587                    }
 588                }
 589                Deduct(prefix, ref maxSizeOfHeaders);
 590                Deduct(localName, ref maxSizeOfHeaders);
 591                Deduct(ns, ref maxSizeOfHeaders);
 592                Deduct(value, ref maxSizeOfHeaders);
 593                attributes[i] = new XmlAttributeHolder(prefix, localName, ns, value);
 594                reader.MoveToNextAttribute();
 595            }
 596            reader.MoveToElement();
 597            return attributes;
 598        }
 599
 600        private static void Deduct(string s, ref int maxSizeOfHeaders)
 601        {
 602            int byteCount = s.Length * sizeof(char);
 603            if (byteCount > maxSizeOfHeaders)
 604            {
 605                string message = SRCommon.XmlBufferQuotaExceeded;
 606                Exception inner = new QuotaExceededException(message);
 607                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(message, inner));
 608            }
 609            maxSizeOfHeaders -= byteCount;
 610        }
 611
 612        public static string GetAttribute(XmlAttributeHolder[] attributes, string localName, string ns)
 613        {
 614            for (int i = 0; i < attributes.Length; i++)
 615            {
 616                if (attributes[i].LocalName == localName && attributes[i].NamespaceUri == ns)
 617                {
 618                    return attributes[i].Value;
 619                }
 620            }
 621
 622            return null;
 623        }
 624    }
 625}