Enum rocket::fs::TempFile[][src]

pub enum TempFile<'v> {
    // some variants omitted
}
Expand description

A data and form guard that streams data into a temporary file.

TempFile is a data and form field (both value and data fields) guard that streams incoming data into file in a temporary location. The file is deleted when the TempFile handle is dropped unless it is persisted with TempFile::persist_to() or copied with TempFile::copy_to().

Hazards

Temporary files are cleaned by system file cleaners periodically. While an attempt is made not to delete temporary files in use, detection of when a temporary file is being used is unreliable. As a result, a time-of-check to time-of-use race condition from the creation of a TempFile to the persistence of the TempFile may occur. Specifically, the following sequence may occur:

  1. A TempFile is created at random path foo.
  2. The system cleaner removes the file at path foo.
  3. Another application creates a file at path foo.
  4. The TempFile, ostesnsibly at path, foo, is persisted unexpectedly with contents different from those in step 1.

To safe-guard against this issue, you should ensure that your temporary file cleaner, if any, does not delete files too eagerly.

Configuration

TempFile is configured via the following config parameters:

NameDefaultDescription
temp_direnv::temp_dir()Directory files are temporarily stored.
limits.file1MiBDefault limit for all file extensions.
limits.file/$extN/ALimit for files with extension $ext.

When used as a form guard, the extension $ext is identified by the form field’s Content-Type (ContentType::extension()). When used as a data guard, the extension is identified by the Content-Type of the request, if any. If there is no Content-Type, the limit file is used.

Cappable

A data stream can be partially read into a TempFile even if the incoming stream exceeds the data limit via the Capped<TempFile> data and form guard.

Examples

Data Guard

use rocket::fs::TempFile;

#[post("/upload", data = "<file>")]
async fn upload(mut file: TempFile<'_>) -> std::io::Result<()> {
    file.persist_to("/tmp/complete/file.txt").await?;
    Ok(())
}

Form Field

use rocket::fs::TempFile;
use rocket::form::Form;

#[derive(FromForm)]
struct Upload<'f> {
    upload: TempFile<'f>
}

#[post("/form", data = "<form>")]
async fn upload(mut form: Form<Upload<'_>>) -> std::io::Result<()> {
    form.upload.persist_to("/tmp/complete/file.txt").await?;
    Ok(())
}

See also the Capped documentation for an example of Capped<TempFile> as a data guard.

Implementations

impl<'v> TempFile<'v>[src]

pub async fn persist_to<P>(&mut self, path: P) -> Result<()> where
    P: AsRef<Path>, 
[src]

Persists the temporary file, moving it to path. If a file exists at the target path, self will atomically replace it. self.path() is updated to path.

This method does not create a copy of self, nor a new link to the contents of self: it renames the temporary file to path and marks it as non-temporary. As a result, this method cannot be used to create multiple copies of self. To create multiple links, use std::fs::hard_link() with path as the src after calling this method.

Cross-Device Persistence

Attemping to persist a temporary file across logical devices (or mount points) will result in an error. This is a limitation of the underlying OS. Your options are thus:

  1. Store temporary file in the same logical device.

    Change the temp_dir configuration parameter to be in the same logical device as the permanent location. This is the preferred solution.

  2. Copy the temporary file using TempFile::copy_to() or TempFile::move_copy_to() instead.

    This is a full copy of the file, creating a duplicate version of the file at the destination. This should be avoided for performance reasons.

Example

use rocket::fs::TempFile;

#[post("/", data = "<file>")]
async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
    file.persist_to(&some_path).await?;
    assert_eq!(file.path(), Some(&*some_path));

    Ok(())
}

pub async fn copy_to<P>(&mut self, path: P) -> Result<()> where
    P: AsRef<Path>, 
[src]

Persists the temporary file at its temporary path and creates a full copy at path. The self.path() is not updated, unless no temporary file existed prior, and the temporary file is not removed. Thus, there will be two files with the same contents.

Unlike TempFile::persist_to(), this method does not incur cross-device limitations, at the performance cost of a full copy. Prefer to use persist_to() with a valid temp_dir configuration parameter if no more than one copy of a file is required.

Example

use rocket::fs::TempFile;

#[post("/", data = "<file>")]
async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
    file.copy_to(&some_path).await?;
    file.copy_to(&some_other_path).await?;
    assert_eq!(file.path(), Some(&*some_path));

    Ok(())
}

pub async fn move_copy_to<P>(&mut self, path: P) -> Result<()> where
    P: AsRef<Path>, 
[src]

Persists the temporary file at its temporary path, creates a full copy at path, and then deletes the temporary file. self.path() is updated to path.

Like TempFile::copy_to() and unlike TempFile::persist_to(), this method does not incur cross-device limitations, at the performance cost of a full copy and file deletion. Prefer to use persist_to() with a valid temp_dir configuration parameter if no more than one copy of a file is required.

Example

use rocket::fs::TempFile;

#[post("/", data = "<file>")]
async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
    file.move_copy_to(&some_path).await?;

    Ok(())
}

pub fn len(&self) -> u64[src]

Returns the size, in bytes, of the file.

This method does not perform any system calls.

use rocket::fs::TempFile;

#[post("/", data = "<file>")]
fn handler(file: TempFile<'_>) {
    let file_len = file.len();
}

pub fn path(&self) -> Option<&Path>[src]

Returns the path to the file if it is known.

Once a file is persisted with TempFile::persist_to(), this method is guaranteed to return Some. Prior to this point, however, this method may return Some or None, depending on whether the file is on disk or partially buffered in memory.

use rocket::fs::TempFile;

#[post("/", data = "<file>")]
async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
    file.persist_to(&some_path).await?;
    assert_eq!(file.path(), Some(&*some_path));

    Ok(())
}

pub fn name(&self) -> Option<&str>[src]

Returns the sanitized file name as specified in the form field.

A multipart data form field can optionally specify the name of a file. A browser will typically send the actual name of a user’s selected file in this field, but clients are also able to specify any name, including invalid or dangerous file names. This method returns a sanitized version of that value, if it was specified, suitable and safe for use as a permanent file name.

Note that you will likely want to prepend or append random or user-specific components to the name to avoid collisions; UUIDs make for a good “random” data.

See FileName::as_str() for specifics on sanitization.

use rocket::fs::TempFile;

#[post("/", data = "<file>")]
async fn handle(mut file: TempFile<'_>) -> std::io::Result<()> {
    if let Some(name) = file.name() {
        // Because of Rocket's sanitization, this is safe.
        file.persist_to(&some_dir.join(name)).await?;
    }

    Ok(())
}

pub fn raw_name(&self) -> Option<&FileName>[src]

Returns the raw name of the file as specified in the form field.

use rocket::fs::TempFile;

#[post("/", data = "<file>")]
async fn handle(mut file: TempFile<'_>) {
    let raw_name = file.raw_name();
}

pub fn content_type(&self) -> Option<&ContentType>[src]

Returns the Content-Type of the file as specified in the form field.

A multipart data form field can optionally specify the content-type of a file. A browser will typically sniff the file’s extension to set the content-type. This method returns that value, if it was specified.

use rocket::fs::TempFile;

#[post("/", data = "<file>")]
fn handle(file: TempFile<'_>) {
    let content_type = file.content_type();
}

Trait Implementations

impl<'v> Debug for TempFile<'v>[src]

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

Formats the value using the given formatter. Read more

impl<'impl0, 'r> FromData<'r> for TempFile<'impl0>[src]

type Error = <Capped<Self> as FromData<'r>>::Error

The associated error to be returned when the guard fails.

fn from_data<'life0, 'async_trait>(
    r: &'r Request<'life0>,
    d: Data<'r>
) -> Pin<Box<dyn Future<Output = Outcome<'r, Self>> + Send + 'async_trait>> where
    'r: 'async_trait,
    'life0: 'async_trait,
    Self: 'async_trait, 
[src]

Asynchronously validates, parses, and converts an instance of Self from the incoming request body data. Read more

impl<'v> FromFormField<'v> for TempFile<'v>[src]

fn default() -> Option<Self>[src]

Returns a default value, if any exists, to be used during lenient parsing when the form field is missing. Read more

fn from_value(f: ValueField<'v>) -> Result<'v, Self>[src]

Parse a value of T from a form value field. Read more

fn from_data<'life0, 'async_trait>(
    field: DataField<'v, 'life0>
) -> Pin<Box<dyn Future<Output = Result<'v, Self>> + Send + 'async_trait>> where
    'v: 'async_trait,
    'life0: 'async_trait,
    Self: 'async_trait, 
[src]

Parse a value of T from a form data field. Read more

impl Len<ByteUnit> for TempFile<'_>[src]

fn len(&self) -> ByteUnit[src]

The length of the value.

fn len_into_u64(len: ByteUnit) -> u64[src]

Convert len into u64.

fn zero_len() -> ByteUnit[src]

The zero value for L.

impl Len<u64> for TempFile<'_>[src]

fn len(&self) -> u64[src]

The length of the value.

fn len_into_u64(len: u64) -> u64[src]

Convert len into u64.

fn zero_len() -> u64[src]

The zero value for L.

Auto Trait Implementations

impl<'v> RefUnwindSafe for TempFile<'v>

impl<'v> Send for TempFile<'v>

impl<'v> Sync for TempFile<'v>

impl<'v> Unpin for TempFile<'v>

impl<'v> UnwindSafe for TempFile<'v>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

pub fn type_id(&self) -> TypeId[src]

Gets the TypeId of self. Read more

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

pub fn borrow(&self) -> &T[src]

Immutably borrows from an owned value. Read more

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

pub fn borrow_mut(&mut self) -> &mut T[src]

Mutably borrows from an owned value. Read more

impl<T> From<T> for T[src]

pub fn from(t: T) -> T[src]

Performs the conversion.

impl<T> Instrument for T[src]

fn instrument(self, span: Span) -> Instrumented<Self>[src]

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more

fn in_current_span(self) -> Instrumented<Self>[src]

Instruments this type with the current Span, returning an Instrumented wrapper. Read more

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

pub fn into(self) -> U[src]

Performs the conversion.

impl<T> IntoCollection<T> for T

pub fn into_collection<A>(self) -> SmallVec<A> where
    A: Array<Item = T>, 

Converts self into a collection.

pub fn mapped<U, F, A>(self, f: F) -> SmallVec<A> where
    F: FnMut(T) -> U,
    A: Array<Item = U>, 

impl<T> Same<T> for T

type Output = T

Should always be Self

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

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

Performs the conversion.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>[src]

Performs the conversion.

impl<V, T> VZip<V> for T where
    V: MultiLane<T>, 

pub fn vzip(self) -> V