init
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
redirect
|
||||||
57
README.md
Normal file
57
README.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# URL Redirect Service
|
||||||
|
|
||||||
|
A minimal Go application for handling URL redirects with the smallest possible memory footprint.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Host-based redirects**: Redirects based on the incoming host header
|
||||||
|
- **Path-based redirects**: Redirects based on the URL path
|
||||||
|
- **Proxy support**: Handles `X-Forwarded-Host` and `X-Forwarded-Uri` headers from reverse proxies
|
||||||
|
- **Protocol agnostic**: Works with both HTTP and HTTPS requests
|
||||||
|
- **Minimal memory usage**: Uses only Go's standard library with no external dependencies
|
||||||
|
|
||||||
|
## Current Redirect Rules
|
||||||
|
|
||||||
|
### Host-based
|
||||||
|
- `mail.terrible.dev` → `https://mail.tommyparnell.com`
|
||||||
|
|
||||||
|
### Path-based
|
||||||
|
- `/test` → `https://blog.terrible.dev`
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
1. Run the application:
|
||||||
|
```bash
|
||||||
|
go run main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
2. The server will start on port 8080
|
||||||
|
|
||||||
|
3. Test the redirects:
|
||||||
|
```bash
|
||||||
|
# Test host-based redirect
|
||||||
|
curl -H "Host: mail.terrible.dev" http://localhost:8080
|
||||||
|
|
||||||
|
# Test path-based redirect
|
||||||
|
curl http://localhost:8080/test
|
||||||
|
|
||||||
|
# Test with X-Forwarded headers (simulating a reverse proxy)
|
||||||
|
curl -H "X-Forwarded-Host: mail.terrible.dev" http://localhost:8080
|
||||||
|
curl -H "X-Forwarded-Uri: /test" http://localhost:8080
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
To build a standalone binary:
|
||||||
|
```bash
|
||||||
|
go build -o redirect main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
## Memory Optimization
|
||||||
|
|
||||||
|
This application is designed for minimal memory usage:
|
||||||
|
- Uses only Go's standard `net/http` package
|
||||||
|
- Single handler function for all routes
|
||||||
|
- Simple map lookups for redirect rules
|
||||||
|
- No external dependencies or frameworks
|
||||||
|
- Supports reverse proxy headers without additional overhead
|
||||||
19
go.mod
Normal file
19
go.mod
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
module redirect
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
|
||||||
|
require github.com/gofiber/fiber/v2 v2.52.5
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||||
|
github.com/google/uuid v1.5.0 // indirect
|
||||||
|
github.com/klauspost/compress v1.17.0 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||||
|
github.com/rivo/uniseg v0.2.0 // indirect
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||||
|
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||||
|
golang.org/x/sys v0.15.0 // indirect
|
||||||
|
)
|
||||||
63
main.go
Normal file
63
main.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Hardcoded redirect rules
|
||||||
|
var (
|
||||||
|
// Host-based redirects
|
||||||
|
hostRedirects = map[string]string{
|
||||||
|
"mail.terrible.dev": "https://mail.tommyparnell.com",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path-based redirects
|
||||||
|
pathRedirects = map[string]string{
|
||||||
|
"/test": "https://blog.terrible.dev",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func redirectHandler(c *fiber.Ctx) error {
|
||||||
|
// Get the actual host, checking X-Forwarded-Host first
|
||||||
|
host := c.Get("X-Forwarded-Host")
|
||||||
|
if host == "" {
|
||||||
|
host = c.Hostname()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for host-based redirects first
|
||||||
|
if redirectURL, exists := hostRedirects[host]; exists {
|
||||||
|
return c.Redirect(redirectURL, fiber.StatusMovedPermanently)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the actual path, checking X-Forwarded-Uri first
|
||||||
|
path := c.Get("X-Forwarded-Uri")
|
||||||
|
if path == "" {
|
||||||
|
path = c.Path()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for path-based redirects
|
||||||
|
if redirectURL, exists := pathRedirects[path]; exists {
|
||||||
|
return c.Redirect(redirectURL, fiber.StatusMovedPermanently)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no redirect rule matches, return 404
|
||||||
|
return c.SendStatus(fiber.StatusNotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Create Fiber app with minimal configuration for lowest memory usage
|
||||||
|
app := fiber.New(fiber.Config{
|
||||||
|
Prefork: false,
|
||||||
|
DisableKeepalive: false,
|
||||||
|
ServerHeader: "",
|
||||||
|
AppName: "redirect",
|
||||||
|
})
|
||||||
|
|
||||||
|
// Use a single handler function to minimize memory overhead
|
||||||
|
app.All("*", redirectHandler)
|
||||||
|
|
||||||
|
// Start server on port 8080
|
||||||
|
if err := app.Listen(":8080"); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user