Skip to main content

ClientConn

Struct ClientConn 

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

The client side of one HTTP/1.1 connection: a sans-IO state machine.

One request is outstanding at a time. send_request serializes a Request; feed and poll parse the response. When the response allows it, the connection returns to ClientEvent::Idle and can send the next request (keep-alive).

The response is framed with the request in mind: a HEAD request’s response has no body whatever its headers say, a CONNECT 2xx becomes a tunnel, and a response with neither Content-Length nor Transfer-Encoding runs until the server closes.

§Examples

use http_net::{ClientConn, ClientEvent, Request};

let mut conn = ClientConn::new();
let mut out = Vec::new();
conn.send_request(&Request::get("/a").header("host", "h"), &mut out).unwrap();
assert_eq!(out, b"GET /a HTTP/1.1\r\nhost: h\r\n\r\n");
let _ = conn.feed(b"HTTP/1.1 204 No Content\r\n\r\n");
assert!(matches!(conn.poll().unwrap(), ClientEvent::Response(_)));
assert!(matches!(conn.poll().unwrap(), ClientEvent::ResponseEnd));
assert!(matches!(conn.poll().unwrap(), ClientEvent::Idle));

Implementations§

Source§

impl ClientConn

Source

pub fn new() -> Self

A connection with the default Limits.

§Examples
let mut conn = http_net::ClientConn::new();
assert!(matches!(conn.poll(), Ok(http_net::ClientEvent::Idle)));
Source

pub fn with_limits(limits: Limits) -> Self

A connection enforcing limits on responses.

§Examples
let conn = http_net::ClientConn::with_limits(http_net::Limits::new().with_max_body(1 << 24));
assert_eq!(conn.limits().max_body(), 1 << 24);
Source

pub fn limits(&self) -> &Limits

The limits this connection enforces.

§Examples
assert_eq!(http_net::ClientConn::new().limits().max_headers(), 100);
Source

pub fn feed(&mut self, bytes: &[u8]) -> usize

Copies as much of bytes into the input buffer as fits; returns how many were taken (see ServerConn::feed).

§Examples
let mut conn = http_net::ClientConn::new();
assert_eq!(conn.feed(b"HTTP/1.1"), 8);
Source

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

Spare space at the end of the input buffer; follow with commit.

§Examples
let mut conn = http_net::ClientConn::new();
assert!(!conn.read_buf().is_empty());
Source

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

Records that n bytes were written into read_buf.

§Examples
let mut conn = http_net::ClientConn::new();
conn.read_buf()[..4].copy_from_slice(b"HTTP");
conn.commit(4);
Source

pub fn feed_eof(&mut self)

Records that the server closed its sending side: ends a body that runs until close, or reports HttpError::UnexpectedEof mid-message.

§Examples
use http_net::{ClientConn, ClientEvent, Request};

let mut conn = ClientConn::new();
conn.send_request(&Request::get("/").header("host", "a"), &mut Vec::new()).unwrap();
let _ = conn.feed(b"HTTP/1.0 200 OK\r\n\r\nall of it");
assert!(matches!(conn.poll().unwrap(), ClientEvent::Response(_)));
assert!(matches!(conn.poll().unwrap(), ClientEvent::Body(b"all of it")));
assert!(matches!(conn.poll().unwrap(), ClientEvent::NeedInput));
conn.feed_eof();
assert!(matches!(conn.poll().unwrap(), ClientEvent::ResponseEnd));
assert!(matches!(conn.poll().unwrap(), ClientEvent::Closed));
Source

pub fn send_request( &mut self, request: &Request, out: &mut Vec<u8>, ) -> Result<(), HttpError>

Writes request into out and starts waiting for its response.

A full body is sent with content-length (omitted for an empty body on methods that do not expect one); a streamed body continues with send_body and end_body.

§Errors
§Examples
use http_net::{ClientConn, HttpError, Request};

