CosmoApiServer.Core 1.4.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package CosmoApiServer.Core --version 1.4.2
                    
NuGet\Install-Package CosmoApiServer.Core -Version 1.4.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CosmoApiServer.Core" Version="1.4.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CosmoApiServer.Core" Version="1.4.2" />
                    
Directory.Packages.props
<PackageReference Include="CosmoApiServer.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CosmoApiServer.Core --version 1.4.2
                    
#r "nuget: CosmoApiServer.Core, 1.4.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CosmoApiServer.Core@1.4.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CosmoApiServer.Core&version=1.4.2
                    
Install as a Cake Addin
#tool nuget:?package=CosmoApiServer.Core&version=1.4.2
                    
Install as a Cake Tool

CosmoApiServer

A high-performance, zero-dependency HTTP server framework for .NET 10, built entirely on System.IO.Pipelines and System.Net.Sockets.

No DotNetty. No ASP.NET. No Kestrel. Just raw sockets → pipes → your handlers.


Benchmark

ApacheBench · c=50 concurrent · n=5,000 requests · keep-alive · macOS arm64

Scenario CosmoApiServer ASP.NET Core Kestrel Advantage
GET /ping 53,159 req/s 17,053 req/s +212%
GET /items (20-item list) 42,752 req/s 15,759 req/s +171%
POST /echo (JSON body) 54,624 req/s 17,943 req/s +204%

Zero failed requests. Performance holds at c=200 (53,874 req/s).


Why so fast?

Traditional .NET HTTP servers (including Kestrel and DotNetty-based servers) have at least one thread-pool context switch per request. CosmoApiServer eliminates this:

Socket → PipeWriter → PipeReader → Parser → Middleware → PipeWriter → Socket

Everything runs inline on the connection task. No EventLoop→ThreadPool hand-off. No intermediate byte arrays. No string allocation on the hot path.

Key design decisions:

  • Zero-copy parsingHttp11Parser uses SequenceReader<byte> directly over the pipe buffer; no string.Split, no intermediate byte[].
  • Lazy headersParsedHeaderDict wraps the raw parsed header list; the backing dictionary is only materialised if your code iterates all headers.
  • Lazy DI scopeLazyScopeProvider only calls IServiceProvider.CreateScope() if a service is actually resolved.
  • Span-based routingRouteTemplate.TryMatch() walks path segments with ReadOnlySpan<char>, no heap allocation for parameterless routes.
  • Pre-computed CORS stringsAllow-Methods / Allow-Headers values are built once at startup.
  • Content-Length cache — small integer → ASCII string is cached to avoid per-request allocation.

Features

  • HTTP/1.1 keep-alive (pipelined)
  • HTTP/2 (h2c cleartext + ALPN over TLS)
  • TLS via SslStream with ALPN (h2 / http/1.1)
  • Attribute-based controllers ([HttpGet], [HttpPost], [Route], [Authorize])
  • Convention-based routing (MapGet, MapPost, …)
  • Route parameters (/items/{id})
  • Query string parsing
  • JSON request/response (WriteJson, ReadJson<T>)
  • IAsyncEnumerable<T> → NDJSON streaming response
  • Middleware pipeline (UseLogging, UseCors, UseJwtAuthentication, custom IMiddleware)
  • Dependency injection (Microsoft.Extensions.DependencyInjection)
  • JWT authentication ([Authorize], HttpContext.User)
  • CORS with pre-computed headers
  • IPv4 + IPv6 dual-stack
  • WebSockets (HttpContext.AcceptWebSocketAsync())
  • Multipart Form Data parsing
  • OpenAPI & Swagger UI auto-generation
  • Rate Limiting, Static Files, Response Compression
  • Security Middlewares (CSRF, HSTS, HTTPS Redirection)
  • Model Validation via DataAnnotations
  • Global Exception Handling

Quick Start

dotnet new console -n MyApp
cd MyApp
dotnet add reference /path/to/src/CosmoApiServer.Core/CosmoApiServer.Core.csproj

Hello World

using CosmoApiServer.Core.Hosting;

var app = CosmoWebApplicationBuilder.Create()
    .ListenOn(8080)
    .Build();

