Public/Headers.ps1

<#
.SYNOPSIS
Appends a header against the Response.
 
.DESCRIPTION
Appends a header against the Response. If the current context is serverless, then this function acts like Set-PodeHeader.
 
.PARAMETER Name
The name of the header.
 
.PARAMETER Value
The value to set against the header.
 
.PARAMETER Secret
If supplied, the secret with which to sign the header's value.
 
.PARAMETER Strict
If supplied, the Secret will be extended using the client request's UserAgent and RemoteIPAddress.
 
.EXAMPLE
Add-PodeHeader -Name 'X-AuthToken' -Value 'AA-BB-CC-33'
#>

function Add-PodeHeader {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]
        $Name,

        [Parameter(Mandatory = $true)]
        [string]
        $Value,

        [Parameter()]
        [string]
        $Secret,

        [switch]
        $Strict
    )

    # sign the value if we have a secret
    if (![string]::IsNullOrWhiteSpace($Secret)) {
        $Value = (Invoke-PodeValueSign -Value $Value -Secret $Secret -Strict:$Strict)
    }

    # add the header to the response
    if ($PodeContext.Server.IsServerless) {
        $WebEvent.Response.Headers[$Name] = $Value
    }
    else {
        $WebEvent.Response.Headers.Add($Name, $Value)
    }
}

<#
.SYNOPSIS
Appends multiple headers against the Response.
 
.DESCRIPTION
Appends multiple headers against the Response. If the current context is serverless, then this function acts like Set-PodeHeaderBulk.
 
.PARAMETER Values
A hashtable of headers to be appended.
 
.PARAMETER Secret
If supplied, the secret with which to sign the header values.
 
.PARAMETER Strict
If supplied, the Secret will be extended using the client request's UserAgent and RemoteIPAddress.
 
.EXAMPLE
Add-PodeHeaderBulk -Values @{ Name1 = 'Value1'; Name2 = 'Value2' }
#>

function Add-PodeHeaderBulk {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [hashtable]
        $Values,

        [Parameter()]
        [string]
        $Secret,

        [switch]
        $Strict
    )

    foreach ($key in $Values.Keys) {
        $value = $Values[$key]

        # sign the value if we have a secret
        if (![string]::IsNullOrWhiteSpace($Secret)) {
            $value = (Invoke-PodeValueSign -Value $value -Secret $Secret -Strict:$Strict)
        }

        # add the header to the response
        if ($PodeContext.Server.IsServerless) {
            $WebEvent.Response.Headers[$key] = $value
        }
        else {
            $WebEvent.Response.Headers.Add($key, $value)
        }
    }
}

<#
.SYNOPSIS
Tests if a header is present on the Request or Response.
 
.DESCRIPTION
Tests if a header is present on the Request or Response.
 
.PARAMETER Name
The name of the header to test.
 
.PARAMETER Response
If supplied, the header will be tested against the Response instead of the Request.
 
.EXAMPLE
Test-PodeHeader -Name 'X-AuthToken'
 
.EXAMPLE
Test-PodeHeader -Name 'X-AuthToken' -Response
#>

function Test-PodeHeader {
    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory = $true)]
        [string]
        $Name,

        [switch]
        $Response
    )

    if ($Response) {
        return $WebEvent.Response.Headers -and $WebEvent.Response.Headers.ContainsKey($Name)
    }

    return $WebEvent.Request.Headers -and $WebEvent.Request.Headers.ContainsKey($Name)
}

<#
.SYNOPSIS
Retrieves the value of a header from the Request or Response.
 
.DESCRIPTION
Retrieves the value of a header from the Request or Response.
 
.PARAMETER Name
The name of the header to retrieve.
 
.PARAMETER Secret
The secret used to unsign the header's value.
 
.PARAMETER Strict
If supplied, the Secret will be extended using the client request's UserAgent and RemoteIPAddress.
 
.PARAMETER Response
If supplied, the header will be retrieved from the Response instead of the Request.
 
.EXAMPLE
Get-PodeHeader -Name 'X-AuthToken'
 
.EXAMPLE
Get-PodeHeader -Name 'X-AuthToken' -Secret 'hunter2' -Strict
 
.EXAMPLE
Get-PodeHeader -Name 'X-AuthToken' -Response
#>

