What is cshttp

What is cshttp?

cshttp is a small, fast, zero-dependency web server for C#, written in pure C# 7.3, that you embed in your own program.

It ships as a single DLL (~105 KB) that runs unchanged on .NET Framework 4.8 and .NET 8 / 9 / 10+. You don't need IIS, the ASP.NET Core runtime or any NuGet packages. Reference the DLL (or drop in the source files), call WebApp.Run, and your program is a web server.

using cshttp;

static class Program
{
    static void Main() => WebApp.Run(8080, OnRequest);

    static void OnRequest()
    {
        switch (Request.Path.ToLower())
        {
            case "/":
                Response.Write("<h1>Hello from cshttp!</h1>");
                break;
            default:
                Response.StatusCode = 404;
                Response.Write("404 Not Found");
                break;
        }
    }
}

Run it, open http://localhost:8080/, and the site is live.


The idea in one sentence

cshttp gives C# the classic, synchronous Request / Response programming model from ASP.NET System.Web, inside a self-contained .exe, built on top of a strict and secure HTTP/1.1 engine.

Why it exists

C# developers who wanted to serve HTTP have usually had to pick one of these:

  • A whole framework: ASP.NET on IIS, or ASP.NET Core with Kestrel, dependency injection, middleware and async everywhere.
  • HttpListener, which is tied to Windows http.sys.
  • A hand-written parser, which tends to break on chunked bodies or multipart uploads and is open to request smuggling.

cshttp is a fourth option. Like llhttp in C, httparse in Rust or net/http in Go, it's a compact HTTP stack whose layers are explicit and can be used separately. Its handler code is plain, synchronous C#: a switch on the path, read Request.Form, call Response.Write.

What's inside: three layers in one DLL

┌───────────────────────────────────────────────────────────┐
│                  Your C# application code                 │
│          (a switch router + synchronous handlers)         │
└─────────────────────────────┬─────────────────────────────┘
┌─────────────────────────────▼─────────────────────────────┐
│ Server/  cshttp.server: the standalone server             │
│   TCP/TLS listener, keep-alive, timeouts, graceful stop   │
├───────────────────────────────────────────────────────────┤
│ Web/     cshttp.web: the Request/Response toolkit         │
│   HttpContext, QueryString, Form, Files, Cookies,         │
│   StaticFiles, MapPath, HttpUtility                       │
├───────────────────────────────────────────────────────────┤
│ Core/    cshttp.core: the HTTP/1.1 wire engine            │
│   byte-level parser, chunked decoder, response writer     │
└───────────────────────────────────────────────────────────┘

All three layers share one namespace, cshttp. Each layer depends only on the layers below it, so you can use just the part you need.

LayerWhat it doesUse it alone when…
Core: wire engineTurns raw bytes into a validated request head and writes response heads back to bytes. Follows RFC 9112. Does no socket I/O, uses no regex, allocates nothing until a full header block has arrived, and blocks request smuggling and header injection.You're building a proxy, gateway, traffic inspector or custom socket loop and need correct HTTP framing only.
Web: content toolkitThe System.Web-style object model: HttpContext.Current, HttpRequest, HttpResponse, cookies, multipart file uploads, HttpUtility, cache headers and secure static file serving with ETag, 304 and byte ranges. Parses everything lazily, so you only pay for what you touch.You want the familiar handler API over your own transport, or you want to unit-test handlers in memory without opening a port.
Server: standalone serverA production HTTP/1.1 + HTTPS server. Idle keep-alive connections wait on OS completion ports and hold zero threads. Active requests run synchronously on worker threads, with no async/await in your code. Includes Slowloris defense, trusted-proxy (X-Forwarded-*) support and graceful shutdown.You're building a complete web app, API, admin UI or dashboard that runs as an .exe or service on Windows or Linux.

Deep dives: Tier 1: Core · Tier 2: Web · Tier 3: Server · Structure Overview

What writing an app looks like

If you've used classic ASP.NET, you already know the API:

You want to…You write…
Route by URLswitch (Request.Path.ToLower())
Read query / form valuesRequest.QueryString["q"], Request.Form["name"], Request["key"]
Read a raw body (JSON, binary)Request.BodyText, Request.BodyBytes, Request.InputStream
Handle file uploadsRequest.Files["avatar"].SaveAs(...)
Use cookiesRequest.Cookies["id"], Response.Cookies.Add(...)
Send outputResponse.Write(...), Response.BinaryWrite(...), Response.StatusCode = 404
Send files / static foldersResponse.TransmitFile(path), StaticFiles.TryServe(ctx, "/css/", "css")
RedirectResponse.Redirect("/home")
Resolve paths safelyWebApp.MapPath("~/App_Data/app.db")
Encode output safelyWebApp.HtmlEncode(...), WebApp.UrlEncode(...)
Run tracked background workWebApp.BackgroundWork(ct => { ... })

cshttp follows System.Web's names and shapes but doesn't copy all of it. Web Forms, Session, HTTP modules and built-in authentication are out of scope.

How fast is it?

In the project's stress test (Intel i7-4770S, 4 cores, with 1,500 idle keep-alive connections plus 50 active clients), cshttp.server handled about 62,000 requests/sec on .NET 10 and 50,000 requests/sec on .NET Framework 4.8, with a p99 latency of about 6 ms. The 1,500 idle connections added only one OS thread. See the Benchmark Report.

Where cshttp fits

Good fit:

  • Self-contained web apps and REST APIs shipped as a single .exe or Windows/Linux service
  • Embedded admin UIs or dashboards inside desktop apps, services, games and tools
  • Porting simple ASP.NET System.Web handlers off IIS
  • Learning web development from first principles (see the 14-day tutorial on Tutorial)
  • Behind Nginx in production: Nginx handles TLS and static files, cshttp handles dynamic routes

Not what it is:

  • Not an MVC/Razor framework, DI container or middleware pipeline
  • Not HTTP/2 or HTTP/3. cshttp speaks HTTP/1.1, and a reverse proxy like Nginx can serve HTTP/2 to clients.

Getting it

  1. Starter pack: download cshttp-starter-pack.zip from Releases, unzip and run.
  2. DLL reference: add cshttp.dll to your project.
  3. Source inclusion: copy the Core/, Web/ and Server/ folders into your solution.

License

Public domain (The Unlicense). Free for any commercial or non-commercial use.