Skip to main content

Connection

Struct Connection 

Source
pub struct Connection { /* private fields */ }
Expand description

One HTTP/2 connection, either end.

Implementations§

Source§

impl Connection

Source

pub fn server(cfg: Config) -> Connection

A server connection. It expects the client preface; its own SETTINGS are already in Connection::output.

Examples found in repository?
examples/bench_h2.rs (line 27)
24fn pair() -> (Connection, Connection, Vec<u8>) {
25    let cfg = Config { window_autotune: false, ..Config::default() };
26    let mut c = Connection::client(cfg.clone());
27    let mut s = Connection::server(cfg);
28    let mut buf = Vec::with_capacity(64 * 1024);
29    for _ in 0..3 {
30        transfer(&mut c, &mut buf);
31        s.recv(&buf, 0, &mut |_| {});
32        transfer(&mut s, &mut buf);
33        c.recv(&buf, 0, &mut |_| {});
34    }
35    (c, s, buf)
36}
Source

pub fn client(cfg: Config) -> Connection

A client connection (h2c prior knowledge, or h2 after ALPN). The preface and SETTINGS are already in Connection::output, and requests can be sent at once.

Examples found in repository?
examples/bench_h2.rs (line 26)
24fn pair() -> (Connection, Connection, Vec<u8>) {
25    let cfg = Config { window_autotune: false, ..Config::default() };
26    let mut c = Connection::client(cfg.clone());
27    let mut s = Connection::server(cfg);
28    let mut buf = Vec::with_capacity(64 * 1024);
29    for _ in 0..3 {
30        transfer(&mut c, &mut buf);
31        s.recv(&buf, 0, &mut |_| {});
32        transfer(&mut s, &mut buf);
33        c.recv(&buf, 0, &mut |_| {});
34    }
35    (c, s, buf)
36}
Source

pub fn server_upgrade( cfg: Config, http2_settings: &[u8], ) -> Result<Connection, Error>

A server connection after an HTTP/1.1 Upgrade: h2c request (RFC 7540 §3.2) was answered with 101 Switching Protocols. http2_settings is the request’s HTTP2-Settings value. The request itself becomes stream 1, half-closed (remote) with its handler running: answer it with Connection::send_response on stream 1.

Source

pub fn client_upgrade(cfg: Config, head: bool) -> Connection

A client connection after the server answered our HTTP/1.1 Upgrade: h2c request with 101. The upgrade request is stream 1, half-closed (local); its response arrives as events for stream 1. head says whether that request was HEAD.

Source

pub fn output(&self) -> &[u8] ⓘ

Bytes waiting to be written to the transport.

Examples found in repository?
examples/bench_h2.rs (line 20)
18fn transfer(from: &mut Connection, buf: &mut Vec<u8>) {
19    buf.clear();
20    buf.extend_from_slice(from.output());
21    from.advance_output(buf.len());
22}
Source

pub fn take_output(&mut self, empty: Vec<u8>) -> Vec<u8> ⓘ

Takes every byte of Connection::output as an owned buffer (no copy), leaving empty (cleared) to collect the next output. Same as reading output() and calling advance_output with its length.

Source

pub fn advance_output(&mut self, n: usize)

Marks n bytes of Connection::output as written.

Examples found in repository?
examples/bench_h2.rs (line 21)
18fn transfer(from: &mut Connection, buf: &mut Vec<u8>) {
19    buf.clear();
20    buf.extend_from_slice(from.output());
21    from.advance_output(buf.len());
22}
Source

pub fn role(&self) -> Role

This end’s role.

Source

pub fn wants_close(&self) -> bool

True when the transport should be closed once Connection::output is flushed: after a connection error, or after a GOAWAY (sent or received) once every stream is done.

Source

pub fn close_code(&self) -> Option<ErrorCode>

The error code of the GOAWAY we closed the connection with.

Source

pub fn active_handlers(&self) -> u32

Streams whose handler work is still running (server).

Source

pub fn open_streams(&self) -> u32

Streams open or half-closed.

Source

pub fn tracked_streams(&self) -> usize

Streams the engine still tracks (open, or closed with work running).

Examples found in repository?
examples/bench_h2.rs (line 81)
66fn bench_requests(streams: usize, total: usize) -> f64 {
67    let (mut c, mut s, mut buf) = pair();
68    let mut ids = Vec::with_capacity(streams);
69    // warm up (tables, buffers)
70    for _ in 0..100 {
71        batch(&mut c, &mut s, &mut buf, &mut ids, streams);
72    }
73    let rounds = total / streams;
74    let t = Instant::now();
75    let mut got = 0;
76    for _ in 0..rounds {
77        got += batch(&mut c, &mut s, &mut buf, &mut ids, streams);
78    }
79    let ns = t.elapsed().as_nanos() as f64 / (rounds * streams) as f64;
80    assert_eq!(got, rounds * streams * BODY.len());
81    assert_eq!(s.tracked_streams(), 0);
82    ns
83}
Source

pub fn peer_max_concurrent_streams(&self) -> u32

The peer’s SETTINGS_MAX_CONCURRENT_STREAMS.

Source

pub fn can_open_stream(&self) -> bool

True when a client may open another stream now.

Source

pub fn send_capacity(&self, stream: u32) -> usize

Bytes stream may send now: the smaller of its window, the connection window and the room in the output buffer.

Source

pub fn receive_windows(&self) -> (u32, u32)

The connection’s current receive targets (connection, per stream), after auto-tuning.

Source

pub fn poll_timeout(&self) -> Option<u64>

The next deadline (settings acknowledgement, graceful shutdown) for Connection::handle_timeout.

Source

pub fn handle_timeout(&mut self, now: u64, sink: &mut dyn FnMut(Event<'_>))

Fires due timers.

Source

pub fn recv( &mut self, input: &[u8], now: u64, sink: &mut dyn FnMut(Event<'_>), ) -> usize

Processes received bytes at time now (monotonic milliseconds from any origin). Returns how many bytes were consumed; the caller keeps the rest and passes it again with more data. A buffer of max_frame_size + 9 bytes always makes progress. Input processing pauses (returns early) while more than twice max_send_buffer of output is waiting, so a peer that does not read cannot make us queue unbounded replies. After the connection is closed all input is consumed and ignored.

Examples found in repository?
examples/bench_h2.rs (line 31)
24fn pair() -> (Connection, Connection, Vec<u8>) {
25    let cfg = Config { window_autotune: false, ..Config::default() };
26    let mut c = Connection::client(cfg.clone());
27    let mut s = Connection::server(cfg);
28    let mut buf = Vec::with_capacity(64 * 1024);
29    for _ in 0..3 {
30        transfer(&mut c, &mut buf);
31        s.recv(&buf, 0, &mut |_| {});
32        transfer(&mut s, &mut buf);
33        c.recv(&buf, 0, &mut |_| {});
34    }
35    (c, s, buf)
36}
37
38/// One batch: `streams` requests out, responses back. Returns body bytes received.
39fn batch(c: &mut Connection, s: &mut Connection, buf: &mut Vec<u8>, ids: &mut Vec<u32>, streams: usize) -> usize {
40    for _ in 0..streams {
41        c.send_request(b"GET", b"https", b"example.com", b"/hello", &[(b"user-agent", b"simoom-bench"), (b"accept", b"*/*")], true).unwrap();
42    }
43    transfer(c, buf);
44    ids.clear();
45    let n = s.recv(buf, 0, &mut |e| {
46        if let Event::Headers { stream, .. } = e {
47            ids.push(stream);
48        }
49    });
50    debug_assert_eq!(n, buf.len());
51    for &id in ids.iter() {
52        s.send_response(id, 200, &[(b"content-type", b"text/plain")], false).unwrap();
53        s.send_data(id, BODY, true).unwrap();
54        s.stream_finished(id);
55    }
56    transfer(s, buf);
57    let mut got = 0;
58    c.recv(buf, 0, &mut |e| {
59        if let Event::Data { data, .. } = e {
60            got += data.len();
61        }
62    });
63    got
64}
Source

pub fn release(&mut self, stream: u32, n: usize)

Tells the engine the application consumed n bytes of DATA on stream, so the peer may send more. Releasing more than was delivered is ignored.

Source

pub fn peer_max_header_list_size(&self) -> u32

The peer’s SETTINGS_MAX_HEADER_LIST_SIZE (u32::MAX until it announces one).

Source

pub fn peer_connect_protocol(&self) -> bool

The peer (a server) allows extended CONNECT: it sent SETTINGS_ENABLE_CONNECT_PROTOCOL = 1 (RFC 8441 §3). Known once its SETTINGS arrived (Event::Settings).

Source

pub fn send_extended_connect( &mut self, protocol: &[u8], scheme: &[u8], authority: &[u8], path: &[u8], fields: &[(&[u8], &[u8])], ) -> Result<u32, Error>

Client: opens an extended CONNECT stream (RFC 8441 §4), for example with protocol = b"websocket" for WebSocket over HTTP/2 (RFC 8441 §5). The stream stays open both ways; a 2xx response accepts the tunnel, whose bytes then travel as DATA. Fails with Error::ConnectProtocolDisabled unless the server enabled extended CONNECT.

Source

pub fn send_response( &mut self, stream: u32, status: u16, fields: &[(&[u8], &[u8])], end_stream: bool, ) -> Result<(), Error>

Server: sends response headers on stream. A status below 200 sends an informational response (101 is not allowed in HTTP/2); then the final one follows.

Examples found in repository?
examples/bench_h2.rs (line 52)
39fn batch(c: &mut Connection, s: &mut Connection, buf: &mut Vec<u8>, ids: &mut Vec<u32>, streams: usize) -> usize {
40    for _ in 0..streams {
41        c.send_request(b"GET", b"https", b"example.com", b"/hello", &[(b"user-agent", b"simoom-bench"), (b"accept", b"*/*")], true).unwrap();
42    }
43    transfer(c, buf);
44    ids.clear();
45    let n = s.recv(buf, 0, &mut |e| {
46        if let Event::Headers { stream, .. } = e {
47            ids.push(stream);
48        }
49    });
50    debug_assert_eq!(n, buf.len());
51    for &id in ids.iter() {
52        s.send_response(id, 200, &[(b"content-type", b"text/plain")], false).unwrap();
53        s.send_data(id, BODY, true).unwrap();
54        s.stream_finished(id);
55    }
56    transfer(s, buf);
57    let mut got = 0;
58    c.recv(buf, 0, &mut |e| {
59        if let Event::Data { data, .. } = e {
60            got += data.len();
61        }
62    });
63    got
64}
Source

pub fn send_request( &mut self, method: &[u8], scheme: &[u8], authority: &[u8], path: &[u8], fields: &[(&[u8], &[u8])], end_stream: bool, ) -> Result<u32, Error>

Client: opens a stream with a request. authority may be empty; path is ignored for CONNECT. Returns the new stream id.

Examples found in repository?
examples/bench_h2.rs (line 41)
39fn batch(c: &mut Connection, s: &mut Connection, buf: &mut Vec<u8>, ids: &mut Vec<u32>, streams: usize) -> usize {
40    for _ in 0..streams {
41        c.send_request(b"GET", b"https", b"example.com", b"/hello", &[(b"user-agent", b"simoom-bench"), (b"accept", b"*/*")], true).unwrap();
42    }
43    transfer(c, buf);
44    ids.clear();
45    let n = s.recv(buf, 0, &mut |e| {
46        if let Event::Headers { stream, .. } = e {
47            ids.push(stream);
48        }
49    });
50    debug_assert_eq!(n, buf.len());
51    for &id in ids.iter() {
52        s.send_response(id, 200, &[(b"content-type", b"text/plain")], false).unwrap();
53        s.send_data(id, BODY, true).unwrap();
54        s.stream_finished(id);
55    }
56    transfer(s, buf);
57    let mut got = 0;
58    c.recv(buf, 0, &mut |e| {
59        if let Event::Data { data, .. } = e {
60            got += data.len();
61        }
62    });
63    got
64}
Source

pub fn send_trailers( &mut self, stream: u32, fields: &[(&[u8], &[u8])], ) -> Result<(), Error>

Sends trailers, ending the stream.

Source

pub fn send_data( &mut self, stream: u32, data: &[u8], end_stream: bool, ) -> Result<usize, Error>

Sends body bytes on stream, as much as the stream window, the connection window and the output buffer cap allow. Returns how many bytes were accepted; end_stream applies only when all of data was accepted. When fewer were accepted the stream is remembered, and Connection::poll_writable reports it once it can send again.

Examples found in repository?
examples/bench_h2.rs (line 53)
39fn batch(c: &mut Connection, s: &mut Connection, buf: &mut Vec<u8>, ids: &mut Vec<u32>, streams: usize) -> usize {
40    for _ in 0..streams {
41        c.send_request(b"GET", b"https", b"example.com", b"/hello", &[(b"user-agent", b"simoom-bench"), (b"accept", b"*/*")], true).unwrap();
42    }
43    transfer(c, buf);
44    ids.clear();
45    let n = s.recv(buf, 0, &mut |e| {
46        if let Event::Headers { stream, .. } = e {
47            ids.push(stream);
48        }
49    });
50    debug_assert_eq!(n, buf.len());
51    for &id in ids.iter() {
52        s.send_response(id, 200, &[(b"content-type", b"text/plain")], false).unwrap();
53        s.send_data(id, BODY, true).unwrap();
54        s.stream_finished(id);
55    }
56    transfer(s, buf);
57    let mut got = 0;
58    c.recv(buf, 0, &mut |e| {
59        if let Event::Data { data, .. } = e {
60            got += data.len();
61        }
62    });
63    got
64}
Source

pub fn poll_writable(&mut self) -> Option<u32>

A stream that was short of capacity in Connection::send_data and can send again. Call it after Connection::recv and Connection::advance_output until it returns None.

Source

pub fn reset(&mut self, stream: u32, code: ErrorCode)

Resets stream with code at the application’s request.

Source

pub fn stream_finished(&mut self, stream: u32)

The application’s work for stream is finished: it no longer counts against the concurrency limit. A stream we have not ended is reset with CANCEL; a request body that was not read to the end is cut off with RST_STREAM(NO_ERROR) (RFC 9113 §8.1).

Examples found in repository?
examples/bench_h2.rs (line 54)
39fn batch(c: &mut Connection, s: &mut Connection, buf: &mut Vec<u8>, ids: &mut Vec<u32>, streams: usize) -> usize {
40    for _ in 0..streams {
41        c.send_request(b"GET", b"https", b"example.com", b"/hello", &[(b"user-agent", b"simoom-bench"), (b"accept", b"*/*")], true).unwrap();
42    }
43    transfer(c, buf);
44    ids.clear();
45    let n = s.recv(buf, 0, &mut |e| {
46        if let Event::Headers { stream, .. } = e {
47            ids.push(stream);
48        }
49    });
50    debug_assert_eq!(n, buf.len());
51    for &id in ids.iter() {
52        s.send_response(id, 200, &[(b"content-type", b"text/plain")], false).unwrap();
53        s.send_data(id, BODY, true).unwrap();
54        s.stream_finished(id);
55    }
56    transfer(s, buf);
57    let mut got = 0;
58    c.recv(buf, 0, &mut |e| {
59        if let Event::Data { data, .. } = e {
60            got += data.len();
61        }
62    });
63    got
64}
Source

pub fn ping(&mut self, data: [u8; 8])

Sends a PING; the answer arrives as Event::Pong.

Source

pub fn shutdown(&mut self, now: u64)

Starts a graceful shutdown (RFC 9113 §6.8). A server sends GOAWAY with the largest stream id and a PING, then, after the PING round trip (or graceful_timeout_ms), the final GOAWAY with the last stream it accepted. Streams already accepted run to the end; Connection::wants_close turns true when they are done.

Source

pub fn close(&mut self, code: ErrorCode, debug: &[u8])

Closes the connection at once with GOAWAY(code). No events follow.

Trait Implementations§

Source§

impl Debug for Connection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.