Structin fastlyfastly 0.13.1View source
pub struct Body { /* private fields */ }

An HTTP body that can be read from, written to, or appended to another body.

The most efficient ways to read from and write to the body are through the Read, BufRead, and Write implementations.

Read and write operations to a Body are automatically buffered, though you can take direct control over aspects of the buffering using the BufRead methods and Write::flush().

Methods

fn append(&mut self, other: Body)

Append another body onto the end of this body.

This operation is performed in amortized constant time, and so should always be preferred to reading an entire body and then writing the same contents to another body.

Parameters

self: &mut Self
other: Body

get_prefix_mut

View source
fn get_prefix_mut(&mut self, length: usize) -> Prefix<'_>

Get a prefix of the body containing up to the given number of bytes.

This is particularly useful when you only need to inspect the first few bytes of a body, or want to read an entire body up to a certain size limit to control memory consumption.

Note that the length of the returned prefix may be shorter than the requested length if the length of the entire body is shorter.

The returned Prefix value is a smart pointer wrapping a &mut Vec<u8>. You can use it as you would a &mut Vec<u8> or a [&mut [u8]]std::slice to view or modify the contents of the prefix.

When the Prefix is dropped, the prefix bytes are returned to the body, including any modifications that have been made. Because the prefix holds a mutable reference to the body, you may need to explicitly drop() the prefix to perform other operations on the body.

If you do not need to return the prefix bytes to the body, use Prefix::take() to consume the prefix as an owned byte vector without writing it back.

Examples

Checking whether the body starts with the WebAssembly magic number:

const MAGIC: &[u8] = b"\0asm";
let prefix = body.get_prefix_mut(MAGIC.len());
if prefix.as_slice() == MAGIC {
println!("might be Wasm!");
}

Zero out the timestamp bytes in a gzip header:

let mut prefix = body.get_prefix_mut(8);
for i in 4..8 {
prefix[i] = 0;
}

Try to consume the body as a JSON value, but only up to the first 4KiB. Note the use of take() to avoid writing the bytes back to the body unnecessarily:

let prefix = body.get_prefix_mut(4096).take();
let json: serde_json::Value = serde_json::from_slice(&prefix).unwrap();

Parameters

self: &mut Self
length: usize

Returns

get_prefix_str_mut

View source
fn get_prefix_str_mut(&mut self, length: usize) -> PrefixString<'_>

Get a prefix of the body as a string containing up to the given number of bytes.

This is particularly useful when you only need to inspect the first few characters of a body or want to read an entire body up to a certain size limit to control memory consumption.

Note that the length of the returned prefix may be shorter than the requested length if the length of the entire body is shorter or if the requested length fell in the middle of a multi-byte UTF-8 codepoint.

The returned PrefixString value is a smart pointer wrapping a &mut String. You can use it as you would a &mut String or a &mut str to view or modify the contents of the prefix.

When the PrefixString is dropped, the prefix characters are returned to the body, including any modifications that have been made. Because the prefix holds a mutable reference to the body, you may need to explicitly drop() the prefix before performing other operations on the body.

If you do not need to return the prefix characters to the body, use PrefixString::take() to consume the prefix as an owned string without writing it back.

Panics

If the prefix contains invalid UTF-8 bytes, this function will panic. The exception to this is if the bytes are invalid because a multi-byte codepoint is cut off by the requested prefix length. In this case, the invalid bytes are left off the end of the prefix.

To explicitly handle the possibility of invalid UTF-8 bytes, use try_get_prefix_str_mut(), which returns an error on failure rather than panicking.

Examples

Check whether the body starts with the M3U8 file header:

const HEADER: &str = "#EXTM3U";
let prefix = body.get_prefix_str_mut(7);
if prefix.as_str() == HEADER {
println!("might be an M3U8 file!");
}

Insert a new playlist entry before the first occurrence of #EXTINF in an M3U8 file:

let mut prefix = body.get_prefix_str_mut(1024);
let first_entry = prefix.find("#EXTINF").unwrap();
prefix.insert_str(first_entry, "#EXTINF:10.0,\nnew_first_file.ts\n");

Try to consume the body as a JSON value, but only up to the first 4KiB. Note the use of take() to avoid writing the characters back to the body unnecessarily:

let prefix = body.get_prefix_str_mut(4096).take();
let json: serde_json::Value = serde_json::from_str(&prefix).unwrap();

Parameters

self: &mut Self
length: usize

Returns

into_bytes

View source
fn into_bytes(self) -> Vec<u8>

Read the entirety of the body into a byte vector.

Memory usage

This method will cause the entire body to be buffering in WebAssembly memory. You should take care not to exceed the WebAssembly memory limits, and consider using methods like BufRead::lines() or Body::read_chunks() to control how much of the body you process at once.

Parameters

self: Self

Returns

Vec<u8>

into_handle

View source
fn into_handle(self) -> BodyHandle

Convert a Body into the low-level BodyHandle interface.

Parameters

self: Self

Returns

into_string

View source
fn into_string(self) -> String

