|
1 | 1 | # Yllibed HttpServer |
2 | 2 |
|
3 | | -This is a versatile http server designed to be used in mobile/UWP applications and any applications which need to expose a simple web server. |
| 3 | + |
4 | 4 |
|
5 | | -## Packages and NuGet Statistics |
| 5 | +A small, self-contained HTTP server for desktop, mobile, and embedded apps that need to expose a simple web endpoint. |
6 | 6 |
|
7 | | -| Package | Downloads | Stable Version | Pre-release Version | |
8 | | -|-------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------| |
9 | | -| [**HttpServer**](https://www.nuget.org/packages/Yllibed.HttpServer/) |  |  |  | |
10 | | -| [**HttpServer.Json**](https://www.nuget.org/packages/Yllibed.HttpServer.Json/) |  |  |  | |
| 7 | +- Lightweight, no ASP.NET dependency |
| 8 | +- Great for OAuth2 redirect URIs, diagnostics, and local tooling |
| 9 | +- IPv4/IPv6, HTTP/1.1, custom handlers, static files, and SSE |
11 | 10 |
|
12 | | -## Quick start-up |
| 11 | +--- |
| 12 | + |
| 13 | +## Packages and NuGet |
| 14 | + |
| 15 | +| Package | Downloads | Stable | Pre-release | |
| 16 | +|---|---|---|---| |
| 17 | +| [Yllibed.HttpServer](https://www.nuget.org/packages/Yllibed.HttpServer/) |  |  |  | |
| 18 | +| [Yllibed.HttpServer.Json](https://www.nuget.org/packages/Yllibed.HttpServer.Json/) |  |  |  | |
| 19 | + |
| 20 | +--- |
| 21 | + |
| 22 | +## Quick start |
13 | 23 |
|
14 | 24 | 1. First install nuget package: |
15 | 25 | ```shell |
@@ -49,36 +59,44 @@ This is a versatile http server designed to be used in mobile/UWP applications a |
49 | 59 | ``` |
50 | 60 |
|
51 | 61 | ## What it is |
52 | | -* Simple web server which can be extended using custom code |
53 | | -* No dependencies on ASP.NET or other frameworks, self-contained |
| 62 | + |
| 63 | +- Simple web server that can be extended with custom code |
| 64 | +- No dependencies on ASP.NET or other frameworks; fully self-contained |
| 65 | +- Intended for small apps and utilities (e.g., OAuth2 redirect URL from an external browser) |
54 | 66 |
|
55 | 67 | ## What it is not |
56 | | -* This HTTP server is not designed for performance or high capacity |
57 | | -* It's perfect for small applications, or small need, like to act as _return url_ for OAuth2 authentication using external browser. |
| 68 | + |
| 69 | +- NOT designed for high performance or high concurrency |
| 70 | +- NOT appropriate for public-facing web services |
| 71 | +- NOT a full-featured web framework (no MVC, no Razor, no routing, etc.) |
| 72 | +- NOT a replacement for ASP.NET Core or Kestrel |
58 | 73 |
|
59 | 74 | ## Features |
60 | | -* Simple, lightweight, self-contained HTTP server |
61 | | -* Supports IPv4 and IPv6 |
62 | | -* Supports HTTP 1.1 (limited: no keep-alive, no chunked encoding) |
63 | | -* Supports GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, PATCH - even custom methods |
64 | | -* Supports static files |
65 | | -* Supports custom headers |
66 | | -* Supports custom status codes |
67 | | -* Supports custom content types |
68 | | -* Supports custom content encodings |
69 | | -* Supports dependency injection and configuration via `IOptions<ServerOptions>` |
70 | | -* Configurable bind addresses and hostnames for IPv4/IPv6 |
71 | | -* Supports dynamic port assignment |
| 75 | + |
| 76 | +- Simple, lightweight, self-contained HTTP server |
| 77 | +- Supports IPv4 and IPv6 |
| 78 | +- Supports HTTP 1.1 (limited: no keep-alive, no chunked encoding) |
| 79 | +- Allows any HTTP method (GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, PATCH, custom). Handlers decide how to handle them. |
| 80 | +- Simple static responses via StaticHandler (no built-in file/directory serving) |
| 81 | +- Supports custom headers |
| 82 | +- Supports custom status codes |
| 83 | +- Supports custom content types |
| 84 | +- Arbitrary response headers (incl. Content-Encoding); no automatic compression/encoding |
| 85 | +- Supports dependency injection and configuration via `IOptions<ServerOptions>` |
| 86 | +- Configurable bind addresses and hostnames for IPv4/IPv6 |
| 87 | +- Supports dynamic port assignment |
72 | 88 |
|
73 | 89 | ## Common use cases |
74 | | -* Return URL for OAuth2 authentication using external browser |
75 | | -* Remote diagnostics/monitoring on your app |
76 | | -* Building a headless Windows IoT app (for SSDP discovery or simply end-user configuration) |
77 | | -* Any other use case where you need to expose a simple web server |
| 90 | + |
| 91 | +- Return URL for OAuth2 authentication using external browser |
| 92 | +- Remote diagnostics/monitoring on your app |
| 93 | +- Building a headless Windows IoT app (for SSDP discovery or simply end-user configuration) |
| 94 | +- Any other use case where you need to expose a simple web server |
78 | 95 |
|
79 | 96 | ## Limitations |
80 | | -* There is no support for HTTP 2.0+ (yet) or WebSockets |
81 | | -* There is no support for HTTPS (TLS) |
| 97 | + |
| 98 | +- There is no support for HTTP/2+ (yet) or WebSockets |
| 99 | +- There is no support for HTTPS (TLS) |
82 | 100 |
|
83 | 101 | ## Security and Intended Use (No TLS) |
84 | 102 | This server uses plain HTTP with no transport encryption. It is primarily intended for: |
@@ -312,11 +330,11 @@ public sealed class SseDemoHandler : IHttpHandler |
312 | 330 |
|
313 | 331 | // Usage during startup |
314 | 332 | var server = new Server(); |
315 | | -var ssePath = new RelativePathHandler("/"); |
| 333 | +var ssePath = new RelativePathHandler("/updates"); |
316 | 334 | ssePath.RegisterHandler(new SseDemoHandler()); |
317 | 335 | server.RegisterHandler(ssePath); |
318 | 336 | var (uri4, _) = server.Start(); |
319 | | -Console.WriteLine($"SSE endpoint: {uri4}/sse"); |
| 337 | +Console.WriteLine($"SSE endpoint: {uri4}/updates/sse"); |
320 | 338 | ``` |
321 | 339 |
|
322 | 340 | SseHandler convenience base class: |
@@ -348,14 +366,14 @@ Client-side (browser): |
348 | 366 | ``` |
349 | 367 |
|
350 | 368 | Notes: |
351 | | -- Heartbeats: send a comment frame (": keepalive\n\n") every 15–30s to prevent proxy timeouts. |
| 369 | +- Heartbeats: send a comment frame (`: keepalive\n\n`) every 15–30s to prevent proxy timeouts. |
352 | 370 | - Long-running streams: handle CancellationToken to stop cleanly when the client disconnects. |
353 | 371 | - Browser connection limits: most browsers cap concurrent HTTP connections per hostname (often 6–15). Without HTTP/2 multiplexing, a single client cannot keep many SSE connections in parallel; this server is not intended for a large number of per-client connections. |
354 | 372 | - Public exposure: there is no TLS; prefer localhost or internal networks, or place behind a TLS-terminating reverse proxy. |
355 | 373 |
|
356 | 374 |
|
357 | 375 | ### SSE Spec and Interop Notes |
358 | | -- Accept negotiation: If a client sends an Accept header that explicitly excludes SSE (text/event-stream), the default SseHandler will reply 406 Not Acceptable. The following values are considered acceptable: text/event-stream, text/*, or */*. If no Accept header is present, requests are accepted. You can override this behavior by overriding ShouldHandle in your handler. |
| 376 | +- Accept negotiation: If a client sends an Accept header that explicitly excludes SSE (text/event-stream), the default SseHandler will reply 406 Not Acceptable. The following values are considered acceptable: text/event-stream, text/*, or */*. If no Accept header is present, requests are accepted. You can override this behavior by overriding ValidateHeaders in your handler (ShouldHandle is for method/path filtering). |
359 | 377 | - Last-Event-ID: When a client reconnects, browsers may send a Last-Event-ID header. It is exposed via ISseSession.LastEventId so you can resume from the last delivered event. Set the id parameter in SendEventAsync to help clients keep position. |
360 | 378 | - Heartbeats: You can configure periodic comment frames via SseOptions.HeartBeatInterval; this keeps intermediaries from timing out idle connections. |
361 | 379 | - Framing: The server uses CRLF (\r\n) in headers and LF (\n) in the SSE body as recommended by typical SSE implementations. Data payloads are normalized to LF before framing each data: line. Each event ends with a blank line. |
|
0 commit comments