| | | 1 | | /******************************************************************************** |
| | | 2 | | * RequestPipeline.cs * |
| | | 3 | | * * |
| | | 4 | | * Author: Denes Solti * |
| | | 5 | | ********************************************************************************/ |
| | | 6 | | using System; |
| | | 7 | | using System.Collections.Generic; |
| | | 8 | | using System.Net; |
| | | 9 | | using System.Net.Http; |
| | | 10 | | using System.Threading; |
| | | 11 | | using System.Threading.Tasks; |
| | | 12 | | |
| | | 13 | | namespace NanoRoute.Internals |
| | | 14 | | { |
| | | 15 | | using Properties; |
| | | 16 | | |
| | 2 | 17 | | 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 | | } |