Discussion about this post

User's avatar
Achanandhi M's avatar

GO CODE

package main

import (

"crypto/rand"

"database/sql"

"encoding/hex"

"fmt"

"html/template"

"log"

"net/http"

_ "github.com/go-sql-driver/mysql"

)

var db *sql.DB

func init() {

var err error

db, err = sql.Open("mysql", "root:password@tcp(localhost:3306)/")

if err != nil {

log.Fatal(err)

}

createDatabaseQuery := `

CREATE DATABASE IF NOT EXISTS url_shortener;

`

_, err = db.Exec(createDatabaseQuery)

if err != nil {

log.Fatal(err)

}

// Now open the connection with the url_shortener database

db, err = sql.Open("mysql", "root:password@tcp(localhost:3306)/url_shortener")

if err != nil {

log.Fatal(err)

}

createTableQuery := `

CREATE TABLE IF NOT EXISTS url_mapping (

short_id VARCHAR(6) PRIMARY KEY,

long_url TEXT NOT NULL

);

`

_, err = db.Exec(createTableQuery)

if err != nil {

log.Fatal(err)

}

}

func shortenURL(longURL string) (string, error) {

// Generate a 6-character random short ID

shortID := generateRandomID(6)

// Check if the short ID already exists in the database

var exists bool

err := db.QueryRow("SELECT EXISTS(SELECT 1 FROM url_mapping WHERE short_id = ?)", shortID).Scan(&exists)

if err != nil {

return "", err

}

if exists {

return shortenURL(longURL)

}

_, err = db.Exec("INSERT INTO url_mapping (short_id, long_url) VALUES (?, ?)", shortID, longURL)

if err != nil {

return "", err

}

return shortID, nil

}

func expandURL(shortID string) (string, error) {

// Retrieve the original long URL using the short ID

var longURL string

err := db.QueryRow("SELECT long_url FROM url_mapping WHERE short_id = ?", shortID).Scan(&longURL)

if err != nil {

return "", fmt.Errorf("short URL not found")

}

return longURL, nil

}

func generateRandomID(length int) string {

bytes := make([]byte, length)

_, err := rand.Read(bytes)

if err != nil {

log.Fatal(err)

}

return hex.EncodeToString(bytes)[:length] // Generate a random string of specified length

}

// Handle shortening URL via web form

func shortenHandler(w http.ResponseWriter, r *http.Request) {

w.Header().Set("Content-Type", "text/html")

if r.Method == "POST" {

longURL := r.FormValue("long_url")

shortID, err := shortenURL(longURL)

if err != nil {

http.Error(w, "Error shortening URL: "+err.Error(), http.StatusInternalServerError)

return

}

fmt.Fprintf(w, "Shorten URL: http://%s<br><br>", shortID)

fmt.Fprintf(w, `Wants to get to the original page: <a href="http://localhost:8080/expand/%s">Click here</a>`, shortID)

} else {

tmpl := template.Must(template.ParseFiles("index.html"))

tmpl.Execute(w, nil)

}

}

// Handle expanding URL via short URL

func expandHandler(w http.ResponseWriter, r *http.Request) {

shortID := r.URL.Path[len("/expand/"):] // Get the short URL from the path

longURL, err := expandURL(shortID)

if err != nil {

http.Error(w, err.Error(), http.StatusNotFound)

return

}

http.Redirect(w, r, longURL, http.StatusFound)

}

func main() {

http.HandleFunc("/", shortenHandler)

http.HandleFunc("/expand/", expandHandler)

log.Println("Server started at http://localhost:8080")

log.Fatal(http.ListenAndServe(":8080", nil))

}

HTML CODE

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>URL Shortener</title>

</head>

<body>

<h1>URL Shortener</h1>

<form method="POST">

<label for="long_url">Enter Long URL:</label>

<input type="text" id="long_url" name="long_url" required>

<button type="submit">Shorten</button>

</form>

</body>

</html>

Expand full comment

No posts

Ready for more?