| File: Matching\HttpMethodDestinationsLookup.cs | Web Access |
| Project: src\aspnetcore\src\Http\Routing\src\Microsoft.AspNetCore.Routing.csproj (Microsoft.AspNetCore.Routing) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Routing.Matching; internal sealed class HttpMethodDestinationsLookup { private readonly int _exitDestination; private readonly int _connectDestination; private readonly int _deleteDestination; private readonly int _getDestination; private readonly int _headDestination; private readonly int _optionsDestination; private readonly int _patchDestination; private readonly int _postDestination; private readonly int _putDestination; private readonly int _traceDestination; private readonly Dictionary<string, int>? _extraDestinations; public HttpMethodDestinationsLookup(List<KeyValuePair<string, int>> destinations, int exitDestination) { _exitDestination = exitDestination; int? connectDestination = null; int? deleteDestination = null; int? getDestination = null; int? headDestination = null; int? optionsDestination = null; int? patchDestination = null; int? postDestination = null; int? putDestination = null; int? traceDestination = null; foreach (var (method, destination) in destinations) { if (method.Length >= 3) // 3 == smallest known method { switch (method[0] | 0x20) { case 'c' when method.Equals(HttpMethods.Connect, StringComparison.OrdinalIgnoreCase): connectDestination = destination; continue; case 'd' when method.Equals(HttpMethods.Delete, StringComparison.OrdinalIgnoreCase): deleteDestination = destination; continue; case 'g' when method.Equals(HttpMethods.Get, StringComparison.OrdinalIgnoreCase): getDestination = destination; continue; case 'h' when method.Equals(HttpMethods.Head, StringComparison.OrdinalIgnoreCase): headDestination = destination; continue; case 'o' when method.Equals(HttpMethods.Options, StringComparison.OrdinalIgnoreCase): optionsDestination = destination; continue; case 'p': if (method.Equals(HttpMethods.Put, StringComparison.OrdinalIgnoreCase)) { putDestination = destination; continue; } else if (method.Equals(HttpMethods.Post, StringComparison.OrdinalIgnoreCase)) { postDestination = destination; continue; } else if (method.Equals(HttpMethods.Patch, StringComparison.OrdinalIgnoreCase)) { patchDestination = destination; continue; } break; case 't' when method.Equals(HttpMethods.Trace, StringComparison.OrdinalIgnoreCase): traceDestination = destination; continue; } } _extraDestinations ??= new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); _extraDestinations.Add(method, destination); } _connectDestination = connectDestination ?? _exitDestination; _deleteDestination = deleteDestination ?? _exitDestination; _getDestination = getDestination ?? _exitDestination; _headDestination = headDestination ?? _exitDestination; _optionsDestination = optionsDestination ?? _exitDestination; _patchDestination = patchDestination ?? _exitDestination; _postDestination = postDestination ?? _exitDestination; _putDestination = putDestination ?? _exitDestination; _traceDestination = traceDestination ?? _exitDestination; } public int GetDestination(string method) { // Implementation skeleton taken from https://github.com/dotnet/runtime/blob/13b43155c31beb844b1b04766fea65235ccd8363/src/libraries/System.Net.Http/src/System/Net/Http/HttpMethod.cs#L179 if (method.Length >= 3) // 3 == smallest known method { (var matchedMethod, var destination) = (method[0] | 0x20) switch { 'c' => (HttpMethods.Connect, _connectDestination), 'd' => (HttpMethods.Delete, _deleteDestination), 'g' => (HttpMethods.Get, _getDestination), 'h' => (HttpMethods.Head, _headDestination), 'o' => (HttpMethods.Options, _optionsDestination), 'p' => method.Length switch { 3 => (HttpMethods.Put, _putDestination), 4 => (HttpMethods.Post, _postDestination), _ => (HttpMethods.Patch, _patchDestination), }, 't' => (HttpMethods.Trace, _traceDestination), _ => (null, 0), }; if (matchedMethod is not null && method.Equals(matchedMethod, StringComparison.OrdinalIgnoreCase)) { return destination; } } if (_extraDestinations != null && _extraDestinations.TryGetValue(method, out var extraDestination)) { return extraDestination; } return _exitDestination; } }