Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ce311e5dd7 |
2
debian/RELEASE
vendored
2
debian/RELEASE
vendored
@@ -1 +1 @@
|
|||||||
18
|
17
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -8,7 +8,6 @@ require (
|
|||||||
github.com/go-swagger/go-swagger v0.23.0
|
github.com/go-swagger/go-swagger v0.23.0
|
||||||
github.com/golang/gddo v0.0.0-20190904175337-72a348e765d2 // indirect
|
github.com/golang/gddo v0.0.0-20190904175337-72a348e765d2 // indirect
|
||||||
github.com/gorilla/mux v1.7.3
|
github.com/gorilla/mux v1.7.3
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
|
||||||
github.com/sour-is/go-assetfs v1.0.0
|
github.com/sour-is/go-assetfs v1.0.0
|
||||||
github.com/spf13/viper v1.6.2
|
github.com/spf13/viper v1.6.2
|
||||||
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e
|
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e
|
||||||
|
|||||||
1
go.sum
1
go.sum
@@ -251,7 +251,6 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn
|
|||||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
package routes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"regexp"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"github.com/patrickmn/go-cache"
|
|
||||||
"sour.is/x/toolbox/httpsrv"
|
|
||||||
"sour.is/x/toolbox/uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
s := NewShortManager(365 * 24 * time.Hour)
|
|
||||||
|
|
||||||
httpsrv.HttpRegister("short", httpsrv.HttpRoutes{
|
|
||||||
{Name: "getShort", Method: "GET", Pattern: "/s/{id}", HandlerFunc: s.getShort},
|
|
||||||
{Name: "putShort", Method: "PUT", Pattern: "/s/{id}", HandlerFunc: s.putShort},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
type shortManager struct {
|
|
||||||
defaultExpire time.Duration
|
|
||||||
db *cache.Cache
|
|
||||||
}
|
|
||||||
|
|
||||||
type shortURL struct {
|
|
||||||
ID string
|
|
||||||
URL string
|
|
||||||
Secret string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewShortManager(defaultExpire time.Duration) *shortManager {
|
|
||||||
return &shortManager{
|
|
||||||
defaultExpire: defaultExpire,
|
|
||||||
db: cache.New(defaultExpire, defaultExpire/10),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *shortManager) GetURL(id string) *shortURL {
|
|
||||||
if u, ok := s.db.Get(id); ok {
|
|
||||||
if url, ok := u.(*shortURL); ok {
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (s *shortManager) PutURL(id string, url *shortURL) {
|
|
||||||
s.db.SetDefault(id, url)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *shortManager) getShort(w http.ResponseWriter, r *http.Request) {
|
|
||||||
vars := mux.Vars(r)
|
|
||||||
|
|
||||||
id := vars["id"]
|
|
||||||
url := s.GetURL(id)
|
|
||||||
|
|
||||||
if url == nil {
|
|
||||||
httpsrv.WriteError(w, 404, "not found")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set("Location", url.URL)
|
|
||||||
w.WriteHeader(http.StatusFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *shortManager) putShort(w http.ResponseWriter, r *http.Request) {
|
|
||||||
defer r.Body.Close()
|
|
||||||
|
|
||||||
vars := mux.Vars(r)
|
|
||||||
|
|
||||||
id := vars["id"]
|
|
||||||
secret := r.FormValue("secret")
|
|
||||||
u, err := url.Parse(r.FormValue("url"))
|
|
||||||
if err != nil {
|
|
||||||
httpsrv.WriteError(w, 400, "bad url")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
short := s.GetURL(id)
|
|
||||||
|
|
||||||
if short == nil {
|
|
||||||
short = newshort(id, secret, u.String())
|
|
||||||
|
|
||||||
s.PutURL(short.ID, short)
|
|
||||||
httpsrv.WriteObject(w, 200, short)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if secret == "" {
|
|
||||||
httpsrv.WriteError(w, 401, "no auth")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if secret != short.Secret {
|
|
||||||
httpsrv.WriteError(w, 403, "forbidden")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
short.URL = u.String()
|
|
||||||
|
|
||||||
s.PutURL(short.ID, short)
|
|
||||||
httpsrv.WriteObject(w, 200, short)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newshort(id, secret, u string) *shortURL {
|
|
||||||
m, err := regexp.MatchString("[a-z-]{1,64}", id)
|
|
||||||
if id == "" || !m || err != nil {
|
|
||||||
id = uuid.V4()
|
|
||||||
}
|
|
||||||
m, err = regexp.MatchString("[a-z-]{1,64}", secret)
|
|
||||||
if secret == "" || !m || err != nil {
|
|
||||||
secret = uuid.V4()
|
|
||||||
}
|
|
||||||
return &shortURL{ID: id, Secret: secret, URL: u}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user