Public/Middleware/Enable-KrStatusCodePage.ps1
<# .SYNOPSIS Enables Status Code Pages for a Kestrun server. .DESCRIPTION Wraps KestrunHostStatusCodePagesExtensions to configure how 4xx–5xx responses produce a body: default text, redirect, re-execute, template body, options object, or a scripted handler via LanguageOptions (PowerShell/C#). .PARAMETER Server The Kestrun server instance (resolved if omitted via Resolve-KestrunServer). .PARAMETER LocationFormat The location URL for Redirect mode (e.g. "/error/{0}"). .PARAMETER PathFormat The path to re-execute for ReExecute mode (e.g. "/error/{0}"). .PARAMETER QueryFormat The query string to append for ReExecute mode (e.g. "?code={0}"). .PARAMETER ContentType The content type for Template mode (e.g. "text/plain" or "application/json"). .PARAMETER BodyFormat The body format string for Template mode (e.g. "Oops {0}"). .PARAMETER LanguageOptions A pre-configured LanguageOptions object for custom scripted handling. .PARAMETER ScriptBlock A PowerShell script block for custom scripted handling. The script block receives a single parameter: the HttpContext object. .PARAMETER Code A code string for custom scripted handling. .PARAMETER Language The scripting language for the code string (PowerShell, CSharp, VisualBasic). .PARAMETER CodeFilePath A file path to a code file for custom scripted handling (.ps1, .cs, .vb). .PARAMETER ExtraRefs Additional assembly references for custom scripted handling. .PARAMETER Arguments Additional arguments (key-value pairs) for custom scripted handling. .PARAMETER PassThru If specified, the function will return the created route object. .EXAMPLE Enable-KrStatusCodePage -Mode Default .EXAMPLE Enable-KrStatusCodePage -Mode Redirect -Location "/error/{0}" .EXAMPLE Enable-KrStatusCodePage -Mode ReExecute -Path "/error/{0}" -Query "?code={0}" .EXAMPLE Enable-KrStatusCodePage -Mode Template -ContentType "text/plain" -BodyFormat "Oops {0}" .EXAMPLE $opts = [Microsoft.AspNetCore.Diagnostics.StatusCodePagesOptions]::new() Enable-KrStatusCodePage -Mode Options -Options $opts .EXAMPLE $lo = [Kestrun.Hosting.Options.LanguageOptions]::new() $lo.ExtraImports = @('System.Net') $lo.Code = { param($Context) $statusCode = $Context.Response.StatusCode $reasonPhrase = [System.Net.HttpStatusCode]::Parse([int]$statusCode).ToString() $message = "Custom handler: Status code $statusCode - $reasonPhrase" $Context.Response.ContentType = 'text/plain' $Context.Response.WriteAsync($message) | Out-Null } Enable-KrStatusCodePage -Mode LanguageOptions -LanguageOptions $lo .EXAMPLE Enable-KrStatusCodePage -Mode ScriptBlock -ScriptBlock { param($Context) $statusCode = $Context.Response.StatusCode $reasonPhrase = [System.Net.HttpStatusCode]::Parse([int]$statusCode).ToString() $message = "Custom handler: Status code $statusCode - $reasonPhrase" $Context.Response.ContentType = 'text/plain' $Context.Response.WriteAsync($message) | Out-Null } .EXAMPLE Enable-KrStatusCodePage -Mode Code -Language PowerShell -Code { param($Context) $statusCode = $Context.Response.StatusCode $reasonPhrase = [System.Net.HttpStatusCode]::Parse([int]$statusCode).ToString() $message = "Custom handler: Status code $statusCode - $reasonPhrase" $Context.Response.ContentType = 'text/plain' $Context.Response.WriteAsync($message) | Out-Null } .EXAMPLE Enable-KrStatusCodePage -Mode CodeFilePath -CodeFilePath 'C:\Scripts\StatusCodeHandler.ps1' .NOTES This function is part of the Kestrun PowerShell module and is used to manage Kestrun servers and their middleware components. #> function Enable-KrStatusCodePage { [KestrunRuntimeApi('Definition')] [CmdletBinding(DefaultParameterSetName = 'Default')] [OutputType([Kestrun.Hosting.KestrunHost])] param( [Parameter(ValueFromPipeline = $true)] [Kestrun.Hosting.KestrunHost] $Server, # Redirect [Parameter(Mandatory = $true, ParameterSetName = 'Redirect')] [string] $LocationFormat, # Re-execute [Parameter(Mandatory = $true, ParameterSetName = 'ReExecute')] [string] $PathFormat, [Parameter(ParameterSetName = 'ReExecute')] [string] $QueryFormat, # Template body [Parameter(Mandatory = $true, ParameterSetName = 'Template')] [string] $ContentType, [Parameter(Mandatory = $true, ParameterSetName = 'Template')] [string] $BodyFormat, # Custom via LanguageOptions or ScriptBlock [Parameter(ParameterSetName = 'LanguageOptions')] [Kestrun.Hosting.Options.LanguageOptions] $LanguageOptions, [Parameter(ParameterSetName = 'ScriptBlock')] [scriptblock] $ScriptBlock, [Parameter(Mandatory = $true, ParameterSetName = 'Code')] [Alias('CodeBlock')] [string]$Code, [Parameter(Mandatory = $true, ParameterSetName = 'Code')] [Kestrun.Scripting.ScriptLanguage]$Language, [Parameter(Mandatory = $true, ParameterSetName = 'CodeFilePath')] [string]$CodeFilePath, [Parameter(ParameterSetName = 'ScriptBlock')] [Parameter(ParameterSetName = 'Code')] [Parameter(ParameterSetName = 'CodeFilePath')] [System.Reflection.Assembly[]]$ExtraRefs = $null, [Parameter(ParameterSetName = 'ScriptBlock')] [Parameter(ParameterSetName = 'Code')] [Parameter(ParameterSetName = 'CodeFilePath')] [hashtable]$Arguments, [switch] $PassThru ) begin { $Server = Resolve-KestrunServer -Server $Server } process { $statusCodeOptions = [Kestrun.Hosting.Options.StatusCodeOptions]::new($Server) switch ($PSCmdlet.ParameterSetName) { 'Default' { # Nothing to configure; use default plain text handler } 'Template' { if ([string]::IsNullOrWhiteSpace($ContentType)) { throw '-ContentType is required for Mode=Template.' } if ([string]::IsNullOrWhiteSpace($BodyFormat)) { throw '-BodyFormat is required for Mode=Template.' } $statusCodeOptions.ContentType = $ContentType $statusCodeOptions.BodyFormat = $BodyFormat } 'Redirect' { if ([string]::IsNullOrWhiteSpace($LocationFormat)) { throw '-LocationFormat is required for Mode=Redirect.' } $statusCodeOptions.LocationFormat = $LocationFormat } 'ReExecute' { if ([string]::IsNullOrWhiteSpace($PathFormat)) { throw '-Path is required for Mode=ReExecute.' } $statusCodeOptions.PathFormat = $PathFormat $statusCodeOptions.QueryFormat = $QueryFormat } 'LanguageOptions' { $statusCodeOptions.LanguageOptions = $LanguageOptions } default { $lo = [Kestrun.Hosting.Options.LanguageOptions]::new() $lo.ExtraImports = $ExtraImports $lo.ExtraRefs = $ExtraRefs if ($null -ne $Arguments) { $dict = [System.Collections.Generic.Dictionary[string, object]]::new() foreach ($key in $Arguments.Keys) { $dict[$key] = $Arguments[$key] } $lo.Arguments = $dict } switch ($PSCmdlet.ParameterSetName) { 'ScriptBlock' { $lo.Language = [Kestrun.Scripting.ScriptLanguage]::PowerShell $lo.Code = $ScriptBlock.ToString() } 'Code' { $lo.Language = $Language $lo.Code = $Code } 'CodeFilePath' { if (-not (Test-Path -Path $CodeFilePath)) { throw "The specified code file path does not exist: $CodeFilePath" } $extension = Split-Path -Path $CodeFilePath -Extension switch ($extension) { '.ps1' { $lo.Language = [Kestrun.Scripting.ScriptLanguage]::PowerShell } '.cs' { $lo.Language = [Kestrun.Scripting.ScriptLanguage]::CSharp } '.vb' { $lo.Language = [Kestrun.Scripting.ScriptLanguage]::VisualBasic } default { throw "Unsupported '$extension' code file extension." } } $lo.Code = Get-Content -Path $CodeFilePath -Raw } default { throw "Unrecognized ParameterSetName: $($PSCmdlet.ParameterSetName)" } } $statusCodeOptions.LanguageOptions = $lo } } # Assign the configured options to the server instance $Server.StatusCodeOptions = $statusCodeOptions if ($PassThru.IsPresent) { # if the PassThru switch is specified, return the modified server instance return $Server } } } |