Browse Source

- updated handleInfo and handleAccess to the gin framework

dependabot/npm_and_yarn/web/prismjs-1.21.0
Max Schmitt 8 years ago
parent
commit
aed25170a7
  1. 2
      README.md
  2. 54
      handlers/handlers.go
  3. 10
      handlers/handlers_test.go
  4. 15
      static/index.html

2
README.md

@ -119,7 +119,7 @@ To use this, POST a JSON with the field `id` to the endpoint. It will return a J
Next changes sorted by priority
- Gin integration
- Update http stuff to integration
- Authorization
- Deletion
- Test docker-compose installation

54
handlers/handlers.go

@ -2,12 +2,10 @@
package handlers
import (
"encoding/json"
"fmt"
"net/http"
"github.com/gin-gonic/gin"
"github.com/julienschmidt/httprouter"
"github.com/maxibanki/golang-url-shortener/store"
)
@ -38,8 +36,10 @@ func New(addr string, store store.Store) *Handler {
func (h *Handler) setHandlers() {
h.engine.POST("/api/v1/create", h.handleCreate)
// h.engine.POST("/api/v1/info", h.handleInfo)
// h.engine.GET("/:id", h.handleAccess)
h.engine.POST("/api/v1/info", h.handleInfo)
h.engine.StaticFile("/", "static/index.html")
h.engine.GET("/:id", h.handleAccess)
gin.SetMode(gin.ReleaseMode)
}
// handleCreate handles requests to create an entry
@ -53,61 +53,57 @@ func (h *Handler) handleCreate(c *gin.Context) {
return
}
id, err := h.store.CreateEntry(data.URL, c.Request.RemoteAddr)
id, err := h.store.CreateEntry(data.URL, c.ClientIP())
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
data.URL = h.getSchemaAndHost(c) + "/" + id
c.JSON(http.StatusOK, data)
}
func (h *Handler) getSchemaAndHost(c *gin.Context) string {
protocol := "http"
if c.Request.TLS != nil {
protocol = "https"
}
data.URL = fmt.Sprintf("%s://%s/%s", protocol, c.Request.Host, id)
c.JSON(http.StatusOK, data)
return fmt.Sprintf("%s://%s", protocol, c.Request.Host)
}
// handleInfo is the http handler for getting the infos
func (h *Handler) handleInfo(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
var req struct {
ID string
func (h *Handler) handleInfo(c *gin.Context) {
var data struct {
ID string `binding:"required"`
}
err := json.NewDecoder(r.Body).Decode(&req)
err := c.ShouldBind(&data)
if err != nil {
http.Error(w, fmt.Sprintf("could not decode JSON: %v", err), http.StatusBadRequest)
return
}
if req.ID == "" {
http.Error(w, "no ID provided", http.StatusBadRequest)
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
entry, err := h.store.GetEntryByID(req.ID)
entry, err := h.store.GetEntryByID(data.ID)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
}
entry.RemoteAddr = ""
w.Header().Add("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(entry)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
c.JSON(http.StatusOK, entry)
}
// handleAccess handles the access for incoming requests
func (h *Handler) handleAccess(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
id := p.ByName("id")
func (h *Handler) handleAccess(c *gin.Context) {
id := c.Param("id")
entry, err := h.store.GetEntryByID(id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
return
}
err = h.store.IncreaseVisitCounter(id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
http.Redirect(w, r, entry.URL, http.StatusTemporaryRedirect)
c.Redirect(http.StatusTemporaryRedirect, entry.URL)
}
// Listen starts the http server

10
handlers/handlers_test.go

@ -36,7 +36,7 @@ func TestCreateEntryJSON(t *testing.T) {
name: "body is nil",
response: "could not decode JSON: EOF",
statusCode: http.StatusBadRequest,
contentType: "text/plain; charset=utf-8",
contentType: "application/json; charset=utf-8",
ignoreResponse: true,
},
{
@ -45,7 +45,7 @@ func TestCreateEntryJSON(t *testing.T) {
URL: "https://www.google.de/",
},
statusCode: http.StatusOK,
contentType: "application/json",
contentType: "application/json; charset=utf-8",
},
{
name: "no valid URL",
@ -53,7 +53,7 @@ func TestCreateEntryJSON(t *testing.T) {
URL: "this is really not a URL",
},
statusCode: http.StatusBadRequest,
contentType: "text/plain; charset=utf-8",
contentType: "application/json; charset=utf-8",
response: store.ErrNoValidURL.Error(),
ignoreResponse: true,
},
@ -65,7 +65,6 @@ func TestCreateEntryJSON(t *testing.T) {
defer cleanup()
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
// build body for the create URL http request
var reqBody []byte
if tc.requestBody.URL != "" {
json, err := json.Marshal(tc.requestBody)
@ -386,7 +385,8 @@ func getBackend() (func(), error) {
if err != nil {
return nil, errors.Wrap(err, "could not create handler")
}
server = httptest.NewServer(handler.handlers())
server = httptest.NewServer(handler.engine)
return func() {
server.Close()
handler.Stop()

15
static/index.html

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Great page!</title>
</head>
<body>
</body>
</html>
Loading…
Cancel
Save