diff --git a/web/handlers.go b/web/handlers.go new file mode 100644 index 0000000..6f8d630 --- /dev/null +++ b/web/handlers.go @@ -0,0 +1,90 @@ +package web + +import ( + "encoding/json" + "fmt" + "net/url" + + "github.com/jimeh/ozu.io/shortner" + "github.com/qiangxue/fasthttp-routing" + "github.com/valyala/fasthttp" +) + +// Handlers handle HTTP requests. +type Handlers struct { + s *shortner.Shortner +} + +// Index handles requests for root. +func (h *Handlers) Index(c *routing.Context) error { + c.WriteString("Welcome to ozu.io, a shitty URL shortner.") + return nil +} + +// Shorten shortens given URL. +func (h *Handlers) Shorten(c *routing.Context) error { + c.SetContentType("application/json") + + uid, url, err := h.s.Shorten(c.FormValue("url")) + if err != nil { + c.SetStatusCode(fasthttp.StatusBadRequest) + response, _ := json.Marshal(ErrorResponse{err.Error()}) + c.Write(response) + return nil + } + + h.respondWithShortened(c, uid, url) + return nil +} + +// Lookup shortened UID. +func (h *Handlers) Lookup(c *routing.Context) error { + c.SetContentType("application/json") + + uid := c.FormValue("uid") + url, err := h.s.Lookup(uid) + if err != nil { + c.SetStatusCode(fasthttp.StatusNotFound) + respBytes, _ := json.Marshal(ErrorResponse{err.Error()}) + c.Write(respBytes) + return nil + } + + h.respondWithShortened(c, uid, url) + return nil +} + +// LookupAndRedirect looks up given UID and redirects to it's URL. +func (h *Handlers) LookupAndRedirect(c *routing.Context) error { + uid := c.Param("uid") + url, err := h.s.Lookup([]byte(uid)) + if err != nil { + c.SetStatusCode(fasthttp.StatusNotFound) + fmt.Fprint(c, "404 Not Found") + return nil + } + + c.Redirect(string(url), fasthttp.StatusMovedPermanently) + return nil +} + +func (h *Handlers) respondWithShortened(c *routing.Context, uid []byte, url []byte) { + c.SetStatusCode(fasthttp.StatusOK) + response := ShortenedResponse{ + UID: string(uid), + ShortURL: h.makeShortURL(c, uid), + URL: string(url), + } + respBytes, _ := json.Marshal(response) + c.Write(respBytes) +} + +func (h *Handlers) makeShortURL(c *routing.Context, uid []byte) string { + shortURL := &url.URL{ + Scheme: "http", + Host: string(c.Host()), + Path: "/" + string(uid), + } + + return shortURL.String() +} diff --git a/web/router.go b/web/router.go index 691cfda..fb68cd6 100644 --- a/web/router.go +++ b/web/router.go @@ -1,13 +1,8 @@ package web import ( - "encoding/json" - "fmt" - "net/url" - "github.com/jimeh/ozu.io/shortner" "github.com/qiangxue/fasthttp-routing" - "github.com/valyala/fasthttp" ) // NewRouter creates a new fasthttprouter.Router with all handlers registered. @@ -22,82 +17,3 @@ func NewRouter(shortner *shortner.Shortner) *routing.Router { return router } - -// Handlers handle HTTP requests. -type Handlers struct { - s *shortner.Shortner -} - -// Index handles requests for root. -func (h *Handlers) Index(c *routing.Context) error { - c.WriteString("Welcome to ozu.io, a shitty URL shortner.") - return nil -} - -// Shorten shortens given URL. -func (h *Handlers) Shorten(c *routing.Context) error { - c.SetContentType("application/json") - - uid, url, err := h.s.Shorten(c.FormValue("url")) - if err != nil { - c.SetStatusCode(fasthttp.StatusBadRequest) - response, _ := json.Marshal(ErrorResponse{err.Error()}) - c.Write(response) - return nil - } - - h.respondWithShortened(c, uid, url) - return nil -} - -// Lookup shortened UID. -func (h *Handlers) Lookup(c *routing.Context) error { - c.SetContentType("application/json") - - uid := c.FormValue("uid") - url, err := h.s.Lookup(uid) - if err != nil { - c.SetStatusCode(fasthttp.StatusNotFound) - respBytes, _ := json.Marshal(ErrorResponse{err.Error()}) - c.Write(respBytes) - return nil - } - - h.respondWithShortened(c, uid, url) - return nil -} - -// LookupAndRedirect looks up given UID and redirects to it's URL. -func (h *Handlers) LookupAndRedirect(c *routing.Context) error { - uid := c.Param("uid") - url, err := h.s.Lookup([]byte(uid)) - if err != nil { - c.SetStatusCode(fasthttp.StatusNotFound) - fmt.Fprint(c, "404 Not Found") - return nil - } - - c.Redirect(string(url), fasthttp.StatusMovedPermanently) - return nil -} - -func (h *Handlers) respondWithShortened(c *routing.Context, uid []byte, url []byte) { - c.SetStatusCode(fasthttp.StatusOK) - response := ShortenedResponse{ - UID: string(uid), - ShortURL: h.makeShortURL(c, uid), - URL: string(url), - } - respBytes, _ := json.Marshal(response) - c.Write(respBytes) -} - -func (h *Handlers) makeShortURL(c *routing.Context, uid []byte) string { - shortURL := &url.URL{ - Scheme: "http", - Host: string(c.Host()), - Path: "/" + string(uid), - } - - return shortURL.String() -}