< Summary - Kestrun — Combined Coverage

Information
Class: Kestrun.Models.KestrunRequest
Assembly: Kestrun
File(s): /home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Models/KestrunRequest.cs
Tag: Kestrun/Kestrun@2d87023b37eb91155071c91dd3d6a2eeb3004705
Line coverage
100%
Covered lines: 51
Uncovered lines: 0
Coverable lines: 51
Total lines: 169
Line coverage: 100%
Branch coverage
62%
Covered branches: 10
Total branches: 16
Branch coverage: 62.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 08/26/2025 - 01:25:22 Line coverage: 100% (49/49) Branch coverage: 64.2% (9/14) Total lines: 160 Tag: Kestrun/Kestrun@07f821172e5dc3657f1be7e6818f18d6721cf38a09/14/2025 - 21:23:16 Line coverage: 100% (51/51) Branch coverage: 62.5% (10/16) Total lines: 169 Tag: Kestrun/Kestrun@c9d2f0b3dd164d7dc0dc2407a9f006293d924223 08/26/2025 - 01:25:22 Line coverage: 100% (49/49) Branch coverage: 64.2% (9/14) Total lines: 160 Tag: Kestrun/Kestrun@07f821172e5dc3657f1be7e6818f18d6721cf38a09/14/2025 - 21:23:16 Line coverage: 100% (51/51) Branch coverage: 62.5% (10/16) Total lines: 169 Tag: Kestrun/Kestrun@c9d2f0b3dd164d7dc0dc2407a9f006293d924223

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%1212100%
get_HttpContext()100%11100%
get_Request()100%11100%
get_Method()100%11100%
get_Host()100%11100%
get_QueryString()100%11100%
get_ContentType()100%11100%
get_Protocol()100%11100%
get_IsHttps()100%11100%
get_ContentLength()100%11100%
get_HasFormContentType()100%11100%
get_Scheme()100%11100%
get_Path()100%11100%
get_PathBase()100%11100%
get_Query()100%11100%
get_Headers()100%11100%
get_Body()100%11100%
get_Authorization()100%11100%
get_Cookies()100%11100%
get_Form()100%11100%
get_RouteValues()100%11100%
NewRequest()100%44100%
NewRequestSync(...)100%11100%

File(s)

/home/runner/work/Kestrun/Kestrun/src/CSharp/Kestrun/Models/KestrunRequest.cs

