Why my http/3 server canot be viist from browser

this is my http/3 server code

[package]
name = "http3_server"
version = "0.1.0"
edition = "2024"

[dependencies]
bytes = "1.10.1"
h3 = "0.0.6"
h3-quinn = "0.0.7"
http = "1.2.0"
quinn = "0.11.6"
rustls = "0.23.23"
rustls-pemfile = "2.2.0"
tokio = { version = "1.43.0", features = ["full"] }

use std::{error::Error, fs::File, io::BufReader};

use h3::server::Connection;
use quinn::{Endpoint, ServerConfig};
use rustls::pki_types::{PrivateKeyDer, pem::PemObject};
use rustls_pemfile::certs;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let addr = "[::1]:3000".parse()?;
    let server_config = load_server_config()?;
    let server = Endpoint::server(server_config, addr)?;

    while let Some(incoming) = server.accept().await {
        let incoming = incoming.await?;
        println!("{:#?}", incoming.remote_address());

        // 倄理 QUIC 连ζŽ₯
        let task = async move {
            let h3_conn = h3_quinn::Connection::new(incoming);
            let mut h3_conn = Connection::new(h3_conn).await.unwrap();

            while let Some((_req, mut stream)) = h3_conn.accept().await.unwrap() {
                let response = http::Response::builder().status(200).body(()).unwrap();
                stream.send_response(response).await.unwrap();

                let data = bytes::Bytes::from_static(&b"Hello from HTTP/3!"[..]);
                stream.send_data(data).await.unwrap();
                stream.finish().await.unwrap();
            }
        };
        tokio::spawn(task);
    }

    Ok(())
}

fn load_server_config() -> Result<ServerConfig, Box<dyn Error>> {
    let mut cert_file = BufReader::new(File::open("cert.pem")?);
    let key_file = BufReader::new(File::open("key.pem")?);

    let cert_chain: Vec<_> = certs(&mut cert_file).collect::<Result<Vec<_>, _>>()?;
    let key = PrivateKeyDer::from_pem_reader(key_file)?;

    Ok(ServerConfig::with_single_cert(cert_chain, key)?)
}

What browser and what error message?

Ubuntu Firefox

GET / undefined
Host: 127.0.0.1:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br, zstd
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Priority: u=0, i

You're binding to IPv6 localhost:

From your error message, you're pointing your browser at IPv4 localhost:

127.0.0.1:3000

On many machines those are the same interface, so this might not matter, but it's a difference I would rule out before checking anything else.

Try binding to 127.0.0.1:3000 instead of [::1]:3000, or try accessing http://[::1]:3000/ in your browser.

4 Likes

concur
though I was half expecting problem where browser only wants HTTPS:

Cheers,

use ipv4 failed, too.

Did you edit code in post 1?
'cuz let addr = "[::1]:3000" is IPv6, not IPv4