User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

go:filestore [2019-11-22 17:48] (current)
ziggi created
Line 1: Line 1:
  
 +====Simple filestore on Golang====
 +
 +Now is very ditry but work =)
 +
 +<code go filestore.go>​
 +/*
 + * Copyright 2019 Oleg Borodin ​ <​borodin@unix7.org>​
 + */
 +
 +package main
 +
 +import (
 +    "​github.com/​gin-gonic/​gin"​
 +    //"​github.com/​sevlyar/​go-daemon"​
 +    "​net/​http"​
 +    "​fmt"​
 +    "​log"​
 +    "​path/​filepath"​
 +    "​os"​
 +    "​path"​
 +    "​time"​
 +    "​io"​
 +    "​mime/​multipart"​
 +)
 +
 +func main() {
 +    context := &​daemon.Context{
 +        PidFileName:​ "​gin.pid",​
 +        PidFilePerm:​ 0644,
 +        LogFileName:​ "​gin.log",​
 +        LogFilePerm:​ 0640,
 +        WorkDir: "​./",​
 +        Umask: 027,
 +        Args: []string{""​},​
 +    }
 +
 +    child, err := context.Reborn()
 +    if err != nil {
 +        log.Fatal("​unable to run: ", err)
 +    }
 +    if child != nil {
 +        return
 +    }
 +
 +    defer context.Release()
 +    log.Println("​daemon started"​)
 +    ginStart()
 +}
 +
 +func logFormatter() func(param gin.LogFormatterParams) string {
 +    return func(param gin.LogFormatterParams) string {
 +        return fmt.Sprintf("​%s - [%s] %s %s %s %d %s \"​%s\"​ \"​%s\"​\n",​
 +            param.ClientIP,​
 +            param.TimeStamp.Format(time.RFC3339),​
 +            param.Method,​
 +            param.Path,
 +            param.Request.Proto,​
 +            param.StatusCode,​
 +            param.Latency,​
 +            param.Request.UserAgent(),​
 +            param.ErrorMessage,​
 +        )
 +    }
 +}
 +
 +func ginStart() {
 +
 +    //​gin.SetMode(gin.DebugMode)
 +    gin.SetMode(gin.ReleaseMode)
 +    gin.DisableConsoleColor()
 +
 +    logFile, err := os.Create("​access.log"​)
 +    if err != nil {
 +      panic(err)
 +    }
 +    gin.DefaultWriter = io.MultiWriter(logFile,​ os.Stdout)
 +    //​log.SetOutput(gin.DefaultWriter)
 +
 +    router := gin.New()
 +    router.Use(gin.LoggerWithFormatter(logFormatter()))
 +    router.MaxMultipartMemory = 8 << 20 // 8 MiB
 +
 +    accounts := gin.Accounts{
 +        "​foo":​ "​bar",​
 +    }
 +    authorized := router.Group("/​api",​ gin.BasicAuth(accounts))
 +
 +    authorized.GET("/​hello",​ func(context *gin.Context) {
 +        user := context.MustGet(gin.AuthUserKey).(string)
 +        context.JSON(http.StatusOK,​ gin.H{
 +            "​message":​ "hello " + user,
 +        })
 +    })
 +
 +    authorized.GET("/​index",​ func(context *gin.Context) {
 +        context.JSON(http.StatusOK,​ gin.H{
 +            "​result"​ : listDir("/​data/​music",​ "​*"​),​
 +        })
 +    })
 +
 +    authorized.GET("/​get",​ func(context *gin.Context) {
 +        type Req struct {
 +            Name string `form:"​name"​ json:"​name"​`
 +        }
 +        var req Req
 +        if context.ShouldBind(&​req) == nil {
 +            context.JSON(http.StatusOK,​ gin.H{
 +                "​result"​ : req,
 +            })
 +        }
 +    })
 +
 +    authorized.POST("/​upload",​ func(context *gin.Context) {
 +        type BindFile struct {
 +            Name  string `form:"​name"​ binding:"​required"​`
 +            File  *multipart.FileHeader `form:"​file"​ binding:"​required"​`
 +        }
 +
 +        var bindFile BindFile
 +        if err := context.ShouldBind(&​bindFile);​ err != nil {
 +                context.String(http.StatusBadRequest,​ fmt.Sprintf("​err:​ %s", err.Error()))
 +                return
 +        }
 +        file := bindFile.File
 +        dest := "​upl_"​ + filepath.Base(file.Filename)
 +        if err := context.SaveUploadedFile(file,​ dest); err != nil {
 +                context.String(http.StatusBadRequest,​ fmt.Sprintf("​upload file err: %s", err.Error()))
 +                return
 +        }
 +        type Result struct {
 +            Name string `json:"​name"​`
 +        }
 +        res := Result{
 +            Name: file.Filename,​
 +        }
 +        context.JSON(http.StatusOK,​ gin.H{
 +            "​result":​ res,
 +        })
 +    })
 +
 +    authorized.GET("/​download",​ func(context *gin.Context) {
 +        type Req struct {
 +            Name string `form:"​name"​ json:"​name"​`
 +        }
 +        var req Req
 +        err := context.ShouldBind(&​req);​
 +
 +        if err == nil && FileExists(req.Name) {
 +            context.FileAttachment(req.Name,​ "​down_"​ + req.Name)
 +            return
 +        } else {
 +            context.Status(http.StatusNotFound)
 +        }
 +
 +    })
 +
 +    router.Run(":​8089"​)
 +}
 +
 +
 +func FileExists(name string) bool {
 +    if _, err := os.Stat(name);​ err != nil {
 +        if os.IsNotExist(err) {
 +            return false
 +        }
 +    }
 +    return true
 +}
 +
 +
 +type File struct {
 +    Name string `json:"​name"​`
 +    Size int64 `json:"​size"​`
 +}
 +
 +func listDir (dir string, glob string) []File {
 +    files, err := filepath.Glob(path.Join(dir,​ glob))
 +    if err != nil {
 +        log.Fatal(err)
 +    }
 +
 +    list := []File{}
 +    for i := 0; i < len(files); i++ {
 +        name := files[i]
 +        fi, err := os.Stat(name);​
 +        if err != nil {
 +            log.Fatal(err)
 +            continue
 +        }
 +
 +        if fi.IsDir() {
 +            continue
 +        }
 +        item := File{
 +            Name: fi.Name(),
 +            Size: fi.Size(),
 +        }
 +        list = append(list,​ item)
 +    }
 +    return list
 +}
 +
 +
 +</​code>​