summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go105
1 files changed, 105 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..11d7370
--- /dev/null
+++ b/main.go
@@ -0,0 +1,105 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "math/rand/v2"
+ "net/http"
+ "unicode/utf8"
+)
+
+const charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+const version = "0.0.1"
+
+var Table map[string]string = make(map[string]string)
+
+type Request struct {
+ URL string
+}
+
+type Response struct {
+ Version string
+ Status string
+ Original string
+ New string
+}
+
+func NewRequest(r *http.Request) (Request, error) {
+ var request Request
+
+ err := json.NewDecoder(r.Body).Decode(&request)
+
+ return request, err
+}
+
+func log_header(r *http.Request) {
+ log.Println("Header {")
+ for k, v := range r.Header {
+ log.Printf("\t\"%s\": \"%s\"\n", k, v)
+ }
+ log.Println("}")
+}
+
+func redirect(w http.ResponseWriter, r *http.Request) {
+ log.Println("Request for:", r.URL.String())
+ log_header(r)
+
+ _, i := utf8.DecodeRuneInString(r.URL.String())
+ url := r.URL.String()[i:]
+
+ original, ok := Table[url]
+
+ if ok {
+ w.Header().Set("location", original)
+ http.Error(w, http.StatusText(301), 301)
+ } else {
+ http.Error(w, http.StatusText(404), 404)
+ }
+}
+
+func shorten(w http.ResponseWriter, r *http.Request) {
+ log.Println("Request to Shorten")
+ log_header(r)
+
+ request, err := NewRequest(r)
+ if err != nil {
+ http.Error(w, http.StatusText(500), 500)
+ }
+
+ url := GenerateString(4)
+ _, ok := Table[url]
+
+ for ok {
+ url = GenerateString(4)
+ _, ok = Table[url]
+ }
+
+ Table[url] = request.URL
+
+ response := Response{version, "ok", request.URL, url}
+
+ data, err := json.Marshal(response)
+ if err != nil {
+ http.Error(w, http.StatusText(500), 500)
+ }
+
+ fmt.Fprintf(w, "%s", string(data))
+}
+
+func GenerateString(size uint) string {
+ buffer := make([]rune, size)
+
+ for i := uint(0); i < size; i++ {
+ index := rand.Uint() % uint(len(charSet))
+ buffer[i] = []rune(charSet)[index]
+ }
+
+ return string(buffer)
+}
+
+func main() {
+ http.HandleFunc("/shorten", shorten)
+ http.HandleFunc("/", redirect)
+ log.Fatal(http.ListenAndServe(":8000", nil))
+}