From b5fdfcb49c70f61116116aa2fd62f8ee0500f050 Mon Sep 17 00:00:00 2001 From: Alvie Rahman Date: Wed, 21 Sep 2022 20:52:40 +0100 Subject: [PATCH] implement conditional redirects --- main.go | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 6 deletions(-) diff --git a/main.go b/main.go index 864e312..7b76a5a 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,9 @@ import ( "log" "net/http" "os" + "strconv" + "strings" + "time" "github.com/go-redis/redis/v8" "github.com/gorilla/mux" @@ -83,7 +86,7 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { alt_condition, ) - formstring := command+":"+shortlink+":"+redirect+":"+alt_condition+":"+alt_redirect + formstring := command + ":" + shortlink + ":" + redirect + ":" + alt_condition + ":" + alt_redirect fmt.Println("formstring: " + formstring) @@ -110,7 +113,21 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { ctx := context.Background() _, err := client.Get(ctx, shortlink).Result() if err == redis.Nil { - err = client.Set(ctx, shortlink, shortlink, 0).Err() + err = client.Set(ctx, shortlink+":redirect", shortlink, 0).Err() + if err != nil { + fmt.Println(err) + w.WriteHeader(500) + w.Write([]byte("500 Internal Server Error")) + return + } + err = client.Set(ctx, shortlink+":altcondition", alt_condition, 0).Err() + if err != nil { + fmt.Println(err) + w.WriteHeader(500) + w.Write([]byte("500 Internal Server Error")) + return + } + err = client.Set(ctx, shortlink+":altredirect", alt_redirect, 0).Err() if err != nil { fmt.Println(err) @@ -139,7 +156,15 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { if command == "delete" { ctx := context.Background() - if err := client.Del(ctx, shortlink).Err(); err != nil { + if err := client.Del(ctx, shortlink+":redirect").Err(); err != nil { + w.WriteHeader(500) + w.Write([]byte("500 Internal Server Error")) + } + if err := client.Del(ctx, shortlink+":altredirect").Err(); err != nil { + w.WriteHeader(500) + w.Write([]byte("500 Internal Server Error")) + } + if err := client.Del(ctx, shortlink+":altcondition").Err(); err != nil { w.WriteHeader(500) w.Write([]byte("500 Internal Server Error")) } @@ -176,7 +201,9 @@ func shortlinkHandler(w http.ResponseWriter, r *http.Request) { fmt.Println("shortlinkHandler called") shortlink := string(mux.Vars(r)["shortlink"]) ctx := context.Background() - redirect, err := client.Get(ctx, shortlink).Result() + client.Incr(ctx, shortlink + ":hits") + + redirect, err := client.Get(ctx, shortlink+":redirect").Result() fmt.Printf("shortlink: %v, redirect: %v\n", shortlink, redirect) if err == redis.Nil { w.WriteHeader(404) @@ -184,13 +211,67 @@ func shortlinkHandler(w http.ResponseWriter, r *http.Request) { return } else if err != nil { fmt.Println(err) + fmt.Println(0) w.WriteHeader(500) w.Write([]byte("500 Internal Server Error")) return } - http.Redirect(w, r, redirect, 302) - return + altcondition, err := client.Get(ctx, shortlink+":altcondition").Result() + if err == redis.Nil { + http.Redirect(w, r, redirect, 302) + return + } else if err != nil { + fmt.Println(err) + fmt.Println(1) + w.WriteHeader(500) + w.Write([]byte("500 Internal Server Error")) + return + } + + altredirect, err := client.Get(ctx, shortlink+":altredirect").Result() + if err == redis.Nil { + http.Redirect(w, r, redirect, 302) + return + } else if err != nil { + fmt.Println(err) + fmt.Println(2) + w.WriteHeader(500) + w.Write([]byte("500 Internal Server Error")) + return + } + + altcondition_split := strings.Split(altcondition, ",") + ac_varname := altcondition_split[0] + ac_operator := altcondition_split[1] + ac_required_value, _ := strconv.Atoi(altcondition_split[2]) + + var ac_varval int + + if ac_varname != "timestamp" { + ac_varvalstr, err := client.Get(ctx, shortlink+":"+ac_varname).Result() + if err == redis.Nil { + ac_varval = 0 + } else if err != nil { + fmt.Println(err) + fmt.Println(3) + w.WriteHeader(500) + w.Write([]byte("500 Internal Server Error")) + return + } else { + ac_varval, _ = strconv.Atoi(ac_varvalstr) + } + } else { + ac_varval = int(time.Now().Unix()) + } + + if (ac_operator == "eq" && ac_varval == ac_required_value) || + (ac_operator == "gt" && ac_varval > ac_required_value) || + (ac_operator == "lt" && ac_varval < ac_required_value) { + http.Redirect(w, r, altredirect, 307) + } else { + http.Redirect(w, r, redirect, 307) + } } func getSha256HMACSignature(secret []byte, data string) string {