rustypaste is a free, open source file management & sync project written in Rust and released under MIT. It has 1,211 GitHub stars, 90 forks and 20 open issues, and was last pushed 6 days ago. On this registry it ranks #53 of 61 tracked projects in File Management & Sync, with 5 head-to-head comparisons available.

What is rustypaste?

Rustypaste is a minimal, self-hosted file upload and pastebin service written in Rust, meant for individuals and small teams who want to share files and text over their own endpoint rather than through a third-party paste site.

What it is

Rustypaste is a single-binary HTTP service written in Rust and released under the MIT licence. It lives in the Rust ecosystem and is distributed through crates.io as the rustypaste crate, through binary releases, through package repositories such as Arch Linux and Alpine Linux, FreeBSD ports, and as a Docker image. Its interface is deliberately plain: you push content with a curl -F "file=@awesome.txt" multipart upload and receive back a direct link such as https://paste.site.com/safe-toad.txt, which anyone can fetch with curl.

The concrete problem it solves is file and text sharing without operating infrastructure for it. There is no database — the filesystem is the storage layer — and configuration is a simple file that supports hot reloading, so a self-hoster does not need to run a database server, a queue, or an admin stack to get a working paste and file-sharing endpoint. It replaces a hosted pastebin or file-sharing site with a service you run yourself, keeping the uploaded content on storage you control.

Key capabilities

  • Handles file upload, URL shortening, and pasting a file from a remote URL through the same endpoint, returning a shareable link.
  • Generates random file names in three selectable styles: pet names such as capital-mosquito.txt, alphanumeric strings such as yB84D2Dv.txt, and random suffixes such as file.MRV5as.tar.gz.
  • Supports expiring links, optional auto-expiration of files, optional auto-deletion of expired files, and one-shot links or URLs that can be viewed only once.
  • Protects files with passwords, including auto-generated passwords, hashed with Argon2id.
  • Restricts access with basic HTTP authentication, and exposes a list endpoint for enumerating stored files alongside deletion of files from the server.
  • Guesses MIME types, forces download through the ?download=true query parameter, and can be configured to reject duplicate uploads.
  • Offers filename overriding and blacklisting, a custom landing page, an HTML form, and a configuration file that hot-reloads.

Who uses it and how

  • Developers who share snippets and files straight from the terminal, using curl to upload and to read back the resulting URL.
  • Operators who deploy it as a container, using the r/orhunp/rustypaste image on Docker Hub or the appjail images, often placed behind an Nginx configuration as documented in the README.
  • Self-hosters who want uploaded content to remain on their own filesystem rather than on a hosted paste service.
  • Teams that need short-lived sharing, using expiring links, one-shot links, and password-protected files for content that should not stay publicly reachable.
  • Contributors working on the project through its Rust codebase, which is tagged for Hacktoberfest.

Getting started

Install with cargo install rustypaste from crates.io, or pacman -S rustypaste on Arch Linux; for containers, run the Docker image r/orhunp/rustypaste from Docker Hub.

How it compares

Rustypaste stands alone in this registry: no comparable tools are named in the available facts, so no direct contrast on licence, hosting, or cost can be drawn from them.

When to use it — and when not

Because it uses the filesystem instead of a database, a self-hoster's operational burden is the storage directory and the configuration file, plus the reverse proxy and basic HTTP authentication setup if the endpoint is public — there is no database or SMTP service to run. It is a poor fit for anyone who needs user accounts, quotas, an administration interface, or a managed hosted option, and the project still carries 20 open issues, so edge cases in uploads and file handling may not all be settled.

project readme (upstream, from github) — read inline

GitHub Release Crate Release Coverage Continuous Integration Continuous Deployment Docker Builds Documentation

Rustypaste is a minimal file upload/pastebin service.

$ echo "some text" > awesome.txt

$ curl -F "file=@awesome.txt" https://paste.site.com
https://paste.site.com/safe-toad.txt

$ curl https://paste.site.com/safe-toad.txt
some text
Table of Contents

