Skip to content

Assorted queries #1

Closed
Closed

Description

@tangent1al

Firstly, many thanks for your efforts to produce a working HTTP3 module for Apache, based on the @machine-moon repository. Plus your blog post concerning PR#699 at https://codeit.guru/apache-http3-pr-699-mpm-quic-backport-2-4-68 which is most informative.

I've been looking at your 00.0.54 build on a local copy of Linux Mint 22.2, having built the various HTTPD (and its dependencies) separately from scratch (into prefix /apache24).

I'm particularly pleased your code builds against Apache HTTPD 2.4.68, rather than the current 'trunk' repository.

Using your CMake build, my log file contains the following salient details:

Building mod_http3-0.0.54 - start Tue 11 Aug 20:36:04 BST 2026
Re-run cmake no build system arguments
-- The C compiler identification is GNU 13.3.0
-- The CXX compiler identification is GNU 13.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- [nghttp3] found (1.18.0): /apache24
-- [openssl] found (3.6.3): /apache24
-- [apr] found (1.7.6): /apache24
-- [apu] found (1.6.3): /apache24
-- [httpd] found (2.4.68): /apache24
-- [ngtcp2] found (1.25.0): /apache24
--
-- Configuration Summary:
--
--   Version        : 0.0.54
--   Platform       : Linux-x86_64
--   Compiler       : GNU (13.3.0)
--   Build Type     : Release
--   BUILD_MODULE   : ON
--   BUILD_EXAMPLES : OFF
--   BUILD_TESTS    : OFF
--
--   ENABLE_NGTCP2  : ON
--
--   ENABLE_UBSAN   : OFF
--   ENABLE_ASAN    : OFF
--   ENABLE_WERROR  : OFF
--
-- Configuring done (0.4s)
-- Generating done (0.0s)
-- Build files have been written to: /development/apache24/build/mod_http3
--
-- etc
-- 
Install the project...
/usr/bin/cmake -P cmake_install.cmake
-- Install configuration: "Release"
-- Installing: /apache24/modules/mod_http3.so
-- Set non-toolchain portion of runtime path of "/apache24/modules/mod_http3.so" to ""
-- Installing: /apache24/share/doc/mod_http3/CHANGES
-- Installing: /apache24/share/doc/mod_http3/NOTICE
-- Installing: /apache24/share/doc/mod_http3/AUTHORS
-- Installing: /apache24/share/licenses/mod_http3/LICENSE

I then followed the INSTALL document to set up a minimal local Apache server, which starts up ok. I did add the following directive to the configuration too:

LogLevel warn http3:trace8

However, the client browser isn't negotiating an HTTP3 connection as expected. Using Firefox with Developer Tools to look at the connection details, I get the following:

GET https://localhost:4433/

Status: 200 Ok
Version: HTTP/1.1
Transferred: 80.46 kB (80.01 kB size)
Request Priority: Highest
DNS Resolution: System

I know my Firefox supports HTTP3, since if I connect to https://www.google.com I get this:

GET https://www.google.com/
Status: 200
Version: HTTP/3
Transferred: 87.38 kB (284.64 kB size)
Request Priority: Highest
DNS Resolution: System

The Apache access and error logs contains the following:

root@janus:/apache24/logs# more access_log 
127.0.0.1 - - [14/Aug/2026:12:27:43 +0100] "GET / HTTP/1.1" 200 191
127.0.0.1 - - [14/Aug/2026:12:27:43 +0100] "GET /favicon.ico HTTP/1.1" 404 236

root@janus:/apache24/logs# more error_log 
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
[Fri Aug 14 14:27:30.255845 2026] [ssl:warn] [pid 16228:tid 16228] AH01873: Init: Session Cache is not configured [hint: SSLSessionCache]
[Fri Aug 14 14:27:30.256579 2026] [http3:info] [pid 16228:tid 16228] h3_post_config: pid=16228 cert=/apache24/common/certs/server.crt key=/apache24/common/certs/server.key h3_port=4433 mpm=event threaded=1 forked=2 max_threads=25
[Fri Aug 14 14:27:30.259276 2026] [http3:warn] [pid 16228:tid 16228] active MPM 'event' does not report externally accepted connections; graceful child shutdown may end active HTTP/3 connections early (an MPM with ap_mpm_note_extra_connection_added/_removed avoids this)
[Fri Aug 14 14:27:30.259388 2026] [http3:info] [pid 16228:tid 16228] mod_http3 loaded with version: 54 (0.0.54) on pid=16228 port=4433
[Fri Aug 14 14:27:30.259415 2026] [http3:info] [pid 16228:tid 16245] event thread started
[Fri Aug 14 14:27:42.127085 2026] [http3:info] [pid 16228:tid 16247] h3_hook_fixups called
[Fri Aug 14 14:27:42.165990 2026] [http3:info] [pid 16228:tid 16248] h3_hook_fixups called

but just occasionally after a restart I get these entries too, but the browser still reports HTTP/1.1