function Get-PodeHeader {
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory = $true)]
        [string]
        $Name,

        [Parameter()]
        [string]
        $Secret,

        [switch]
        $Strict,

        [switch]
        $Response
    )

    # if the Response switch is supplied, get the value from the Response headers
    if ($Response) {
        if ($WebEvent.Response.Headers) {
            $header = $WebEvent.Response.Headers[$Name]
        }
    }

    # else, get the value for the header from the request
    else {
        if ($WebEvent.Request.Headers) {
            $header = $WebEvent.Request.Headers.$Name
        }
    }

    # if a secret was supplied, attempt to unsign the header's value
    if (![string]::IsNullOrEmpty($Secret) -and ![string]::IsNullOrEmpty($header)) {
        $header = Invoke-PodeValueUnsign -Value $header -Secret $Secret -Strict:$Strict
    }

    return $header
}

<#
.SYNOPSIS
Sets a header on the Response, clearing all current values for the header.
 
.DESCRIPTION
Sets a header on the Response, clearing all current values for the header.
 
.PARAMETER Name
The name of the header.
 
.PARAMETER Value
The value to set against the header.
 
.PARAMETER Secret
If supplied, the secret with which to sign the header's value.
 
.PARAMETER Strict
If supplied, the Secret will be extended using the client request's UserAgent and RemoteIPAddress.
 
.EXAMPLE
Set-PodeHeader -Name 'X-AuthToken' -Value 'AA-BB-CC-33'
#>

function Set-PodeHeader {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [string]
        $Name,

        [Parameter(Mandatory = $true)]
        [string]
        $Value,

        [Parameter()]
        [string]
        $Secret,

        [switch]
        $Strict
    )

    # sign the value if we have a secret
    if (![string]::IsNullOrWhiteSpace($Secret)) {
        $Value = (Invoke-PodeValueSign -Value $Value -Secret $Secret -Strict:$Strict)
    }

    # set the header on the response
    if ($PodeContext.Server.IsServerless) {
        $WebEvent.Response.Headers[$Name] = $Value
    }
    else {
        $WebEvent.Response.Headers.Set($Name, $Value)
    }
}

<#
.SYNOPSIS
Sets multiple headers on the Response, clearing all current values for the header.
 
.DESCRIPTION
Sets multiple headers on the Response, clearing all current values for the header.
 
.PARAMETER Values
A hashtable of headers to be set.
 
.PARAMETER Secret
If supplied, the secret with which to sign the header values.
 
.PARAMETER Strict
If supplied, the Secret will be extended using the client request's UserAgent and RemoteIPAddress.
 
.EXAMPLE
Set-PodeHeaderBulk -Values @{ Name1 = 'Value1'; Name2 = 'Value2' }
#>

function Set-PodeHeaderBulk {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [hashtable]
        $Values,

        [Parameter()]
        [string]
        $Secret,

        [switch]
        $Strict
    )

    foreach ($key in $Values.Keys) {
        $value = $Values[$key]

        # sign the value if we have a secret
        if (![string]::IsNullOrWhiteSpace($Secret)) {
            $value = (Invoke-PodeValueSign -Value $value -Secret $Secret -Strict:$Strict)
        }

        # set the header on the response
        if ($PodeContext.Server.IsServerless) {
            $WebEvent.Response.Headers[$key] = $value
        }
        else {
            $WebEvent.Response.Headers.Set($key, $value)
        }
    }
}

<#
.SYNOPSIS
Tests if a header on the Request or Response is validly signed.
 
.DESCRIPTION
Tests if a header on the Request or Response is validly signed, by attempting to unsign it using some secret.
 
.PARAMETER Name
The name of the header to test.
 
.PARAMETER Secret
A secret to use for attempting to unsign the header's value.
 
.PARAMETER Strict
If supplied, the Secret will be extended using the client request's UserAgent and RemoteIPAddress.
 
.PARAMETER Response
If supplied, the header will be tested against the Response instead of the Request.
 
.EXAMPLE
Test-PodeHeaderSigned -Name 'X-Header-Name' -Secret 'hunter2'
 
.EXAMPLE
Test-PodeHeaderSigned -Name 'X-Header-Name' -Secret 'hunter2' -Strict
 
.EXAMPLE
Test-PodeHeaderSigned -Name 'X-Header-Name' -Secret 'hunter2' -Response
#>

function Test-PodeHeaderSigned {
    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory = $true)]
        [string]
        $Name,

        [Parameter()]
        [string]
        $Secret,

        [switch]
        $Strict,

        [switch]
        $Response
    )

    if ($Response) {
        $header = $WebEvent.Response.Headers[$Name]
    }
    else {
        $header = $WebEvent.Request.Headers.$Name
    }

    return Test-PodeValueSigned -Value $header -Secret $Secret -Strict:$Strict
}