Struct OctetStream
pub struct OctetStream<S> { /* private fields */ }Expand description
An octet-stream response for serving arbitrary binary data.
Will automatically get Content-Type: application/octet-stream.
This is commonly used for:
- Serving unknown or arbitrary binary files
- Downloadable content that doesn’t fit other MIME types
- Raw binary data streams
User Agents often treat it as if the Content-Disposition header was set to attachment,
and propose a “Save As” dialog.
§Examples
§Basic binary response
use rama_http::service::web::response::{IntoResponse, OctetStream};
use rama_core::stream::io::ReaderStream;
async fn handler() -> impl IntoResponse {
let data = b"Hello";
let cursor = std::io::Cursor::new(data);
let stream = ReaderStream::new(cursor);
OctetStream::new(stream)
}§Download with filename and size
use rama_http::service::web::response::{IntoResponse, OctetStream};
use rama_core::stream::io::ReaderStream;
async fn download() -> impl IntoResponse {
let data = b"file contents";
let size = data.len() as u64;
let cursor = std::io::Cursor::new(data);
let stream = ReaderStream::new(cursor);
OctetStream::new(stream)
.with_file_name("data.bin".to_owned())
.with_content_size(size)
}§Partial content (range request)
use rama_http::service::web::response::OctetStream;
use rama_core::stream::io::ReaderStream;
// Serving first 5 bytes of "Hello, World!" (13 bytes total)
let partial_data = b"Hello";
let cursor = std::io::Cursor::new(partial_data);
let stream = ReaderStream::new(cursor);
let response = OctetStream::new(stream)
.with_content_size(13) // Total size of "Hello, World!"
.try_into_range_response(0..5)?; // Serving bytes 0-4Implementations§
§impl<S> OctetStream<S>
impl<S> OctetStream<S>
pub fn new(stream: S) -> OctetStream<S>
pub fn new(stream: S) -> OctetStream<S>
Create a new OctetStream response.
pub fn with_file_name(self, filename: String) -> OctetStream<S>
pub fn with_file_name(self, filename: String) -> OctetStream<S>
Set the filename for Content-Disposition: attachment header.
This will trigger a file download in browsers with the specified filename.
pub fn set_file_name(&mut self, filename: String) -> &mut OctetStream<S>
pub fn set_file_name(&mut self, filename: String) -> &mut OctetStream<S>
Set the filename for Content-Disposition: attachment header.
This will trigger a file download in browsers with the specified filename.
pub fn with_content_size(self, content_size: u64) -> OctetStream<S>
pub fn with_content_size(self, content_size: u64) -> OctetStream<S>
Set the content size for Content-Length- or as part of the Content-Range header.
This indicates the total size of the resource in bytes. When set, it will
be included as Content-Length header in normal responses, or used as the
complete length in Content-Range header for partial content responses.
pub fn set_content_size(&mut self, content_size: u64) -> &mut OctetStream<S>
pub fn set_content_size(&mut self, content_size: u64) -> &mut OctetStream<S>
Set the content size for Content-Length- or as part of the Content-Range header.
This indicates the total size of the resource in bytes. When set, it will
be included as Content-Length header in normal responses, or used as the
complete length in Content-Range header for partial content responses.
pub fn try_into_range_response(
self,
range: impl RangeBounds<u64>,
) -> Result<Response, Error>
pub fn try_into_range_response( self, range: impl RangeBounds<u64>, ) -> Result<Response, Error>
Convert into a partial content (HTTP 206) range response.
This method consumes the OctetStream and converts it into a Response
with HTTP 206 status and appropriate Content-Range header.
The content_size field must be set before calling this method to indicate
the total size of the complete resource.
§Arguments
range- The byte range being served (e.g.,0..500for bytes 0-499)
§Note
It is the responsibility of the caller to ensure that the stream contains the correct data matching the specified range. This method does not validate the stream contents against the provided range by design, to avoid performance overhead of reading the entire stream.
§Returns
Returns Ok(Response) with status 206 (Partial Content) if successful,
or Err(Error) if the range is invalid or content_size is not set.
§Example
use rama_http::service::web::response::OctetStream;
use rama_core::stream::io::ReaderStream;
// Serving first 5 bytes of "Hello, World!" (13 bytes total)
let partial_data = b"Hello";
let cursor = std::io::Cursor::new(partial_data);
let stream = ReaderStream::new(cursor);
let response = OctetStream::new(stream)
.with_content_size(13) // Total size of "Hello, World!"
.try_into_range_response(0..5)?; // Serving bytes 0-4pub async fn try_from_path(
path: impl AsRef<Path>,
) -> Result<OctetStream<ReaderStream<File>>, Error>
pub async fn try_from_path( path: impl AsRef<Path>, ) -> Result<OctetStream<ReaderStream<File>>, Error>
Create an OctetStream from a file path.
This constructor opens the file and automatically extracts metadata when available:
- File size is set as
content_sizeif the metadata can be read - Filename is extracted from the path if it can be converted to a valid UTF-8 string
Both operations are graceful - if metadata cannot be read or the filename cannot
be extracted, the corresponding field will be None.
§Arguments
path- Path to the file to serve
§Returns
Returns Ok(OctetStream) if the file can be opened, or Err(io::Error) if the
file cannot be accessed.
§Example
use rama_http::service::web::response::OctetStream;
use rama_core::stream::io::ReaderStream;
use tokio::fs::File;
// Opens file and automatically sets filename and content_size
let response = OctetStream::<ReaderStream<File>>::try_from_path("/path/to/file.bin").await?;pub async fn try_range_response_from_path(
path: impl AsRef<Path>,
start: u64,
end: u64,
) -> Result<Response, Error>
pub async fn try_range_response_from_path( path: impl AsRef<Path>, start: u64, end: u64, ) -> Result<Response, Error>
Create a range response directly from a file path.
This is a convenience method that combines file opening, seeking to the range start, and creating a partial content (HTTP 206) response in one step. It automatically extracts the filename from the path and uses the file size as the complete length.
§Arguments
path- Path to the file to servestart- Start byte position (inclusive)end- End byte position (exclusive, following Rust range convention)
§Returns
Returns Ok(Response) with status 206 (Partial Content) if successful,
or Err(io::Error) if the file cannot be accessed, or if the range is invalid.
§Example
use rama_http::service::web::response::OctetStream;
use rama_core::stream::io::ReaderStream;
use tokio::fs::File;
// Serve bytes 0-499 of a file
let response = OctetStream::<ReaderStream<File>>::try_range_response_from_path("/path/to/file.bin", 0, 500).await?;Trait Implementations§
§impl<S> Clone for OctetStream<S>where
S: Clone,
impl<S> Clone for OctetStream<S>where
S: Clone,
§fn clone(&self) -> OctetStream<S>
fn clone(&self) -> OctetStream<S>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more§impl<S> Debug for OctetStream<S>where
S: Debug,
impl<S> Debug for OctetStream<S>where
S: Debug,
§impl<S> From<S> for OctetStream<S>
impl<S> From<S> for OctetStream<S>
§fn from(stream: S) -> OctetStream<S>
fn from(stream: S) -> OctetStream<S>
Auto Trait Implementations§
impl<S> Freeze for OctetStream<S>where
S: Freeze,
impl<S> RefUnwindSafe for OctetStream<S>where
S: RefUnwindSafe,
impl<S> Send for OctetStream<S>where
S: Send,
impl<S> Sync for OctetStream<S>where
S: Sync,
impl<S> Unpin for OctetStream<S>where
S: Unpin,
impl<S> UnwindSafe for OctetStream<S>where
S: UnwindSafe,
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<R> IntoEndpointService<()> for R
impl<R> IntoEndpointService<()> for R
§fn into_endpoint_service(
self,
) -> impl Service<Request, Response = Response, Error = Infallible>
fn into_endpoint_service( self, ) -> impl Service<Request, Response = Response, Error = Infallible>
rama_core::Service.§impl<R, State> IntoEndpointServiceWithState<(), State> for R
impl<R, State> IntoEndpointServiceWithState<(), State> for R
§fn into_endpoint_service_with_state(
self,
_state: State,
) -> impl Service<Request, Response = Response, Error = Infallible>
fn into_endpoint_service_with_state( self, _state: State, ) -> impl Service<Request, Response = Response, Error = Infallible>
rama_core::Service with state.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§fn and<P, B, E>(self, other: P) -> And<T, P>
fn and<P, B, E>(self, other: P) -> And<T, P>
Policy that returns Action::Follow only if self and other return
Action::Follow. Read more