# shortener
`shortener` is a small URL shortener written in Rust.
It serves HTTP redirects, stores mappings in SQLite, and optionally protects
URL creation with API keys.
## Features
- Plain HTTP interface with no frontend dependency.
- SQLite-backed URL storage.
- Random alphanumeric codes with configurable length.
- Custom aliases using letters, digits, dashes (`-`), and underscores (`_`).
- Optional bearer-token authentication for URL creation.
- Access logging to stdout and a log file.
- Reverse-proxy support through `--trust-proxy`.
- Optional redirect from `/` to a configured main page.
- URL management through `shortener-url` CLI.
- User and API key management through `shortener-key` CLI.
## Installation
- Cargo
```sh
cargo install shortener
```
By default, `shortener` uses the system's SQLite library.
If you don't have it installed, or want to use the bundled version, add
`--features bundled-sqlite` to the `cargo install` command.
- Homebrew
```sh
brew install zhongruoyu/tap/shortener
```
- Release binaries
`shortener`'s GitHub releases come with pre-built binaries for
Linux, macOS, and Windows.
Download the binaries from
[the latest release](https://github.com/ZhongRuoyu/shortener/releases/latest).
- Docker
A Docker image is available on Docker Hub as
[`zhongruoyu/shortener`](https://hub.docker.com/r/zhongruoyu/shortener),
and on GitHub Container Registry as
[`ghcr.io/zhongruoyu/shortener`](https://ghcr.io/zhongruoyu/shortener).
Use the `latest` tag or a specific version tag to track releases,
and `main` to track the latest commit on the main branch.
See [Run with Docker](#run-with-docker) for usage instructions with Docker.
## Usage
`shortener` comes with three executables:
- `shortener`: the HTTP server.
- `shortener-url`: a CLI for creating and managing short URLs directly.
- `shortener-key`: a CLI for user and API key management.
### Starting the server
Start a local instance:
```sh
shortener \
--listen-port 8080 \
--url-prefix http://localhost:8080/ \
--database shortener.db \
--log-file access.log
```
Useful flags:
- `--auth`: require `Authorization: Bearer ...` for `POST` requests.
- `--main-page URL`: redirect `/` to a separate landing page.
- `--code-length N`: change generated code length. The default is `6`.
- `--trust-proxy`: use the first `X-Forwarded-For` address for logging.
See the full CLI help with `shortener --help`.
### Creating and using short URLs
Create a short URL by sending the target URL as the plain-text request body:
```sh
curl -X POST http://localhost:8080/ -d 'https://example.com/some/long/path'
```
The response is the new shortened URL as plain text.
Create a custom alias by posting to `/<code>`:
```sh
curl -X POST http://localhost:8080/docs -d 'https://example.com/docs'
```
Open the generated short URL and the server returns a `302 Found` redirect to
the stored destination.
### Managing short URLs
`shortener-url` provides a CLI for managing short URLs directly through the
database:
```sh
# Create a short URL with an auto-generated code
shortener-url --database shortener.db create 'https://example.com/some/path'
# Create a short URL with a custom code
shortener-url --database shortener.db create 'https://example.com/docs' docs
# List all short URLs
shortener-url --database shortener.db list
# List all short URLs in JSON format (also supported: CSV and table)
shortener-url --database shortener.db list --format json
# Get details of a short URL by code
shortener-url --database shortener.db get docs
# Delete a short URL by code
shortener-url --database shortener.db delete docs
```
Some other options are also available.
See `shortener-url --help` for full usage instructions.
### Authentication and API keys
When `--auth` is enabled, only authenticated `POST` requests can create short
URLs, though `GET` requests for URL redirection remain unauthenticated.
Use `shortener-key` to manage users and API keys against the same SQLite
database:
```sh
shortener-key --database shortener.db create-user alice
shortener-key --database shortener.db create-key alice
```
Then create a short URL with the returned key:
```sh
curl -X POST http://localhost:8080/ \
-H 'Authorization: Bearer MY_API_KEY' \
-d 'https://example.com/some/long/path'
```
Other management commands include:
- `list-users`
- `delete-user <username>`
- `check-key <key-or-hash>`
- `list-keys <username>`
- `delete-key <key-or-hash>`
See `shortener-key --help` for full usage instructions.
### Run with Docker
Run the server and persist the database and logs in a local directory:
```sh
mkdir -p data
docker run --rm \
-p 8080:8080 \
-v "$PWD/data:/data" \
zhongruoyu/shortener \
--listen-port 8080 \
--url-prefix http://localhost:8080/ \
--database /data/shortener.db \
--log-file /data/access.log
```
You can also run `shortener-url` or `shortener-key` inside the same image by
overriding the entrypoint:
```sh
docker run --rm \
--entrypoint shortener-url \
-v "$PWD/data:/data" \
zhongruoyu/shortener \
--database /data/shortener.db list
docker run --rm \
--entrypoint shortener-key \
-v "$PWD/data:/data" \
zhongruoyu/shortener \
--database /data/shortener.db create-user alice
```
### Shell completions
Shell completions are available for `shortener` and `shortener-key`.
To enable them, add the relevant command to your shell's profile:
```sh
# Bash
source <(shortener completions bash)
source <(shortener-url completions bash)
source <(shortener-key completions bash)
# Zsh
source <(shortener completions zsh)
source <(shortener-url completions zsh)
source <(shortener-key completions zsh)
# Fish
shortener-key completions fish | source
# PowerShell
shortener-key completions powershell | Out-String | Invoke-Expression
```
## License
This project is licensed under the MIT License.
See [LICENSE](./LICENSE).