app.MapGet("/hello", async ctx =>
    ctx.Response.WriteJson(new { message = "Hello, World!" }));

app.Run();

With middleware, DI, and controllers

using CosmoApiServer.Core.Hosting;
using Microsoft.Extensions.DependencyInjection;

var builder = CosmoWebApplicationBuilder.Create()
    .ListenOn(8080)
    .UseLogging()
    .UseCors()
    .UseJwtAuthentication(opts =>
    {
        opts.SecretKey = "your-secret-key-32-chars-minimum!";
        opts.Issuer    = "my-app";
        opts.Audience  = "my-app";
    })
    .AddControllers();   // scans current assembly for [HttpGet]/[HttpPost] controllers

builder.Services.AddSingleton<IMyService, MyService>();

var app = builder.Build();

app.MapGet("/health", async ctx =>
    ctx.Response.WriteJson(new { status = "ok" }));

app.Run();

TLS + HTTP/2

var app = CosmoWebApplicationBuilder.Create()
    .ListenOn(8443)
    .UseHttps("./certs/server.pfx", "changeme")
    .UseHttp2()          // enables ALPN h2/http1.1 negotiation
    .Build();

app.Run();

Routing

Convention routing

app.MapGet("/",              async ctx => { ... });
app.MapGet("/items/{id}",    async ctx =>
{
    var id = ctx.Request.RouteValues["id"];
    var q  = ctx.Request.Query["filter"];   // query string
    ctx.Response.WriteJson(new { id, q });
});
app.MapPost("/items",        async ctx => { ... });
app.MapPut("/items/{id}",    async ctx => { ... });
app.MapDelete("/items/{id}", async ctx => { ... });
app.MapPatch("/items/{id}",  async ctx => { ... });

Attribute-based controllers

using CosmoApiServer.Core.Controllers;

[Route("/api/products")]
public class ProductController
{
    private readonly IProductService _svc;
    public ProductController(IProductService svc) => _svc = svc;

    [HttpGet("")]
    public async Task<IEnumerable<Product>> GetAll() =>
        await _svc.GetAllAsync();

    [HttpGet("{id}")]
    public async Task<Product?> GetById(int id) =>
        await _svc.GetByIdAsync(id);

    [HttpPost("")]
    [Authorize]
    public async Task<Product> Create([FromBody] CreateProductRequest req) =>
        await _svc.CreateAsync(req);

    [HttpDelete("{id}")]
    [Authorize]
    public async Task Delete(int id) =>
        await _svc.DeleteAsync(id);
}

// DataAnnotations are automatically validated for [FromBody] requests
public class CreateProductRequest
{
    [Required]
    [StringLength(100, MinimumLength = 3)]
    public string Name { get; set; } = string.Empty;

    [Range(0.01, 10000)]
    public decimal Price { get; set; }
}

Supported action return types:

Return type Behaviour
void / Task 200 OK, empty body
T / Task<T> 200 OK, JSON-serialised
IActionResult status + body determined by result
IAsyncEnumerable<T> 200 OK, chunked NDJSON stream

Request & Response API

// Request
string path       = ctx.Request.Path;
HttpMethod method = ctx.Request.Method;
string? header    = ctx.Request.Headers["Content-Type"];
string? query     = ctx.Request.Query["page"];
string? routeVal  = ctx.Request.RouteValues["id"];
byte[]  body      = ctx.Request.Body;
T?      obj       = ctx.Request.ReadJson<T>();

// Response
ctx.Response.StatusCode = 201;
ctx.Response.Headers["X-Custom"] = "value";
ctx.Response.WriteText("plain text");
ctx.Response.WriteJson(new { id = 1 });
ctx.Response.WriteBytes(bytes, "application/octet-stream");

// User (JWT, set by UseJwtAuthentication)
ClaimsPrincipal? user = ctx.User;
string? userId        = ctx.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;

Middleware

Built-in middleware

