Skip to main content

Request

Struct Request 

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

A request for a ClientConn to send.

HTTP/1.1 requires a Host field; the connection refuses to send a request without one. The request line always says HTTP/1.1.

§Examples

use http_net::Request;

let get = Request::get("/index.html").header("host", "example.com");
let post = Request::post("/api")
    .header("host", "example.com")
    .header("content-type", "application/json")
    .body(br#"{"ok":true}"#.to_vec());
assert_eq!(get.method(), "GET");
assert_eq!(post.target(), "/api");

Implementations§

Source§

impl Request

Source

pub fn new(method: &str, target: &str) -> Self

A request with method and target, validated when it is sent: the method must be a token and the target must be in a form the method allows (/path?query, an absolute URI, host:port for CONNECT, or * for OPTIONS).

§Examples
let r = http_net::Request::new("PURGE", "/cache/a");
assert_eq!(r.method(), "PURGE");
Source

pub fn get(target: &str) -> Self

A GET request.

§Examples
assert_eq!(http_net::Request::get("/").method(), "GET");
Source

pub fn post(target: &str) -> Self

A POST request.

§Examples
assert_eq!(http_net::Request::post("/").method(), "POST");
Source

pub fn head(target: &str) -> Self

A HEAD request: its response carries headers and no body.

§Examples
assert_eq!(http_net::Request::head("/").method(), "HEAD");
Source

pub fn put(target: &str) -> Self

A PUT request.

§Examples
assert_eq!(http_net::Request::put("/files/a").method(), "PUT");
Source

pub fn delete(target: &str) -> Self

A DELETE request.

§Examples
assert_eq!(http_net::Request::delete("/files/a").method(), "DELETE");
Source

pub fn options(target: &str) -> Self

An OPTIONS request; * asks about the server as a whole.

§Examples
assert_eq!(http_net::Request::options("*").target(), "*");
Source

pub fn forward_from(head: &RequestHead<'_>) -> Self

A request for an upstream server built from a received head, for a proxy: the same method and target, every field except the hop-by-hop ones (RFC 9110 section 7.6.1: connection, keep-alive, proxy-connection, te, transfer-encoding, upgrade, trailer, and any name the head’s Connection lists; see is_hop_by_hop) in their original order, except content-length, which the connection derives again from the body mode of the head’s framing: a chunked body stays chunked, a length stays that length (stream it with ClientConn::send_body). The connection writes its own framing and connection fields.

The target is copied as received: an absolute-form target (a request to a proxy) stays absolute, which an origin server also accepts (RFC 9112 section 3.2.2); rewrite it with Request::new if the upstream wants origin form. Host is forwarded as a field. Add via and forwarding fields with header; requests are re-serialized, never passed through as raw bytes.

§Errors

Recorded and returned by ClientConn::send_request: HttpError::InvalidState for an upgrade request (the upgrade is hop-by-hop; a proxy tunnels it instead), and the builder errors of Request::new and Request::header (for example a missing or second host surfaces at send).

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

let mut downstream = ServerConn::new();
let _ = downstream.feed(b"POST /api HTTP/1.1\r\nHost: app\r\nConnection: X-Hop\r\nX-Hop: 1\r\nKeep-Alive: timeout=5\r\nAccept: */*\r\nContent-Length: 2\r\n\r\nhi");
let ServerEvent::Request(head) = downstream.poll()? else { unreachable!() };
let upstream_req = Request::forward_from(&head).header("via", "1.1 proxy");

let mut upstream = ClientConn::new();
let mut out = Vec::new();
upstream.send_request(&upstream_req, &mut out)?;
assert_eq!(out, b"POST /api HTTP/1.1\r\nHost: app\r\nAccept: */*\r\nvia: 1.1 proxy\r\ncontent-length: 2\r\n\r\n");
Source

pub fn header(self, name: &str, value: impl AsRef<[u8]>) -> Self

Adds a header field, validated as for Response::header. A second host is refused with HttpError::InvalidHost.

§Examples
let r = http_net::Request::get("/").header("host", "a").header("accept", "*/*");
assert_eq!(r.header_value("accept"), Some(&b"*/*"[..]));
Source

pub fn body(self, body: impl Into<Cow<'static, [u8]>>) -> Self

Sets the whole body, sent with content-length.

§Examples
let r = http_net::Request::post("/").body(&b"x=1"[..]);
assert_eq!(r.body_bytes(), Some(&b"x=1"[..]));
Source

pub fn chunked(self) -> Self

Streams the body with chunked encoding through ClientConn::send_body and ClientConn::end_body.

§Examples
assert_eq!(http_net::Request::post("/").chunked().body_bytes(), None);
Source

pub fn content_length(self, len: u64) -> Self

Streams a body of exactly len bytes.

§Examples
assert_eq!(http_net::Request::post("/").content_length(4).body_bytes(), None);
Source

pub fn close(self) -> Self

Asks the server to close the connection after its response.

§Examples
let _ = http_net::Request::get("/").header("host", "a").close();
Source

pub fn expect_continue(self) -> Self

Sends expect: 100-continue and holds the body back until the server agrees (RFC 9110 section 10.1.1): for large uploads the server may refuse from the head alone. The body must be streamed (content_length or chunked); send it with ClientConn::send_body after ClientEvent::Continue, or after a wait of your choosing. A final status instead means the server does not want the body: it must not be sent, and the connection closes after the response.

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

let mut conn = ClientConn::new();
let mut out = Vec::new();
let upload = Request::put("/f").header("host", "a").content_length(9).expect_continue();
conn.send_request(&upload, &mut out)?;
assert!(out.ends_with(b"expect: 100-continue\r\ncontent-length: 9\r\n\r\n"));
let _ = conn.feed(b"HTTP/1.1 413 Content Too Large\r\nContent-Length: 0\r\n\r\n");
assert!(matches!(conn.poll()?, ClientEvent::Response(r) if r.status() == 413));
assert!(matches!(conn.send_body(b"too large", &mut out), Err(HttpError::InvalidState(_))));
assert!(matches!(conn.poll()?, ClientEvent::ResponseEnd));
assert!(matches!(conn.poll()?, ClientEvent::Closed));
Source

pub fn upgrade(self, protocol: &str) -> Self

Asks to switch the connection to protocol (writes connection: upgrade and upgrade: <protocol>). A 101 answer hands the connection over; see ClientEvent::Upgraded.

protocol is a token or a name/version product token. h2c is refused with HttpError::UpgradeNotOffered: RFC 9113 section 3.1 deprecates the HTTP/2 upgrade.

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

let r = Request::get("/rpc").header("host", "a").upgrade("websocket");
assert_eq!(r.header_value("upgrade"), Some(&b"websocket"[..]));

let h2c = Request::get("/").header("host", "a").upgrade("h2c");
assert_eq!(
    ClientConn::new().send_request(&h2c, &mut Vec::new()),
    Err(HttpError::UpgradeNotOffered)
);
Source

pub fn method(&self) -> &str

The method text.

§Examples
assert_eq!(http_net::Request::new("OPTIONS", "*").method(), "OPTIONS");
Source

pub fn target(&self) -> &str

The request target.

§Examples
assert_eq!(http_net::Request::get("/a?b").target(), "/a?b");
Source

pub fn body_bytes(&self) -> Option<&[u8]>

The full body, or None for a streamed one.

§Examples
assert_eq!(http_net::Request::get("/").body_bytes(), Some(&[][..]));
Source

pub fn header_value(&self, name: &str) -> Option<&[u8]>

The value of the first header named name added to this request.

§Examples
let r = http_net::Request::get("/").header("host", "a");
assert_eq!(r.header_value("HOST"), Some(&b"a"[..]));

Trait Implementations§

Source§

impl Clone for Request

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Request

Shows method, target, fields, and body size; the values of credential fields (authorization, proxy-authorization, cookie) are replaced by <redacted N bytes>.

Source§

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

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

impl Eq for Request

Source§

impl PartialEq for Request

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Request

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.