Read the entirety of the body into a String, interpreting the bytes as UTF-8.

Memory usage

This method will cause the entire body to be buffering in WebAssembly memory. You should take care not to exceed the WebAssembly memory limits, and consider using methods like BufRead::lines() or Body::read_chunks() to control how much of the body you process at once.

Panics

If the body does not contain a valid UTF-8 string, this function will panic. To explicitly handle the possibility of invalid UTF-8 data, use into_bytes() and then convert the bytes explicitly with a function like String::from_utf8.

Parameters

self: Self

Returns

String

known_length

View source
fn known_length(&mut self) -> Option<u64>

The body's length in bytes, if it is known.

If the length is not known, it is likely due to the body arising from an HTTP/1.1 message with chunked encoding, an HTTP/2 or later message with no content-length, or other response-streaming technique.

Note that receiving a length from this function does not guarantee that the full number of bytes can actually be read from the body. For example, when proxying a response from a backend, this length may reflect the content-length promised in the response, but if the backend connection is closed prematurely, fewer bytes may be delivered before the body can no longer be read.

Parameters

self: &mut Self

Returns

Option<u64>
fn new() -> Self

Get a new, empty HTTP body.

Returns

Self

read_chunks

View source
fn read_chunks(&mut self, chunk_size: usize) -> impl Iterator<Item = Result<Vec<u8>, Error>> + '_

Return an iterator that reads the body in chunks of at most the given number of bytes.

If chunk_size does not evenly divide the length of the body, then the last chunk will not have length chunk_size.

Examples

1
2
3
4
5
6
7
8
9
10
11
use std::io::Write;
fn remove_0s(body: &mut Body) -> Result<(), Box<dyn std::error::Error>> {
let mut no_0s = Body::new();
for chunk in body.read_chunks(4096) {
let mut chunk = chunk?;
chunk.retain(|b| *b != 0);
no_0s.write_all(&chunk)?;
}
*body = no_0s;
Ok(())
}

Parameters

self: &mut Self
chunk_size: usize

Returns

impl Iterator<Item = Result<Vec<u8>, Error>> + '_

try_get_prefix_mut

View source
fn try_get_prefix_mut(&mut self, length: usize) -> Result<Prefix<'_>>

Try to get a prefix of the body up to the given number of bytes.

Unlike get_prefix_mut(), this method does not panic if an I/O error occurs.

Parameters

self: &mut Self
length: usize

Returns

std::io::Result<Prefix>

try_get_prefix_str_mut

View source
fn try_get_prefix_str_mut(&mut self, length: usize) -> Result<PrefixString<'_>, Utf8Error>

Try to get a prefix of the body as a string containing up to the given number of bytes.

Unlike get_prefix_str_mut(), this function does not panic when the prefix contains invalid UTF-8 bytes.

Parameters

self: &mut Self
length: usize

Returns

Trait implementations

impl BodyExt for Body

append_trailer

View source
fn append_trailer(&mut self, name: impl ToHeaderName, value: impl ToHeaderValue)

Parameters

self: &mut Self
name: impl ToHeaderName
value: impl ToHeaderValue

get_trailers

View source
fn get_trailers(&mut self) -> Result<HeaderMap, Error>

Parameters

self: &mut Self

Returns

impl BufRead for Body

fn consume(&mut self, amt: usize)

Parameters

self: &mut Self
amt: usize

fill_buf

View source
fn fill_buf(&mut self) -> Result<&[u8]>

Parameters

self: &mut Self

Returns

std::io::Result<&[u8]>

impl Debug for Body

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

Parameters

self: &Self
f: &mut std::fmt::Formatter

Returns

std::fmt::Result

impl From<&[u8]> for Body

fn from(s: &[u8]) -> Self

Parameters

s: &[u8]

Returns

Self

impl From<&str> for Body

fn from(s: &str) -> Self

Parameters

s: &str

Returns

Self

impl From<BodyHandle> for Body

fn from(handle: BodyHandle) -> Self

Parameters

handle: BodyHandle

Returns

Self

impl From<String> for Body

fn from(s: String) -> Self

Parameters

s: String

Returns

Self

impl From<Vec<u8>> for Body

fn from(s: Vec<u8>) -> Self

Parameters

s: Vec<u8>

Returns

Self

impl Read for Body

fn read(&mut self, buf: &mut [u8]) -> Result<usize>

Parameters

self: &mut Self
buf: &mut [u8]

Returns

std::io::Result<usize>

read_vectored

View source
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize>

Parameters

self: &mut Self
bufs: &mut [std::io::IoSliceMut]

Returns

std::io::Result<usize>

impl Write for Body

fn flush(&mut self) -> Result<()>

Parameters

self: &mut Self

Returns

std::io::Result<()>
fn write(&mut self, buf: &[u8]) -> Result<usize>

Parameters

self: &mut Self
buf: &[u8]

Returns

std::io::Result<usize>

write_vectored

View source
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize>

Parameters

self: &mut Self
bufs: &[std::io::IoSlice]

Returns

std::io::Result<usize>

Auto trait implementations

Blanket implementations