< 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@9d3a582b2d63930269564a7591aa77ef297cadeb
Line coverage
100%
Covered lines: 49
Uncovered lines: 0
Coverable lines: 49
Total lines: 160
Line coverage: 100%
Branch coverage
64%
Covered branches: 9
Total branches: 14
Branch coverage: 64.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%1010100%
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{
 7911    private KestrunRequest(HttpRequest request, Dictionary<string, string>? formDict, string body)
 12    {
 7913        Request = request;
 7914        Query = request.Query
 9915                            .ToDictionary(x => x.Key, x => x.Value.ToString() ?? string.Empty);
 7916        Headers = request.Headers
 14917                            .ToDictionary(x => x.Key, x => x.Value.ToString() ?? string.Empty);
 7918        Cookies = request.Cookies
 8319                            .ToDictionary(x => x.Key, x => x.Value.ToString() ?? string.Empty);
 7920        Form = formDict;
 7921        Body = body;
 7922        RouteValues = request.RouteValues
 8123                            .ToDictionary(x => x.Key, x => x.Value?.ToString() ?? string.Empty);
 7924    }
 25
 12526    private HttpRequest Request { get; init; }
 27    /// <summary>
 28    /// Gets the HTTP method for the request (e.g., GET, POST).
 29    /// </summary>
 1430    public string Method => Request.Method;
 31
 32    /// <summary>
 33    /// Gets the host header value for the request.
 34    /// </summary>
 135    public string Host => Request.Host.ToUriComponent();
 36
 37    /// <summary>
 38    /// Gets the query string for the request (e.g., "?id=123").
 39    /// </summary>
 140    public string QueryString => Request.QueryString.ToUriComponent();
 41
 42    /// <summary>
 43    /// Gets the content type of the request (e.g., "application/json").
 44    /// </summary>
 145    public string? ContentType => Request.ContentType;
 46
 47    /// <summary>
 48    /// Gets the protocol used for the request (e.g., "HTTP/1.1").
 49    /// </summary>
 150    public string Protocol => Request.Protocol;
 51
 52    /// <summary>
 53    /// Gets a value indicating whether the request is made over HTTPS.
 54    /// </summary>
 155    public bool IsHttps => Request.IsHttps;
 56
 57    /// <summary>
 58    /// Gets the content length of the request, if available.
 59    /// </summary>
 260    public long? ContentLength => Request.ContentLength;
 61
 62    /// <summary>
 63    /// Gets a value indicating whether the request has a form content type.
 64    /// </summary>
 165    public bool HasFormContentType => Request.HasFormContentType;
 66
 67    /// <summary>
 68    /// Gets the request scheme (e.g., "http", "https").
 69    /// </summary>
 170    public string Scheme => Request.Scheme;
 71
 72    /// <summary>
 73    /// Gets the request path (e.g., "/api/resource").
 74    /// </summary>
 1575    public string Path => Request.Path.ToString();
 76
 77    /// <summary>
 78    /// Gets the base path for the request (e.g., "/api").
 79    /// </summary>
 180    public string PathBase => Request.PathBase.ToString();
 81
 82    /// <summary>
 83    /// Gets the query parameters for the request as a dictionary of key-value pairs.
 84    /// </summary>
 8585    public Dictionary<string, string> Query { get; init; }
 86
 87
 88    /// <summary>
 89    /// Gets the headers for the request as a dictionary of key-value pairs.
 90    /// </summary>
 16791    public Dictionary<string, string> Headers { get; init; }
 92
 93    /// <summary>
 94    /// Gets the body content of the request as a string.
 95    /// </summary>
 8596    public string Body { get; init; }
 97
 98    /// <summary>
 99    /// Gets the authorization header value for the request, if present.
 100    /// </summary>
 7101    public string? Authorization => Request.Headers.Authorization.ToString();
 102    /// <summary>
 103    /// Gets the cookies for the request as an <see cref="IRequestCookieCollection"/>, if present.
 104    /// </summary>
 83105    public Dictionary<string, string> Cookies { get; init; }
 106
 107    /// <summary>
 108    /// Gets the form data for the request as a dictionary of key-value pairs, if present.
 109    /// </summary>
 84110    public Dictionary<string, string>? Form { get; init; }
 111
 112
 113    /// <summary>
 114    /// Gets the route values for the request as a <see cref="RouteValueDictionary"/>, if present.
 115    /// </summary>
 80116    public Dictionary<string, string> RouteValues { get; init; }
 117
 118
 119    /// <summary>
 120    /// Creates a new <see cref="KestrunRequest"/> instance from the specified <see cref="HttpContext"/>.
 121    /// </summary>
 122    /// <param name="context">The HTTP context containing the request information.</param>
 123    /// <returns>A task that represents the asynchronous operation. The task result contains the constructed <see cref="
 124    public static async Task<KestrunRequest> NewRequest(HttpContext context)
 125    {
 126        // ① Allow the body to be read multiple times
 79127        context.Request.EnableBuffering();
 128
 129        // ② Read the raw body into a string, then rewind
 130        string body;
 79131        using (var reader = new StreamReader(
 79132                   context.Request.Body,
 79133                   encoding: Encoding.UTF8,
 79134                   detectEncodingFromByteOrderMarks: false,
 79135                   leaveOpen: true))
 136        {
 79137            body = await reader.ReadToEndAsync();
 79138            context.Request.Body.Position = 0;
 79139        }
 140
 141        // ③ If it's a form, read it safely
 79142        var formDict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 79143        if (context.Request.HasFormContentType)
 144        {
 1145            var form = await context.Request.ReadFormAsync();
 6146            foreach (var kv in form)
 147            {
 2148                formDict[kv.Key] = kv.Value.ToString();
 149            }
 150        }
 151
 79152        return new KestrunRequest(request: context.Request, formDict: formDict, body: body);
 79153    }
 154
 155    /// <summary>
 156    /// Synchronous helper for tests and simple call sites that prefer not to use async/await.
 157    /// Avoid in ASP.NET request pipelines; intended for unit tests only.
 158    /// </summary>
 49159    public static KestrunRequest NewRequestSync(HttpContext context) => NewRequest(context).GetAwaiter().GetResult();
 160}