Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/assets/[metadata].json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "example"
}
1 change: 1 addition & 0 deletions examples/public/[brackets].txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Brackets test file
28 changes: 24 additions & 4 deletions src/Private/Helpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,33 @@ function Get-PodeFileContent {
param(
[Parameter(Mandatory = $true)]
[string]
$Path
$Path,

[switch]
$NoEscape
)

$Path = Protect-PodePath -Path $Path -NoEscape:$NoEscape
return (Get-Content -Path $Path -Raw -Encoding utf8)
}

function Protect-PodePath {
param(
[Parameter()]
[string]
$Path,

[switch]
$NoEscape
)

if ($NoEscape -or [string]::IsNullOrEmpty($Path)) {
return $Path
}

return [WildcardPattern]::Escape($Path)
}

function Get-PodeType {
param(
[Parameter()]
Expand Down Expand Up @@ -1799,7 +1820,6 @@ function Test-PodePath {
catch {
$statusCode = 400
}

}

if ($statusCode -eq 200) {
Expand Down Expand Up @@ -2497,7 +2517,6 @@ function Get-PodeRelativePath {

[switch]
$TestPath

)

# if the path is relative, join to root if flagged
Expand All @@ -2517,7 +2536,8 @@ function Get-PodeRelativePath {

# if flagged, test the path and throw error if it doesn't exist
if ($TestPath -and !(Test-PodePath $Path -NoStatus)) {
throw ($PodeLocale.pathNotExistExceptionMessage -f (Protect-PodeValue -Value $Path -Default $_rawPath))#"The path does not exist: $(Protect-PodeValue -Value $Path -Default $_rawPath)"
# "The path does not exist: $(Protect-PodeValue -Value $Path -Default $_rawPath)"
throw ($PodeLocale.pathNotExistExceptionMessage -f (Protect-PodeValue -Value $Path -Default $_rawPath))
}

return $Path
Expand Down
43 changes: 35 additions & 8 deletions src/Private/Responses.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ The HTTP status code to accompany the response. Defaults to 200 (OK).
.PARAMETER Cache
A switch to indicate whether the response should include HTTP caching headers. Applies only to static content.

.PARAMETER NoEscape
If supplied, the path will not be escaped. This is useful for paths that contain expected wildcards, or are already escaped.

.EXAMPLE
Write-PodeFileResponseInternal -Path 'index.pode' -Data @{ Title = 'Home Page' } -ContentType 'text/html'

Expand All @@ -129,7 +132,6 @@ None. The function writes directly to the HTTP response stream.
.NOTES
This is an internal function and may change in future releases of Pode.
#>

function Write-PodeFileResponseInternal {
[CmdletBinding()]
param (
Expand Down Expand Up @@ -157,9 +159,15 @@ function Write-PodeFileResponseInternal {
$Cache,

[switch]
$FileBrowser
$FileBrowser,

[switch]
$NoEscape
)

# escape the path
$Path = Protect-PodePath -Path $Path -NoEscape:$NoEscape

# Attempt to retrieve information about the path
$pathInfo = Test-PodePath -Path $Path -Force -ReturnItem -FailOnDirectory:(!$FileBrowser)

Expand Down Expand Up @@ -238,6 +246,8 @@ serves the file directly.
.PARAMETER Path
The relative path to the directory that should be displayed. This path is resolved and used to generate a list of contents.

.PARAMETER NoEscape
If supplied, the path will not be escaped. This is useful for paths that contain expected wildcards, or are already escaped.

.EXAMPLE
# resolve for relative path
Expand All @@ -255,9 +265,16 @@ function Write-PodeDirectoryResponseInternal {
[Parameter(Mandatory = $true)]
[ValidateNotNull()]
[string]
$Path
$Path,

[switch]
$NoEscape
)

# escape the path
$Path = Protect-PodePath -Path $Path -NoEscape:$NoEscape

# Attempt to retrieve information about the path
if ($WebEvent.Path -eq '/') {
$leaf = '/'
$rootPath = '/'
Expand All @@ -268,9 +285,9 @@ function Write-PodeDirectoryResponseInternal {
$rootPath = $WebEvent.Path -ireplace "$($leaf)$", ''
}

# Determine if the server is running in Windows mode or is running a varsion that support Linux
# Determine if the server is running in Windows mode or is running a version that support Linux
# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-7.4#example-10-output-for-non-windows-operating-systems
$windowsMode = ((Test-PodeIsWindows) -or ($PSVersionTable.PSVersion -lt [version]'7.1.0') )
$windowsMode = ((Test-PodeIsWindows) -or ($PSVersionTable.PSVersion -lt [version]'7.1.0'))

# Construct the HTML content for the file browser view
$htmlContent = [System.Text.StringBuilder]::new()
Expand All @@ -281,6 +298,7 @@ function Write-PodeDirectoryResponseInternal {
[uri]::EscapeDataString($atom)
}
})

if ([string]::IsNullOrWhiteSpace($atoms)) {
$baseLink = ''
}
Expand Down Expand Up @@ -320,6 +338,7 @@ function Write-PodeDirectoryResponseInternal {
$htmlContent.Append($ParentLink)
$htmlContent.AppendLine("'>..</a></td> </tr>")
}

# Retrieve the child items of the specified directory
$child = Get-ChildItem -Path $Path -Force
foreach ($item in $child) {
Expand Down Expand Up @@ -369,9 +388,9 @@ function Write-PodeDirectoryResponseInternal {
}

$podeRoot = Get-PodeModuleMiscPath
# Write the response
Write-PodeFileResponseInternal -Path ([System.IO.Path]::Combine($podeRoot, 'default-file-browsing.html.pode')) -Data $Data

# Write the response
Write-PodeFileResponseInternal -Path ([System.IO.Path]::Combine($podeRoot, 'default-file-browsing.html.pode')) -Data $Data -NoEscape
}


Expand All @@ -392,6 +411,9 @@ The MIME type of the file being served. This is validated against a pattern to e
.PARAMETER FileBrowser
A switch parameter that, when present, enables directory browsing. If the path points to a directory and this parameter is enabled, the function will list the directory's contents instead of returning a 404 error.

.PARAMETER NoEscape
If supplied, the path will not be escaped. This is useful for paths that contain expected wildcards, or are already escaped.

.EXAMPLE
Write-PodeAttachmentResponseInternal -Path './files/document.pdf' -ContentType 'application/pdf'

Expand Down Expand Up @@ -419,10 +441,15 @@ function Write-PodeAttachmentResponseInternal {

[Parameter()]
[switch]
$FileBrowser
$FileBrowser,

[switch]
$NoEscape
)

# escape the path
$Path = Protect-PodePath -Path $Path -NoEscape:$NoEscape

# Attempt to retrieve information about the path
$pathInfo = Test-PodePath -Path $Path -Force -ReturnItem -FailOnDirectory:(!$FileBrowser)
if (!$pathInfo) {
Expand Down
45 changes: 25 additions & 20 deletions src/Private/Routes.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,23 @@ function Find-PodePublicRoute {
param(
[Parameter(Mandatory = $true)]
[string]
$Path
$Path,

[switch]
$NoEscape
)

$source = $null
$publicPath = $PodeContext.Server.InbuiltDrives['public']

# reutrn null if there is no public directory
# return null if there is no public directory
if ([string]::IsNullOrWhiteSpace($publicPath)) {
return $source
}

# escape characters in the path
$Path = Protect-PodePath -Path $Path -NoEscape:$NoEscape

# use the public static directory (but only if path is a file, and a public dir is present)
if (Test-PodePathIsFile $Path) {
$source = [System.IO.Path]::Combine($publicPath, $Path.TrimStart('/', '\'))
Expand Down Expand Up @@ -138,6 +144,9 @@ Optional. Specifies the name of the endpoint to which the route may belong. If n
.PARAMETER CheckPublic
A switch parameter. If specified, the function also checks for the route in public routes as a fallback option.

.PARAMETER NoEscape
If supplied, the path will not be escaped. This is useful for paths that contain expected wildcards, or are already escaped.

.EXAMPLE
$staticRoute = Find-PodeStaticRoute -Path '/images/logo.png' -CheckPublic

Expand Down Expand Up @@ -167,33 +176,34 @@ function Find-PodeStaticRoute {
$EndpointName,

[switch]
$CheckPublic
$CheckPublic,

[switch]
$NoEscape
)

# escape characters in the path
$Path = Protect-PodePath -Path $Path -NoEscape:$NoEscape

# attempt to get a static route for the path
$found = Find-PodeRoute -Method 'static' -Path $Path -EndpointName $EndpointName
$download = ([bool]$found.Download)
$download = [bool]$found.Download
$source = $null
$isDefault = $false
$redirectToDefault = ([bool]$found.RedirectToDefault)
$redirectToDefault = [bool]$found.RedirectToDefault

# if we have a defined static route, use that
if ($null -ne $found) {
# see if we have a file
$file = [string]::Empty
$matchingPath = "$($found.Path.Replace('*', '.+?'))$"

if ($found.KleeneStar) {
$matchingPath = "$($found.Path -ireplace '.\*', '.+?')$"
}
else {
$matchingPath = "$($found.Path)$"
}
if ($Path -imatch $matchingPath) {
$file = (Protect-PodeValue -Value $Matches['file'] -Default ([string]::Empty))
}

# if $file doesn't exist return $null
$fileInfo = Get-Item -Path ([System.IO.Path]::Combine($found.Source, $file)) -Force -ErrorAction Ignore
#if $file doesn't exist return $null
if ($null -eq $fileInfo) {
return $null
}
Expand All @@ -209,8 +219,8 @@ function Find-PodeStaticRoute {
}
}
}
$source = [System.IO.Path]::Combine($found.Source, $file)

$source = [System.IO.Path]::Combine($found.Source, $file)
}

# check public, if flagged
Expand All @@ -228,12 +238,7 @@ function Find-PodeStaticRoute {
}

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

return @{
Content = @{
Expand Down Expand Up @@ -368,7 +373,7 @@ function Get-PodeRouteByUrl {
return $null
}


<#
.SYNOPSIS
Updates a Pode route path to ensure proper formatting.
Expand Down
Loading