Features

  • File upload & URL shortening & upload from URL
    • supports basic HTTP authentication
    • random file names (optional)
      • pet name (e.g. capital-mosquito.txt)
      • alphanumeric string (e.g. yB84D2Dv.txt)
      • random suffix (e.g. file.MRV5as.tar.gz)
    • supports expiring links
      • auto-expiration of files (optional)
      • auto-deletion of expired files (optional)
    • supports one shot links/URLs (can only be viewed once)
    • supports password-protected files
      • auto-generated passwords
      • Argon2id hashing
    • guesses MIME types
      • supports overriding and blacklisting
      • supports forcing to download via ?download=true
    • no duplicate uploads (optional)
    • listing/deleting files
    • custom landing page
  • Single binary
  • Simple configuration
    • supports hot reloading
  • Easy to deploy
  • No database
    • filesystem is used
  • Self-hosted
    • centralization is bad!
  • Written in Rust
    • blazingly fast!

Installation

Packaging status

Packaging status

From crates.io

cargo install rustypaste

Arch Linux

pacman -S rustypaste

Alpine Linux

rustypaste is available for Alpine Edge. It can be installed via apk after enabling the community repository.

apk add rustypaste

FreeBSD

pkg install rustypaste

Binary releases

See the available binaries on the releases page.

Build from source

git clone https://github.com/orhun/rustypaste.git
cd rustypaste/
cargo build --release
Feature flags
  • openssl: use distro OpenSSL (binary size is reduced ~20% in release mode)
  • rustls: use rustls (enabled as default)

To enable a feature for build, pass --features flag to cargo build command.

For example, to reuse the OpenSSL present on a distro already:

cargo build --release --no-default-features --features openssl
Testing
Unit tests
cargo test -- --test-threads 1
Test Fixtures
./fixtures/test-fixtures.sh

Usage

The standalone command line tool (rpaste) is available here.

CLI

function rpaste() {
  curl -F "file=@$1" -H "Authorization: <auth_token>" "<server_address>"
}

* consider reading authorization headers from a file. (e.g. -H @rpaste_auth)

# upload a file
$ rpaste x.txt

# paste from stdin
$ rpaste -
Expiration
$ curl -F "file=@x.txt" -H "expire:10min" "<server_address>"

supported units:

  • nsec, ns
  • usec, us
  • msec, ms
  • seconds, second, sec, s
  • minutes, minute, min, m
  • hours, hour, hr, h
  • days, day, d
  • weeks, week, w
  • months, month, M
  • years, year, y
One shot files
$ curl -F "oneshot=@x.txt" "<server_address>"
One shot URLs
$ curl -F "oneshot_url=https://example.com" "<server_address>"
Password-protected files

Upload a file with auto-generated password:

$ curl -F "protected=@secret.txt" "<server_address>"
https://paste.site.com/secret.txt
Password: aBcD1234EfGh5678IjKl9012

Download with Bearer token:

$ curl -H "Authorization: Bearer aBcD1234EfGh5678IjKl9012" https://paste.site.com/secret.txt

Or with Basic Auth:

$ curl -u "user:aBcD1234EfGh5678IjKl9012" https://paste.site.com/secret.txt

Note: Protected files cannot be combined with other paste types (oneshot, URL). The password is permanently tied to the file and cannot be changed. If the password is lost, the file becomes inaccessible. Password files are deleted automatically when the main file is deleted or expires.

URL shortening
$ curl -F "url=https://example.com/some/long/url" "<server_address>"
Paste file from remote URL
$ curl -F "remote=https://example.com/file.png" "<server_address>"
Cleaning up expired files

Configure [paste].delete_expired_files to set an interval for deleting the expired files automatically.

On the other hand, following script can be used as cron for cleaning up the expired files manually:

#!/bin/env sh
now=$(date +%s)
find upload/ -maxdepth 2 -type f -iname "*.[0-9]*" |
while read -r filename; do
	[ "$(( ${filename##*.} / 1000 - "${now}" ))" -lt 0 ] && rm -v "${filename}"
done
Delete file from server

Set delete_tokens array in config.toml to activate the DELETE endpoint and secure it with one (or more) auth token(s).

$ curl -H "Authorization: <auth_token>" -X DELETE "<server_address>/file.txt"

