From 731ae92be838504506a392c35e4b8ca9f68d8a24 Mon Sep 17 00:00:00 2001 From: Matthew Kelly Date: Thu, 2 Jan 2020 20:22:31 +0000 Subject: [PATCH] #448: support on routes for multiple EndpointNames --- examples/web-route-listen-names.ps1 | 11 +++- src/Private/Routes.ps1 | 53 +++++++++++++++++- src/Public/Routes.ps1 | 83 ++++++++++++----------------- 3 files changed, 96 insertions(+), 51 deletions(-) diff --git a/examples/web-route-listen-names.ps1 b/examples/web-route-listen-names.ps1 index 763cd3792..b2cb0204e 100644 --- a/examples/web-route-listen-names.ps1 +++ b/examples/web-route-listen-names.ps1 @@ -10,20 +10,27 @@ Start-PodeServer { # listen on localhost:8080/8443 Add-PodeEndpoint -Address 127.0.0.1 -Port 8080 -Protocol Http -Name 'local1' Add-PodeEndpoint -Address 127.0.0.2 -Port 8080 -Protocol Http -Name 'local2' + Add-PodeEndpoint -Address 127.0.0.3 -Port 8080 -Protocol Http -Name 'local3' + Add-PodeEndpoint -Address 127.0.0.4 -Port 8080 -Protocol Http -Name 'local4' # set view engine to pode Set-PodeViewEngine -Type Pode - # GET request for web page + # GET request for web page - all endpoints Add-PodeRoute -Method Get -Path '/' -ScriptBlock { Write-PodeViewResponse -Path 'simple' -Data @{ 'numbers' = @(1, 2, 3); } } - # GET request for web page, but only for the local2 endpoint + # GET request for web page - local2 endpoint Add-PodeRoute -Method Get -Path '/' -EndpointName 'local2' -ScriptBlock { Write-PodeViewResponse -Path 'simple' -Data @{ 'numbers' = @(1, 2, 3, 4, 5, 6, 7, 8); } } + # GET request for web page - local3 and local4 endpoints + Add-PodeRoute -Method Get -Path '/' -EndpointName 'local3', 'local4' -ScriptBlock { + Write-PodeViewResponse -Path 'simple' -Data @{ 'numbers' = @(2, 4, 6, 8, 10, 12, 14, 16); } + } + # GET request to download a file Add-PodeRoute -Method Get -Path '/download' -ScriptBlock { Set-PodeResponseAttachment -Path 'Anger.jpg' diff --git a/src/Private/Routes.ps1 b/src/Private/Routes.ps1 index 76d036612..0674f2219 100644 --- a/src/Private/Routes.ps1 +++ b/src/Private/Routes.ps1 @@ -307,7 +307,7 @@ function Test-PodeRouteAndError $found = @($PodeContext.Server.Routes[$Method][$Path]) - if (($found | Where-Object { $_.Protocol -ieq $Protocol -and $_.Endpoint -ieq $Endpoint } | Measure-Object).Count -eq 0) { + if (($found | Where-Object { ($_.Protocol -ieq $Protocol) -and ($_.Endpoint -ieq $Endpoint) } | Measure-Object).Count -eq 0) { return } @@ -359,6 +359,57 @@ function Get-PodeEndpointByName return $found } +function Find-PodeEndpoints +{ + param( + [Parameter()] + [ValidateSet('', 'Http', 'Https')] + [string] + $Protocol, + + [Parameter()] + [string] + $Endpoint, + + [Parameter()] + [string[]] + $EndpointName + ) + + $endpoints = @() + + # just use a single endpoint/protocol + if ([string]::IsNullOrWhiteSpace($EndpointName)) { + $endpoints += @{ + Protocol = $Protocol + Address = $Endpoint + } + } + + # get all defined endpoints by name + else { + foreach ($name in @($EndpointName)) { + $_endpoint = Get-PodeEndpointByName -EndpointName $name -ThrowError + if ($null -ne $_endpoint) { + $endpoints += @{ + Protocol = $_endpoint.Protocol + Address = $_endpoint.RawAddress + } + } + } + } + + # convert the endpoint's address into host:port format + foreach ($_endpoint in $endpoints) { + if (![string]::IsNullOrWhiteSpace($_endpoint.Address)) { + $_addr = Get-PodeEndpointInfo -Endpoint $_endpoint.Address -AnyPortOnZero + $_endpoint.Address = "$($_addr.Host):$($_addr.Port)" + } + } + + return $endpoints +} + function Convert-PodeFunctionVerbToHttpMethod { param ( diff --git a/src/Public/Routes.ps1 b/src/Public/Routes.ps1 index 20d202d46..a53013e0e 100644 --- a/src/Public/Routes.ps1 +++ b/src/Public/Routes.ps1 @@ -24,7 +24,7 @@ The protocol this Route should be bound against. The endpoint this Route should be bound against. .PARAMETER EndpointName -The EndpointName of an Endpoint this Route should be bound against. +The EndpointName of an Endpoint(s) this Route should be bound against. .PARAMETER ContentType The content type the Route should use when parsing any payloads. @@ -84,7 +84,7 @@ function Add-PodeRoute $Endpoint, [Parameter()] - [string] + [string[]] $EndpointName, [Parameter()] @@ -114,22 +114,14 @@ function Add-PodeRoute $Path = Update-PodeRouteSlashes -Path $Path $Path = Update-PodeRoutePlaceholders -Path $Path - # if an EndpointName was supplied, find it and use it - $_endpoint = Get-PodeEndpointByName -EndpointName $EndpointName -ThrowError - if ($null -ne $_endpoint) { - $Protocol = $_endpoint.Protocol - $Endpoint = $_endpoint.RawAddress - } + # get endpoints from name, or use single passed endpoint/protocol + $endpoints = Find-PodeEndpoints -Endpoint $Endpoint -Protocol $Protocol -EndpointName $EndpointName - # if we have an endpoint, set any appropriate wildcards - if (!(Test-IsEmpty $Endpoint)) { - $_endpoint = Get-PodeEndpointInfo -Endpoint $Endpoint -AnyPortOnZero - $Endpoint = "$($_endpoint.Host):$($_endpoint.Port)" + # ensure the route doesn't already exist for each endpoint + foreach ($_endpoint in $endpoints) { + Test-PodeRouteAndError -Method $Method -Path $Path -Protocol $_endpoint.Protocol -Endpoint $_endpoint.Address } - # ensure route doesn't already exist - Test-PodeRouteAndError -Method $Method -Path $Path -Protocol $Protocol -Endpoint $Endpoint - # if middleware, scriptblock and file path are all null/empty, error if ((Test-IsEmpty $Middleware) -and (Test-IsEmpty $ScriptBlock) -and (Test-IsEmpty $FilePath)) { throw "[$($Method)] $($Path): No logic passed" @@ -192,15 +184,17 @@ function Add-PodeRoute # add the route Write-Verbose "Adding Route: [$($Method)] $($Path)" - $PodeContext.Server.Routes[$Method][$Path] += @(@{ - Logic = $ScriptBlock - Middleware = $Middleware - Protocol = $Protocol - Endpoint = $Endpoint.Trim() - ContentType = $ContentType - ErrorType = $ErrorContentType - Arguments = $ArgumentList - }) + foreach ($_endpoint in $endpoints) { + $PodeContext.Server.Routes[$Method][$Path] += @(@{ + Logic = $ScriptBlock + Middleware = $Middleware + Protocol = $_endpoint.Protocol + Endpoint = $_endpoint.Address.Trim() + ContentType = $ContentType + ErrorType = $ErrorContentType + Arguments = $ArgumentList + }) + } } <# @@ -223,7 +217,7 @@ The protocol this static Route should be bound against. The endpoint this static Route should be bound against. .PARAMETER EndpointName -The EndpointName of an Endpoint to bind the static Route against. +The EndpointName of an Endpoint(s) to bind the static Route against. .PARAMETER Defaults An array of default pages to display, such as 'index.html'. @@ -262,7 +256,7 @@ function Add-PodeStaticRoute $Endpoint, [Parameter()] - [string] + [string[]] $EndpointName, [Parameter()] @@ -285,22 +279,14 @@ function Add-PodeStaticRoute # ensure the route has appropriate slashes $Path = Update-PodeRouteSlashes -Path $Path -Static - # if an EndpointName was supplied, find it and use it - $_endpoint = Get-PodeEndpointByName -EndpointName $EndpointName -ThrowError - if ($null -ne $_endpoint) { - $Protocol = $_endpoint.Protocol - $Endpoint = $_endpoint.RawAddress - } + # get endpoints from name, or use single passed endpoint/protocol + $endpoints = Find-PodeEndpoints -Endpoint $Endpoint -Protocol $Protocol -EndpointName $EndpointName - # if we have an endpoint, set any appropriate wildcards - if (!(Test-IsEmpty $Endpoint)) { - $_endpoint = Get-PodeEndpointInfo -Endpoint $Endpoint -AnyPortOnZero - $Endpoint = "$($_endpoint.Host):$($_endpoint.Port)" + # ensure the route doesn't already exist for each endpoint + foreach ($_endpoint in $endpoints) { + Test-PodeRouteAndError -Method $Method -Path $Path -Protocol $_endpoint.Protocol -Endpoint $_endpoint.Address } - # ensure route doesn't already exist - Test-PodeRouteAndError -Method $Method -Path $Path -Protocol $Protocol -Endpoint $Endpoint - # if static, ensure the path exists at server root $Source = Get-PodeRelativePath -Path $Source -JoinRoot if (!(Test-PodePath -Path $Source -NoStatus)) { @@ -315,15 +301,16 @@ function Add-PodeStaticRoute $Defaults = Get-PodeStaticRouteDefaults } - # add the route path - $PodeContext.Server.Routes[$Method][$Path] += @(@{ - Path = $Source - Defaults = $Defaults - Protocol = $Protocol - Endpoint = $Endpoint.Trim() - Download = $DownloadOnly - }) - + # add the static route for each endpoint + foreach ($_endpoint in $endpoints) { + $PodeContext.Server.Routes[$Method][$Path] += @(@{ + Path = $Source + Defaults = $Defaults + Protocol = $_endpoint.Protocol + Endpoint = $_endpoint.Address.Trim() + Download = $DownloadOnly + }) + } } <#