Skip to content

Commit

Permalink
Created url-shortener
Browse files Browse the repository at this point in the history
  • Loading branch information
osakitadev committed Dec 25, 2024
0 parents commit 2f7bcb8
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shortened-urls.json
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# url-shortener
This is other of my personal projects, this is just a pretty basic url shortener.

It works with base64 and sha256 encoding to generate the shorten URL. It works only locally so you can't share the link to others. But hey, it still works.

## Usage
Run `go run . -url=<YOUR_URL>` to execute the program. Once you do this, the program will show you the shorten URL in the output so you can copy or just write it in your browser.

> [!IMPORTANT]
> The shorten URLs are saved on a JSON file. You have to create it manually. Name it as `shortened-urls.json`.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/Osaka/url-shortener

go 1.23.4
34 changes: 34 additions & 0 deletions httpserver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import (
"log"
"net/http"
"strings"
)

func redirectURL(w http.ResponseWriter, r *http.Request) {
urlPath := r.PathValue("hashurl")

// For some reason, the browser is requesting the favicon.ico when I visit
// the root path 🤷‍♂️
if strings.HasPrefix(urlPath, "favicon.ico") {
http.NotFound(w, r)
return
}

allURLs := GetAllURLs()
targetURL, ok := allURLs[urlPath]

if !ok {
http.NotFound(w, r)
return
}

log.Println("Redirecting to", targetURL)
http.Redirect(w, r, targetURL, http.StatusSeeOther)
}

func ServeServer() {
http.HandleFunc("/{hashurl}", redirectURL)
http.ListenAndServe(":8080", nil)
}
27 changes: 27 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"flag"
"log"
)

var (
URL string
)

func init() {
flag.StringVar(&URL, "url", "", "URL to shorten")
flag.Parse()
}

func main() {
if URL == "" {
panic("URL is required")
}
hashedURL := HashURL(URL)

log.Println("Shortened URL:", "localhost:8080/"+hashedURL)

SaveURLToFile(hashedURL, URL)
ServeServer()
}
67 changes: 67 additions & 0 deletions url_shortener.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package main

import (
"crypto/sha256"
"encoding/base64"
"encoding/json"
"log"
"math/rand"
"os"
)

func GetAllURLs() map[string]string {
content, err := os.ReadFile("shortened-urls.json")

if err != nil {
return make(map[string]string)
}

// Parse the JSON content
urlsMap := make(map[string]string)

err = json.Unmarshal(content, &urlsMap)

if err != nil {
return make(map[string]string)
}

return urlsMap
}

func SaveURLToFile(hashedUrl, originalUrl string) {
alreadySavedURLs := GetAllURLs()
alreadySavedURLs[hashedUrl] = originalUrl

// Convert the map to JSON
jsonContent, err := json.Marshal(alreadySavedURLs)

if err != nil {
log.Fatal(err)
}

err = os.WriteFile("shortened-urls.json", jsonContent, 0644)

if err != nil {
log.Fatal(err)
}
}

func HashURL(urlToShorten string) string {
randomStr := randomString(8)
combined := urlToShorten + randomStr
hash := sha256.Sum256([]byte(combined))
encoded := base64.URLEncoding.EncodeToString(hash[:])

return encoded[:8] // Take the first 8 characters for a shorter URL
}

func randomString(length int) string {
letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
b := make([]rune, length)

for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}

return string(b)
}

0 comments on commit 2f7bcb8

Please sign in to comment.