From powering the old-future of AOL and to the new-future of now, fantastically done! From myself and I'm sure others too; many kudos to you Gustaf and NaviServer!
I also wanted to send praise this way as I've recently started a new job. Today where I needed to setup an PXE/KickStart server, after messing with the de-facto standard of Apache it failed in revealing hidden files (.treeinfo in this case). This too is with (no) help from certain ML-Bots. Testing Lighttpd ish-worked which is another old favorite of mine also failed the task. (I realized after it was missing the mime type) I threw up NaviServer & Tcl, applied the "hide dotfiles = false" parameter to the out-of-box simple configuration file and low & behold the studio now has a working kickstart system for Linux powered by NaviServer. It's not much but it puts me in the good books and I now I have Tcl available at my paws too. Lesson learnt, I should of jumped straight to NaviServer! All the best, David F -----Original Message----- From: Gustaf <[email protected]> To: naviserver-devel <[email protected]> Date: Friday, 12 September 2025 7:10 PM BST Subject: [naviserver-devel] NaviServer and HTTP/3 Dear all, you may have noticed that I have been rather quiet over the last weeks. Some emails and pull requests are still waiting for feedback from me - the reason is that I have been fully absorbed with adding HTTP/3 support to NaviServer. A week ago, I managed to serve a simple curl GET request over HTTP/3 from NaviServer. Today, for the first time, I was able to load the OpenACS start page via HTTP/3 — including many parallel streams and a POST request (see “Protocol” column).  To give some background on why this effort matters: HTTP/3 is a very different animal compared to HTTP/1.x. It is built on top of QUIC, a UDP-based transport protocol originally developed by Google and later standardized by the IETF. QUIC integrates TLS 1.3, multiplexed bidirectional and unidirectional streams, flow control, and loss recovery directly into the transport layer. This avoids head-of-line blocking, enables faster connection establishment (including 0-RTT resumption), and even allows connections to survive client IP changes (e.g., Wi-Fi <-> mobile). The relevant RFCs were finalized in 2021–2022: • RFC 9000: QUIC Transport • RFC 9001: QUIC + TLS • RFC 9002: QUIC Loss Detection and Congestion Control • RFC 9114: HTTP/3 • RFC 9204: QPACK (Header Compression for HTTP/3) Cloudflare was one of the earliest providers of HTTP/3 starting in 2021. nginx added support in 2023, while Apache still lacks native support. All major browsers can support HTTP/3 today, though deployment is not yet universal. Integration into NaviServer Adding HTTP/3 support required adapting NaviServer’s C-level APIs, because the QUIC stack provided by OpenSSL 3.5+ introduces a different threading model (e.g., using SSL_poll()). To handle this, NaviServer must allow drivers with their own event loop. The new h3 module provides this driver, while still reusing the nsssl configuration for ports, certificates, etc. As long as the new module is not loaded, existing HTTPS setups will continue to work unchanged. At the moment, HTTP/3 is implemented as an extra module linked via configuration to nsssl. My plan is to include HTTP/3 in NaviServer 5.1, though some supporting changes will also land in the 5.0.x series. It’s important to note that serving a few requests over HTTP/3 is only the first milestone. There will be still a long way to go to reach a similar support level as for HTTP/1, including the full range of server features (e.g., 100-continue, streaming requests) in a stable way. iIt will take some time, until the support is production-ready (leaks, no concurrency issues with higher load, etc.) Once that is achieved, the next logical step will be HTTP/3 client support, which will in turn be required for reverse proxying to upstream HTTP/3 servers (maybe in 5.2) Connection Model In TCP connections over HTTP/1.x and HTTP/2, each client connection is identified by: client IP + client port + server IP + server port + protocol Every new client connection to the listening port creates an ephemeral port on the server side for later direct communication. With HTTP/3 over QUIC, things are different: all requests are directed to the same port and these are then multiplexed over a single QUIC connection. This means, there is no ephemeral port on the server side, regardless of the number of streams. The server simply binds on startup to a well-known port (usually UDP/443) and must handle the multiplexing logic internally. This has strong consequences for the integration into NaviServer - including how events are managed, how Ns_Socket is interpreted, and how drivers are implemented, etc. Furthermore, one needs a bidirectional mapping form between ns_sets and the QPAC headers, string based interfaces must be generalized, etc. QUIC Stream Model Each QUIC connection can multiplex multiple bidirectional streams for HTTP requests/responses, along with several unidirectional control streams for session management and header compression: +-----------------------------------------------------------+ | QUIC Connection | | | | Client-Initiated Unidirectional Streams: | | ┌──────────────────┐ ┌──────────────────┐ | | | Control Stream | | QPACK Encoder | | | └──────────────────┘ └──────────────────┘ | | | | Server-Initiated Unidirectional Streams: | | ┌──────────────────┐ ┌──────────────────┐ | | | Control Stream | | QPACK Decoder | | | └──────────────────┘ └──────────────────┘ | | | | Bidirectional Streams (many in parallel): | | ┌───────────────────────────────────────────────┐ | | | Request/Response Stream #1 | | | └───────────────────────────────────────────────┘ | | ┌───────────────────────────────────────────────┐ | | | Request/Response Stream #2 | | | └───────────────────────────────────────────────┘ | | ┌───────────────────────────────────────────────┐ | | | Request/Response Stream #N | | | └───────────────────────────────────────────────┘ | +-----------------------------------------------------------+ Each side (client and server) must open its own control stream (unidirectional). QPACK requires two unidirectional streams (encoder, decoder). Request/response pairs always use bidirectional streams. Streams are independent — packet loss in one stream does not block progress in others. For a recent comparison of HTTP/2 and HTTP/3 in terms of features and performance, see: https://www.debugbear.com/blog/http3-vs-http2-performance Best regards, -gustaf _______________________________________________ naviserver-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/naviserver-devel _______________________________________________ naviserver-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/naviserver-devel
