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()) }