1use std::any;
2use std::thread;
3
4use tls_api::runtime::AsyncReadExt;
5use tls_api::runtime::AsyncWriteExt;
6use tls_api::TlsAcceptor;
7use tls_api::TlsAcceptorBuilder;
8use tls_api::TlsConnector;
9use tls_api::TlsConnectorBuilder;
10use tls_api::TlsStreamDyn;
11
12use crate::block_on;
13use crate::new_acceptor;
14use crate::new_connector_builder_with_root_ca;
15use crate::TcpListener;
16use crate::TcpStream;
17use crate::BIND_HOST;
18
19async fn test_alpn_impl<C, A>()
20where
21 C: TlsConnector,
22 A: TlsAcceptor,
23{
24 drop(env_logger::try_init());
25
26 if !C::IMPLEMENTED {
27 eprintln!(
28 "connector {} is not implemented; skipping",
29 any::type_name::<C>()
30 );
31 return;
32 }
33
34 if !A::IMPLEMENTED {
35 eprintln!(
36 "acceptor {} is not implemented; skipping",
37 any::type_name::<A>()
38 );
39 return;
40 }
41
42 if !C::SUPPORTS_ALPN {
43 eprintln!("connector {} does not support ALPN", any::type_name::<C>());
44 return;
45 }
46
47 if !A::SUPPORTS_ALPN {
48 eprintln!("acceptor {} does not support ALPN", any::type_name::<A>());
49 return;
50 }
51
52 let mut acceptor: A::Builder = new_acceptor::<A>(None);
53
54 acceptor
55 .set_alpn_protocols(&[b"abc", b"de", b"f"])
56 .expect("set_alpn_protocols");
57
58 let acceptor: A = t!(acceptor.build());
59
60 #[allow(unused_mut)]
61 let mut listener = t!(TcpListener::bind((BIND_HOST, 0)).await);
62 let port = listener.local_addr().expect("local_addr").port();
63
64 let j = thread::spawn(move || {
65 let f = async {
66 let socket = t!(listener.accept().await).0;
67 let mut socket = t!(acceptor.accept(socket).await);
68
69 assert_eq!(b"de", &socket.get_alpn_protocol().unwrap().unwrap()[..]);
70
71 let mut buf = [0; 5];
72 t!(socket.read_exact(&mut buf).await);
73 assert_eq!(&buf, b"hello");
74
75 t!(socket.write_all(b"world").await);
76
77 #[cfg(feature = "runtime-tokio")]
78 t!(socket.shutdown().await);
79
80 #[cfg(feature = "runtime-async-std")]
81 t!(socket.close().await);
82 };
83 block_on(f);
84 });
85
86 let socket = t!(TcpStream::connect((BIND_HOST, port)).await);
87
88 let mut connector: C::Builder = new_connector_builder_with_root_ca::<C>();
89
90 connector
91 .set_alpn_protocols(&[b"xyz", b"de", b"u"])
92 .expect("set_alpn_protocols");
93
94 let connector: C = connector.build().expect("acceptor build");
95 let mut socket = t!(connector.connect("localhost", socket).await);
96
97 assert_eq!(b"de", &socket.get_alpn_protocol().unwrap().unwrap()[..]);
98
99 t!(socket.write_all(b"hello").await);
100 let mut buf = vec![];
101 t!(socket.read_to_end(&mut buf).await);
102 assert_eq!(buf, b"world");
103
104 j.join().expect("thread join");
105}
106
107pub fn test_alpn<C, A>()
108where
109 C: TlsConnector,
110 A: TlsAcceptor,
111{
112 block_on(test_alpn_impl::<C, A>())
113}