Files
services/url/handler/url.go
Asim Aslam d456ff28e1 fix url
2021-12-11 20:52:48 +00:00

138 lines
2.7 KiB
Go

package handler
import (
"context"
"strings"
"time"
"github.com/micro/micro/v3/service/config"
"github.com/micro/micro/v3/service/errors"
"github.com/micro/micro/v3/service/store"
"github.com/micro/services/pkg/tenant"
url "github.com/micro/services/url/proto"
cache "github.com/patrickmn/go-cache"
"github.com/teris-io/shortid"
)
const hostPrefix = "https://m3o.one/u/"
type Url struct {
cache *cache.Cache
hostPrefix string
}
func NewUrl() *Url {
var hp string
cfg, err := config.Get("micro.url.host_prefix")
if err != nil {
hp = cfg.String(hostPrefix)
}
if len(strings.TrimSpace(hp)) == 0 {
hp = hostPrefix
}
return &Url{
cache: cache.New(cache.NoExpiration, cache.NoExpiration),
hostPrefix: hp,
}
}
func (e *Url) Shorten(ctx context.Context, req *url.ShortenRequest, rsp *url.ShortenResponse) error {
tenantId, ok := tenant.FromContext(ctx)
if !ok {
return errors.Unauthorized("url.shorten", "not authorized")
}
sid, err := shortid.New(1, shortid.DefaultABC, 2342)
if err != nil {
return err
}
id, err := sid.Generate()
if err != nil {
return err
}
val := &url.URLPair{
DestinationURL: req.DestinationURL,
ShortURL: e.hostPrefix + id,
Created: time.Now().Format(time.RFC3339Nano),
}
// write a global key
key := "url/" + id
if err := store.Write(store.NewRecord(key, val)); err != nil {
return err
}
// write per owner key
key = "urlOwner/" + tenantId + "/" + id
if err := store.Write(store.NewRecord(key, val)); err != nil {
return err
}
rsp.ShortURL = val.ShortURL
return nil
}
func (e *Url) List(ctx context.Context, req *url.ListRequest, rsp *url.ListResponse) error {
tenantId, ok := tenant.FromContext(ctx)
if !ok {
return errors.Unauthorized("url.shorten", "not authorized")
}
var err error
key := "urlOwner/" + tenantId + "/"
var opts []store.ReadOption
if len(req.ShortURL) > 0 {
id := strings.Replace(req.ShortURL, e.hostPrefix, "", -1)
key += id
} else {
opts = append(opts, store.ReadPrefix())
}
records, err := store.Read(key, opts...)
if err != nil {
return err
}
for _, rec := range records {
uri := new(url.URLPair)
if err := rec.Decode(uri); err != nil {
continue
}
rsp.UrlPairs = append(rsp.UrlPairs, uri)
}
return nil
}
func (e *Url) Proxy(ctx context.Context, req *url.ProxyRequest, rsp *url.ProxyResponse) error {
id := strings.Replace(req.ShortURL, e.hostPrefix, "", -1)
records, err := store.Read("url/" + id)
if err != nil {
return err
}
if len(records) == 0 {
return errors.NotFound("url.proxy", "not found")
}
uri := new(url.URLPair)
if err := records[0].Decode(uri); err != nil {
return err
}
rsp.DestinationURL = uri.DestinationURL
return nil
}