feat: initial dnslink support
This commit is contained in:
parent
3e80bb43fa
commit
cd2f63eb72
|
@ -50,13 +50,13 @@ func sendErrorCustom(ctx iris.Context, err error, customError error, irisError i
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
func internalError(ctx iris.Context, err error) bool {
|
func InternalError(ctx iris.Context, err error) bool {
|
||||||
return sendErrorCustom(ctx, err, nil, iris.StatusInternalServerError)
|
return sendErrorCustom(ctx, err, nil, iris.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
func internalErrorCustom(ctx iris.Context, err error, customError error) bool {
|
func internalErrorCustom(ctx iris.Context, err error, customError error) bool {
|
||||||
return sendErrorCustom(ctx, err, customError, iris.StatusInternalServerError)
|
return sendErrorCustom(ctx, err, customError, iris.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
func sendError(ctx iris.Context, err error, irisError int) bool {
|
func SendError(ctx iris.Context, err error, irisError int) bool {
|
||||||
return sendErrorCustom(ctx, err, nil, irisError)
|
return sendErrorCustom(ctx, err, nil, irisError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
var errStreamDone = errors.New("done")
|
var ErrStreamDone = errors.New("done")
|
||||||
|
|
||||||
type FilesController struct {
|
type FilesController struct {
|
||||||
Controller
|
Controller
|
||||||
|
@ -36,21 +36,21 @@ func (f *FilesController) PostUpload() {
|
||||||
|
|
||||||
upload, err := files.Upload(file, meta.Size, nil, auth.GetCurrentUserId(ctx))
|
upload, err := files.Upload(file, meta.Size, nil, auth.GetCurrentUserId(ctx))
|
||||||
|
|
||||||
if internalError(ctx, err) {
|
if InternalError(ctx, err) {
|
||||||
logger.Get().Debug("failed uploading file", zap.Error(err))
|
logger.Get().Debug("failed uploading file", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = files.Pin(upload.Hash, upload.AccountID)
|
err = files.Pin(upload.Hash, upload.AccountID)
|
||||||
|
|
||||||
if internalError(ctx, err) {
|
if InternalError(ctx, err) {
|
||||||
logger.Get().Debug("failed pinning file", zap.Error(err))
|
logger.Get().Debug("failed pinning file", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cidString, err := cid.EncodeString(upload.Hash, uint64(meta.Size))
|
cidString, err := cid.EncodeString(upload.Hash, uint64(meta.Size))
|
||||||
|
|
||||||
if internalError(ctx, err) {
|
if InternalError(ctx, err) {
|
||||||
logger.Get().Debug("failed creating cid", zap.Error(err))
|
logger.Get().Debug("failed creating cid", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -65,20 +65,20 @@ func (f *FilesController) PostUpload() {
|
||||||
func (f *FilesController) GetDownloadBy(cidString string) {
|
func (f *FilesController) GetDownloadBy(cidString string) {
|
||||||
ctx := f.Ctx
|
ctx := f.Ctx
|
||||||
|
|
||||||
hashHex, valid := validateCid(cidString, true, ctx)
|
hashHex, valid := ValidateCid(cidString, true, ctx)
|
||||||
|
|
||||||
if !valid {
|
if !valid {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
download, err := files.Download(hashHex)
|
download, err := files.Download(hashHex)
|
||||||
if internalError(ctx, err) {
|
if InternalError(ctx, err) {
|
||||||
logger.Get().Debug("failed fetching file", zap.Error(err))
|
logger.Get().Debug("failed fetching file", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = passThroughStream(download, ctx)
|
err = PassThroughStream(download, ctx)
|
||||||
if err != errStreamDone && internalError(ctx, err) {
|
if err != ErrStreamDone && InternalError(ctx, err) {
|
||||||
logger.Get().Debug("failed streaming file", zap.Error(err))
|
logger.Get().Debug("failed streaming file", zap.Error(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,20 +86,20 @@ func (f *FilesController) GetDownloadBy(cidString string) {
|
||||||
func (f *FilesController) GetProofBy(cidString string) {
|
func (f *FilesController) GetProofBy(cidString string) {
|
||||||
ctx := f.Ctx
|
ctx := f.Ctx
|
||||||
|
|
||||||
hashHex, valid := validateCid(cidString, true, ctx)
|
hashHex, valid := ValidateCid(cidString, true, ctx)
|
||||||
|
|
||||||
if !valid {
|
if !valid {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
proof, err := files.DownloadProof(hashHex)
|
proof, err := files.DownloadProof(hashHex)
|
||||||
if internalError(ctx, err) {
|
if InternalError(ctx, err) {
|
||||||
logger.Get().Debug("failed fetching file proof", zap.Error(err))
|
logger.Get().Debug("failed fetching file proof", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = passThroughStream(proof, ctx)
|
err = PassThroughStream(proof, ctx)
|
||||||
if internalError(ctx, err) {
|
if InternalError(ctx, err) {
|
||||||
logger.Get().Debug("failed streaming file proof", zap.Error(err))
|
logger.Get().Debug("failed streaming file proof", zap.Error(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ func (f *FilesController) GetProofBy(cidString string) {
|
||||||
func (f *FilesController) GetStatusBy(cidString string) {
|
func (f *FilesController) GetStatusBy(cidString string) {
|
||||||
ctx := f.Ctx
|
ctx := f.Ctx
|
||||||
|
|
||||||
hashHex, valid := validateCid(cidString, false, ctx)
|
hashHex, valid := ValidateCid(cidString, false, ctx)
|
||||||
|
|
||||||
if !valid {
|
if !valid {
|
||||||
return
|
return
|
||||||
|
@ -136,14 +136,14 @@ func (f *FilesController) GetStatusBy(cidString string) {
|
||||||
func (f *FilesController) PostPinBy(cidString string) {
|
func (f *FilesController) PostPinBy(cidString string) {
|
||||||
ctx := f.Ctx
|
ctx := f.Ctx
|
||||||
|
|
||||||
hashHex, valid := validateCid(cidString, true, ctx)
|
hashHex, valid := ValidateCid(cidString, true, ctx)
|
||||||
|
|
||||||
if !valid {
|
if !valid {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := files.Pin(hashHex, auth.GetCurrentUserId(ctx))
|
err := files.Pin(hashHex, auth.GetCurrentUserId(ctx))
|
||||||
if internalError(ctx, err) {
|
if InternalError(ctx, err) {
|
||||||
logger.Get().Error(err.Error())
|
logger.Get().Error(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -155,9 +155,9 @@ func (f *FilesController) GetUploadLimit() {
|
||||||
f.respondJSON(&response.UploadLimit{Limit: f.Ctx.Application().ConfigurationReadOnly().GetPostMaxMemory()})
|
f.respondJSON(&response.UploadLimit{Limit: f.Ctx.Application().ConfigurationReadOnly().GetPostMaxMemory()})
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateCid(cidString string, validateStatus bool, ctx iris.Context) (string, bool) {
|
func ValidateCid(cidString string, validateStatus bool, ctx iris.Context) (string, bool) {
|
||||||
_, err := cid.Valid(cidString)
|
_, err := cid.Valid(cidString)
|
||||||
if sendError(ctx, err, iris.StatusBadRequest) {
|
if SendError(ctx, err, iris.StatusBadRequest) {
|
||||||
logger.Get().Debug("invalid cid", zap.Error(err))
|
logger.Get().Debug("invalid cid", zap.Error(err))
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ func validateCid(cidString string, validateStatus bool, ctx iris.Context) (strin
|
||||||
|
|
||||||
if status == files.STATUS_NOT_FOUND {
|
if status == files.STATUS_NOT_FOUND {
|
||||||
err := errors.New("cid not found")
|
err := errors.New("cid not found")
|
||||||
sendError(ctx, errors.New("cid not found"), iris.StatusNotFound)
|
SendError(ctx, errors.New("cid not found"), iris.StatusNotFound)
|
||||||
logger.Get().Debug("cid not found", zap.Error(err))
|
logger.Get().Debug("cid not found", zap.Error(err))
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
@ -179,12 +179,12 @@ func validateCid(cidString string, validateStatus bool, ctx iris.Context) (strin
|
||||||
return hashHex, true
|
return hashHex, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func passThroughStream(stream io.Reader, ctx iris.Context) error {
|
func PassThroughStream(stream io.Reader, ctx iris.Context) error {
|
||||||
closed := false
|
closed := false
|
||||||
|
|
||||||
err := ctx.StreamWriter(func(w io.Writer) error {
|
err := ctx.StreamWriter(func(w io.Writer) error {
|
||||||
if closed {
|
if closed {
|
||||||
return errStreamDone
|
return ErrStreamDone
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := io.CopyN(w, stream, 1024)
|
count, err := io.CopyN(w, stream, 1024)
|
||||||
|
@ -205,7 +205,7 @@ func passThroughStream(stream io.Reader, ctx iris.Context) error {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err == errStreamDone {
|
if err == ErrStreamDone {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
db/db.go
2
db/db.go
|
@ -53,7 +53,7 @@ func Init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically migrate the database schema based on the model definitions.
|
// Automatically migrate the database schema based on the model definitions.
|
||||||
err = db.Migrator().AutoMigrate(&model.Account{}, &model.Key{}, &model.KeyChallenge{}, &model.LoginSession{}, &model.Upload{}, &model.Pin{}, &model.Tus{})
|
err = db.Migrator().AutoMigrate(&model.Account{}, &model.Key{}, &model.KeyChallenge{}, &model.LoginSession{}, &model.Upload{}, &model.Pin{}, &model.Tus{}, &model.Dnslink{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("Database setup failed database type: %s \n", err))
|
panic(fmt.Errorf("Database setup failed database type: %s \n", err))
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,225 @@
|
||||||
|
package dnslink
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/cid"
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/controller"
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/db"
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/logger"
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/model"
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/service/files"
|
||||||
|
dnslink "github.com/dnslink-std/go"
|
||||||
|
"github.com/kataras/iris/v12"
|
||||||
|
"github.com/kataras/iris/v12/context"
|
||||||
|
"github.com/vmihailenco/msgpack/v5"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"io"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrFailedReadAppManifest = errors.New("failed to read app manifest")
|
||||||
|
ErrInvalidAppManifest = errors.New("invalid app manifest")
|
||||||
|
)
|
||||||
|
|
||||||
|
type CID string
|
||||||
|
type ExtraMetadata map[string]interface{}
|
||||||
|
|
||||||
|
type WebAppMetadata struct {
|
||||||
|
Schema string `msgpack:"$schema,omitempty"`
|
||||||
|
Type string `msgpack:"type"`
|
||||||
|
Name string `msgpack:"name,omitempty"`
|
||||||
|
TryFiles []string `msgpack:"tryFiles,omitempty"`
|
||||||
|
ErrorPages map[string]string `msgpack:"errorPages,omitempty"`
|
||||||
|
Paths map[string]PathContent `msgpack:"paths"`
|
||||||
|
ExtraMetadata ExtraMetadata `msgpack:"extraMetadata,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PathContent struct {
|
||||||
|
CID CID `msgpack:"cid"`
|
||||||
|
ContentType string `msgpack:"contentType,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handler(ctx *context.Context) {
|
||||||
|
record := model.Dnslink{}
|
||||||
|
|
||||||
|
domain := ctx.Request().Host
|
||||||
|
|
||||||
|
if err := db.Get().Model(&model.Dnslink{Domain: domain}).First(&record).Error; err != nil {
|
||||||
|
ctx.StopWithStatus(iris.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ret, err := dnslink.Resolve(domain)
|
||||||
|
if err != nil {
|
||||||
|
switch e := err.(type) {
|
||||||
|
default:
|
||||||
|
ctx.StopWithStatus(iris.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
case dnslink.DNSRCodeError:
|
||||||
|
if e.DNSRCode == 3 {
|
||||||
|
ctx.StopWithStatus(iris.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ret.Links["sia"] == nil || len(ret.Links["sia"]) == 0 {
|
||||||
|
ctx.StopWithStatus(iris.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
appManifest := ret.Links["sia"][0]
|
||||||
|
|
||||||
|
decodedCid, valid := controller.ValidateCid(appManifest.Identifier, true, ctx)
|
||||||
|
if !valid {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
manifest := fetchManifest(ctx, decodedCid)
|
||||||
|
if manifest == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
path := ctx.Path()
|
||||||
|
|
||||||
|
if strings.HasSuffix(path, "/") || filepath.Ext(path) == "" {
|
||||||
|
var directoryIndex *PathContent
|
||||||
|
for _, indexFile := range manifest.TryFiles {
|
||||||
|
path, exists := manifest.Paths[indexFile]
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := cid.Valid(string(manifest.Paths[indexFile].CID))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
cidObject, _ := cid.Decode(string(path.CID))
|
||||||
|
hashHex := cidObject.StringHash()
|
||||||
|
|
||||||
|
status := files.Status(hashHex)
|
||||||
|
|
||||||
|
if status == files.STATUS_NOT_FOUND {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if status == files.STATUS_UPLOADED {
|
||||||
|
directoryIndex = &path
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if directoryIndex == nil {
|
||||||
|
ctx.StopWithStatus(iris.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := fetchFile(directoryIndex)
|
||||||
|
if maybeHandleFileError(err, ctx) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Header("Content-Type", directoryIndex.ContentType)
|
||||||
|
streamFile(file, ctx)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
requestedPath, exists := manifest.Paths[path]
|
||||||
|
|
||||||
|
if !exists {
|
||||||
|
ctx.StopWithStatus(iris.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := fetchFile(&requestedPath)
|
||||||
|
if maybeHandleFileError(err, ctx) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Header("Content-Type", requestedPath.ContentType)
|
||||||
|
streamFile(file, ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func maybeHandleFileError(err error, ctx *context.Context) bool {
|
||||||
|
if err != nil {
|
||||||
|
if err == files.ErrInvalidFile {
|
||||||
|
controller.SendError(ctx, err, iris.StatusNotFound)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
controller.SendError(ctx, err, iris.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func streamFile(stream io.Reader, ctx *context.Context) {
|
||||||
|
err := controller.PassThroughStream(stream, ctx)
|
||||||
|
if err != controller.ErrStreamDone && controller.InternalError(ctx, err) {
|
||||||
|
logger.Get().Debug("failed streaming file", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchFile(path *PathContent) (io.Reader, error) {
|
||||||
|
_, err := cid.Valid(string(path.CID))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cidObject, _ := cid.Decode(string(path.CID))
|
||||||
|
hashHex := cidObject.StringHash()
|
||||||
|
|
||||||
|
status := files.Status(hashHex)
|
||||||
|
|
||||||
|
if status == files.STATUS_NOT_FOUND {
|
||||||
|
return nil, errors.New("cid not found")
|
||||||
|
}
|
||||||
|
if status == files.STATUS_UPLOADED {
|
||||||
|
stream, err := files.Download(hashHex)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, errors.New("cid not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchManifest(ctx iris.Context, hash string) *WebAppMetadata {
|
||||||
|
stream, err := files.Download(hash)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, files.ErrInvalidFile) {
|
||||||
|
controller.SendError(ctx, err, iris.StatusNotFound)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
controller.SendError(ctx, err, iris.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
var metadata WebAppMetadata
|
||||||
|
|
||||||
|
data, err := io.ReadAll(stream)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logger.Get().Debug(ErrFailedReadAppManifest.Error(), zap.Error(err))
|
||||||
|
controller.SendError(ctx, ErrFailedReadAppManifest, iris.StatusInternalServerError)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = msgpack.Unmarshal(data, &metadata)
|
||||||
|
if err != nil {
|
||||||
|
logger.Get().Debug(ErrFailedReadAppManifest.Error(), zap.Error(err))
|
||||||
|
controller.SendError(ctx, ErrFailedReadAppManifest, iris.StatusInternalServerError)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if metadata.Type != "web_app" {
|
||||||
|
logger.Get().Debug(ErrInvalidAppManifest.Error())
|
||||||
|
controller.SendError(ctx, ErrInvalidAppManifest, iris.StatusInternalServerError)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &metadata
|
||||||
|
}
|
4
go.mod
4
go.mod
|
@ -3,6 +3,7 @@ module git.lumeweb.com/LumeWeb/portal
|
||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/dnslink-std/go v0.6.0
|
||||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0
|
github.com/go-ozzo/ozzo-validation/v4 v4.3.0
|
||||||
github.com/go-resty/resty/v2 v2.7.0
|
github.com/go-resty/resty/v2 v2.7.0
|
||||||
github.com/golang-queue/queue v0.1.3
|
github.com/golang-queue/queue v0.1.3
|
||||||
|
@ -16,6 +17,7 @@ require (
|
||||||
github.com/spf13/viper v1.16.0
|
github.com/spf13/viper v1.16.0
|
||||||
github.com/swaggo/swag v1.16.1
|
github.com/swaggo/swag v1.16.1
|
||||||
github.com/tus/tusd v1.11.0
|
github.com/tus/tusd v1.11.0
|
||||||
|
github.com/vmihailenco/msgpack/v5 v5.3.5
|
||||||
go.uber.org/zap v1.24.0
|
go.uber.org/zap v1.24.0
|
||||||
golang.org/x/crypto v0.10.0
|
golang.org/x/crypto v0.10.0
|
||||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df
|
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df
|
||||||
|
@ -74,6 +76,7 @@ require (
|
||||||
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
||||||
github.com/mediocregopher/radix/v3 v3.8.1 // indirect
|
github.com/mediocregopher/radix/v3 v3.8.1 // indirect
|
||||||
github.com/microcosm-cc/bluemonday v1.0.24 // indirect
|
github.com/microcosm-cc/bluemonday v1.0.24 // indirect
|
||||||
|
github.com/miekg/dns v1.1.43 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||||
github.com/multiformats/go-base32 v0.1.0 // indirect
|
github.com/multiformats/go-base32 v0.1.0 // indirect
|
||||||
|
@ -94,7 +97,6 @@ require (
|
||||||
github.com/tdewolff/minify/v2 v2.12.7 // indirect
|
github.com/tdewolff/minify/v2 v2.12.7 // indirect
|
||||||
github.com/tdewolff/parse/v2 v2.6.6 // indirect
|
github.com/tdewolff/parse/v2 v2.6.6 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
|
|
||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
||||||
github.com/yosssi/ace v0.0.5 // indirect
|
github.com/yosssi/ace v0.0.5 // indirect
|
||||||
go.uber.org/atomic v1.11.0 // indirect
|
go.uber.org/atomic v1.11.0 // indirect
|
||||||
|
|
9
go.sum
9
go.sum
|
@ -691,6 +691,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE=
|
github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE=
|
||||||
|
github.com/dnslink-std/go v0.6.0 h1:i+5HdSFNrpKxozvyebtvUgjXdqm7SW35NWkO4mnxyjQ=
|
||||||
|
github.com/dnslink-std/go v0.6.0/go.mod h1:LZoJk4C4PpPZdJhsfi3ADdOVz7teVr1q2MZTtRrCTLE=
|
||||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
|
@ -765,6 +767,8 @@ github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9
|
||||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
|
||||||
|
github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
|
||||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||||
|
@ -998,6 +1002,8 @@ github.com/mediocregopher/radix/v3 v3.8.1 h1:rOkHflVuulFKlwsLY01/M2cM2tWCjDoETcM
|
||||||
github.com/mediocregopher/radix/v3 v3.8.1/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
|
github.com/mediocregopher/radix/v3 v3.8.1/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw=
|
github.com/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw=
|
||||||
github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8=
|
github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8=
|
||||||
|
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
|
||||||
|
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||||
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=
|
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=
|
||||||
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=
|
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=
|
||||||
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
|
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
|
||||||
|
@ -1109,6 +1115,7 @@ github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
|
||||||
github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
|
github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
@ -1297,6 +1304,7 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
@ -1416,6 +1424,7 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|
8
main.go
8
main.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"git.lumeweb.com/LumeWeb/portal/config"
|
"git.lumeweb.com/LumeWeb/portal/config"
|
||||||
"git.lumeweb.com/LumeWeb/portal/controller"
|
"git.lumeweb.com/LumeWeb/portal/controller"
|
||||||
"git.lumeweb.com/LumeWeb/portal/db"
|
"git.lumeweb.com/LumeWeb/portal/db"
|
||||||
|
"git.lumeweb.com/LumeWeb/portal/dnslink"
|
||||||
_ "git.lumeweb.com/LumeWeb/portal/docs"
|
_ "git.lumeweb.com/LumeWeb/portal/docs"
|
||||||
"git.lumeweb.com/LumeWeb/portal/logger"
|
"git.lumeweb.com/LumeWeb/portal/logger"
|
||||||
"git.lumeweb.com/LumeWeb/portal/middleware"
|
"git.lumeweb.com/LumeWeb/portal/middleware"
|
||||||
|
@ -66,7 +67,8 @@ func main() {
|
||||||
app.UseRouter(cors.New().Handler())
|
app.UseRouter(cors.New().Handler())
|
||||||
|
|
||||||
// Serve static files from the embedded directory at the app's root path
|
// Serve static files from the embedded directory at the app's root path
|
||||||
app.HandleDir("/", embedFrontend)
|
_ = embedFrontend
|
||||||
|
// app.HandleDir("/", embedFrontend)
|
||||||
|
|
||||||
api := app.Party("/api")
|
api := app.Party("/api")
|
||||||
v1 := api.Party("/v1")
|
v1 := api.Party("/v1")
|
||||||
|
@ -94,7 +96,7 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
tusRoute.Any("/{fileparam:path}", fromStd(http.StripPrefix(v1.GetRelPath()+tus.TUS_API_PATH+"/", tusHandler)))
|
tusRoute.Any("/{fileparam:path}", fromStd(http.StripPrefix(v1.GetRelPath()+tus.TUS_API_PATH+"/", tusHandler)))
|
||||||
tusRoute.Post("/", fromStd(http.StripPrefix(tusRoute.GetRelPath()+tus.TUS_API_PATH, tusHandler)))
|
tusRoute.Post("/{p:path}", fromStd(http.StripPrefix(tusRoute.GetRelPath()+tus.TUS_API_PATH, tusHandler)))
|
||||||
|
|
||||||
app.Handle(new(controller.FilesController))
|
app.Handle(new(controller.FilesController))
|
||||||
})
|
})
|
||||||
|
@ -114,6 +116,8 @@ func main() {
|
||||||
// And the wildcard one for index.html, *.js, *.css and e.t.c.
|
// And the wildcard one for index.html, *.js, *.css and e.t.c.
|
||||||
app.Get("/swagger/{any:path}", swaggerUI)
|
app.Get("/swagger/{any:path}", swaggerUI)
|
||||||
|
|
||||||
|
app.Party("*").Any("*", dnslink.Handler)
|
||||||
|
|
||||||
// Start the Iris app and listen for incoming requests on port 80
|
// Start the Iris app and listen for incoming requests on port 80
|
||||||
err := app.Listen(":8080", func(app *iris.Application) {
|
err := app.Listen(":8080", func(app *iris.Application) {
|
||||||
routes := app.GetRoutes()
|
routes := app.GetRoutes()
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Dnslink struct {
|
||||||
|
gorm.Model
|
||||||
|
ID uint `gorm:"primaryKey" gorm:"AUTO_INCREMENT"`
|
||||||
|
Domain string `gorm:"uniqueIndex"`
|
||||||
|
}
|
Loading…
Reference in New Issue