The DELETE endpoint will not be exposed and will return 404 error if delete_tokens are not set.

Override the filename

When using the random_url config option, or when pasting a file from remote URL, rustypaste automatically selects a filename.

This can be overridden by sending a header called filename:

curl -F "file=@x.txt" -H "filename: <file_name>" "<server_address>"
curl -F "remote=https://example.com/file.png" -H "filename: <file_name>" "<server_address>"

Server

To start the server:

$ rustypaste

If the configuration file is not found in the current directory, specify it via CONFIG environment variable:

$ CONFIG="$HOME/.rustypaste.toml" rustypaste
Authentication

To enable basic HTTP auth, set the AUTH_TOKEN environment variable (via .env):

$ echo "AUTH_TOKEN=$(openssl rand -base64 16)" > .env
$ rustypaste

There are 2 options for setting multiple auth tokens:

  • Via the array field [server].auth_tokens in your config.toml.
  • Or by writing a newline separated list to a file and passing its path to rustypaste via AUTH_TOKENS_FILE and DELETE_TOKENS_FILE respectively.

If neither AUTH_TOKEN, AUTH_TOKENS_FILE nor [server].auth_tokens are set, the server will not require any authentication.

Exception is the DELETE endpoint, which requires at least one token to be set. See deleting files from server for more information.

See config.toml for configuration options.

MIME handling

rustypaste determines a file's MIME type from its extension (with optional overrides) and serves text-like types as text/plain; charset=utf-8 to avoid script execution.

  • [paste].mime_override lets you override MIME types by filename regex.
  • [paste].mime_blacklist blocks uploads of specific MIME types.
  • [paste].text_mime_overrides forces additional detected/guessed MIME types to be rendered as plaintext (unlike mime_override which matches by filename regex, this matches the content's actual MIME type).
List endpoint

Set expose_list to true in config.toml to be able to retrieve a JSON formatted list of files in your uploads directory. This will not include oneshot files, oneshot URLs, or URLs.

$ curl "http://<server_address>/list"

[{"file_name":"accepted-cicada.txt","file_size":241,"expires_at_utc":null}]

This route will require an AUTH_TOKEN if one is set.

HTML Form

It is possible to use an HTML form for uploading files. To do so, you need to update two fields in your config.toml:

  • Set the [landing_page].content_type to text/html; charset=utf-8.
  • Update the [landing_page].text field with your HTML form or point [landing_page].file to your html file.

For an example, see examples/html_form.toml

Docker

Following command can be used to run a container which is built from the Dockerfile in this repository:

$ docker run --rm -d \
  -v "$(pwd)/upload/":/app/upload \
  -v "$(pwd)/config.toml":/app/config.toml \
  --env-file "$(pwd)/.env" \
  -e "RUST_LOG=debug" \
  -p 8000:8000 \
  --name rustypaste \
  orhunp/rustypaste
  • uploaded files go into ./upload (on the host machine)
  • set the AUTH_TOKEN via -e or --env-file to enable auth

You can build this image using docker build -t rustypaste . command.

If you want to run the image using docker compose, simply run docker-compose up -d. (see docker-compose.yml)

Nginx

Example server configuration with reverse proxy:

server {
    listen 80;
    location / {
        proxy_pass                         http://localhost:8000/;
        proxy_set_header Host              $host;
        proxy_set_header X-Forwarded-For   $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        add_header X-XSS-Protection        "1; mode=block";
        add_header X-Frame-Options         "sameorigin";
        add_header X-Content-Type-Options  "nosniff";
    }
}

If you get a 413 Request Entity Too Large error during upload, set the max body size in nginx.conf:

http {
    # ...
    client_max_body_size 100M;
}

Third Party Clients

Contributing

Pull requests are welcome!

Consider submitting your ideas via issues first and check out the existing issues.

License
All code is licensed under The MIT License.

Frequently asked questions

Is rustypaste free to use?

rustypaste is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does rustypaste do?

A minimal file upload/pastebin service.

What is rustypaste written in?

rustypaste is primarily written in Rust. Its source is publicly available at https://github.com/orhun/rustypaste, and it has 1,211 GitHub stars.