< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Channels.AspNetCoreReplyChannel
Assembly: CoreWCF.Http
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Http/src/CoreWCF/Channels/AspNetCoreReplyChannel.cs
Line coverage
72%
Covered lines: 42
Uncovered lines: 16
Coverable lines: 58
Total lines: 175
Line coverage: 72.4%
Branch coverage
83%
Covered branches: 15
Total branches: 18
Branch coverage: 83.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
Abort()100%110%
CloseAsync()100%110%
CloseAsync(...)100%110%
GetProperty()100%11100%
OpenAsync()100%11100%
OpenAsync(...)100%110%
ReceiveRequestAsync()100%110%
ReceiveRequestAsync(...)100%110%
TryReceiveRequestAsync(...)100%110%
WaitForRequestAsync(...)100%110%
HandleRequest()80%101090.47%
HandleProcessInboundException()87.5%8893.33%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Http/src/CoreWCF/Channels/AspNetCoreReplyChannel.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.Net;
 6using System.Threading;
 7using System.Threading.Tasks;
 8using CoreWCF.Configuration;
 9using CoreWCF.Runtime;
 10using Microsoft.AspNetCore.Http;
 11using Microsoft.Extensions.DependencyInjection;
 12
 13namespace CoreWCF.Channels
 14{
 15    internal class AspNetCoreReplyChannel : IReplyChannel
 16    {
 17        private readonly IServiceProvider _serviceProvider;
 18        private readonly HttpTransportSettings _httpSettings;
 19
 42220        public AspNetCoreReplyChannel(IServiceProvider serviceProvider, HttpTransportSettings httpSettings)
 21        {
 42222            _serviceProvider = serviceProvider;
 42223            _httpSettings = httpSettings;
 42224        }
 25
 26        // TODO: Verify what happens on .NET Framework. Looking at code it looks like it doesn't set this value
 027        public EndpointAddress LocalAddress => null;
 28
 29        // TODO: Might want to do something a bit smarter with the state and actually have a concept of opening and clos
 30        // connected and fire them when the service is shutting down.
 70031        public CommunicationState State { get; private set; } = CommunicationState.Created;
 32
 165233        public IServiceChannelDispatcher ChannelDispatcher { get; set; }
 34
 35#pragma warning disable CS0067 // The event is never used - see issue #290
 36        public event EventHandler Closed;
 37        public event EventHandler Closing;
 38        public event EventHandler Faulted;
 39        public event EventHandler Opened;
 40        public event EventHandler Opening;
 41#pragma warning restore CS0067 // The event is never used
 42
 43        public void Abort()
 44        {
 45            // Can skip Closing state as there's nothing to do during the Abort call
 046            State = CommunicationState.Closed;
 047        }
 48
 49        public Task CloseAsync()
 50        {
 51            // Can skip Closing state as there's nothing to do during the Close call
 052            State = CommunicationState.Closed;
 053            return Task.CompletedTask;
 54        }
 55
 56        public Task CloseAsync(CancellationToken token)
 57        {
 58            // Can skip Closing state as there's nothing to do during the Close call
 059            State = CommunicationState.Closed;
 060            return Task.CompletedTask;
 61        }
 62
 63        public T GetProperty<T>() where T : class
 64        {
 136365            return _serviceProvider.GetService<T>();
 66        }
 67
 68        public Task OpenAsync()
 69        {
 70            // Can skip Opening state as there's nothing to do during the Open call
 39271            State = CommunicationState.Opened;
 39272            return Task.CompletedTask;
 73        }
 74
 75        public Task OpenAsync(CancellationToken token)
 76        {
 77            // Can skip Opening state as there's nothing to do during the Open call
 078            State = CommunicationState.Opened;
 079            return Task.CompletedTask;
 80        }
 81
 82        public Task<RequestContext> ReceiveRequestAsync()
 83        {
 084            throw new NotImplementedException();
 85        }
 86
 87        public Task<RequestContext> ReceiveRequestAsync(CancellationToken token)
 88        {
 089            throw new NotImplementedException();
 90        }
 91
 92        public Task<(RequestContext requestContext, bool success)> TryReceiveRequestAsync(CancellationToken token)
 93        {
 094            throw new NotImplementedException();
 95        }
 96
 97        public Task<bool> WaitForRequestAsync(CancellationToken token)
 98        {
 099            throw new NotImplementedException();
 100        }
 101
 102        internal async Task HandleRequest(HttpContext context)
 103        {
 650104            if (ChannelDispatcher == null)
 105            {
 106                // TODO: Look for existing SR which would work here. Cleanup how the exception is thrown.
 0107                throw new InvalidOperationException("Channel Dispatcher can't be null");
 108            }
 109
 650110            using (var requestContext = HttpRequestContext.CreateContext(_httpSettings, context))
 111            {
 650112                bool authenticationResult = await requestContext.ProcessAuthenticationAsync();
 650113                if (!authenticationResult)
 114                {
 0115                    return;
 116                }
 117
 118                try
 119                {
 650120                    HttpInput httpInput = requestContext.GetHttpInput(true);
 650121                    (Message requestMessage, Exception requestException) = await httpInput.ParseIncomingMessageAsync();
 649122                    if ((requestMessage == null) && (requestException == null))
 123                    {
 1124                        await requestContext.SendResponseAndCloseAsync(System.Net.HttpStatusCode.BadRequest);
 1125                        return;
 126                    }
 127
 648128                    if (requestMessage != null)
 129                    {
 648130                        requestMessage.Properties.Add("Microsoft.AspNetCore.Http.HttpContext", context);
 131                    }
 132
 648133                    requestContext.SetMessage(requestMessage, requestException);
 134
 648135                    await ChannelDispatcher.DispatchAsync(requestContext);
 618136                    await requestContext.ReplySent;
 616137                }
 31138                catch (Exception ex)
 139                {
 31140                    await HandleProcessInboundException(ex, requestContext);
 141                }
 647142            }
 648143        }
 144
 145        private static async Task HandleProcessInboundException(Exception ex, HttpRequestContext requestContext)
 146        {
 31147            if (Fx.IsFatal(ex))
 148            {
 0149                return;
 150            }
 151
 31152            if (ex is ProtocolException)
 153            {
 1154                ProtocolException protocolException = (ProtocolException)ex;
 1155                HttpStatusCode statusCode = HttpStatusCode.BadRequest;
 1156                string statusDescription = string.Empty;
 1157                if (protocolException.Data.Contains(HttpChannelUtilities.HttpStatusCodeExceptionKey))
 158                {
 1159                    statusCode = (HttpStatusCode)protocolException.Data[HttpChannelUtilities.HttpStatusCodeExceptionKey]
 1160                    protocolException.Data.Remove(HttpChannelUtilities.HttpStatusCodeExceptionKey);
 161                }
 1162                if (protocolException.Data.Contains(HttpChannelUtilities.HttpStatusDescriptionExceptionKey))
 163                {
 1164                    statusDescription = (string)protocolException.Data[HttpChannelUtilities.HttpStatusDescriptionExcepti
 1165                    protocolException.Data.Remove(HttpChannelUtilities.HttpStatusDescriptionExceptionKey);
 166                }
 1167                await requestContext.SendResponseAndCloseAsync(statusCode, statusDescription);
 168            }
 169            else
 170            {
 30171                await requestContext.SendResponseAndCloseAsync(HttpStatusCode.BadRequest);
 172            }
 31173        }
 174    }
 175}