Struct fastly::Body

source · []
pub struct Body { /* private fields */ }
Expand description

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().

Implementations

Get a new, empty HTTP body.

Convert a Body into the low-level BodyHandle interface.

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.

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.

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.

Write a slice of bytes to the end of this body, and return the number of bytes written.

Examples
body.write_bytes(&[0, 1, 2, 3]);

Write a string slice to the end of this body, and return the number of bytes written.

Examples
body.write_str("woof woof");

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
fn remove_0s(body: &mut Body) {
    let mut no_0s = Body::new();
    for chunk in body.read_chunks(4096) {
        let mut chunk = chunk.unwrap();
        chunk.retain(|b| *b != 0);
        no_0s.write_bytes(&chunk);
    }
    *body = no_0s;
}

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] 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();

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();

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.

Trait Implementations

Returns the contents of the internal buffer, filling it with more data from the inner reader if it is empty. Read more

Tells this buffer that amt bytes have been consumed from the buffer, so they should no longer be returned in calls to read. Read more

🔬 This is a nightly-only experimental API. (buf_read_has_data_left)

Check if the underlying Read has any data left to be read. Read more

Read all bytes into buf until the delimiter byte or EOF is reached. Read more

Read all bytes until a newline (the 0xA byte) is reached, and append them to the provided buffer. Read more

Returns an iterator over the contents of this reader split on the byte byte. Read more

Returns an iterator over the lines of this reader. Read more

Formats the value using the given formatter. Read more

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Pull some bytes from this source into the specified buffer, returning how many bytes were read. Read more

Like read, except that it reads into a slice of buffers. Read more

🔬 This is a nightly-only experimental API. (can_vector)

Determines if this Reader has an efficient read_vectored implementation. Read more

Read all bytes until EOF in this source, placing them into buf. Read more

Read all bytes until EOF in this source, appending them to buf. Read more

Read the exact number of bytes required to fill buf. Read more

🔬 This is a nightly-only experimental API. (read_buf)

Pull some bytes from this source into the specified buffer. Read more

🔬 This is a nightly-only experimental API. (read_buf)

Read the exact number of bytes required to fill buf. Read more

Creates a “by reference” adaptor for this instance of Read. Read more

Transforms this Read instance to an Iterator over its bytes. Read more

Creates an adapter which will chain this stream with another. Read more

Creates an adapter which will read at most limit bytes from it. Read more

Write a buffer into this writer, returning how many bytes were written. Read more

Like write, except that it writes from a slice of buffers. Read more

Flush this output stream, ensuring that all intermediately buffered contents reach their destination. Read more

🔬 This is a nightly-only experimental API. (can_vector)

Determines if this Writer has an efficient write_vectored implementation. Read more

Attempts to write an entire buffer into this writer. Read more

🔬 This is a nightly-only experimental API. (write_all_vectored)

Attempts to write multiple buffers into this writer. Read more

Writes a formatted string into this writer, returning any error encountered. Read more

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

Should always be Self

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.