feat(qs2) add qs2 framework

This commit is contained in:
hexxa 2020-12-05 10:30:03 +08:00
parent 6ae65fe09b
commit 83100007e3
33 changed files with 2934 additions and 60 deletions

View file

@ -1,67 +1,149 @@
package server
import (
"context"
"crypto/rand"
"fmt"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/ihexxa/gocfg"
"github.com/ihexxa/quickshare/src/handlers"
"github.com/ihexxa/quickshare/src/cryptoutil/jwt"
"github.com/ihexxa/quickshare/src/depidx"
"github.com/ihexxa/quickshare/src/fs"
"github.com/ihexxa/quickshare/src/fs/local"
"github.com/ihexxa/quickshare/src/handlers/fileshdr"
"github.com/ihexxa/quickshare/src/handlers/singleuserhdr"
"github.com/ihexxa/quickshare/src/idgen/simpleidgen"
"github.com/ihexxa/quickshare/src/kvstore"
"github.com/ihexxa/quickshare/src/kvstore/boltdbpvd"
"github.com/ihexxa/quickshare/src/logging/simplelog"
"github.com/ihexxa/quickshare/src/uploadmgr"
)
type Server struct {
server *http.Server
}
type ServerCfg struct {
Addr string `json:"addr"`
ReadTimeout int `json:"readTimeout"`
WriteTimeout int `json:"writeTimeout"`
MaxHeaderBytes int `json:"maxHeaderBytes"`
deps *depidx.Deps
}
func NewServer(cfg gocfg.ICfg) (*Server, error) {
// gin.SetMode(gin.ReleaseMode)
deps := initDeps(cfg)
if cfg.BoolOr("Server.ProdMode", true) {
gin.SetMode(gin.ReleaseMode)
}
router := gin.Default()
router, err := addHandlers(router)
router, err := addHandlers(router, cfg, deps)
if err != nil {
return nil, err
}
srv := &http.Server{
// TODO: set more options
Addr: cfg.StringOr("ServerCfg.Addr", ":8080"),
Addr: cfg.GrabString("Server.Addr"),
Handler: router,
ReadTimeout: time.Duration(cfg.IntOr("ServerCfg.ReadTimeout", 1)) * time.Second,
WriteTimeout: time.Duration(cfg.IntOr("ServerCfg.ReadTimeout", 1)) * time.Second,
MaxHeaderBytes: cfg.IntOr("ServerCfg.MaxHeaderBytes", 512),
ReadTimeout: time.Duration(cfg.GrabInt("Server.ReadTimeout")) * time.Millisecond,
WriteTimeout: time.Duration(cfg.GrabInt("Server.WriteTimeout")) * time.Millisecond,
MaxHeaderBytes: cfg.GrabInt("Server.MaxHeaderBytes"),
}
return &Server{
server: srv,
deps: deps,
}, nil
}
func addHandlers(router *gin.Engine) (*gin.Engine, error) {
func (s *Server) depsFS() fs.ISimpleFS {
return s.deps.FS()
}
func (s *Server) depsKVStore() kvstore.IKVStore {
return s.deps.KV()
}
func makeRandToken() string {
b := make([]byte, 32)
_, err := rand.Read(b)
if err != nil {
panic(err)
}
return string(b)
}
func initDeps(cfg gocfg.ICfg) *depidx.Deps {
secret, ok := cfg.String("ENV.TOKENSECRET")
if !ok {
secret = makeRandToken()
fmt.Println("warning: TOKENSECRET is not given, using generated token")
}
rootPath := cfg.GrabString("Fs.Root")
opensLimit := cfg.GrabInt("Fs.OpensLimit")
openTTL := cfg.GrabInt("Fs.OpenTTL")
filesystem := local.NewLocalFS(rootPath, 0660, opensLimit, openTTL)
jwtEncDec := jwt.NewJWTEncDec(secret)
logger := simplelog.NewSimpleLogger()
kv := boltdbpvd.New(".", 1024)
ider := simpleidgen.New()
deps := depidx.NewDeps(cfg)
deps.SetFS(filesystem)
deps.SetToken(jwtEncDec)
deps.SetLog(logger)
deps.SetKV(kv)
deps.SetID(ider)
uploadMgr, err := uploadmgr.NewUploadMgr(deps)
if err != nil {
panic(err)
}
deps.SetUploader(uploadMgr)
return deps
}
func addHandlers(router *gin.Engine, cfg gocfg.ICfg, deps *depidx.Deps) (*gin.Engine, error) {
v1 := router.Group("/v1")
users := v1.Group("/users")
users.POST("/login", handlers.Login)
users.POST("/logout", handlers.Logout)
userHdrs := singleuserhdr.NewSimpleUserHandlers(cfg, deps)
users.POST("/login", userHdrs.Login)
users.POST("/logout", userHdrs.Logout)
files := v1.Group("files")
files.POST("/upload/", handlers.Upload)
files.GET("/list/", handlers.List)
files.DELETE("/delete/", handlers.Delete)
files.GET("/metadata/", handlers.Metadata)
files.POST("/copy/", handlers.Copy)
files.POST("/move/", handlers.Move)
filesSvc := v1.Group("/fs")
fileHdrs, err := fileshdr.NewFileHandlers(cfg, deps)
if err != nil {
panic(err)
}
filesSvc.POST("/files", fileHdrs.Create)
filesSvc.DELETE("/files", fileHdrs.Delete)
filesSvc.GET("/files", fileHdrs.Download)
filesSvc.PATCH("/files/chunks", fileHdrs.UploadChunk)
filesSvc.GET("/files/chunks", fileHdrs.UploadStatus)
filesSvc.PATCH("/files/copy", fileHdrs.Copy)
filesSvc.PATCH("/files/move", fileHdrs.Move)
filesSvc.GET("/dirs", fileHdrs.List)
filesSvc.POST("/dirs", fileHdrs.Mkdir)
// files.POST("/dirs/copy", fileHdrs.CopyDir)
filesSvc.GET("/metadata", fileHdrs.Metadata)
return router, nil
}
func (s *Server) Start() error {
return s.server.ListenAndServe()
err := s.server.ListenAndServe()
if err != http.ErrServerClosed {
return err
}
return nil
}
func (s *Server) Shutdown() error {
// TODO: add timeout
return s.server.Shutdown(context.Background())
}