[Fri Aug 14 14:33:40.628941 2026] [http3:info] [pid 14748:tid 14765] accepted new QUIC connection
[Fri Aug 14 14:33:40.631772 2026] [http3:error] [pid 14748:tid 14765] QUIC handshake did not complete: peer closed the connection during the handshake

If I run my build of curl (8.21.0), built with QUIC (ngtcp2) support, against the local Apache, I get a valid HTTP3 response:

root@janus:/# /apache24/bin/curl --http3 -I -k https://localhost:4433
HTTP/3 200 
alt-svc: h3=":4433"; ma=86400; persist=1
last-modified: Fri, 07 Nov 2025 08:23:08 GMT
etag: "bf-642fce432f300"
accept-ranges: bytes
content-length: 191
content-type: text/html
date: Fri, 14 Aug 2026 10:38:12 GMT
server: Apache/2.4.68 (Unix) OpenSSL/3.6.3

curl: (56) ngtcp2_conn_writev_stream returned error: ERR_CLOSING

and these additional Apache error log entries are created:

[Fri Aug 14 12:32:36.475501 2026] [http3:info] [pid 14748:tid 14765] accepted new QUIC connection
[Fri Aug 14 12:32:36.478622 2026] [http3:info] [pid 14748:tid 14765] QUIC handshake complete
[Fri Aug 14 12:32:36.479040 2026] [http3:info] [pid 14748:tid 14764] before ap_process_request
[Fri Aug 14 12:32:36.479070 2026] [http3:info] [pid 14748:tid 14764] h3_hook_access_checker called
[Fri Aug 14 12:32:36.479078 2026] [http3:info] [pid 14748:tid 14764] h3_hook_fixups called
[Fri Aug 14 12:32:36.479105 2026] [http3:info] [pid 14748:tid 14764] h3_filter_in_proto called, readbytes=8192
[Fri Aug 14 12:32:36.479109 2026] [http3:info] [pid 14748:tid 14764] serve_request_body started, h3s=
[Fri Aug 14 12:32:36.479129 2026] [http3:info] [pid 14748:tid 14764] h3_filter_out_proto: received bucket type=FILE length=191
[Fri Aug 14 12:32:36.479154 2026] [http3:info] [pid 14748:tid 14764] h3_filter_out_proto: received bucket type=EOS length=0
[Fri Aug 14 12:32:36.479162 2026] [http3:info] [pid 14748:tid 14764] h3_filter_in_proto called, readbytes=8192
[Fri Aug 14 12:32:36.479166 2026] [http3:info] [pid 14748:tid 14764] serve_request_body started, h3s=
[Fri Aug 14 12:32:36.479186 2026] [http3:info] [pid 14748:tid 14764] after ap_process_request
[Fri Aug 14 12:32:36.479336 2026] [http3:info] [pid 14748:tid 14764] queued response for stream 0, status=200, body=191
[Fri Aug 14 12:32:36.479377 2026] [http3:info] [pid 14748:tid 14765] QUIC connection terminated (idle timeout, peer close, or transport error)
[Fri Aug 14 12:32:37.368961 2026] [http3:info] [pid 14748:tid 14765] connection servicing done

So to some questions:

a) Why does the Curl request seem to work, whereas the Firefox (153.0.4) browser requests fail?

b) What's the significance of the Curl error ERR_CLOSING against the request?

c) Do you consider the NGTCP2 package a worthy option (as used by Curl HTTP3), or is the QUIC support in recent OpenSSL sufficient?

d) Your code builds against HTTPD 2.4.68, whereas @machine-moon currently needs HTTPD trunk. Is your code solution now significantly different from his, such that they might be able to build against the 2.4.x branch too? I'll probably post this question back to his repository too, but your view on the code differences would be appreciated.

e) Concerning Apache issue PR#699, if this were implemented against the 2.4.x branch, knowing UDP connections are stateless, how would added connections be removed in a timely manner? I note @covener has raised this concern in recent updates to this PR - apache/httpd#699 (review)

f) Finally, would it be possible to update your code and CMake build, to support Windows as well? I made this request to @machine-moon too, and he's responded positively. I'm going to take a look at his latest release presently, but have the frustration his code doesn't currently build against HTTPD 2.4.68.

You guys evidently have some serious programming skill; I hope between you the Apache community will soon have the option of offering a stable HTTP3 solution capable of being put into production systems.

Once again, many thanks for your efforts to date.

