< Summary

Information
Class: NanoRoute.Internals.RequestPipeline
Assembly: NanoRoute.dll
File(s): /home/runner/work/nanoroute/nanoroute/Src/NanoRoute/Private/RequestPipeline.cs
Line coverage
98%
Covered lines: 52
Uncovered lines: 1
Coverable lines: 53
Total lines: 100
Line coverage: 98.1%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/nanoroute/nanoroute/Src/NanoRoute/Private/RequestPipeline.cs

#LineLine coverage
 1/********************************************************************************
 2* RequestPipeline.cs                                                            *
 3*                                                                               *
 4* Author: Denes Solti                                                           *
 5********************************************************************************/
 6using System;
 7using System.Net;
 8using System.Net.Http;
 9using System.Threading;
 10using System.Threading.Tasks;
 11
 12namespace NanoRoute.Internals
 13{
 14    using Properties;
 15
 216    internal sealed class RequestPipeline(RouteNode root, MatchingPrecedence matchingPrecedence, HttpRequestMessage requ
 17    {
 18        #region Private
 219        private readonly RouteMatchCursor _matches = new
 220        (
 221            root,
 222            ParseVerb(request),
 223            request.RequestUri,
 224            services,
 225            matchingPrecedence,
 226            cancellation
 227        );
 28
 29        private static HttpVerb ParseVerb(HttpRequestMessage request)
 230        {
 231            if (!Enum.TryParse(request.Method.Method, ignoreCase: true, out HttpVerb verb))
 132                throw new ArgumentException
 133                (
 134                    string.Format(Resources.Culture, Resources.ERR_INVALID_VERB, request.Method.Method), nameof(request)
 135                );
 36
 237            return verb;
 238        }
 39
 40        private Task<HttpResponseMessage> CallNextHandler()
 241        {
 242            ValueTask<bool> matched = _matches.MoveNextAsync();
 43
 244            if (!matched.IsCompletedSuccessfully)
 045                return CallNextHandlerAwaitedAsync(matched);
 46
 247            if (!matched.Result)
 148                ThrowNotFound();
 49
 250            return InvokeCurrentHandler();
 251        }
 52
 53        private async Task<HttpResponseMessage> CallNextHandlerAwaitedAsync(ValueTask<bool> matched)
 54        {
 55            if (!await matched)
 56                ThrowNotFound();
 57
 58            return await InvokeCurrentHandler();
 59        }
 60
 61        private Task<HttpResponseMessage> InvokeCurrentHandler()
 262        {
 263            RouteMatch match = _matches.Current;
 64
 265            RouterEventSource.Info.Write("MatchingHandler", static (request, match) => new
 266            {
 267                RequestUri = request.RequestUri.OriginalString,
 268                Verb = request.Method.Method,
 269                Pattern = match.HandlerRegistration.Pattern,
 270                ParameterCount = match.AttachedParameters.Count
 271            }, request, match);
 72
 273            RequestContext requestContext = new()
 274            {
 275                Parameters = match.AttachedParameters,
 276                Services = services,
 277                Request = request,
 278                Cancellation = cancellation
 279            };
 80
 281            return match.HandlerRegistration.Handler(requestContext, CallNextHandler);
 282        }
 83
 84        private void ThrowNotFound()
 185        {
 186            RouterEventSource.Info.Write("NoMatchingHandler", static request => new
 187            {
 188                RequestUri = request.RequestUri.OriginalString,
 189                Verb = request.Method.Method
 190            }, request);
 91
 192            HttpRequestException.Throw(HttpStatusCode.NotFound, Resources.ERR_NOT_FOUND);
 93        }
 94        #endregion
 95
 296        public ValueTask DisposeAsync() => _matches.DisposeAsync();
 97
 298        public Task<HttpResponseMessage> RunAsync() => CallNextHandler();
 99    }
 100}