Interface ByteBody

All Known Subinterfaces:
AvailableByteBody, CloseableAvailableByteBody, CloseableByteBody, InternalByteBody
All Known Implementing Classes:
AvailableByteArrayBody, AvailableNettyByteBody, InputStreamByteBody, NettyByteBody, StreamingNettyByteBody

public interface ByteBody
This class represents a stream of bytes from an HTTP connection. These bytes may be streamed or fully in memory, depending on implementation.

Each ByteBody may only be used once for a "primary" operation (such as toInputStream()). However, before that primary operation, it may be split multiple times. Splitting returns a new ByteBody that is independent. That means if you want to do two primary operations on the same ByteBody, you can instead split it once and then do one of the primary operations on the body returned by split().

To ensure resource cleanup, split() returns a CloseableByteBody. This body must be closed if no terminal operation is performed, otherwise there may be a memory leak or stalled connection!

An individual ByteBody is not thread-safe: You may not call split() concurrently from multiple threads for example. However, the new ByteBody returned from split() is independent, so you may use it on a different thread as this one.

Since:
4.5.0
Author:
Jonas Konrad
  • Method Details

    • split

      Equivalent to split(SplitBackpressureMode.SLOWEST).
      Returns:
      The newly split body. Must be closed by the caller, unless a terminal operation is performed on it
    • split

      Create a new, independent ByteBody that contains the same data as this one.
      Parameters:
      backpressureMode - How to handle backpressure between the old and new body. See ByteBody.SplitBackpressureMode documentation
      Returns:
      The newly split body. Must be closed by the caller, unless a terminal operation is performed on it
    • allowDiscard

      @Contract("-> this") @NonNull default @NonNull ByteBody allowDiscard()
      Signal that the upstream may discard any remaining body data. Only if all consumers of the body allow discarding will the body be discarded, otherwise it will still be sent to all consumers. It is an optional operation.

      Discarding may be implemented e.g. by closing the input side of an HTTP/2 stream.

      This method must be called before any primary operation.

      Returns:
      This body
    • expectedLength

      @NonNull @NonNull OptionalLong expectedLength()
      Get the expected length of this body, if known (either from Content-Length or from previous buffering). The actual length will never exceed this value, though it may sometimes be lower if there is a connection error.

      This value may go from OptionalLong.empty() to a known value over the lifetime of this body.

      This is not a primary operation and does not modify this ByteBody.

      Returns:
      The expected length of this body
    • toInputStream

      @NonNull @NonNull InputStream toInputStream()
      Get this body as an InputStream.

      This is a primary operation. After this operation, no other primary operation or split() may be done.

      Returns:
      The streamed bytes
    • toByteArrayPublisher

      @NonNull @NonNull Publisher<byte[]> toByteArrayPublisher()
      Get this body as a reactive stream of byte arrays.

      This is a primary operation. After this operation, no other primary operation or split() may be done.

      Returns:
      The streamed bytes
    • toByteBufferPublisher

      @NonNull @NonNull Publisher<ByteBuffer<?>> toByteBufferPublisher()
      Get this body as a reactive stream of ByteBuffers. Note that the buffers may be reference counted, and the caller must take care of releasing them.

      This is a primary operation. After this operation, no other primary operation or split() may be done.

      Returns:
      The streamed bytes
    • buffer

      Buffer the full body and return an CompletableFuture that will complete when all bytes are available, or an error occurs.

      This is a primary operation. After this operation, no other primary operation or split() may be done.

      Returns:
      A future that completes when all bytes are available
    • move

      Create a new CloseableByteBody with the same content but an independent lifecycle, claiming this body in the process.

      This is a primary operation. After this operation, no other primary operation or split() may be done.

      The purpose of this method is to move the data to a different component in an application, making clear that the receiving component claims ownership of the body. If the sending component then closes the original ByteBody for example, it will have no impact on the new CloseableByteBody that the receiver is working with.

      Returns:
      A new CloseableByteBody with the same content.
      Since:
      4.8.0