Activity

  1. xl32 commented on Aug 14, 2026

    @xl32
    Owner

    @tangent1al, thank you for the thourough report, I will try to answer all the questions, but there is a note. My fork runs well on patched 2.4.68 httpd, and d) I backported some things from httpd trunk to my variant of mod_http3. So, what is needed is a small modification of 2.4.68, everything else is taken from @machine-moon's repo and some things are backported from httpd trunk.
    Can you first try to run it with patched httpd? Patch is here: https://github.com/xl32/mod_http3/blob/master/.patches/httpd-2.4.66-pr699.patch

  2. xl32 commented on Aug 14, 2026

    @xl32
    Owner

    c) @machine-moon just dropped all the ngtcp2 stuff, so I pulled his changes and reworked it against openssl + mod_http3. OpenSSL + mod_http3 are sufficient.
    d) not different, but some apis needs to be backported - see commit 215d601
    f) please check my 0.0.60 - @machine-moon added a lot of Windows stuff in latest versions - I just rebased my work on top of his 0.0.59

  3. tangent1al commented on Aug 16, 2026

    @tangent1al
    Author

    Ok, so I've download your 0.0.60, applied the above httpd-2.4.66-pr699.patch file to the 2.4.68 source; then rebuilt Apache, and then your module. No errors during the build. Minor niggle though is the CMakeLists.txt install section puts the mod_http3.so file into lib64, rather than modules, so I have to copy it over.

    Apache starts up fine, but the Firefox request fails as before. I've cleared Firefox caches, etc. before the request, to no avail. Here's the Apache error log

    root@janus:/apache24/logs# tail -f error_log 
    AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
    [Sun Aug 16 15:01:42.538208 2026] [ssl:warn] [pid 65189:tid 65189] AH01873: Init: Session Cache is not configured [hint: SSLSessionCache]
    [Sun Aug 16 15:01:42.539383 2026] [http3:info] [pid 65189:tid 65189] h3_post_config: pid=65189 cert=/apache24/common/certs/server.crt key=/apache24/common/certs/server.key h3_port=4433 mpm=event threaded=1 forked=2 max_threads=25
    [Sun Aug 16 15:01:42.539414 2026] [core:warn] [pid 65189:tid 65189] AH00098: pid file /apache24/logs/httpd.pid overwritten -- Unclean shutdown of previous Apache run?
    [Sun Aug 16 15:01:42.542125 2026] [http3:info] [pid 65189:tid 65189] mod_http3 loaded with version: 60 (0.0.60) on pid=65189 port=4433
    [Sun Aug 16 15:01:42.542158 2026] [http3:info] [pid 65189:tid 65207] event thread started
    [Sun Aug 16 15:01:58.090673 2026] [http3:info] [pid 65189:tid 65210] h3_hook_fixups called
    [Sun Aug 16 15:01:58.095191 2026] [http3:info] [pid 65189:tid 65207] accepted new QUIC connection
    [Sun Aug 16 15:01:58.113037 2026] [http3:info] [pid 65189:tid 65211] h3_hook_fixups called
    [Sun Aug 16 15:01:58.179312 2026] [http3:error] [pid 65189:tid 65207] QUIC handshake did not complete: peer closed the connection during the handshake close=[remote transport err=0xc frame=0x0 reason="" (error:00000000:lib(0)::reason(0))]
    
    

    You'll note the h3_hook_fixups entry at 15:01:58 when I started the browser request, and guess the err=0xc code is somewhat generic, and probably doesn't help localise the issue?

    The Firefox console confirms the request was served with http/1.1, whilst tcpdump also confirms there was some UDP traffic on port 4433

    root@janus:/# tcpdump -n -i lo udp port 4433
    15:01:58.092886 IP 127.0.0.1.56652 > 127.0.0.1.4433: UDP, length 2504
    15:01:58.093115 IP 127.0.0.1.4433 > 127.0.0.1.56652: UDP, length 107
    15:01:58.093306 IP 127.0.0.1.56652 > 127.0.0.1.4433: UDP, length 2504
    15:01:58.093383 IP 127.0.0.1.4433 > 127.0.0.1.56652: UDP, length 107
    15:01:58.095050 IP 127.0.0.1.56652 > 127.0.0.1.4433: UDP, length 2504
    15:01:58.095163 IP 127.0.0.1.4433 > 127.0.0.1.56652: UDP, length 1200
    etc
    

    Once the request has been served as http/1.1 though, I have to restart Firefox to get the above sequence again.

    The Curl request works as before every time (though I still get that final error over closing the request)

    curl: (56) ngtcp2_conn_writev_stream returned error: ERR_CLOSING

    I've also tried the request from a remote instance of Chrome, and it equally only responds with http/1.1

    According to AI, after any number of tests it suggests "Firefox is intentionally not attempting HTTP/3 for “localhost / local network” style hostnames"

    Since you say this configuration works for you, do you have any further thoughts on what I should try? Would it be worth trying a different certificate setup with a FQDN common name?

    Further, regarding PR#699 and Windows support, I note @machine-moon has kindly added a request to update mpm_winnt -
    apache/httpd@e473a86

  4. xl32 commented on Aug 16, 2026

    @xl32
    Owner

    @tangent1al I also tested it with firefox on local WSL2 almalinux 10 docker using my rpm. It not that easy, you are correct that Firefox refuses to work with local hosts and self-signed certificates over HTTP/3. So the easiest check is osslclient from the CodeIT Repo - you can simply check if it connects, handshakes and can get an index.html file over HTTP/3.
    After that you can ask your AI how to create a CA cert, add it to the firefox and chrome cert storage as trusted, generate a server key pair and sign it with the CA key; fix the setting that prevent localhost connection over HTTP/3. Alternatively, just play with some public host in VM and issue the certificates with Let's Encrypt plain HTTP/1.1 - this can be much much easier :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions