初步实现文件上传与下载
This commit is contained in:
parent
794bd74337
commit
d6f618888d
|
|
@ -1,4 +1,5 @@
|
|||
data/*
|
||||
go.sum
|
||||
*.exe
|
||||
leveldb-demo
|
||||
leveldb-demo
|
||||
upload/
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package gin
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"myschools.me/yyjishu/yy-base/redis"
|
||||
)
|
||||
|
||||
//从redis中认证用户
|
||||
func AuthUser() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
token := c.GetHeader("Authorization")
|
||||
claims := cacheGet(&token)
|
||||
if claims == nil {
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
c.Set("user", claims)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
//从redis中获取用户信息,最佳实践经验建议把此代码放service层
|
||||
func cacheGet(token *string) interface{} {
|
||||
var user interface{}
|
||||
b, err := redis.GetBytes(token)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if err := json.Unmarshal(*b, &user); err != nil {
|
||||
return nil
|
||||
}
|
||||
return &user
|
||||
}
|
||||
|
||||
// gin拦截,基于微服务的拦截
|
||||
// func AuthUserBS() gin.HandlerFunc {
|
||||
// return func(c *gin.Context) {
|
||||
// token := c.GetHeader("Authorization")
|
||||
// claims := userAuthWithGrpc(&token)
|
||||
// if claims == nil {
|
||||
// yy.RespUnauth(c, "token无效或过期,请重新登录", nil, nil)
|
||||
// c.Abort()
|
||||
// }
|
||||
// c.Set("user", claims)
|
||||
// c.Next()
|
||||
// }
|
||||
// }
|
||||
|
||||
// func userAuthWithGrpc(token *string) *yy.UserClaims {
|
||||
// srv, err := consul.FindService("oauth", "v1")
|
||||
// if err != nil {
|
||||
// logrus.WithFields(logrus.Fields{
|
||||
// "func": "userAuthWithGrpc",
|
||||
// }).Errorf("consul.FindServer: %s", err.Error())
|
||||
// return nil
|
||||
// }
|
||||
// defer srv.Close()
|
||||
// client := pb.NewCertificationClient(srv)
|
||||
// resp, err := client.Auth(context.Background(), &pb.CertificationAuthRequest{
|
||||
// Token: *token,
|
||||
// })
|
||||
// if err != nil {
|
||||
// logrus.WithFields(logrus.Fields{
|
||||
// "func": "userAuthWithGrpc",
|
||||
// }).Errorf("client.Auth: %s", err.Error())
|
||||
// return nil
|
||||
// }
|
||||
// if resp.Result == "ok" {
|
||||
// r := &yy.UserClaims{}
|
||||
// if err := json.Unmarshal(resp.Data.Value, r); err != nil {
|
||||
// logrus.WithFields(logrus.Fields{
|
||||
// "func": "userAuthWithGrpc",
|
||||
// }).Errorf("json.Unmarshal: %s", err.Error())
|
||||
// return nil
|
||||
// }
|
||||
// return r
|
||||
// }
|
||||
// logrus.WithFields(logrus.Fields{
|
||||
// "func": "userAuthWithGrpc",
|
||||
// }).Warnln("nil")
|
||||
// return nil
|
||||
// }
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package gin
|
||||
|
||||
//GIN 配置
|
||||
type Config struct {
|
||||
RootPath string
|
||||
Addr string
|
||||
Port int
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package gin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Service(conf *Config) {
|
||||
if conf == nil {
|
||||
conf = &Config{
|
||||
RootPath: "/",
|
||||
Addr: "0.0.0.0",
|
||||
Port: 80,
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
router := gin.New()
|
||||
routerSetup(router, &conf.RootPath)
|
||||
s := &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", conf.Addr, conf.Port),
|
||||
Handler: router,
|
||||
ReadTimeout: 10 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
}
|
||||
log.Printf("start service on %s", fmt.Sprintf("%s:%d", conf.Addr, conf.Port))
|
||||
log.Fatal(s.ListenAndServe())
|
||||
}()
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package gin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"myschools.me/suguo/leveldb-demo/handler"
|
||||
)
|
||||
|
||||
//路由配置
|
||||
func routerSetup(router *gin.Engine, rootpath *string) {
|
||||
router.Use(gin.Recovery())
|
||||
|
||||
r := router.Group(fmt.Sprintf("/%s", *rootpath))
|
||||
{
|
||||
r.POST(`/upload`, handler.FileUpload)
|
||||
r.POST(`/update`, handler.FileUpdate)
|
||||
r.POST(`/delete`, handler.FileDelete)
|
||||
r.GET(`/get/:id`, handler.FileGet)
|
||||
}
|
||||
}
|
||||
31
go.mod
31
go.mod
|
|
@ -1,8 +1,33 @@
|
|||
module myschools.me/suguo/leveldb-demo
|
||||
|
||||
go 1.18
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.0 // indirect
|
||||
github.com/gin-gonic/gin v1.7.4
|
||||
github.com/gofrs/uuid v4.2.0+incompatible
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
myschools.me/yyjishu/yy-base v0.16.133
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.9.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/gomodule/redigo v1.8.5 // indirect
|
||||
github.com/google/uuid v1.1.2 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/ugorji/go/codec v1.2.6 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
|
||||
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"myschools.me/suguo/leveldb-demo/service"
|
||||
"myschools.me/yyjishu/yy-base/yy"
|
||||
)
|
||||
|
||||
func FileUpload(c *gin.Context) {
|
||||
reqid := yy.NewRequestID()
|
||||
fs, fh, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
yy.RespBadRequest(c, "上传文件获取失败", err, &reqid)
|
||||
return
|
||||
}
|
||||
defer fs.Close()
|
||||
payload, err := ioutil.ReadAll(fs)
|
||||
if err != nil {
|
||||
yy.RespBadRequest(c, "上传文件中断", err, &reqid)
|
||||
return
|
||||
}
|
||||
if fh.Header.Get("Content-Type") != "image/png" {
|
||||
yy.RespBadRequest(c, "文件类型不支持", nil, &reqid)
|
||||
return
|
||||
}
|
||||
ret, err := service.FileUpload(&payload)
|
||||
if err != nil {
|
||||
yy.RespInternalServerError(c, "上传失败", err, &reqid)
|
||||
return
|
||||
}
|
||||
yy.RespSuccess(c, "ok", gin.H{
|
||||
"id": *ret,
|
||||
}, &reqid)
|
||||
|
||||
}
|
||||
|
||||
func FileGet(c *gin.Context) {
|
||||
reqid := yy.NewRequestID()
|
||||
id := c.Param("id")
|
||||
data, err := service.FileGet(&id)
|
||||
if err != nil {
|
||||
yy.RespInternalServerError(c, "获取文件失败", err, &reqid)
|
||||
return
|
||||
}
|
||||
c.Writer.Write(*data)
|
||||
c.Writer.Flush()
|
||||
}
|
||||
|
||||
func FileUpdate(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
||||
func FileDelete(c *gin.Context) {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
@url=http://127.0.0.1:8080/assets/file
|
||||
@createdAt = {{$datetime iso8601}}
|
||||
|
||||
###
|
||||
POST {{url}}/upload HTTP/1.1
|
||||
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
|
||||
|
||||
------WebKitFormBoundary7MA4YWxkTrZu0gW
|
||||
Content-Disposition: form-data; name="text"
|
||||
|
||||
title
|
||||
------WebKitFormBoundary7MA4YWxkTrZu0gW
|
||||
Content-Disposition: form-data; name="file"; filename="1.png"
|
||||
Content-Type: image/png
|
||||
|
||||
< /home/suguo/Pictures/kindeditor_201907201649420191.jpg
|
||||
------WebKitFormBoundary7MA4YWxkTrZu0gW--
|
||||
|
||||
###
|
||||
GET {{url}}/get/1ecb19989cd76cf69cdae53c0efeef79 HTTP/1.1
|
||||
45
main.go
45
main.go
|
|
@ -1,37 +1,28 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"context"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"myschools.me/suguo/leveldb-demo/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := leveldb.OpenFile("./data", nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
for i := 0; i < 50; i++ {
|
||||
if err := db.Put([]byte(fmt.Sprintf("hello %d", i)), []byte("a hello world."), nil); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
ret, err := db.Has([]byte("hello 49"), &opt.ReadOptions{
|
||||
DontFillCache: false,
|
||||
Strict: 0,
|
||||
gin.Service(&gin.Config{
|
||||
RootPath: "assets/file",
|
||||
Addr: "0.0.0.0",
|
||||
Port: 8080,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(ret)
|
||||
|
||||
val, err := db.Get([]byte("hello 4"), nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(string(val))
|
||||
// 服务停止相应
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
<-c
|
||||
_, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
logrus.Println("file storage service shutting down")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"github.com/syndtr/goleveldb/leveldb/opt"
|
||||
)
|
||||
|
||||
var (
|
||||
storagepath string = "./upload"
|
||||
)
|
||||
|
||||
func init() {
|
||||
sp := os.Getenv("p")
|
||||
if sp != "" {
|
||||
storagepath = sp
|
||||
}
|
||||
}
|
||||
|
||||
func FileGet(id *string) (*[]byte, error) {
|
||||
db, err := leveldb.OpenFile(storagepath, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
ret, err := db.Has([]byte(*id), &opt.ReadOptions{
|
||||
DontFillCache: false,
|
||||
Strict: 0,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.New("文件不存在")
|
||||
}
|
||||
|
||||
if !ret {
|
||||
return nil, errors.New("文件不存在")
|
||||
}
|
||||
|
||||
val, err := db.Get([]byte(*id), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &val, nil
|
||||
}
|
||||
|
||||
func FileUpload(payload *[]byte) (*string, error) {
|
||||
db, err := leveldb.OpenFile(storagepath, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer db.Close()
|
||||
key := strings.ReplaceAll(uuid.Must(uuid.NewV6()).String(), "-", "")
|
||||
if err := db.Put([]byte(key), *payload, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &key, nil
|
||||
}
|
||||
|
||||
func FileUpdate() {
|
||||
db, err := leveldb.OpenFile(storagepath, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
ret, err := db.Has([]byte("hello 49"), &opt.ReadOptions{
|
||||
DontFillCache: false,
|
||||
Strict: 0,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(ret)
|
||||
|
||||
val, err := db.Get([]byte("hello 4"), nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(string(val))
|
||||
}
|
||||
Loading…
Reference in New Issue