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§

source§

impl Body

source

pub fn new() -> Self

Get a new, empty HTTP body.

source

pub fn into_handle(self) -> BodyHandle

Convert a Body into the low-level BodyHandle interface.

source

pub 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.

source

pub 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.

source

pub 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.

source

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

👎Deprecated since 0.10.0: use std::io::Write::write() instead

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

pub fn write_str(&mut self, string: &str) -> usize

👎Deprecated since 0.10.0: use std::io::Write::write() instead

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

§Examples
body.write_str("woof woof");
source

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

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
use std::io::Write;
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_all(&chunk).unwrap();
    }
    *body = no_0s;
}
source

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

pub 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.

source

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

pub 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.

Trait Implementations§

source§

impl BodyExt for Body

source§

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

Append the given trailer name and value to this body. Read more
source§

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

Get the trailers associated with this body. Read more
source§

impl BufRead for Body

source§

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

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

fn consume(&mut self, amt: usize)

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
source§

fn has_data_left(&mut self) -> Result<bool, Error>

🔬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
1.0.0 · source§

fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize, Error>

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

fn skip_until(&mut self, byte: u8) -> Result<usize, Error>

🔬This is a nightly-only experimental API. (bufread_skip_until)
Skip all bytes until the delimiter byte or EOF is reached. Read more
1.0.0 · source§

fn read_line(&mut self, buf: &mut String) -> Result<usize, Error>

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

fn split(self, byte: u8) -> Split<Self>
where Self: Sized,

Returns an iterator over the contents of this reader split on the byte byte. Read more
1.0.0 · source§

fn lines(self) -> Lines<Self>
where Self: Sized,

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

impl Debug for Body

source§

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

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

impl From<&[u8]> for Body

source§

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

Converts to this type from the input type.
source§

impl From<&str> for Body

source§

fn from(s: &str) -> Self

Converts to this type from the input type.
source§

impl From<BodyHandle> for Body

source§

fn from(handle: BodyHandle) -> Self

Converts to this type from the input type.
source§

impl From<String> for Body

source§

fn from(s: String) -> Self

Converts to this type from the input type.
source§

impl From<Vec<u8>> for Body

source§

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

Converts to this type from the input type.
source§

impl Read for Body

source§

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

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

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

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

fn is_read_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Reader has an efficient read_vectored implementation. Read more
1.0.0 · source§

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>

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

fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>

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

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

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

fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Pull some bytes from this source into the specified buffer. Read more
source§

fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Read the exact number of bytes required to fill cursor. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

Creates a “by reference” adaptor for this instance of Read. Read more
1.0.0 · source§

fn bytes(self) -> Bytes<Self>
where Self: Sized,

Transforms this Read instance to an Iterator over its bytes. Read more
1.0.0 · source§

fn chain<R>(self, next: R) -> Chain<Self, R>
where R: Read, Self: Sized,

Creates an adapter which will chain this stream with another. Read more
1.0.0 · source§

fn take(self, limit: u64) -> Take<Self>
where Self: Sized,

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

impl Write for Body

source§

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

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

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

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

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

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

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored implementation. Read more
1.0.0 · source§

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

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

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · source§

fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error encountered. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

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

Auto Trait Implementations§

§

impl Freeze for Body

§

impl RefUnwindSafe for Body

§

impl Send for Body

§

impl Sync for Body

§

impl Unpin for Body

§

impl UnwindSafe for Body

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> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

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

§

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.