#LineLine coverage
 1using System.Text;
 2
 3namespace Kestrun.Models;
 4
 5
 6/// <summary>
 7/// Represents a request model for Kestrun, containing HTTP method, path, query, headers, body, authorization, cookies, 
 8/// </summary>
 9public partial class KestrunRequest
 10{
 10411    private KestrunRequest(HttpContext context, Dictionary<string, string>? formDict, string body)
 12    {
 10413        HttpContext = context ?? throw new ArgumentNullException(nameof(context));
 10414        Request = context.Request;
 10415        Query = Request.Query
 12416                            .ToDictionary(x => x.Key, x => x.Value.ToString() ?? string.Empty);
 10417        Headers = Request.Headers
 21018                            .ToDictionary(x => x.Key, x => x.Value.ToString() ?? string.Empty);
 10419        Cookies = Request.Cookies
 11020                            .ToDictionary(x => x.Key, x => x.Value.ToString() ?? string.Empty);
 10421        Form = formDict;
 10422        Body = body;
 10423        RouteValues = Request.RouteValues
 10624                            .ToDictionary(x => x.Key, x => x.Value?.ToString() ?? string.Empty);
 10425    }
 26
 27    /// <summary>
 28    /// Gets the <see cref="Microsoft.AspNetCore.Http.HttpContext"/> associated with the request.
 29    /// </summary>
 20130    public HttpContext HttpContext { get; init; }
 31
 32    /// <summary>
 33    /// Gets the <see cref="HttpRequest"/> associated with the request.
 34    /// </summary>
 56835    public HttpRequest Request { get; init; }
 36    /// <summary>
 37    /// Gets the HTTP method for the request (e.g., GET, POST).
 38    /// </summary>
 1539    public string Method => Request.Method;
 40
 41    /// <summary>
 42    /// Gets the host header value for the request.
 43    /// </summary>
 144    public HostString Host => Request.Host;
 45
 46    /// <summary>
 47    /// Gets the query string for the request (e.g., "?id=123").
 48    /// </summary>
 149    public string QueryString => Request.QueryString.ToUriComponent();
 50
 51    /// <summary>
 52    /// Gets the content type of the request (e.g., "application/json").
 53    /// </summary>
 154    public string? ContentType => Request.ContentType;
 55
 56    /// <summary>
 57    /// Gets the protocol used for the request (e.g., "HTTP/1.1").
 58    /// </summary>
 159    public string Protocol => Request.Protocol;
 60
 61    /// <summary>
 62    /// Gets a value indicating whether the request is made over HTTPS.
 63    /// </summary>
 164    public bool IsHttps => Request.IsHttps;
 65
 66    /// <summary>
 67    /// Gets the content length of the request, if available.
 68    /// </summary>
 269    public long? ContentLength => Request.ContentLength;
 70
 71    /// <summary>
 72    /// Gets a value indicating whether the request has a form content type.
 73    /// </summary>
 174    public bool HasFormContentType => Request.HasFormContentType;
 75
 76    /// <summary>
 77    /// Gets the request scheme (e.g., "http", "https").
 78    /// </summary>
 179    public string Scheme => Request.Scheme;
 80
 81    /// <summary>
 82    /// Gets the request path (e.g., "/api/resource").
 83    /// </summary>
 1684    public string Path => Request.Path.ToString();
 85
 86    /// <summary>
 87    /// Gets the base path for the request (e.g., "/api").
 88    /// </summary>
 189    public string PathBase => Request.PathBase.ToString();
 90
 91    /// <summary>
 92    /// Gets the query parameters for the request as a dictionary of key-value pairs.
 93    /// </summary>
 11094    public Dictionary<string, string> Query { get; init; }
 95
 96
 97    /// <summary>
 98    /// Gets the headers for the request as a dictionary of key-value pairs.
 99    /// </summary>
 218100    public Dictionary<string, string> Headers { get; init; }
 101
 102    /// <summary>
 103    /// Gets the body content of the request as a string.
 104    /// </summary>
 110105    public string Body { get; init; }
 106
 107    /// <summary>
 108    /// Gets the authorization header value for the request, if present.
 109    /// </summary>
 7110    public string? Authorization => Request.Headers.Authorization.ToString();
 111    /// <summary>
 112    /// Gets the cookies for the request as an <see cref="IRequestCookieCollection"/>, if present.
 113    /// </summary>
 108114    public Dictionary<string, string> Cookies { get; init; }
 115
 116    /// <summary>
 117    /// Gets the form data for the request as a dictionary of key-value pairs, if present.
 118    /// </summary>
 109119    public Dictionary<string, string>? Form { get; init; }
 120
 121
 122    /// <summary>
 123    /// Gets the route values for the request as a <see cref="RouteValueDictionary"/>, if present.
 124    /// </summary>
 105125    public Dictionary<string, string> RouteValues { get; init; }
 126
 127
 128    /// <summary>
 129    /// Creates a new <see cref="KestrunRequest"/> instance from the specified <see cref="Microsoft.AspNetCore.Http.Http
 130    /// </summary>
 131    /// <param name="context">The HTTP context containing the request information.</param>
 132    /// <returns>A task that represents the asynchronous operation. The task result contains the constructed <see cref="
 133    public static async Task<KestrunRequest> NewRequest(HttpContext context)
 134    {
 135        // ① Allow the body to be read multiple times
 104136        context.Request.EnableBuffering();
 137
 138        // ② Read the raw body into a string, then rewind
 139        string body;
 104140        using (var reader = new StreamReader(
 104141                   context.Request.Body,
 104142                   encoding: Encoding.UTF8,
 104143                   detectEncodingFromByteOrderMarks: false,
 104144                   leaveOpen: true))
 145        {
 104146            body = await reader.ReadToEndAsync();
 104147            context.Request.Body.Position = 0;
 104148        }
 149
 150        // ③ If it's a form, read it safely
 104151        var formDict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 104152        if (context.Request.HasFormContentType)
 153        {
 1154            var form = await context.Request.ReadFormAsync();
 6155            foreach (var kv in form)
 156            {
 2157                formDict[kv.Key] = kv.Value.ToString();
 158            }
 159        }
 160
 104161        return new KestrunRequest(context: context, formDict: formDict, body: body);
 104162    }
 163
 164    /// <summary>
 165    /// Synchronous helper for tests and simple call sites that prefer not to use async/await.
 166    /// Avoid in ASP.NET request pipelines; intended for unit tests only.
 167    /// </summary>
 60168    public static KestrunRequest NewRequestSync(HttpContext context) => NewRequest(context).GetAwaiter().GetResult();
 169}