let mut conn = ClientConn::new();
let mut out = Vec::new();
assert_eq!(conn.send_request(&Request::get("/"), &mut out), Err(HttpError::MissingHost));
conn.send_request(&Request::post("/f").header("host", "a").body(&b"xyz"[..]), &mut out).unwrap();
assert_eq!(out, b"POST /f HTTP/1.1\r\nhost: a\r\ncontent-length: 3\r\n\r\nxyz");
Source

pub fn send_body( &mut self, data: &[u8], out: &mut Vec<u8>, ) -> Result<(), HttpError>

Writes body bytes of a streamed request.

§Errors

HttpError::BodyLengthMismatch past the declared length; HttpError::InvalidState when no streamed request is in progress.

§Examples
use http_net::{ClientConn, Request};

let mut conn = ClientConn::new();
let mut out = Vec::new();
conn.send_request(&Request::post("/up").header("host", "a").chunked(), &mut out).unwrap();
conn.send_body(b"part", &mut out).unwrap();
conn.end_body(&mut out).unwrap();
assert!(out.ends_with(b"4\r\npart\r\n0\r\n\r\n"));
Source

pub fn end_body(&mut self, out: &mut Vec<u8>) -> Result<(), HttpError>

Ends a streamed request body.

§Errors

HttpError::BodyLengthMismatch when fewer bytes than declared were sent; HttpError::InvalidState when no streamed request is in progress.

§Examples
use http_net::{ClientConn, Request};

let mut conn = ClientConn::new();
let mut out = Vec::new();
conn.send_request(&Request::post("/").header("host", "a").content_length(2), &mut out).unwrap();
conn.send_body(b"ok", &mut out).unwrap();
conn.end_body(&mut out).unwrap();
assert!(out.ends_with(b"\r\n\r\nok"));
Source

pub fn poll(&mut self) -> Result<ClientEvent<'_>, HttpError>

Advances the response parser and reports what happened.

§Errors

Any HttpError parse error; the connection is then closed and must not be reused.

§Examples
use http_net::{ClientConn, HttpError, Request};

let mut conn = ClientConn::new();
conn.send_request(&Request::get("/").header("host", "a"), &mut Vec::new()).unwrap();
let _ = conn.feed(b"HTTP/1.1 200 OK\r\nContent-Length: 1\r\nContent-Length: 1\r\n\r\nx");
assert_eq!(conn.poll().unwrap_err(), HttpError::DuplicateContentLength);
Source

pub fn response(&self) -> Option<ResponseHead<'_>>

The current response’s head, from its arrival until the next request is sent (still available after an upgrade).

§Examples
use http_net::{ClientConn, ClientEvent, Request};

let mut conn = ClientConn::new();
conn.send_request(&Request::get("/").header("host", "a"), &mut Vec::new()).unwrap();
let _ = conn.feed(b"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n");
while !matches!(conn.poll().unwrap(), ClientEvent::ResponseEnd) {}
assert_eq!(conn.response().unwrap().status(), 200);
Source

pub fn is_upgraded(&self) -> bool

Whether the server switched protocols and the connection now belongs to another protocol.

§Examples
assert!(!http_net::ClientConn::new().is_upgraded());
Source

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

Input that arrived after the last message parsed: after ClientEvent::Upgraded, the first bytes of the new protocol.

§Examples
use http_net::{ClientConn, ClientEvent, Request};

let mut conn = ClientConn::new();
conn.send_request(&Request::get("/").header("host", "a").upgrade("x"), &mut Vec::new()).unwrap();
let _ = conn.feed(b"HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nUpgrade: x\r\n\r\nhi");
assert!(matches!(conn.poll().unwrap(), ClientEvent::Response(_)));
assert!(matches!(conn.poll().unwrap(), ClientEvent::Upgraded));
assert_eq!(conn.remaining_input(), b"hi");

Trait Implementations§

Source§

impl Debug for ClientConn

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for ClientConn

Source§

fn default() -> Self

Returns the “default value” for a type. 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.