1use std::{
18 fmt, io,
19 pin::Pin,
20 sync::Arc,
21 task::{Context, Poll},
22};
23
24use scion_quic::h3::client::{H3DuplexStream, Http3Client};
25use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
26
27use crate::authority::Authority;
28
29pub(crate) fn connect_request(authority: &Authority) -> http::Request<()> {
31 http::Request::builder()
32 .method(http::Method::CONNECT)
33 .uri(format!("https://{authority}"))
34 .body(())
35 .expect("a valid authority forms a valid URI")
36}
37
38pub struct Tunnel {
45 stream: H3DuplexStream,
46 _connection: Arc<Http3Client>,
48}
49
50impl Tunnel {
51 pub(crate) fn new(stream: H3DuplexStream, connection: Arc<Http3Client>) -> Self {
52 Tunnel {
53 stream,
54 _connection: connection,
55 }
56 }
57}
58
59impl AsyncRead for Tunnel {
60 fn poll_read(
61 self: Pin<&mut Self>,
62 cx: &mut Context<'_>,
63 buf: &mut ReadBuf<'_>,
64 ) -> Poll<io::Result<()>> {
65 Pin::new(&mut self.get_mut().stream).poll_read(cx, buf)
66 }
67}
68
69impl AsyncWrite for Tunnel {
70 fn poll_write(
71 self: Pin<&mut Self>,
72 cx: &mut Context<'_>,
73 buf: &[u8],
74 ) -> Poll<io::Result<usize>> {
75 Pin::new(&mut self.get_mut().stream).poll_write(cx, buf)
76 }
77
78 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
79 Pin::new(&mut self.get_mut().stream).poll_flush(cx)
80 }
81
82 fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
83 Pin::new(&mut self.get_mut().stream).poll_shutdown(cx)
84 }
85}
86
87impl fmt::Debug for Tunnel {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 f.debug_struct("Tunnel").finish_non_exhaustive()
90 }
91}