Method Effect
.UseLogging() Logs method, path, status, duration for every request
.UseExceptionHandler() Catches unhandled exceptions and returns 500
.UseStaticFiles(path) Serves files from the specified directory
.UseCors(opts) Adds CORS headers; handles OPTIONS preflight
.UseRateLimiting(opts) Throttles requests based on IP/token
.UseCsrf(opts) Validates CSRF tokens
.UseHttpsRedirection() Redirects HTTP traffic to HTTPS
.UseHsts(opts) Adds HTTP Strict Transport Security header
.UseResponseCompression() Gzip/Deflate response compression
.UseOpenApi(path) Auto-generates and serves OpenAPI JSON
.UseSwaggerUI(path) Hosts Swagger UI for the OpenAPI spec
.UseJwtAuthentication(opts) Validates Bearer token; sets ctx.User

Custom middleware

using CosmoApiServer.Core.Middleware;

public class TimingMiddleware : IMiddleware
{
    public async Task InvokeAsync(HttpContext ctx, RequestDelegate next)
    {
        var sw = Stopwatch.StartNew();
        await next(ctx);
        ctx.Response.Headers["X-Elapsed-Ms"] = sw.ElapsedMilliseconds.ToString();
    }
}

// Register
builder.UseMiddleware(new TimingMiddleware());

Streaming with IAsyncEnumerable

Return IAsyncEnumerable<T> from a controller action to stream NDJSON line-by-line:

[HttpGet("stream")]
public async IAsyncEnumerable<Product> StreamAll()
{
    await foreach (var product in _svc.GetAllStreamingAsync())
        yield return product;
}

The transport writes chunked transfer-encoding (HTTP/1.1) or DATA frames (HTTP/2) automatically. The connection closes after the stream completes.


JWT Authentication

// Configure
builder.UseJwtAuthentication(opts =>
{
    opts.SecretKey = "your-32-char-minimum-secret-key!";
    opts.Issuer    = "my-app";
    opts.Audience  = "my-app";
    opts.ExpiryMinutes = 60;
});

// Issue a token (in a login controller)
[HttpPost("")]
[Route("/auth/login")]
public IActionResult Login([FromBody] LoginRequest req)
{
    if (!_authService.Validate(req.Username, req.Password))
        return new StatusCodeResult(401);

    var claims = new[] { new Claim(ClaimTypes.NameIdentifier, req.Username) };
    var token  = JwtTokenHelper.Generate(claims, _jwtOptions);
    return new JsonResult(new { token });
}

// Protect a route
[HttpGet("")]
[Route("/api/me")]
[Authorize]
public object GetMe(ClaimsPrincipal user) =>
    new { id = user.FindFirst(ClaimTypes.NameIdentifier)?.Value };

WebSockets

CosmoApiServer provides built-in, low-allocation WebSocket support. Call ctx.AcceptWebSocketAsync() to upgrade an HTTP connection.

app.MapGet("/ws", async ctx =>
{
    if (!ctx.IsWebSocketRequest)
    {
        ctx.Response.StatusCode = 400;
        return;
    }

    using var ws = await ctx.AcceptWebSocketAsync();
    
    // Send a message
    var msg = Encoding.UTF8.GetBytes("Hello WebSocket!");
    await ws.SendAsync(msg, WebSocketMessageType.Text, endOfMessage: true);

    // Close
    await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Done");
});

Multipart Form Data

Parse multipart/form-data uploads directly from the request body.

using CosmoApiServer.Core.Http;

[HttpPost("/upload")]
public IActionResult Upload(HttpContext ctx)
{
    var form = MultipartParser.Parse(ctx.Request);
    
    var description = form.Fields.GetValueOrDefault("description");
    if (form.Files.TryGetValue("document", out var file))
    {
        // file.Filename, file.ContentType, file.Data (byte[])
        File.WriteAllBytes($"/tmp/{file.Filename}", file.Data);
    }
    
    return new StatusCodeResult(200);
}

OpenAPI & Swagger UI

Generate an openapi.json spec automatically from your [Route], [HttpGet], and [HttpPost] controllers and host Swagger UI:

var builder = CosmoWebApplicationBuilder.Create()
    .ListenOn(8080)
    .UseOpenApi(configure: info => 
    {
        info.Title = "My API";
        info.Version = "v1";
    })
    .UseSwaggerUI("/swagger") // Access at http://localhost:8080/swagger
    .AddControllers();

