Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

help: error maybe when handshake with browser #281

Open
aksjfds opened this issue Mar 9, 2025 · 1 comment
Open

help: error maybe when handshake with browser #281

aksjfds opened this issue Mar 9, 2025 · 1 comment

Comments

@aksjfds
Copy link

aksjfds commented Mar 9, 2025

my code is try to build h1_connection with browser and respond res with header: Alt-Svc: h3=:443.
the h1_server is ok but got error in h3_server:

I got a error when

while let Some(new_conn) = endpoint.accept().await {
        println!("{:#?}", 2);
        tokio::spawn(async move {
            match new_conn.await {             // got error here
ConnectionClosed(
    ConnectionClose {
        error_code: APPLICATION_ERROR,
        frame_type: None,
        reason: b"",
    },
)

this is my code :

use bytes::Bytes;
use h3::quic::BidiStream;
use h3::server::RequestStream;
use http::Request;
use quinn::crypto::rustls::QuicServerConfig;
use rustls::pki_types::{PrivateKeyDer, pem::PemObject};
use rustls_pemfile::certs;
use std::error::Error;
use std::thread;
use std::{fs::File, io::BufReader, sync::Arc};
use tokio::io::AsyncWriteExt;
use tokio::{
    io::{self},
    net::TcpListener,
};
use tokio_rustls::TlsAcceptor;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    rustls::crypto::ring::default_provider()
        .install_default()
        .unwrap();

    tokio::spawn(h1_server_tls());
    tokio::spawn(h3_server_tls()).await.unwrap().unwrap();

    thread::park();
    Ok(())
}

fn load_config() -> Result<rustls::ServerConfig, Box<dyn Error + Sync + Send>> {
    let mut cert_file =
        BufReader::new(File::open("/home/aksjfds/codes/http3_server/cert.pem").unwrap());
    let key_file = BufReader::new(File::open("/home/aksjfds/codes/http3_server/key.pem").unwrap());

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

    let config = rustls::ServerConfig::builder()
        .with_no_client_auth()
        .with_single_cert(cert_chain, key)
        .unwrap();

    Ok(config)
}

pub async fn h1_server_tls() -> Result<(), Box<dyn Error + Sync + Send>> {
    let config = load_config()?;
    // config.alpn_protocols = vec![b"h2".to_vec()];

    let acceptor = TlsAcceptor::from(Arc::new(config));

    let addr = "127.0.0.1:443";
    let listener = TcpListener::bind(addr).await.unwrap();
    println!("Server running on {}", addr);

    loop {
        let (stream, peer_addr) = listener.accept().await.unwrap();
        let acceptor = acceptor.clone();

        println!("{:#?}", peer_addr);
        let fut = async move {
            let mut stream = acceptor.accept(stream).await.unwrap();

            let response = b"HTTP/1.1 200 OK\r\n\
                Alt-Svc: h3=\":443\"\r\n\
                Content-Type: text/html; charset=UTF-8\r\n\
                Content-Length: 14\r\n\r\n\
                Hello, HTTP/3!";

            stream.write_all(response).await.unwrap();
            stream.flush().await.unwrap();
            Ok(()) as io::Result<()>
        };

        tokio::spawn(fut);
    }
}

static ALPN: &[u8] = b"h3";
pub async fn h3_server_tls() -> Result<(), Box<dyn Error + Sync + Send>> {
    // load cert
    let mut tls_config = load_config()?;
    tls_config.max_early_data_size = u32::MAX;
    tls_config.alpn_protocols = vec![ALPN.into()];

    let server_config =
        quinn::ServerConfig::with_crypto(Arc::new(QuicServerConfig::try_from(tls_config).unwrap()));
    let endpoint =
        quinn::Endpoint::server(server_config, "127.0.0.1:443".parse().unwrap()).unwrap();

    println!("{:#?}", 1);
    while let Some(new_conn) = endpoint.accept().await {
        println!("{:#?}", 2);
        tokio::spawn(async move {







          // got error here
            match new_conn.await {                        // got error here
          // got error here







                Ok(conn) => {
                    let mut h3_conn = h3::server::Connection::new(h3_quinn::Connection::new(conn))
                        .await
                        .unwrap();

                    loop {
                        match h3_conn.accept().await {
                            Ok(Some((req, stream))) => {
                                tokio::spawn(async {
                                    if let Err(_e) = handle_request(req, stream).await {}
                                });
                            }

                            // indicating no more streams to be received
                            Ok(None) => {
                                break;
                            }

                            Err(_err) => {}
                        }
                    }
                }
                Err(e) => println!("{:#?}", e),
            }
        });
    }

    Ok(())
}

async fn handle_request<T>(
    req: Request<()>,
    mut stream: RequestStream<T, Bytes>,
) -> Result<(), Box<dyn std::error::Error>>
where
    T: BidiStream<Bytes>,
{
    let _ = req;
    let resp = http::Response::builder().status(200).body(()).unwrap();

    match stream.send_response(resp).await {
        Ok(_) => {
            println!("successfully respond to connection");
        }
        Err(_err) => {}
    }

    Ok(stream.finish().await.unwrap())
}
@aksjfds aksjfds changed the title error maybe when handshake with browser help: error maybe when handshake with browser Mar 9, 2025
@Ruben2424
Copy link
Contributor

Your error occurs before any code from this repository is executed. But according to quinns documentation your error means, that your client (browser) closed the connection during the handshake.
Maybe you can find out why the browser closes the connection with logs or something. Does your browser trust your certificate?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants