Skip to content

File Upload

The file upload component allows users to select files and then upload them to your server.

You can include a file upload component as so:

go
FormFileUpload("spreadsheets")

Common Methods

For a list of common field component methods, see here.

Getting started

Security

Accepting file uploads from your users can expose your application and its server to security risks that may not be immediately apparent. Attackers often will try to upload files that are executable, like .php files, 'fake' files, files with pathing, etc. etc.. They then will attempt to run those malicious files by exploiting various parts of your application.

Iridium's pre-built file driver and its configuration options are designed to mitigate common security risks. However, this is not the end of securing your application. Introducing additional security measures like our auth, placing your application behind a firewall, etc. are all recommended.

We recommend taking your time in the following steps to make every effort to secure your application where applicable.

Iridium's file upload component is powered by filepond.

Local File Driver

The file upload component accepts a driver that handles the actual uploading of files to your server, in accordance with filepond's server requirements.

By default, the file upload component uses our local file driver, but you can also write your own driver to handle uploads to any other storage location (e.g. cloud storage services like AWS S3, Google Cloud Storage, etc.). It's worth checking our plugins to see if someone has already written a driver for your use case.

Learn more about the local file driver here

Path

Multiple

You can define if your FileUpload component allows multi files as so:

go
// static
FormFileUpload("spreadsheets").
    Multiple()


// callback
FormFileUpload("spreadsheets").
    MultipleFn(
        func (ctx FieldContext) bool {
            return false
        }
    )

Draggable

The Draggable option will allow users to drag file(s) into your input box. The default behaviour requires users to click on the box and then select their files with their system's file manager.

go
// static
FormFileUpload("spreadsheets").
    Draggable()

// callback
FormFileUpload("spreadsheets").
    DraggableFn(
        func (ctx FieldContext) bool {
            return false
        }
    )

Accept

The accepted method will define which types of files are accepted in your upload. This applies the following HTML input tag as seen here.

go
// static
FormFileUpload("images").
    Accept([]string{
        "image/png", "image/jpeg"
    })

// callback
FormFileUpload("images").
    Accept(
        func (ctx FieldContext) []string {
            return []string{
                "video/*",
            }
        }
    )

Capture

The Capture method is (generally) a mobile specific option that allows users to open specific device camera to generate a image file to upload. It will respect your Accept options. Read more here.

go
// static
FormFileUpload("images").
    Capture(config.UserCapture). // for front facing camera
    Caputre(config.EnvironmentCapture) // for back facing camera

// callback
FormFileUpload("images").
    CaptureFn(
        func (ctx FieldContext) config.FileUploadCapture {
            return config.UserCapture
        }
    )

Max Size Bytes

The MaxSizeBytes option will specify the maximum file sizes allowed in bytes.

go
// static
FormFileUpload("images").
    MaxSizeBytes(1024 << 32)

// callback
FormFileUpload("images").
    MaxSizeBytesFn(func (ctx FieldContext) int64 {
        return 2048  << 32
    })

Applies Rule

Storage Max File Count

The StorageMaxFileCount option will specify the maximum number of files allowed in your storage location.

go
// static
FormFileUpload("images".
    StorageMaxFileCount(10)

// callback
FormFileUpload("images").
    StorageMaxFileCountFn(func (ctx FieldContext) int {
        return 5
    })

If you don't specify a TempMaxFileCount, its value will be 3 times the StorageMaxFileCount value.

Applies Rule

Temp Max File Count

The TempMaxFileCount option will specify the maximum number of files allowed in your temporary storage location.

go
// static
FormFileUpload("images").
    TempMaxFileCount(10)
    
// callback
FormFileUpload("images").
    TempMaxFileCountFn(func (ctx FieldContext) int {
        return 3
    })

Applies Rule

Storage Max Dir Size Bytes

The StorageMaxDirSizeBytes option will specify the maximum size of the storage directory in bytes.

go
// static
FormFileUpload("images").
    StorageMaxDirSizeBytes(1024 << 32)
    
// callback
FormFileUpload("images").
    StorageMaxDirSizeBytesFn(func (ctx FieldContext) int64 {
        return 2048 << 32
    })

If you don't specify a TempMaxDirSizeBytes value, its value will be 3 times the StorageMaxDirSizeBytes value.

Applies Rule

Temp Max Dir Size Bytes

The TempMaxDirSizeBytes option will specify the maximum size of the temporary directory in bytes.

go
// static
FormFileUpload("images").
    TempMaxDirSizeBytes(1024 << 32)
    
// callback
FormFileUpload("images").
    TempMaxDirSizeBytesFn(func (ctx FieldContext) int64 {
        return 2048 << 32
    })

Applies Rule

Max File Name Length

The MaxFileNameLength option will specify the maximum length of the file name allowed.

go
// static
FormFileUpload("images").
    MaxFilenameLength(100)
    
// callback
FormFileUpload("images").
    MaxFilenameLengthFn(func (ctx FieldContext) int {
        return 100
    })

Applied Rule

Keep in mind that the file's UUID is prefix to the name when stored on your server.

Blocked Extensions

The BlockedExtensions option will specify the file extensions that are blocked from being uploaded.

go
// static
FormFileUpload("files").
    BlockedExtensions([]string{"exe", "php"})
    
//callback
FormFileUpload("files").
    BlockedExtensionsFn(func (ctx FieldContext) []string {
        return []string{"php"}
    })

Unsafe

Checking a file's extension is not a foolproof way to prevent malicious files from being uploaded. An honest user will be warned that their file is not accepted due to their extension, but an attacker could simply rename a .php file to .txt and upload it.

For this reason, prefer AllowedMimeTypes instead.

Allowed Extensions

The AllowedExtensions option will specify the file extensions that are allowed to be uploaded.

go
// static
FormFileUpload("files").
    AllowedExtensions([]string{"png","txt"})
    
//callback
FormFileUpload("files").
    AllowedExtensionsFn(func (ctx FieldContext) []string {
        return []string{"png"}
    })

Unsafe

Checking a file's extension is not a foolproof way to prevent malicious files from being uploaded. An honest user will be warned that their file is not accepted due to their extension, but an attacker could simply rename a .php file to .txt and upload it.

For this reason, prefer AllowedMimeTypes instead.

Allowed Mime Types

The AllowedMimeTypes option will specify the mime types that are allowed to be uploaded.

go
// static
FormFileUpload("files").
    AllowedMimeTypes([]string{"image/png", "image/jpeg"})
    
// callback
FormFileUpload("files").
    AllowedMimeTypesFn(func (ctx FieldContext) []string {
        return []string{"image/png"}
    })

The MimeType is generated server-side using http.DetectContentType. For this reason it is preferred to use this option over file extension rules that can be spoofed.

Rules

The Rules option allows you to specify custom validation rules for your file uploads.

go
import"github.com/iridiumgo/iridium/core/rules"

FormFileUpload("files").
    Rules(
        rules.MaxFileNameLength(24),
    ),

Async

The Async method allows you to immediantly upload a user's chosen file as soon as it is selected. The default file upload box will wait till the user submits their form to post their files.

go
// static
FormFileUpload("images").
    Async()

// callback
FormFileUpload("images").
    AsyncFn(
        func (ctx FieldContext) bool {
            return true
        }
    }

Validation & Rules

Server Side

Unlike similar form components, Iridium does not bundle in rules for your file upload components. Instead, Iridium passes in a UploadConfig struct to the StoreFilesUsing method. This allows you to take full control of your validation for file uploads.

Iridium still resolves your file upload's configuration (which includes things like the max file size, max count of files, etc.) from your file uploads *Fn methods for you, but their enforcement is not handled for you when you write a custom store method. You'll need to do that on your own.

Our default StoreFilesUsing method has its own implementation of enforcing these rules however, so if you rely on our implementation, your files will be validated.

Client side

Client side validation occurs using our file upload component based on the rules you apply to your component, so you don't need to worry about these. If you want greater control, we recommend overriding the file upload component yourself

Released under the MIT License.