Skip to content

Repository files navigation

SpeedyShort

SpeedyShort is a lightweight, fast URL shortener written in Go. It uses an in-memory index for instant lookups and an embedded key-value store for persistence. No external services or databases are required.


🚀 Features

  • Random alphanumeric short codes
  • Instant redirects (in-memory hash map)
  • Persistent storage via Badger (embedded KV store)
  • Clean and simple REST API
  • Minimal static landing page
  • No external dependencies
  • Single self-contained binary
  • Built-in rate limiting
  • Domain blacklist with abuse reporting
  • Telegram notifications for incoming reports

📦 Project Structure

/
├─ main.go
├─ handlers.go
├─ storage.go
├─ background.go
├─ rate_limit.go
├─ config.go
├─ model.go
├─ blacklist.go
├─ telegram.go
├─ telegram.example.json
├─ public/
│    ├─ index.html
│    ├─ blocked.html
│    ├─ icon.svg
│    └─ favicon.ico
└─ cmd/
     ├─ listlinks/    – CLI tool to list all stored links
     └─ adminctl/     – CLI tool for report review and domain management

🛠 Build

All binaries are output to the bin/ directory.

go build -o bin/speedyshort .
go build -o bin/listlinks  ./cmd/listlinks/
go build -o bin/adminctl   ./cmd/adminctl/

Cross-compile for Linux from another OS (e.g. macOS or Windows):

GOOS=linux GOARCH=amd64 go build -o bin/speedyshort .
GOOS=linux GOARCH=amd64 go build -o bin/listlinks  ./cmd/listlinks/
GOOS=linux GOARCH=amd64 go build -o bin/adminctl   ./cmd/adminctl/

▶️ Run

./bin/speedyshort

Default address:

http://localhost:8080

Environment variables:

FASTSHORTNER_BASE_URL          – Base URL used inside generated short links
FASTSHORTNER_ADDR              – Listen address (default: :8080)
FASTSHORTNER_DATA_DIR          – Path to the Badger data directory (default: ./data)
FASTSHORTNER_TELEGRAM_CONFIG   – Path to the Telegram config file (default: ./telegram.json)

Example:

FASTSHORTNER_BASE_URL="https://syrt.cc" FASTSHORTNER_ADDR=":8080" ./bin/speedyshort

📲 Telegram notifications & moderation

SpeedyShort can send a Telegram message when a new report is submitted, and lets you act on it by replying directly to the notification.

Copy the example config and fill in your values:

cp telegram.example.json telegram.json
{
  "bot_token": "123456789:ABCdefGHIjklMNOpqrSTUvwxYZ",
  "chat_ids": [123456789, 987654321]
}
  • bot_token — token from @BotFather
  • chat_ids — list of Telegram user IDs that will receive notifications and are authorized to issue commands

If the file does not exist or is incomplete, the server starts normally with notifications disabled.

telegram.json is listed in .gitignore and will never be committed.

Moderating reports via Telegram

When a report arrives you receive a notification like:

🚨 New report on SpeedyShort

Link: abc123
Reason: This link points to a phishing page

Reply with /b to ban the domain or /d to dismiss.

Reply to the message (not in a new message) with:

Command Action
/b Resolve the domain from the reported input, blacklist it, deactivate all active links pointing to it, delete the report
/d Delete the report without taking any action

Domain resolution for /b:

The server resolves the domain to ban in this order:

  1. If the input is a short code or short URL → look up the target URL → extract its domain
  2. If the input is a full external URL → extract the domain directly
  3. If the input has no scheme (e.g. evil.com/path) → prepend https:// and extract the domain

Note: the message↔report mapping is kept in memory. If the server restarts after a notification is sent, those old notifications can no longer be actioned via Telegram. Use adminctl for those cases.


🌐 API Reference

Create a short link

POST /api/shorten

Headers

Content-Type: application/json

Body

{
  "url": "https://www.example.com"
}

Response

{
  "code": "a7X9pQ",
  "short_url": "http://localhost:8080/a7X9pQ",
  "target_url": "https://www.example.com"
}

Returns 403 Forbidden if the domain has been blacklisted.


Redirect

GET /<code>

Returns 301 to the target URL, or a blocked page (451) if the link has been disabled.


Report a link

POST /api/report

Body

{
  "code": "a7X9pQ",
  "reason": "This link points to a phishing page"
}

The code field also accepts a full short URL (e.g. https://syrt.cc/a7X9pQ).

Constraints:

  • reason — required, between 10 and 100 characters
  • Rate limit: max 3 reports per IP per day

The report is recorded and queued for manual review. The link remains active until an administrator takes action. A Telegram notification is sent to all configured recipients.


🛡 Abuse management (admin CLI)

Reports are reviewed and acted upon locally on the server using the adminctl tool.
Stop the server before running any write command.

systemctl stop speedyshort

# List all links pending review (shows code, report count, URL, reason)
./bin/adminctl reports /opt/speedyshort/data

# Deactivate a single reported link (domain is NOT blacklisted)
./bin/adminctl blacklist <code> /opt/speedyshort/data

# Blacklist a domain: all active links pointing to it are deactivated
./bin/adminctl blacklist-domain malicious.com /opt/speedyshort/data

# Dismiss a report without taking action (link stays active)
./bin/adminctl dismiss <code> /opt/speedyshort/data

# Show all blacklisted domains
./bin/adminctl blacklist-list /opt/speedyshort/data

systemctl start speedyshort

If FASTSHORTNER_DATA_DIR is set in the environment, the data-dir argument can be omitted.


🔍 Inspecting stored links

The listlinks tool prints all links currently stored in the database.
Stop the server before running it.

systemctl stop speedyshort
./bin/listlinks /opt/speedyshort/data
systemctl start speedyshort

🧪 Testing locally

Start the server and open:

http://localhost:8080

A minimal web interface is included for generating short links and submitting abuse reports.


🌍 Live Demo

You can try a live hosted version here:

👉 https://syrt.cc

This instance runs the exact same code from this repository.


📜 License

SpeedyShort is released under the Prosperity Public License 3.0.0.

  • Free for personal, research, and open-source use
  • Commercial use requires a paid license

See the LICENSE file for the full text.

About

A fast and light link shortner

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages