diff --git a/pages/api.go b/pages/api.go new file mode 100644 index 0000000..4e74b49 --- /dev/null +++ b/pages/api.go @@ -0,0 +1,86 @@ +package pages + +import ( + "bytes" + "encoding/json" + "fmt" + "net" + "net/http" + "qurl/qurl" + "time" +) + +type apijson struct { + URL string `json:"url",omitempty` + Exists bool `json:"exists",omitempty` + Error string `json:"error",omitempty` +} + +func (ctx *RootHandler) ServeAPI(w http.ResponseWriter, r *http.Request) { + var ( + j apijson + q *qurl.QURL + err error + ) + + u := r.FormValue("url") + + if u == "" { + j.Error = "Not a valid URL." + goto complete + } + + q, err = ctx.Storage.GetQURLByURL(u) + if err != nil { + j.Error = err.Error() + goto complete + } + + // Deal with URLs that already exist in the database + if q != nil { + j.Exists = true + j.URL = fmt.Sprintf("https://qurl.org/%s", qurl.ToString(q.ID)) + goto complete + } + + q = &qurl.QURL{ + URL: u, + Created: time.Now(), + } + if h, _, err := net.SplitHostPort(r.RemoteAddr); err == nil && h != "" { + q.IP = net.ParseIP(h) + } + if b := r.Header.Get("User-Agent"); b != "" { + q.Browser = b + } + + // Check if the URL we're adding is valid + err = q.CheckValid() + if err != nil { + j.Error = err.Error() + goto complete + } + + // Add the URL + err = ctx.Storage.AddQURL(q) + if err != nil { + j.Error = err.Error() + goto complete + } + + j.URL = fmt.Sprintf("https://qurl.org/%s", qurl.ToString(q.ID)) + +complete: + + var buf bytes.Buffer + encoder := json.NewEncoder(&buf) + err = encoder.Encode(j) + if err != nil { + http.Error(w, fmt.Sprintf("JSON encoding error: %s", err.Error()), + http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Header().Set("Content-Length", fmt.Sprintf("%d", buf.Len())) + w.Write(buf.Bytes()) +} diff --git a/pages/root.go b/pages/root.go index a2d08a3..aada701 100644 --- a/pages/root.go +++ b/pages/root.go @@ -35,6 +35,9 @@ func (ctx *RootHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { case "/favicon.ico": ctx.favi.ServeHTTP(w, r) + case "/api/url": + ctx.ServeAPI(w, r) + default: fmt.Printf("Path: %s\n", fname) } diff --git a/storage/storage.go b/storage/storage.go index 5c9d81d..960af25 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -10,7 +10,6 @@ import ( type Storage interface { AddQURL(*qurl.QURL) error - // GetQURL(uint64) (*qurl.QURL, error) GetQURLByURL(string) (*qurl.QURL, error) SetQURLSequence(uint64) error Backup(string) error