< Summary

Information
Class: NanoRoute.Internals.RequestPipeline
Assembly: NanoRoute.dll
File(s): /home/runner/work/nanoroute/nanoroute/Src/NanoRoute/Private/RequestPipeline.cs
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 77
Line coverage: 100%
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

MethodBlocks covered Blocks not covered
RequestPipeline(...)20

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.Collections.Generic;
 8using System.Net;
 9using System.Net.Http;
 10using System.Threading;
 11using System.Threading.Tasks;
 12
 13namespace NanoRoute.Internals
 14{
 15    using Properties;
 16
 217    internal sealed class RequestPipeline(RouteNode root, RouterConfig routerConfig)
 18    {
 19        public async Task<HttpResponseMessage> RunAsync(HttpRequestMessage request, IServiceProvider services, Cancellat
 20        {
 21            if (!HttpVerb.TryParseFast(request.Method.Method, out HttpVerb verb))
 22                throw new InvalidOperationException
 23                (
 24                    string.Format(Resources.Culture, Resources.ERR_INVALID_VERB, request.Method.Method)
 25                );
 26
 27            using RouteMatchCursor cursor = new
 28            (
 29                root,
 30                verb,
 31                request.RequestUri,
 32                services,
 33                new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase),
 34                routerConfig.MatchingPrecedence,
 35                cancellation
 36            );
 37
 38            return await CallNextHandler().ConfigureAwait(false);
 39
 40            async Task<HttpResponseMessage> CallNextHandler()
 41            {
 42                if (!await cursor.MoveNextAsync().ConfigureAwait(false))
 43                {
 44                    RouterEventSource.Info.Write("NoMatchingHandler", static request => new
 45                    {
 46                        RequestUri = request.RequestUri.OriginalString,
 47                        Verb = request.Method.Method
 48                    }, request);
 49
 50                    HttpRequestException.Throw(HttpStatusCode.NotFound, Resources.ERR_NOT_FOUND);
 51                }
 52
 53                RouterEventSource.Info.Write("MatchingHandler", static (request, cursor) => new
 54                {
 55                    RequestUri = request.RequestUri.OriginalString,
 56                    Verb = request.Method.Method,
 57                    cursor.HandlerRegistration.Pattern,
 58                    ParameterCount = cursor.Parameters.Count
 59                }, request, cursor);
 60
 61                RequestContext requestContext = new()
 62                {
 63                    Parameters = cursor.Parameters,
 64                    RemainingPath = cursor.RemainingPath,
 65                    Services = services,
 66                    Request = request,
 67                    Cancellation = cancellation
 68                };
 69
 70                return await cursor
 71                    .HandlerRegistration
 72                    .Handler(requestContext, CallNextHandler)
 73                    .ConfigureAwait(false);
 74            }
 75        }
 76    }
 77}