Skip to content

Commit

Permalink
Merge pull request #1246 from Badgerati/Issue-1228
Browse files Browse the repository at this point in the history
Fix for Static Route ordering, and redirecting to Default file option
  • Loading branch information
Badgerati authored Feb 25, 2024
2 parents c8119bf + 9a57c27 commit df86e0f
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 44 deletions.
5 changes: 3 additions & 2 deletions src/Private/Context.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -819,8 +819,9 @@ function Set-PodeWebConfiguration {
# setup the main web config
$Context.Server.Web = @{
Static = @{
Defaults = $Configuration.Static.Defaults
Cache = @{
Defaults = $Configuration.Static.Defaults
RedirectToDefault = [bool]$Configuration.Static.RedirectToDefault
Cache = @{
Enabled = [bool]$Configuration.Static.Cache.Enable
MaxAge = [int](Protect-PodeValue -Value $Configuration.Static.Cache.MaxAge -Default 3600)
Include = (Convert-PodePathPatternsToRegex -Paths @($Configuration.Static.Cache.Include) -NotSlashes)
Expand Down
4 changes: 4 additions & 0 deletions src/Private/PodeServer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ function Start-PodeWebServer {
if ($WebEvent.StaticContent.IsDownload) {
Set-PodeResponseAttachment -Path $WebEvent.Path -EndpointName $WebEvent.Endpoint.Name
}
elseif ($WebEvent.StaticContent.RedirectToDefault) {
$file = [System.IO.Path]::GetFileName($WebEvent.StaticContent.Source)
Move-PodeResponseUrl -Url "$($WebEvent.Path)/$($file)"
}
else {
$cachable = $WebEvent.StaticContent.IsCachable
Write-PodeFileResponse -Path $WebEvent.StaticContent.Source -MaxAge $PodeContext.Server.Web.Static.Cache.MaxAge -Cache:$cachable
Expand Down
42 changes: 32 additions & 10 deletions src/Private/Routes.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,31 @@ function Find-PodeRoute {
}
}

# is this a static route?
$isStatic = ($Method -ieq 'static')

# first ensure we have the method
$_method = $PodeContext.Server.Routes[$Method]
if ($null -eq $_method) {
return $null
}

# is this a static route?
$isStatic = ($Method -ieq 'static')

# if we have a perfect match for the route, return it if the protocol is right
$found = Get-PodeRouteByUrl -Routes $_method[$Path] -EndpointName $EndpointName
if (!$isStatic -and ($null -ne $found)) {
return $found
if (!$isStatic) {
$found = Get-PodeRouteByUrl -Routes $_method[$Path] -EndpointName $EndpointName
if ($null -ne $found) {
return $found
}
}

# otherwise, match the path to routes on regex (first match only)
$valid = @(foreach ($key in $_method.Keys) {
$paths = @($_method.Keys)
if ($isStatic) {
[array]::Sort($paths)
[array]::Reverse($paths)
}

$valid = @(foreach ($key in $paths) {
if ($Path -imatch "^$($key)$") {
$key
break
Expand Down Expand Up @@ -131,6 +139,8 @@ function Find-PodeStaticRoute {
$found = Find-PodeRoute -Method 'static' -Path $Path -EndpointName $EndpointName
$download = ([bool]$found.Download)
$source = $null
$isDefault = $false
$redirectToDefault = ([bool]$found.RedirectToDefault)

# if we have a defined static route, use that
if ($null -ne $found) {
Expand All @@ -144,11 +154,13 @@ function Find-PodeStaticRoute {
if (!$found.Download -and !(Test-PodePathIsFile $file) -and (Get-PodeCount @($found.Defaults)) -gt 0) {
if ((Get-PodeCount @($found.Defaults)) -eq 1) {
$file = [System.IO.Path]::Combine($file, @($found.Defaults)[0])
$isDefault = $true
}
else {
foreach ($def in $found.Defaults) {
if (Test-PodePath ([System.IO.Path]::Combine($found.Source, $def)) -NoStatus) {
$file = [System.IO.Path]::Combine($file, $def)
$isDefault = $true
break
}
}
Expand All @@ -163,6 +175,8 @@ function Find-PodeStaticRoute {
$source = Find-PodePublicRoute -Path $Path
$download = $false
$found = $null
$isDefault = $false
$redirectToDefault = $false
}

# return nothing if no source
Expand All @@ -171,11 +185,19 @@ function Find-PodeStaticRoute {
}

# return the route details
if ($redirectToDefault -and $isDefault) {
$redirectToDefault = $true
}
else {
$redirectToDefault = $false
}

return @{
Content = @{
Source = $source
IsDownload = $download
IsCachable = (Test-PodeRouteValidForCaching -Path $Path)
Source = $source
IsDownload = $download
IsCachable = (Test-PodeRouteValidForCaching -Path $Path)
RedirectToDefault = $redirectToDefault
}
Route = $found
}
Expand Down
8 changes: 8 additions & 0 deletions src/Private/Serverless.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ function Start-PodeAzFuncServer {
if ($WebEvent.StaticContent.IsDownload) {
Set-PodeResponseAttachment -Path $WebEvent.Path -EndpointName $WebEvent.Endpoint.Name
}
elseif ($WebEvent.StaticContent.RedirectToDefault) {
$file = [System.IO.Path]::GetFileName($WebEvent.StaticContent.Source)
Move-PodeResponseUrl -Url "$($WebEvent.Path)/$($file)"
}
else {
$cachable = $WebEvent.StaticContent.IsCachable
Write-PodeFileResponse -Path $WebEvent.StaticContent.Source -MaxAge $PodeContext.Server.Web.Static.Cache.MaxAge -Cache:$cachable
Expand Down Expand Up @@ -193,6 +197,10 @@ function Start-PodeAwsLambdaServer {
if ($WebEvent.StaticContent.IsDownload) {
Set-PodeResponseAttachment -Path $WebEvent.Path -EndpointName $WebEvent.Endpoint.Name
}
elseif ($WebEvent.StaticContent.RedirectToDefault) {
$file = [System.IO.Path]::GetFileName($WebEvent.StaticContent.Source)
Move-PodeResponseUrl -Url "$($WebEvent.Path)/$($file)"
}
else {
$cachable = $WebEvent.StaticContent.IsCachable
Write-PodeFileResponse -Path $WebEvent.StaticContent.Source -MaxAge $PodeContext.Server.Web.Static.Cache.MaxAge -Cache:$cachable
Expand Down
93 changes: 61 additions & 32 deletions src/Public/Routes.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,9 @@ One or more optional Scopes that will be authorised to access this Route, when u
.PARAMETER User
One or more optional Users that will be authorised to access this Route, when using Authentication with an Access method.
.PARAMETER RedirectToDefault
If supplied, the user will be redirected to the default page if found instead of the page being rendered as the folder path.
.EXAMPLE
Add-PodeStaticRoute -Path '/assets' -Source './assets'
Expand All @@ -484,6 +487,9 @@ Add-PodeStaticRoute -Path '/assets' -Source './assets' -Defaults @('index.html')
.EXAMPLE
Add-PodeStaticRoute -Path '/installers' -Source './exes' -DownloadOnly
.EXAMPLE
Add-PodeStaticRoute -Path '/assets' -Source './assets' -Defaults @('index.html') -RedirectToDefault
#>
function Add-PodeStaticRoute {
[CmdletBinding()]
Expand Down Expand Up @@ -558,7 +564,10 @@ function Add-PodeStaticRoute {
$DownloadOnly,

[switch]
$PassThru
$PassThru,

[switch]
$RedirectToDefault
)

# check if we have any route group info defined
Expand Down Expand Up @@ -611,6 +620,10 @@ function Add-PodeStaticRoute {
$DownloadOnly = $RouteGroup.DownloadOnly
}

if ($RouteGroup.RedirectToDefault) {
$RedirectToDefault = $RouteGroup.RedirectToDefault
}

if ($RouteGroup.IfExists -ine 'default') {
$IfExists = $RouteGroup.IfExists
}
Expand Down Expand Up @@ -700,6 +713,10 @@ function Add-PodeStaticRoute {
$Defaults = Get-PodeStaticRouteDefaults
}

if (!$RedirectToDefault) {
$RedirectToDefault = $PodeContext.Server.Web.Static.RedirectToDefault
}

# convert any middleware into valid hashtables
$Middleware = @(ConvertTo-PodeMiddleware -Middleware $Middleware -PSSession $PSCmdlet.SessionState)

Expand Down Expand Up @@ -744,30 +761,31 @@ function Add-PodeStaticRoute {
Write-Verbose "Adding Route: [$($Method)] $($Path)"
$newRoutes = @(foreach ($_endpoint in $endpoints) {
@{
Source = $Source
Path = $Path
Method = $Method
Defaults = $Defaults
Middleware = $Middleware
Authentication = $Authentication
Access = $Access
AccessMeta = @{
Source = $Source
Path = $Path
Method = $Method
Defaults = $Defaults
RedirectToDefault = $RedirectToDefault
Middleware = $Middleware
Authentication = $Authentication
Access = $Access
AccessMeta = @{
Role = $Role
Group = $Group
Scope = $Scope
User = $User
Custom = $CustomAccess
}
Endpoint = @{
Endpoint = @{
Protocol = $_endpoint.Protocol
Address = $_endpoint.Address.Trim()
Name = $_endpoint.Name
}
ContentType = $ContentType
TransferEncoding = $TransferEncoding
ErrorType = $ErrorContentType
Download = $DownloadOnly
OpenApi = @{
ContentType = $ContentType
TransferEncoding = $TransferEncoding
ErrorType = $ErrorContentType
Download = $DownloadOnly
OpenApi = @{
Path = $OpenApiPath
Responses = @{
'200' = @{ description = 'OK' }
Expand All @@ -777,8 +795,8 @@ function Add-PodeStaticRoute {
RequestBody = @{}
Authentication = @()
}
IsStatic = $true
Metrics = @{
IsStatic = $true
Metrics = @{
Requests = @{
Total = 0
StatusCodes = @{}
Expand Down Expand Up @@ -1234,6 +1252,9 @@ One or more optional Scopes that will be authorised to access this Route, when u
.PARAMETER User
One or more optional Users that will be authorised to access this Route, when using Authentication with an Access method.
.PARAMETER RedirectToDefault
If supplied, the user will be redirected to the default page if found instead of the page being rendered as the folder path.
.EXAMPLE
Add-PodeStaticRouteGroup -Path '/static' -Routes { Add-PodeStaticRoute -Path '/images' -Etc }
#>
Expand Down Expand Up @@ -1311,7 +1332,10 @@ function Add-PodeStaticRouteGroup {
$AllowAnon,

[switch]
$DownloadOnly
$DownloadOnly,

[switch]
$RedirectToDefault
)

if (Test-PodeIsEmpty $Routes) {
Expand Down Expand Up @@ -1375,6 +1399,10 @@ function Add-PodeStaticRouteGroup {
$DownloadOnly = $RouteGroup.DownloadOnly
}

if ($RouteGroup.RedirectToDefault) {
$RedirectToDefault = $RouteGroup.RedirectToDefault
}

if ($RouteGroup.IfExists -ine 'default') {
$IfExists = $RouteGroup.IfExists
}
Expand All @@ -1401,20 +1429,21 @@ function Add-PodeStaticRouteGroup {
}

$RouteGroup = @{
Path = $Path
Source = $Source
Middleware = $Middleware
EndpointName = $EndpointName
ContentType = $ContentType
TransferEncoding = $TransferEncoding
Defaults = $Defaults
ErrorContentType = $ErrorContentType
Authentication = $Authentication
Access = $Access
AllowAnon = $AllowAnon
DownloadOnly = $DownloadOnly
IfExists = $IfExists
AccessMeta = @{
Path = $Path
Source = $Source
Middleware = $Middleware
EndpointName = $EndpointName
ContentType = $ContentType
TransferEncoding = $TransferEncoding
Defaults = $Defaults
RedirectToDefault = $RedirectToDefault
ErrorContentType = $ErrorContentType
Authentication = $Authentication
Access = $Access
AllowAnon = $AllowAnon
DownloadOnly = $DownloadOnly
IfExists = $IfExists
AccessMeta = @{
Role = $Role
Group = $Group
Scope = $Scope
Expand Down

0 comments on commit df86e0f

Please sign in to comment.