2021-07-26 18:29:46 +00:00
< a href = "https://github.com/orhun/rustypaste" > < img src = "img/rustypaste_logo.png" width = "500" > < / a >
2023-05-17 01:32:54 +00:00
[![GitHub Release ](https://img.shields.io/github/v/release/orhun/rustypaste?style=flat&labelColor=823213&color=2c2c2c&logo=GitHub&logoColor=white )](https://github.com/orhun/rustypaste/releases)
[![Crate Release ](https://img.shields.io/crates/v/rustypaste?style=flat&labelColor=823213&color=2c2c2c&logo=Rust&logoColor=white )](https://crates.io/crates/rustypaste/)
[![Coverage ](https://img.shields.io/codecov/c/gh/orhun/rustypaste?style=flat&labelColor=823213&color=2c2c2c&logo=Codecov&logoColor=white )](https://codecov.io/gh/orhun/rustypaste)
[![Continuous Integration ](https://img.shields.io/github/actions/workflow/status/orhun/rustypaste/ci.yml?branch=master&style=flat&labelColor=823213&color=2c2c2c&logo=GitHub%20Actions&logoColor=white )](https://github.com/orhun/rustypaste/actions?query=workflow%3A%22Continuous+Integration%22)
[![Continuous Deployment ](https://img.shields.io/github/actions/workflow/status/orhun/rustypaste/cd.yml?style=flat&labelColor=823213&color=2c2c2c&logo=GitHub%20Actions&logoColor=white&label=deploy )](https://github.com/orhun/rustypaste/actions?query=workflow%3A%22Continuous+Deployment%22)
[![Docker Builds ](https://img.shields.io/github/actions/workflow/status/orhun/rustypaste/docker.yml?style=flat&labelColor=823213&color=2c2c2c&label=docker&logo=Docker&logoColor=white )](https://hub.docker.com/r/orhunp/rustypaste)
[![Documentation ](https://img.shields.io/docsrs/rustypaste?style=flat&labelColor=823213&color=2c2c2c&logo=Rust&logoColor=white )](https://docs.rs/rustypaste/)
2021-07-26 18:29:46 +00:00
**Rustypaste** is a minimal file upload/pastebin service.
```sh
$ echo "some text" > awesome.txt
2021-07-27 13:20:01 +00:00
$ curl -F "file=@awesome.txt" https://paste.site.com
https://paste.site.com/safe-toad.txt
2021-07-26 18:29:46 +00:00
2021-07-27 13:20:01 +00:00
$ curl https://paste.site.com/safe-toad.txt
2021-07-26 18:29:46 +00:00
some text
```
2023-05-14 16:03:53 +00:00
The public instance is available at [https://rustypaste.shuttleapp.rs ](https://rustypaste.shuttleapp.rs ) 🚀
2023-05-30 22:22:57 +00:00
2023-05-30 22:24:46 +00:00
Here you can read the blog post about how it is deployed on Shuttle: [https://blog.orhun.dev/blazingly-fast-file-sharing ](https://blog.orhun.dev/blazingly-fast-file-sharing )
2023-05-30 22:22:57 +00:00
< / details >
< details >
< summary > Table of Contents< / summary >
<!-- vim - markdown - toc GFM -->
- [Features ](#features )
- [Installation ](#installation )
- [From crates.io ](#from-cratesio )
- [Arch Linux ](#arch-linux )
- [Alpine Linux ](#alpine-linux )
2023-11-03 09:32:32 +00:00
- [FreeBSD ](#freebsd )
2023-05-30 22:22:57 +00:00
- [Binary releases ](#binary-releases )
- [Build from source ](#build-from-source )
- [Feature flags ](#feature-flags )
- [Testing ](#testing )
- [Unit tests ](#unit-tests )
- [Test Fixtures ](#test-fixtures )
- [Usage ](#usage )
- [CLI ](#cli )
- [Expiration ](#expiration )
- [One shot files ](#one-shot-files )
- [One shot URLs ](#one-shot-urls )
- [URL shortening ](#url-shortening )
- [Paste file from remote URL ](#paste-file-from-remote-url )
- [Cleaning up expired files ](#cleaning-up-expired-files )
2023-09-03 15:47:52 +00:00
- [Delete file from server ](#delete-file-from-server )
2024-02-12 12:06:12 +00:00
- [Override the filename when using `random_url` ](#override-the-filename-when-using-random_url )
2023-05-30 22:22:57 +00:00
- [Server ](#server )
2023-09-03 15:47:52 +00:00
- [List endpoint ](#list-endpoint )
2023-05-30 22:22:57 +00:00
- [HTML Form ](#html-form )
- [Docker ](#docker )
- [Nginx ](#nginx )
- [Contributing ](#contributing )
- [License ](#license )
<!-- vim - markdown - toc -->
< / details >
2023-05-14 16:03:53 +00:00
2021-07-26 18:29:46 +00:00
## Features
2021-11-07 13:06:57 +00:00
- File upload & URL shortening & upload from URL
2021-07-26 18:29:46 +00:00
- supports basic HTTP authentication
- random file names (optional)
- pet name (e.g. `capital-mosquito.txt` )
- alphanumeric string (e.g. `yB84D2Dv.txt` )
2023-06-30 22:11:16 +00:00
- random suffix (e.g. `file.MRV5as.tar.gz` )
2021-08-27 18:12:18 +00:00
- supports expiring links
2023-05-14 20:55:47 +00:00
- auto-expiration of files (optional)
2022-03-23 08:38:32 +00:00
- auto-deletion of expired files (optional)
2023-05-28 20:09:14 +00:00
- supports one shot links/URLs (can only be viewed once)
2021-07-26 18:29:46 +00:00
- guesses MIME types
2021-08-09 20:12:51 +00:00
- supports overriding and blacklisting
2023-01-31 17:56:04 +00:00
- supports forcing to download via `?download=true`
2021-10-12 16:35:06 +00:00
- no duplicate uploads (optional)
2023-09-03 15:47:52 +00:00
- listing/deleting files
2023-08-26 20:40:04 +00:00
- custom landing page
2021-07-26 18:29:46 +00:00
- Single binary
2021-07-27 10:25:47 +00:00
- [binary releases ](https://github.com/orhun/rustypaste/releases )
2021-11-07 13:06:57 +00:00
- Simple configuration
- supports hot reloading
2021-07-26 18:29:46 +00:00
- Easy to deploy
- [docker images ](https://hub.docker.com/r/orhunp/rustypaste )
2023-11-03 09:32:32 +00:00
- [appjail images ](https://github.com/AppJail-makejails/rustypaste )
2021-07-26 18:29:46 +00:00
- No database
- filesystem is used
- Self-hosted
- _centralization is bad!_
- Written in Rust
- _blazingly fast!_
2021-09-18 22:49:59 +00:00
## Installation
2024-03-27 14:39:35 +00:00
< details >
< summary > Packaging status< / summary >
[![Packaging status ](https://repology.org/badge/vertical-allrepos/rustypaste.svg )](https://repology.org/project/rustypaste/versions)
< / details >
2021-09-18 22:49:59 +00:00
### From crates.io
```sh
cargo install rustypaste
```
2022-03-13 18:13:31 +00:00
### Arch Linux
```sh
pacman -S rustypaste
```
2023-05-17 09:28:39 +00:00
### Alpine Linux
2023-06-16 14:41:59 +00:00
`rustypaste` is available for [Alpine Edge ](https://pkgs.alpinelinux.org/packages?name=rustypaste&branch=edge ). It can be installed via [apk ](https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper ) after enabling the [community repository ](https://wiki.alpinelinux.org/wiki/Repositories ).
2023-05-17 09:28:39 +00:00
```sh
apk add rustypaste
```
2023-11-03 09:32:09 +00:00
### FreeBSD
```sh
pkg install rustypaste
```
2021-09-18 22:49:59 +00:00
### Binary releases
2023-05-17 09:28:39 +00:00
See the available binaries on the [releases ](https://github.com/orhun/rustypaste/releases/ ) page.
2021-09-18 22:49:59 +00:00
### Build from source
```sh
git clone https://github.com/orhun/rustypaste.git
cd rustypaste/
cargo build --release
```
2023-05-17 11:04:32 +00:00
#### Feature flags
- `shuttle` : enable an entry point for deploying on Shuttle
- `openssl` : use distro OpenSSL (binary size is reduced ~20% in release mode)
- `rustls` : use [rustls ](https://github.com/rustls/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:
```sh
2023-05-17 11:27:04 +00:00
cargo build --release --no-default-features --features openssl
2023-05-17 11:04:32 +00:00
```
2022-03-23 13:41:09 +00:00
#### Testing
2023-05-17 09:29:40 +00:00
##### Unit tests
2022-03-23 13:41:09 +00:00
```sh
cargo test -- --test-threads 1
```
2023-05-17 09:29:40 +00:00
##### Test Fixtures
```sh
./fixtures/test-fixtures.sh
```
2021-07-26 18:29:46 +00:00
## Usage
2021-09-18 22:46:50 +00:00
The standalone command line tool (`rpaste`) is available [here ](https://github.com/orhun/rustypaste-cli ).
2021-07-26 18:29:46 +00:00
### CLI
```sh
function rpaste() {
2022-03-11 21:03:37 +00:00
curl -F "file=@$1" -H "Authorization: < auth_token > " "< server_address > "
2021-07-26 18:29:46 +00:00
}
```
**\*** consider reading authorization headers from a file. (e.g. `-H @rpaste_auth` )
```sh
# upload a file
$ rpaste x.txt
# paste from stdin
$ rpaste -
```
2021-08-27 18:12:18 +00:00
#### Expiration
```sh
2021-09-18 22:27:14 +00:00
$ curl -F "file=@x.txt" -H "expire:10min" "< server_address > "
2021-08-27 18:12:18 +00:00
```
2023-06-12 22:14:05 +00:00
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`
2023-05-28 20:09:14 +00:00
#### One shot files
2021-08-26 20:13:32 +00:00
```sh
2021-09-18 22:27:14 +00:00
$ curl -F "oneshot=@x.txt" "< server_address > "
2021-08-26 20:13:32 +00:00
```
2023-05-28 20:09:14 +00:00
#### One shot URLs
```sh
$ curl -F "oneshot_url=https://example.com" "< server_address > "
```
2021-11-06 20:55:55 +00:00
#### URL shortening
2021-08-04 14:49:57 +00:00
```sh
2021-09-18 22:27:14 +00:00
$ curl -F "url=https://example.com/some/long/url" "< server_address > "
2021-08-04 14:49:57 +00:00
```
2021-11-07 14:25:42 +00:00
#### Paste file from remote URL
2021-11-06 20:55:55 +00:00
```sh
$ curl -F "remote=https://example.com/file.png" "< server_address > "
```
2022-03-17 08:53:16 +00:00
#### Cleaning up expired files
2023-07-21 10:28:17 +00:00
Configure `[paste].delete_expired_files` to set an interval for deleting the expired files automatically.
2022-03-23 08:38:32 +00:00
On the other hand, following script can be used as [cron ](https://en.wikipedia.org/wiki/Cron ) for cleaning up the expired files manually:
2022-03-17 08:53:16 +00:00
```sh
#!/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
```
2023-09-03 15:47:52 +00:00
#### Delete file from server
Set `delete_tokens` array in [config.toml ](./config.toml ) to activate the [`DELETE` ](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE ) endpoint and secure it with one (or more) auth token(s).
```sh
$ curl -H "Authorization: < auth_token > " -X DELETE "< server_address > /file.txt"
```
2023-12-11 18:19:18 +00:00
> The `DELETE` endpoint will not be exposed and will return `404` error if `delete_tokens` are not set.
2024-02-12 12:06:12 +00:00
#### Override the filename when using `random_url`
The generation of a random filename can be overridden by sending a header called `filename` :
```sh
curl -F "file=@x.txt" -H "filename: < file_name > " "< server_address > "
```
2021-07-26 18:29:46 +00:00
### Server
To start the server:
```sh
$ rustypaste
```
If the configuration file is not found in the current directory, specify it via `CONFIG` environment variable:
```sh
$ CONFIG="$HOME/.rustypaste.toml" rustypaste
```
To enable basic HTTP auth, set the `AUTH_TOKEN` environment variable (via `.env` ):
```sh
2021-07-27 12:48:21 +00:00
$ echo "AUTH_TOKEN=$(openssl rand -base64 16)" > .env
2021-07-26 18:29:46 +00:00
$ rustypaste
```
2023-07-21 10:28:17 +00:00
You can also set multiple auth tokens via the array field `[server].auth_tokens` in your `config.toml` .
2023-12-11 18:19:18 +00:00
> If neither `AUTH_TOKEN` 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](#delete-file-from-server) for more information.
2021-07-26 18:29:46 +00:00
See [config.toml ](./config.toml ) for configuration options.
2023-09-03 15:47:52 +00:00
#### List endpoint
2023-08-07 10:55:13 +00:00
Set `expose_list` to true in [config.toml ](./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.
```sh
$ 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.
2023-05-30 22:21:15 +00:00
#### 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` :
2023-07-21 10:28:17 +00:00
- 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.
2023-05-30 22:21:15 +00:00
For an example, see [examples/html_form.toml ](./examples/html_form.toml )
2021-07-26 18:29:46 +00:00
#### Docker
Following command can be used to run a container which is built from the [Dockerfile ](./Dockerfile ) in this repository:
```sh
$ docker run --rm -d \
-v "$(pwd)/upload/":/app/upload \
2021-08-09 20:27:35 +00:00
-v "$(pwd)/config.toml":/app/config.toml \
2021-07-26 18:29:46 +00:00
--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 ](https://docs.docker.com/compose/ ), simply run `docker-compose up -d` . (see [docker-compose.yml ](./docker-compose.yml ))
#### Nginx
Example server configuration with reverse proxy:
```nginx
server {
listen 80;
location / {
2021-07-27 13:16:31 +00:00
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";
2021-07-26 18:29:46 +00:00
}
}
```
If you get a `413 Request Entity Too Large` error during upload, set the max body size in `nginx.conf` :
```nginx
http {
# ...
client_max_body_size 100M;
}
```
### Contributing
Pull requests are welcome!
2022-05-16 07:28:57 +00:00
Consider submitting your ideas via [issues ](https://github.com/orhun/rustypaste/issues/new ) first and check out the [existing issues ](https://github.com/orhun/rustypaste/issues ).
2021-07-26 18:38:15 +00:00
#### License
< sup >
All code is licensed under < a href = "LICENSE" > The MIT License< / a > .
< / sup >