2024-04-03 20:40:26 -05:00
<!-- SPDX - FileCopyrightText: 2023 Sayantan Santra <sayantan.santra689@gmail.com> -->
<!-- SPDX - License - Identifier: MIT -->
2024-04-10 13:46:29 -05:00
[![docker-pulls-badge ](https://img.shields.io/docker/pulls/sintan1729/chhoto-url )](https://hub.docker.com/r/sintan1729/chhoto-url)
[![maintainer-badge ](https://img.shields.io/badge/maintainer-SinTan1729-blue )](https://github.com/SinTan1729)
[![latest-release-badge ](https://img.shields.io/github/v/release/SinTan1729/chhoto-url?label=latest%20release )](https://github.com/SinTan1729/chhoto-url/releases/latest)
2024-06-21 10:01:19 -05:00
![docker-image-size-badge ](https://img.shields.io/docker/image-size/sintan1729/chhoto-url )
2024-04-10 13:46:29 -05:00
![commit-since-latest-release-badge ](https://img.shields.io/github/commits-since/SinTan1729/chhoto-url/latest?sort=semver&label=commits%20since%20latest%20release )
[![license-badge ](https://img.shields.io/github/license/SinTan1729/chhoto-url )](https://spdx.org/licenses/MIT.html)
2023-04-09 21:35:51 -05:00
2024-03-08 13:33:44 -06:00
# ![Logo](resources/assets/favicon-32.png) <span style="font-size:42px">Chhoto URL</span>
2022-11-09 17:46:43 -06:00
2020-02-14 15:36:50 -06:00
# What is it?
2024-03-04 19:05:11 -06:00
A simple selfhosted URL shortener with no unnecessary features. Simplicity
and speed are the main foci of this project. The docker image is ~6 MB (compressed),
and it uses < 5 MB of RAM under regular use .
2020-06-18 13:09:43 -05:00
2020-06-18 13:13:07 -05:00
Don't worry if you see no activity for a long time. I consider this project
to be complete, not dead. I'm unlikely to add any new features, but I will try
2024-03-04 19:05:11 -06:00
and fix every bug you report. I will also try to keep it updated in terms of
security vulnerabilities.
2020-06-18 13:09:43 -05:00
2020-06-18 13:13:07 -05:00
If you feel like a feature is missing, please let me know by creating an issue
using the "feature request" template.
2020-02-14 15:36:50 -06:00
## But why another URL shortener?
2024-03-26 17:46:26 -05:00
Most URL shorteners are either bloated with unnecessary features, or are a pain to set up.
2024-05-31 01:51:11 -05:00
Even fewer are written with simplicity and lightness in mind. When I saw the `simply-shorten`
project (linked below), I really liked the idea but thought that it missed some features. Also,
2024-03-26 17:46:26 -05:00
I didn't like the fact that a simple app like this had a ~200 MB docker image (mostly due to the
included java runtime). So, I decided to rewrite it in Rust and add some features to it that I
thought were essential (e.g. hit counting).
2020-02-14 15:36:50 -06:00
2024-02-10 18:44:15 -06:00
## What does the name mean?
2024-02-29 18:29:36 -06:00
Chhoto (ছোট, [IPA ](https://en.wikipedia.org/wiki/Help:IPA/Bengali ): /tʃʰoʈo/) is the Bangla word
for small. URL means, well... URL. So the name simply means Small URL.
2024-02-10 18:44:15 -06:00
2020-02-14 15:36:50 -06:00
# Features
2024-03-04 19:37:36 -06:00
- Shortens URLs of any length to a randomly generated link.
2020-02-14 15:36:50 -06:00
- (Optional) Allows you to specify the shortened URL instead of the generated
2024-03-04 19:37:36 -06:00
one. (It's surprisingly missing in a surprising number of alternatives.)
- Opening the shortened URL in your browser will instantly redirect you
to the correct long URL. (So no stupid redirecting pages.)
- Super lightweight and snappy. (The docker image is only ~6MB and RAM uasge
stays under 5MB under normal use.)
2022-11-04 18:53:13 -05:00
- Counts number of hits for each short link in a privacy respecting way
2022-12-28 07:31:03 -06:00
i.e. only the hit is recorded, and nothing else.
2024-04-03 20:50:27 -05:00
- Has a mobile friendly UI.
2024-05-28 18:20:09 -05:00
- Has a public mode, where anyone can add links without authentication. Deleting
or listing available links will need admin access using the password.
2022-12-28 07:31:03 -06:00
- Allows setting the URL of your website, in case you want to conveniently
generate short links locally.
- Links are stored in an SQLite database.
- Available as a Docker container.
2023-04-03 13:52:01 -05:00
- Backend written in Rust using [Actix ](https://actix.rs/ ), frontend
2020-02-14 15:36:50 -06:00
written in plain HTML and vanilla JS, using [Pure CSS ](https://purecss.io/ )
2022-12-28 07:31:03 -06:00
for styling.
2023-04-08 17:22:59 -05:00
- Uses very basic authentication using a provided password. It's not encrypted in transport.
2024-03-06 22:42:06 -06:00
I recommend using something like [caddy ](https://caddyserver.com/ ) to
2023-04-08 17:22:59 -05:00
encrypt the connection by SSL.
2020-05-23 12:16:27 -05:00
# Bloat that will not be implemented
2022-11-04 01:41:15 -05:00
- Tracking or spying of any kind. The only logs that still exist are
2023-04-10 11:51:20 -05:00
errors printed to stderr and the basic logging (only warnings) provided by the
[`env_logger` ](https://crates.io/crates/env_logger ) crate.
2023-04-09 21:35:51 -05:00
- User management. If you need a shortener for your whole organization, either
2020-05-23 12:54:27 -05:00
run separate containers for everyone or use something else.
2020-05-23 12:16:27 -05:00
- Cookies, newsletters, "we value your privacy" popups or any of the multiple
2020-05-23 12:54:27 -05:00
other ways modern web shows how anti-user it is. We all hate those, and they're
not needed here.
- Paywalls or messages begging for donations. If you want to support me (for
2023-04-09 21:35:51 -05:00
whatever reason), you can message me through GitHub issues.
2020-02-14 15:36:50 -06:00
2024-10-06 20:38:05 -05:00
# Screenshots
#### Note: I'm using Dark Reader here to get the dark theme.
2024-06-21 09:46:47 -05:00
< p align = "middle" >
2024-06-21 10:01:19 -05:00
< img src = "screenshot-desktop.webp" height = "250" alt = "desktop screenshot" / >
< img src = "screenshot-mobile.webp" height = "250" alt = "mobile screenshot" / >
2024-06-21 09:46:47 -05:00
< / p >
2020-02-16 07:50:49 -06:00
2020-02-14 15:36:50 -06:00
# Usage
2022-11-05 14:41:00 -05:00
## Using `docker compose` (Recommended method)
2022-11-14 23:12:26 -06:00
There is a sample `compose.yaml` file in this repository. It contains
2022-11-05 14:41:00 -05:00
everything needed for a basic install. You can use it as a base, modifying
it as needed. Run it with
```
docker compose up -d
```
2022-11-05 14:44:15 -05:00
If you're using a custom location for the `db_url` , make sure to make that file
before running the docker image, as otherwise a directory will be created in its
2023-04-09 21:35:51 -05:00
place, resulting in possibly unwanted behavior.
2020-02-14 15:36:50 -06:00
2024-03-13 19:26:10 -05:00
## Building and running with docker
2020-02-14 15:36:50 -06:00
### `docker run` method
2024-03-25 01:22:54 -05:00
0. (Only if you really want to) Build the image for the default `x86_64-unknown-linux-musl` target:
2020-02-14 15:36:50 -06:00
```
2024-03-25 01:22:54 -05:00
docker build . -t chhoto-url
2020-02-14 15:36:50 -06:00
```
2024-03-25 01:22:54 -05:00
For building on `arm64` or `arm/v7` , use the following:
```
docker build . -t chhoto-url --build-arg target=< desired-target >
```
2024-03-25 01:40:10 -05:00
Make sure that the desired target is a `musl` one, since the docker image is built from `scratch` .
2024-03-25 01:22:54 -05:00
For cross-compilation, take a look at the `Makefile` . It builds and pushes for `linux/amd64` , `linux/aarch64`
and `linux/arm/v7` architectures. For any other architectures, open a discussion, and I'll try to help you out.
2020-05-23 12:54:27 -05:00
1. Run the image
2020-02-14 15:36:50 -06:00
```
2020-03-24 03:07:25 -05:00
docker run -p 4567:4567
-e password="password"
2024-02-10 18:29:50 -06:00
-d chhoto-url:latest
2020-02-14 15:36:50 -06:00
```
2020-05-23 12:54:27 -05:00
1.a Make the database file available to host (optional)
2020-02-14 15:36:50 -06:00
```
2020-04-18 15:53:01 -05:00
touch ./urls.sqlite
2020-02-14 15:36:50 -06:00
docker run -p 4567:4567 \
2020-03-24 03:07:25 -05:00
-e password="password" \
2020-04-18 15:53:01 -05:00
-v ./urls.sqlite:/urls.sqlite \
2020-05-23 12:54:27 -05:00
-e db_url=/urls.sqlite \
2024-02-10 18:29:50 -06:00
-d chhoto-url:latest
2020-02-14 15:36:50 -06:00
```
2022-11-10 20:17:39 -06:00
1.b Further, set the URL of your website (optional)
```
touch ./urls.sqlite
docker run -p 4567:4567 \
-e password="password" \
-v ./urls.sqlite:/urls.sqlite \
-e db_url=/urls.sqlite \
-e site_url="https://www.example.com" \
2024-02-10 18:29:50 -06:00
-d chhoto-url:latest
2022-11-10 20:17:39 -06:00
```
2024-12-31 04:13:37 -06:00
1.c Optionally, set an API key to activate JSON result mode (optional)
```
docker run -p 4567:4567 \
-e password="password" \
-e api_key="SECURE_API_KEY" \
-v ./urls.sqlite:/urls.sqlite \
-e db_url=/urls.sqlite \
-e site_url="https://www.example.com" \
-d chhoto-url:latest
```
2020-09-19 03:01:36 -05:00
2024-03-31 00:51:10 -05:00
You can set the redirect method to Permanent 308 (default) or Temporary 307 by setting
the `redirect_method` variable to `TEMPORARY` or `PERMANENT` (it's matched exactly). By
default, the auto-generated links are adjective-name pairs. You can use UIDs by setting
the `slug_style` variable to `UID` . You can also set the length of those slug by setting
the `slug_length` variable. It defaults to 8, and a minimum of 4 is supported.
2023-04-28 00:22:30 -05:00
2024-05-28 18:20:09 -05:00
To enable public mode, set `public_mode` to `Enable` . With this, anyone will be able to add
links. Listing existing links or deleting links will need admin access using the password.
2024-05-31 20:30:09 -05:00
By default, the server sends no Cache-Control headers. You can set custom `cache_control_header`
to send your desired headers. It must be a comma separated list of valid
[RFC 7234 §5.2 ](https://datatracker.ietf.org/doc/html/rfc7234#section-5.2 ) headers. For example,
you can set it to `no-cache, private` to disable caching. It might help during testing if
served through a proxy.
2024-05-31 01:42:51 -05:00
2024-04-01 00:47:25 -05:00
## Instructions for CLI usage
2024-03-31 21:07:31 -05:00
The application can be used from the terminal using something like `curl` . In all the examples
below, replace `http://localhost:4567` with where your instance of `chhoto-url` is accessible.
2024-12-31 04:13:37 -06:00
### Cookie validation
2024-03-31 21:07:31 -05:00
If you have set up
a password, first do the following to get an authentication cookie and store it in a file.
```bash
2024-12-31 00:19:20 -06:00
curl -X POST -d "< your-password > " -c cookie.txt http://localhost:4567/api/login
2024-03-31 21:07:31 -05:00
```
2024-04-01 13:43:03 -05:00
You should receive "Correct password!" if the provided password was correct. For any subsequent
request, please add `-b cookie.txt` to provide authentication.
2024-03-31 21:07:31 -05:00
To add a link, do
```bash
2024-04-01 00:47:25 -05:00
curl -X POST -d '{"shortlink":"< shortlink > ", "longlink":"< longlink > "}' http://localhost:4567/api/new
2024-03-31 21:07:31 -05:00
```
Send an empty `<shortlink>` if you want it to be auto-generated. The server will reply with the generated shortlink.
To get a list of all the currently available links as `json` , do
```bash
curl http://localhost:4567/api/all
```
To delete a link, do
```bash
curl -X DELETE http://localhost:4567/api/del/< shortlink >
```
The server will send a confirmation.
2024-12-31 04:13:37 -06:00
### API key validation
**This is required for programs that rely on a JSON response from Chhoto URL**
In order to use API key validation, set the `api_key` environment variable. If this is not set, the API will default to cookie validation (see section above).
If the API key is insecure, a warning will be outputted. Aditionally, in this situation, a generated API key will be outputted which may be used.
To add a link:
``` bash
curl -X POST -H "Chhoto-Api-Key: < YOUR_API_KEY > " -d '{"shortlink":"< shortlink > ", "longlink":"< longlink > "}' http://localhost:4567/api/new
```
To get a list of all the currently available links:
``` bash
curl -H "Chhoto-Api-Key: < YOUR_API_KEY > " http://localhost:4567/api/all
```
To delete a link:
``` bash
curl -X DELETE -H "Chhoto-Api-Key: < YOUR_API_KEY > http://localhost:4567/api/del/< shortlink > "
```
Where `<shortlink>` is name of the shortened link you would like to delete. For example, if the shortened link is `http://localhost:4567/example` , `<shortlink>` would be `example` .
The server will output when the instance is accessed over API, when an incorrect API key is received, etc.
2024-03-31 21:07:31 -05:00
You can get the version of `chhoto-url` the server is running using `curl http://localhost:4567/api/version` and
get the siteurl using `curl http://localhost:4567/api/siteurl` .
2020-09-19 03:01:36 -05:00
## Disable authentication
2023-04-09 17:31:00 -05:00
If you do not define a password environment variable when starting the docker image, authentication
will be disabled.
2023-04-08 15:56:42 -05:00
This if not recommended in actual use however, as it will allow anyone to create new links and delete
2020-09-19 03:01:36 -05:00
old ones. This might not seem like a bad idea, until you have hundreds of links
pointing to illegal content. Since there are no logs, it's impossible to prove
that those links aren't created by you.
2022-11-11 17:50:12 -06:00
## Notes
2024-05-31 20:30:09 -05:00
- It started as a fork of [`simply-shorten` ](https://gitlab.com/draganczukp/simply-shorten ).
2022-11-11 17:50:12 -06:00
- The list of adjectives and names used for random short url generation is a modified
2024-03-04 19:05:11 -06:00
version of [this list used by docker ](https://github.com/moby/moby/blob/master/pkg/namesgenerator/names-generator.go ).