A lightweight C# web server that serves static files, markdown pages, and server-rendered <cs>...</cs> blocks.
- Serve HTTP content from a configurable content directory
- Optionally serve HTTPS using a local
.pfxcertificate - Auto-redirect all HTTP traffic to HTTPS when HTTPS is enabled
- Render markdown (
.md) as HTML - Execute server-side C# in
<cs>...</cs>blocks - Allow
<cs>scripts in HTML pages to access DOM nodes by id (GetById(...)) - Auto-create
config.yamlif it is missing - Expose
/healthendpoint (200 healthy)
Program.cs: app startup and service wiringConfigLoader.cs:config.yamlloading + defaults + HTTPS validation/fallbackWebServer.cs: HTTP listenerHttpsWebServer.cs: HTTPS listener (TLS 1.2/1.3)ContentService.cs: shared content serving logic for HTTP + HTTPSCsTagsParser.cs:<cs>parser + script execution globalsMarkdownParser.cs: markdown to HTML renderer
Configuration file: config.yaml
port: 8080
contentPath: ./content
https:
enabled: false
port: 8443
certificate:
path: ./certs/server.pfx
pass: change-me
pem:
usePem: false
certPath: ./certs/server.crt
keyPath: ./certs/server.key
keyPass: ""port: HTTP portcontentPath: directory to serve files fromhttps.enabled: enables HTTPS listener + HTTP→HTTPS redirectshttps.port: HTTPS porthttps.certificate.path: path to.pfxcertificate filehttps.certificate.pass:.pfxcertificate passwordhttps.certificate.pem.usePem: whentrue, load certificate from PEM files instead of.pfxhttps.certificate.pem.certPath: PEM certificate pathhttps.certificate.pem.keyPath: PEM private key pathhttps.certificate.pem.keyPass: encrypted PEM key password (empty if key is unencrypted)
If https.enabled: true but certificate config is invalid:
- Server logs a warning
- HTTPS is disabled automatically
- HTTP continues running (no crash)
Generate a local .pfx cert for this project:
mkdir -p certs
dotnet dev-certs https -ep ./certs/server.pfx -p change-meOptional (trust dev cert on your machine):
dotnet dev-certs https --trustUse matching config values:
https:
enabled: true
port: 8443
certificate:
path: ./certs/server.pfx
pass: change-me
pem:
usePem: false
certPath: ./certs/server.crt
keyPath: ./certs/server.key
keyPass: ""dotnet runThen browse:
- HTTP:
http://localhost:<port> - HTTPS:
https://localhost:<httpsPort>(if enabled)
Health check:
http://localhost:<port>/health
Serves files directly from contentPath with content-type mapping for common extensions.
.mdfiles are converted to HTML- Supports headings, lists, code fences, tables, blockquotes, inline code, emphasis, and horizontal rules
<cs> blocks are executed on the server and replaced with their output.
The original <cs> tags/code are never sent to clients.
NuGet packages can be pulled in dynamically from <cs> blocks with either
#r "nuget: PackageId, Version" or #:package PackageId@Version.
The parser resolves packages at runtime through the NuGet V3 feed, downloads
the package graph it needs, extracts it into a local staging cache, and adds
the managed assemblies before compiling the script. Use @* or omit the
version to ask for the latest available package version.
Current time: <cs>Now.ToString("yyyy-MM-dd HH:mm:ss")</cs><div id="time">Loading...</div>
<cs>
var el = GetById("time");
if (el is not null)
{
el.InnerHtml = $"Server time: {Now:yyyy-MM-dd HH:mm:ss}";
}
"";
</cs>NowUtcNowFilePathRequestPathDocument(HTML only)GetById(string id)(HTML only)
- Sending HTTPS traffic to the HTTP port is safely ignored as invalid HTTP input.
- HTTP redirect uses
308 Permanent Redirectwhen HTTPS is enabled.