[server/handlers] Implement short url creation

This commit is contained in:
Richard Huang 2020-05-11 22:52:45 -07:00
parent fb59b69703
commit 37d93881e8
No known key found for this signature in database
GPG key ID: FFDEF81D05C2EC94
4 changed files with 68 additions and 1 deletions

View file

@ -1,8 +1,10 @@
package handlers
import (
"../utils"
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/gorilla/mux"
@ -50,3 +52,36 @@ func (a *App) GetURL(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "No such link")
}
}
func (a *App) CreateShortURL(w http.ResponseWriter, r *http.Request) {
if err := r.ParseForm(); err != nil {
log.Fatal("Could not parse JSON")
}
reqURL := r.PostFormValue("url")
alias := r.PostFormValue("alias")
// Verify URL is valid
if !utils.IsValidUrl(reqURL) {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "Invalid URL")
return
}
// Check if URL entry already exists
var urlEntry URLEntry
a.DB.Where("url = ?", reqURL).Find(&urlEntry)
if urlEntry.URL != "" {
alias = urlEntry.Alias
} else {
// Check if alias is already taken
for alias == "" || !a.DB.Where("alias = ?", alias).First(&urlEntry).RecordNotFound() {
alias = utils.RandString(6)
}
newURLEntry := &URLEntry{URL: reqURL, Alias: alias}
a.DB.Create(newURLEntry)
}
// Write HTTP Response
shortlink := r.Host + "/s/" + alias
w.WriteHeader(http.StatusCreated)
w.Header().Set("Location", shortlink)
fmt.Fprintf(w, shortlink)
}

View file

@ -14,6 +14,7 @@ func main() {
r := mux.NewRouter()
r.Handle("/", http.FileServer(http.Dir("./static"))).Methods("GET")
r.HandleFunc("/", a.CreateShortURL).Methods("POST")
r.HandleFunc("/all", a.ListAll).Methods("GET")
r.HandleFunc("/s/{alias:.*}", a.GetURL).Methods("GET")
http.Handle("/", r)

View file

@ -10,7 +10,7 @@
<body>
<form method="POST" action="/">
<input name="url" type="text" placeholder="paste a long url" value="" /></label>
<input name="url" type="text" placeholder="paste a long url" value="" required />
<br>
<input name="alias" type="text" placeholder="custom alias (optional)" value="" />
<br>

31
utils/utils.go Normal file
View file

@ -0,0 +1,31 @@
package utils
import (
"math/rand"
"net/url"
"time"
)
// Charset for random string generator
const Charset = "abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
// Tests a string to determine if it is a well-structured url or not
func IsValidUrl(str string) bool {
u, err := url.Parse(str)
return err == nil && u.Scheme != "" && u.Host != ""
}
// Generate a random alphanumeric string of given length
func RandString(length int) string {
return randStringWithCharset(length, Charset)
}
func randStringWithCharset(length int, charset string) string {
seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
}