var app = builder.Build();
app.Run();

Architecture

CosmoApiServer.Core
├── Transport/
│   ├── PipelineHttpServer.cs   TCP accept loop (Socket.AcceptAsync)
│   │                           TLS via SslStream, ALPN h2/http1.1
│   ├── Http11Connection.cs     Per-connection HTTP/1.1 keep-alive loop
│   │                           h2c preface detection → Http2Connection
│   ├── Http11Parser.cs         Zero-alloc parser (SequenceReader<byte>)
│   ├── Http11Writer.cs         Response writer direct to PipeWriter
│   ├── Http2Connection.cs      HTTP/2 frame dispatch + stream multiplexing
│   ├── HpackDecoder.cs         RFC 7541 HPACK + Huffman codec
│   └── StreamingBodyWriter.cs  IAsyncEnumerable → NDJSON chunked stream
├── Hosting/
│   ├── CosmoWebApplicationBuilder.cs   Fluent builder (services, options)
│   └── CosmoWebApplication.cs          Wires middleware + starts server
├── Middleware/
│   ├── MiddlewarePipeline.cs
│   ├── RouterMiddleware.cs
│   ├── LoggingMiddleware.cs
│   ├── CorsMiddleware.cs
│   └── JwtMiddleware.cs
├── Controllers/
│   └── ControllerScanner.cs    Reflection-based attribute controller scan
├── Routing/
│   ├── RouteTable.cs           Method-keyed O(1) route lookup
│   └── RouteTemplate.cs        Span-based path matching
├── Auth/
│   └── JwtTokenHelper.cs
└── Http/
    ├── HttpContext.cs
    ├── HttpRequest.cs
    ├── HttpResponse.cs
    └── HttpMethod.cs

Projects in this repository

Project Description
src/CosmoApiServer.Core Core framework library
src/CosmoS3 Amazon S3–compatible object storage built on CosmoApiServer
samples/HelloWorldSample Minimal hello world + controller demo
samples/WeatherApp Full REST API: JWT auth, DI, streaming, CosmoSQLClient
samples/CosmoS3Host Standalone CosmoS3 server host
samples/CosmoApiBenchHost Benchmark server (port 9001)
samples/AspNetBenchHost ASP.NET Core equivalent for comparison (port 9002)
tests/CosmoApiServer.Core.Tests Unit tests for routing, middleware, JWT
tests/CosmoS3.Tests S3 integration tests (requires running CosmoS3Host)
tests/ApiServer.Benchmark Sequential HTTP benchmark tool

Dependencies

CosmoApiServer.Core has two NuGet dependencies:

Package Purpose
Microsoft.Extensions.DependencyInjection DI container
System.IdentityModel.Tokens.Jwt JWT validation / issuance

Everything else — HTTP parsing, TLS, HTTP/2, HPACK, routing, middleware — is implemented in-repo using only .NET 10 BCL types (System.IO.Pipelines, System.Net.Sockets, System.Buffers).


  • CosmoS3 — Amazon S3–compatible middleware built on CosmoApiServer
  • CosmoSQLClient — Zero-dependency SQL client (SQL Server, PostgreSQL, MySQL, SQLite) used by WeatherApp and CosmoS3
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on CosmoApiServer.Core:

Package Downloads
CosmoS3

Amazon S3-compatible object storage server built on CosmoApiServer.Core.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.1 128 3/26/2026
2.0.0 92 3/24/2026
1.8.8 83 3/19/2026
1.8.7 82 3/19/2026
1.8.6 98 3/19/2026
1.8.5 77 3/19/2026
1.8.4 79 3/19/2026
1.8.3 78 3/19/2026
1.8.2 77 3/19/2026
1.8.1 87 3/18/2026
1.8.0 76 3/18/2026
1.7.0 118 3/17/2026
1.6.3 92 3/17/2026
1.6.2 142 3/16/2026
1.6.1 88 3/14/2026
1.6.0 103 3/9/2026
1.5.0 83 3/9/2026
1.4.4 92 3/8/2026
1.4.3 77 3/8/2026
1.4.2 77 3/8/2026
Loading failed