Thanks for the detailed thoughts. I need to ponder them some more, this seems like a good direction for long-term.

My concern is that waiting for the full design could delay HTTP/3 work. The mod_http3 project is still young and has a lot of maturing ahead of it.

I propose retargeting PR #699 to the 2.4.x series as an enabling step, while developing the broader design on 2.5.x. This would let the community continue to grow, test, and gather feedback on mod_http3 in parallel.

mod_http3 would adopt an odd/even release strategy. 0.2.0 could target stable httpd 2.4.x, while 0.3.0-dev targets httpd 2.5.x-dev. When httpd 2.6.x is released, we could then ship mod_http3 0.4.0 as the corresponding stable release, perhaps ready to be bundled with httpd by then.

On 2026-08-16 14:28, Graham Leggett via dev wrote:
On 07 Aug 2026, at 15:05, Steffen <[email protected]> wrote:

Developing an HTTP3 module for Apache HTTPD is something that is desperately needed, noting alternative web servers already offer HTTP3 support, e.g. NGINX and Caddy.

This is very cool work, happy to help you.

Whilst there's evidence of people actively working towards this, e.g. https://github.com/machine-moon/mod_http3, it's evidently not possible with the current 2.4.x code branch. To that end PR#699 https://github.com/apache/httpd/pull/699 has been raised, as a workaround to allow (some) MPM's to note connections that are not TCP based.

The following post provides a detailed insight to these issues - https://codeit.guru/apache-http3-pr-699-mpm-quic-backport-2-4-68

Not had a chance to look at the code yet, but some comments on the post above.

Brain dump to follow.

"The pull request proposes two optional MPM functions"

Optional functions come with the limitation that only one module can grab them. Ideally instead of optional functions they should be hooks, this allows more than one module to be present and do potentially do work in different ways.

One place where httpd definitely needs a hook is receiving socket descriptors.

Right now there is code hardcoded in httpd core that is aware of systemd for example, which can pass a pre-opened socket to httpd. That really should be a hook that is called when some code in a module has a socket ready. The core can be pure "open TCP or UDP", while an extra module can be systemd.

This means systemd can pass UDP sockets to mod_http3 in future and it just works.

"Every successful call to: ap_mpm_note_extra_connection_added() must eventually have exactly one matching call to: ap_mpm_note_extra_connection_removed()"

This is largely impractical, it is pretty much guaranteed that an error path will be mishandled at some point, which will lead to instability in the server.

The way httpd handles this is through the use of memory pools (arenas), each unit of work in httpd has its own pool. When the unit of work is finished, because it succeeded or failed, doesn't matter, the memory is cleaned up as a single unit, along with any extra resources like connection handles etc.

https://apr.apache.org/docs/apr/1.7/group___pool_cleanup.html

Pools are hierarchical, for example a request is created from a connection. If the request ends for whatever reason, run apr_pool_destroy(r->pool) will make that request go away. If the connection dies for whatever reason, run apr_pool_destroy(c->pool) and the connection, along with any requests currently in progress, will all go away.

Sometimes you might have a relationship between things that aren't nested, like an LDAP connection pool. The LDAP connection pool lives alongside HTTP requests. While the LDAP connection is being used by a request, a cleanup is registered with the request to return the LDAP connection to the pool at the end. No matter what happens to the request, sanity returns to the LDAP connection pool.

What all this means is that you need just one call, ap_mpm_note_extra_connection_added(), which is passed a pool, and it's the job of your code to register a cleanup in that pool.

"The MPM owns the process lifecycle, but protocol modules may own additional connection lifecycles and report them through a defined API."

We have the option to rethink how nghttp3 and httpd mesh with one another, and given certain limitations inside the core, this is likely to be necessary.

Thinking out loud, the first hook needed is the hook that allows us to open TCP or UDP sockets, either natively or from systemd, at or around make_sock() here https://github.com/apache/httpd/blob/trunk/server/listen.c#L72

Then each MPM would need a hook to pass UDP packets to. This hook might use ngtcp2 or openssl to decode the packets, and then pass to a hook that does nghttp3.

nghttp3 would the make a conn_rec out of nghttp3_conn, and then make a request_rec out of the callbacks for headers.

The entry point where the request is processed is possibly here at ‎ap_process_async_request‎():

https://github.com/apache/httpd/blob/trunk/modules/http/http_request.c#L406

Alternatively, if the above function has too many side effects, run these three hooks ap_run_quick_handler‎(), ap_process_request_internal‎(), and ap_invoke_handler‎() one after the other and process the return code appropriately:

https://github.com/apache/httpd/blob/trunk/modules/http/http_request.c#L447
https://github.com/apache/httpd/blob/trunk/modules/http/http_request.c#L449
https://github.com/apache/httpd/blob/trunk/modules/http/http_request.c#L451

You would need to replace the connection filters with a filter that injects data into the request, and then allows writing of data from the request.

The filter would return EAGAIN until all the request is read, and unlike ap_process_async_request‎(), you would pass more data in and keep going until that hook is happy.

Some work might be required to make sure things are properly re-entrant, but that's doable and reasonable I think.

At the end of ap_invoke_handler‎() you will have buckets ready to be written, you can write those buckets to the network and process the next request. Make sure you limit the number of requests in flight like this lest you run out of file handles.

We believe it would be really helpful if PR#699 could be approved for subsequent 2.4.x releases, and equally whether similar functionality could be added to mpm_winnt, so support for HTTP3 could be developed for Windows platforms too.

Windows has its own http3 implementation called MsQuic, if the hooks above are created carefully it should be possible to switch in MsQuic instead of ngtcp2/nghttp3.

Regards,
Graham
--

--
Cheers,
Tarek

GPG Fingerprint: B9BD295C26A1ED077599810CA284507F96DB79EF

Reply via email to