WebAdministrationDsc icon indicating copy to clipboard operation
WebAdministrationDsc copied to clipboard

[Feature Request] xHttpErrors resource to handle httpErrors

Open guitarrapc opened this issue 9 years ago • 4 comments

Hi, it is required to handle IIS Errors when when you are using ASP.NET MVC in almost cases. IIS Errors can be handle with httpErrors element.

HTTP Errors <httpErrors>

I believe there are many users who wants this resource to manage their error responses.

guitarrapc avatar Jul 04 '16 03:07 guitarrapc

@guitarrapc can you provide an example of setting this in PowerShell?

nzspambot avatar Jul 28 '16 05:07 nzspambot

Sure. Here's what I should do with ScriptResource.

configuration ConfigureIisError
{
    Import-DscResource -ModuleName PSDesiredStateConfiguration;

    Node localhost
    {
        # configure ErrorMode
        $errorMode = $Node.IisHttpError.ErrorMode;
        Script HttpErrorsErrorMode
        {
            SetScript = {
                Start-WebCommitDelay 
                Set-WebConfigurationProperty -Filter /system.webServer/httpErrors -Name errorMode -Value $using:errorMode
                Stop-WebCommitDelay -Commit $true 
            }
            TestScript = {
                return (Get-WebConfigurationProperty -Filter /system.webServer/httpErrors -Name errorMode) -eq $using:errorMode
            }
            GetScript = {
                @{
                    GetScript = Get-WebConfigurationProperty -Filter /system.webServer/httpErrors -Name errorMode
                    Result = (Get-WebConfigurationProperty -Filter /system.webServer/httpErrors -Name errorMode) -eq $using:errorMode
                }
            }
        }

        foreach ($errorDetail in $Node.ErrorDetails)
        {
            # Configure ErrorDetail
            $errorEnsure = $errorDetail.Ensure;
            $errorStatusCode = $errorDetail.StatusCode;
            $errorPrefixLanguageFilePath = $errorDetail.PrefixLanguageFilePath;
            $errorPath = $errorDetail.Path;
            $errorResponseMode = $errorDetail.ResponseMode;                
            Script "HttpErrors-$errorStatusCode"
            {
                DependsOn = "[Script]HttpErrorsErrorMode"
                SetScript = {
                    Start-WebCommitDelay
                    if ($using:errorEnsure -eq "Present")
                    {
                        if (((Get-WebConfiguration -Filter /system.webServer/httpErrors/error) | where statusCode -eq $using:errorStatusCode | measure).Count -eq 1)
                        {
                            # overwrite
                            Set-WebConfiguration -Filter /system.webServer/httpErrors/error[@statusCode=$using:errorStatusCode] -Value @{prefixLanguageFilePath = $using:errorPrefixLanguageFilePath; path = $using:errorPath}
                        }
                        else
                        {
                            # add
                            Add-WebConfiguration -Filter /system.webServer/httpErrors -Value @{statusCode = $using:errorStatusCode ; prefixLanguageFilePath = $using:errorPrefixLanguageFilePath; path = $using:errorPath}
                        }
                    }
                    else
                    {
                        if (((Get-WebConfiguration -Filter /system.webServer/httpErrors/error) | where statusCode -eq $using:errorStatusCode | measure).Count -eq 1)
                        {
                            # remove
                            Clear-WebConfiguration -Filter /system.webServer/httpErrors/error[@statusCode=$using:errorStatusCode]
                        }

                    }
                    Stop-WebCommitDelay -Commit $true 
                }
                TestScript = {
                    $result = ((Get-WebConfiguration -Filter /system.webServer/httpErrors/error) | where statusCode -eq $using:errorStatusCode | where prefixLanguageFilePath -eq $using:errorPrefixLanguageFilePath | where path -eq $using:errorPath | measure).Count;
                    if ($using:errorEnsure -eq "Present")
                    {
                        return $result -eq 1
                    }
                    else
                    {
                        return $result -eq 0
                    }
                }
                GetScript = {
                    $result = ((Get-WebConfiguration -Filter /system.webServer/httpErrors/error) | where statusCode -eq $using:errorStatusCode | where prefixLanguageFilePath -eq $using:errorPrefixLanguageFilePath | where path -eq $using:errorPath | measure).Count;
                    @{
                        GetScript = if ($using:errorEnsure -eq "Present")
                        {
                            return $result -eq 1
                        }
                        else
                        {
                            return $result -eq 0
                        }
                        Result = ((Get-WebConfiguration -Filter /system.webServer/httpErrors/error) | where statusCode -eq $using:errorStatusCode | where prefixLanguageFilePath -eq $using:errorPrefixLanguageFilePath | where path -eq $using:errorPath | measure).Count -eq 1
                    }
                }
            }
        }
    }
}

enum EnsureType
{
    Present
    Absent
}

enum HttpErrorsErrorMode
{
    DetailedLocalOnly
    Custom
    Detailed
}

enum HttpErrorsResponseMode
{
    File
    ExecuteURL
    Redirect
}

class IisHttpErrorDetail
{
    [int]$StatusCode;
    [string]$PrefixLanguageFilePath;
    [string]$Path;
    [string]$ResponseMode;
    [string]$Ensure = [EnsureType]::Present.ToString();

    IisHttpErrorDetail([int]$statusCode, [string]$prefixLanguageFilePath, [string]$path, [HttpErrorsResponseMode]$responseMode)
    {
        $this.StatusCode = $statusCode;
        $this.PrefixLanguageFilePath = $prefixLanguageFilePath;
        $this.Path = $path;
        $this.ResponseMode = $responseMode.ToString();
    }

    IisHttpErrorDetail([int]$statusCode, [string]$prefixLanguageFilePath, [string]$path, [HttpErrorsResponseMode]$responseMode, [EnsureType]$ensure)
    {
        $this.StatusCode = $statusCode;
        $this.PrefixLanguageFilePath = $prefixLanguageFilePath;
        $this.Path = $path;
        $this.ResponseMode = $responseMode.ToString();
        $this.Ensure = $ensure.ToString();
    }
}

$data = @{
    AllNodes = @(
        @{
            NodeName = "localhost"
            ErrorMode = [HttpErrorsErrorMode]::Custom.ToString()
            ErrorDetails = @(
                [IisHttpErrorDetail]::New(400, "%SystemDrive%\inetpub\custerr", "C:\path\to\Error400.html", [HttpErrorsResponseMode]::File),
                [IisHttpErrorDetail]::New(401, "%SystemDrive%\inetpub\custerr", "C:\path\to\Error401.html", [HttpErrorsResponseMode]::File),
                [IisHttpErrorDetail]::New(402, "%SystemDrive%\inetpub\custerr", "C:\path\to\Error402.html", [HttpErrorsResponseMode]::File)
            )
        }
    )
}

ConfigureIisError -ConfigurationData $data

guitarrapc avatar Jul 28 '16 13:07 guitarrapc

Interesting; thanks for that; let me find some time to have a stab at something

nzspambot avatar Jul 28 '16 23:07 nzspambot

This would be very useful to me. Is there any movement on this issue?

nacr2425 avatar Jan 20 '22 15:01 nacr2425