File Server & Directory Browsing

Serve a directory tree with optional HTML listings and custom MIME mappings.

Prerequisites: see Introduction.

Full source

File: pwsh/tutorial/examples/3.2-File-Server.ps1

<#
    Sample Kestrun Server on how to configure a static file server.
    These examples demonstrate how to configure static routes with directory browsing in a Kestrun server.
    FileName: 3.2-File-Server.ps1
#>

param(
    [int]$Port = 5000,
    [IPAddress]$IPAddress = [IPAddress]::Loopback
)

# Initialize Kestrun root directory
# the default value is $PWD
# This is recommended in order to use relative paths without issues
Initialize-KrRoot -Path $PSScriptRoot

# Create a new Kestrun server
New-KrServer -Name "Simple Server"

# Add a listener on the configured port and IP address
Add-KrEndpoint -Port $Port -IPAddress $IPAddress

# Define the content type map to add to the default set
$map = @{
    ".yaml" = "application/x-yaml"
    ".yml" = "application/x-yaml"
    ".ps1" = "text/plain"
}

# Add a file server with browsing enabled
Add-KrFileServerMiddleware -RequestPath '/' -RootPath '.\Assets\wwwroot' -EnableDirectoryBrowsing -ContentTypeMap $map -Public -MaxAge 300 -mustRevalidate

# Enable Kestrun configuration
Enable-KrConfiguration


# Start the server asynchronously
Start-KrServer

Step-by-step

  1. Root initialization: Initialize-KrRoot ensures '.\Assets\wwwroot' is resolved relative to the script.
  2. Listener: same loopback listener as earlier samples.
  3. Content type mapping: A hashtable $map extends built‑in MIME mappings (e.g., adds YAML, forces .ps1 to text/plain so scripts display rather than download/execute).
  4. File server registration: Add-KrFileServer -RequestPath '/' ... -ContentTypeMap $map mounts the root of the hosted site and applies the custom provider.
  5. Directory browsing: -EnableDirectoryBrowsing renders an HTML listing when a request targets a directory without a default document.
  6. Start & serve: Enable-KrConfiguration then Start-KrServer activates the service.

File Server vs Static Files Service

Aspect Add-KrStaticFilesService Add-KrFileServer
Purpose Serve static files under a path prefix Serve files and optionally list directories
Directory listing Not built-in Supported via -EnableDirectoryBrowsing
Typical mount path A sub-path (e.g., /assets) Root (/) or sub-path needing browsing
Minimal configuration -RequestPath + -RootPath Same, plus optional browsing flag
Custom MIME map Via options object (advanced) Simple -ContentTypeMap hashtable parameter
Serve unknown types Flag available (-ServeUnknownFileTypes on options) -ServeUnknownFileTypes switch (use sparingly)
Use case Performance asset bundle File repository / docs / ad-hoc downloads / exploratory dirs

Choose Add-KrStaticFilesService for performance-focused asset hosting (no listing page). Choose Add-KrFileServer when you want users to navigate folders or you need a quick file drop.

Try it

Save the sample locally so it’s easy to run. Copy the contents of pwsh/tutorial/examples/3.2-File-Server.ps1 into a new file in an empty working folder (for example, file-server.ps1), then run:

# From your working folder
pwsh .\file-server.ps1

Browse:

Open http://127.0.0.1:5000/ in a browser. You should see an index (listing) including the sample files you created under Assets/wwwroot (e.g., /files/sample.txt, /files/data.json, images, docs, etc.). YAML files should now show Content-Type: application/x-yaml and .ps1 files as text/plain per the mapping.

Fetch examples (PowerShell):

Invoke-WebRequest -Uri 'http://127.0.0.1:5000/files/sample.txt' | Select-Object -ExpandProperty Content
Invoke-WebRequest -Uri 'http://127.0.0.1:5000/files/data.json' | Select-Object -ExpandProperty Content

Security considerations

  • Mount only directories intended for public access.
  • Exclude secrets/build artifacts from the root path.
  • For large directories disable browsing in production unless needed.

Troubleshooting

Symptom Cause Fix
404 for expected file Wrong path or root misconfigured Verify physical file exists under RootPath; check Initialize-KrRoot usage.
Directory listing not shown -EnableDirectoryBrowsing omitted Re-register service with the flag or add it.
Incorrect MIME type Unrecognized extension Add a custom mapping if supported or rename file with standard extension.
Access to parent dirs Attempt to traverse with .. Requests should be safely rooted; ensure latest version if traversal appears.

References


Previous / Next

Go back to Serving Static Files or continue to Static Route Overrides.