|
@@ -1,20 +1,23 @@
|
|
|
package api
|
|
|
|
|
|
import (
|
|
|
+ "encoding/json"
|
|
|
"io"
|
|
|
"net/http"
|
|
|
|
|
|
"github.com/annybs/ezdb"
|
|
|
"github.com/annybs/go/rest"
|
|
|
"github.com/annybs/go/validate"
|
|
|
+ "github.com/annybs/shorty/internal/types"
|
|
|
"github.com/rs/zerolog"
|
|
|
)
|
|
|
|
|
|
type API struct {
|
|
|
- DB ezdb.Collection[[]byte]
|
|
|
+ DB ezdb.Collection[*types.Redirect]
|
|
|
Log zerolog.Logger
|
|
|
|
|
|
- Token string
|
|
|
+ AllPath string
|
|
|
+ Token string
|
|
|
}
|
|
|
|
|
|
func (api *API) Delete(w http.ResponseWriter, req *http.Request) {
|
|
@@ -24,6 +27,11 @@ func (api *API) Delete(w http.ResponseWriter, req *http.Request) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ if req.URL.Path == api.AllPath {
|
|
|
+ w.WriteHeader(http.StatusBadRequest)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
path := req.URL.Path
|
|
|
|
|
|
if exist, _ := api.DB.Has(path); !exist {
|
|
@@ -40,18 +48,54 @@ func (api *API) Delete(w http.ResponseWriter, req *http.Request) {
|
|
|
}
|
|
|
|
|
|
func (api *API) Get(w http.ResponseWriter, req *http.Request) {
|
|
|
+ if req.URL.Path == api.AllPath {
|
|
|
+ api.GetAll(w, req)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
path := req.URL.Path
|
|
|
|
|
|
- dest, _ := api.DB.Get(path)
|
|
|
- if len(dest) > 0 {
|
|
|
- w.Header().Set("Location", string(dest))
|
|
|
- w.WriteHeader(http.StatusPermanentRedirect)
|
|
|
- } else {
|
|
|
+ redirect, err := api.DB.Get(path)
|
|
|
+ if err != nil {
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
+ w.Write([]byte(err.Error()))
|
|
|
+ return
|
|
|
}
|
|
|
+
|
|
|
+ if len(redirect.Destination) == 0 || redirect.StatusCode == 0 {
|
|
|
+ w.WriteHeader(http.StatusInternalServerError)
|
|
|
+ w.Write([]byte("invalid redirect"))
|
|
|
+ }
|
|
|
+
|
|
|
+ w.Header().Set("Location", string(redirect.Destination))
|
|
|
+ w.WriteHeader(redirect.StatusCode)
|
|
|
w.Write([]byte{})
|
|
|
}
|
|
|
|
|
|
+func (api *API) GetAll(w http.ResponseWriter, req *http.Request) {
|
|
|
+ if !rest.IsAuthenticated(req, api.Token) {
|
|
|
+ w.WriteHeader(http.StatusUnauthorized)
|
|
|
+ w.Write([]byte{})
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ all, err := api.DB.Iter().GetAll()
|
|
|
+ if err != nil {
|
|
|
+ w.WriteHeader(http.StatusInternalServerError)
|
|
|
+ w.Write([]byte(err.Error()))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ data, err := json.Marshal(all)
|
|
|
+ if err != nil {
|
|
|
+ w.WriteHeader(http.StatusInternalServerError)
|
|
|
+ w.Write([]byte(err.Error()))
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ w.Write(data)
|
|
|
+}
|
|
|
+
|
|
|
func (api *API) Put(w http.ResponseWriter, req *http.Request) {
|
|
|
if !rest.IsAuthenticated(req, api.Token) {
|
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
@@ -59,6 +103,11 @@ func (api *API) Put(w http.ResponseWriter, req *http.Request) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+ if req.URL.Path == api.AllPath {
|
|
|
+ w.WriteHeader(http.StatusBadRequest)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
path := req.URL.Path
|
|
|
|
|
|
dest, err := io.ReadAll(req.Body)
|
|
@@ -73,7 +122,12 @@ func (api *API) Put(w http.ResponseWriter, req *http.Request) {
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- if err := api.DB.Put(path, dest); err != nil {
|
|
|
+ redirect := &types.Redirect{
|
|
|
+ Destination: string(dest),
|
|
|
+ StatusCode: http.StatusPermanentRedirect,
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := api.DB.Put(path, redirect); err != nil {
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
|
w.Write([]byte(err.Error()))
|
|
|
} else {
|