Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"bucekt.go",
"dir.go",
"file.go",
"http.go",
"sniff.go",
"upload.go",
],
importpath = "go-common/app/admin/main/upload/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/upload/conf:go_default_library",
"//app/admin/main/upload/model:go_default_library",
"//app/admin/main/upload/service:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/binding:go_default_library",
"//library/net/http/blademaster/middleware/permit:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//library/net/http/blademaster/render:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,68 @@
package http
import (
"net/http"
"go-common/app/admin/main/upload/model"
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
"go-common/library/net/http/blademaster/render"
)
func addBucket(c *bm.Context) {
var err error
abp := new(model.AddBucketParam)
if err = c.BindWith(abp, binding.FormPost); err != nil {
return
}
if len(abp.KeyID) != 16 {
c.Render(http.StatusOK, render.JSON{
Code: ecode.RequestErr.Code(),
Message: "key_id should length 16",
Data: nil,
})
c.Abort()
return
}
if len(abp.KeySecret) != 30 {
c.Render(http.StatusOK, render.JSON{
Code: ecode.RequestErr.Code(),
Message: "key_secret should length 30",
Data: nil,
})
c.Abort()
return
}
c.JSON(nil, uaSvc.AddBucket(c, abp))
}
func listBucket(c *bm.Context) {
var err error
lbp := new(model.ListBucketParam)
if err = c.Bind(lbp); err != nil {
return
}
c.JSON(uaSvc.ListBucket(c, lbp))
}
func listPublicBucket(c *bm.Context) {
var err error
lbp := new(model.ListBucketParam)
if err = c.Bind(lbp); err != nil {
return
}
c.JSON(uaSvc.ListPublicBucket(c, lbp))
}
func detailBucket(c *bm.Context) {
var err error
dbp := new(struct {
Bucket string `json:"bucket" form:"bucket" validate:"required"`
})
if err = c.Bind(dbp); err != nil {
return
}
c.JSON(uaSvc.DetailBucket(c, dbp.Bucket))
}

View File

@@ -0,0 +1,17 @@
package http
import (
"go-common/app/admin/main/upload/model"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
)
func addDir(c *bm.Context) {
var err error
adp := &model.AddDirParam{}
if err = c.BindWith(adp, binding.FormPost); err != nil {
return
}
c.JSON(nil, uaSvc.AddDir(c, adp))
}

View File

@@ -0,0 +1,36 @@
package http
import (
"bytes"
"io"
"go-common/app/admin/main/upload/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
)
// InternalUploadAdminImage .
func InternalUploadAdminImage(c *bm.Context) {
var err error
up := new(model.UploadParam)
if err = c.BindWith(up, binding.FormMultipart); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
up.WMInit()
file, _, err := c.Request.FormFile("file")
if err != nil {
log.Error("upload.UploadImage.file.illegal,err::%v", err.Error())
c.JSON(nil, ecode.RequestErr)
return
}
defer file.Close()
buf := new(bytes.Buffer)
if _, err = io.Copy(buf, file); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(uaSvc.UploadAdminRecord(c, "internal_admin_upload", up, buf.Bytes()))
}

View File

@@ -0,0 +1,73 @@
package http
import (
"go-common/app/admin/main/upload/conf"
"go-common/app/admin/main/upload/service"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/permit"
"go-common/library/net/http/blademaster/middleware/verify"
)
var (
authSvc *permit.Permit
uaSvc *service.Service
verifySvc *verify.Verify
)
// Init init
func Init(c *conf.Config, s *service.Service) {
initService(c, s)
// init router
engine := bm.DefaultServer(c.BM)
innerRouter(engine)
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
// initService init services.
func initService(c *conf.Config, s *service.Service) {
authSvc = permit.New(c.Auth)
verifySvc = verify.New(nil)
uaSvc = s
}
// innerRouter init outer router api path.
func innerRouter(e *bm.Engine) {
//init api
e.Ping(ping)
uploadAdmin := e.Group("/x/admin/upload")
{
uploadAdmin.POST("/add", add)
uploadAdmin.GET("/list", authSvc.Permit(""), list)
uploadAdmin.DELETE("/delete", authSvc.Permit(""), deleteFile)
file := uploadAdmin.Group("/file")
{
file.POST("/upload", authSvc.Permit(""), InternalUploadAdminImage)
file.DELETE("/delete", authSvc.Permit(""), deleteRawFile)
}
}
uploadAdminV2 := e.Group("/x/admin/upload/v2")
{
uploadAdminV2.GET("/list", authSvc.Permit(""), multiList)
uploadAdminV2.DELETE("/delete", authSvc.Permit(""), deleteFileV2)
}
bucket := uploadAdmin.Group("/bucket")
{
bucket.POST("/add", verifySvc.Verify, addBucket)
bucket.GET("/list", listBucket)
bucket.GET("/list/public", listPublicBucket)
bucket.GET("/detail", detailBucket)
dir := bucket.Group("/dir")
{
dir.POST("/add", verifySvc.Verify, addDir)
}
}
}

View File

@@ -0,0 +1,261 @@
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package http
import (
"bytes"
"encoding/binary"
)
// The algorithm uses at most sniffLen bytes to make its decision.
const sniffLen = 512
// DetectContentType implements the algorithm described
// at http://mimesniff.spec.whatwg.org/ to determine the
// Content-Type of the given data. It considers at most the
// first 512 bytes of data. DetectContentType always returns
// a valid MIME type: if it cannot determine a more specific one, it
// returns "application/octet-stream".
func DetectContentType(data []byte) string {
if len(data) > sniffLen {
data = data[:sniffLen]
}
// Index of the first non-whitespace byte in data.
firstNonWS := 0
for ; firstNonWS < len(data) && isWS(data[firstNonWS]); firstNonWS++ {
}
for _, sig := range sniffSignatures {
if ct := sig.match(data, firstNonWS); ct != "" {
return ct
}
}
return "application/octet-stream" // fallback
}
func isWS(b byte) bool {
switch b {
case '\t', '\n', '\x0c', '\r', ' ':
return true
}
return false
}
type sniffSig interface {
// match returns the MIME type of the data, or "" if unknown.
match(data []byte, firstNonWS int) string
}
// Data matching the table in section 6.
var sniffSignatures = []sniffSig{
htmlSig("<!DOCTYPE HTML"),
htmlSig("<HTML"),
htmlSig("<HEAD"),
htmlSig("<SCRIPT"),
htmlSig("<IFRAME"),
htmlSig("<H1"),
htmlSig("<DIV"),
htmlSig("<FONT"),
htmlSig("<TABLE"),
htmlSig("<A"),
htmlSig("<STYLE"),
htmlSig("<TITLE"),
htmlSig("<B"),
htmlSig("<BODY"),
htmlSig("<BR"),
htmlSig("<P"),
htmlSig("<!--"),
&maskedSig{mask: []byte("\xFF\xFF\xFF\xFF\xFF"), pat: []byte("<?xml"), skipWS: true, ct: "text/xml; charset=utf-8"},
&exactSig{[]byte("%PDF-"), "application/pdf"},
&exactSig{[]byte("%!PS-Adobe-"), "application/postscript"},
// UTF BOMs.
&maskedSig{mask: []byte("\xFF\xFF\x00\x00"), pat: []byte("\xFE\xFF\x00\x00"), ct: "text/plain; charset=utf-16be"},
&maskedSig{mask: []byte("\xFF\xFF\x00\x00"), pat: []byte("\xFF\xFE\x00\x00"), ct: "text/plain; charset=utf-16le"},
&maskedSig{mask: []byte("\xFF\xFF\xFF\x00"), pat: []byte("\xEF\xBB\xBF\x00"), ct: "text/plain; charset=utf-8"},
&exactSig{[]byte("GIF87a"), "image/gif"},
&exactSig{[]byte("GIF89a"), "image/gif"},
&exactSig{[]byte("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A"), "image/png"},
&exactSig{[]byte("\xFF\xD8\xFF"), "image/jpeg"},
&exactSig{[]byte("BM"), "image/bmp"},
&maskedSig{
mask: []byte("\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF"),
pat: []byte("RIFF\x00\x00\x00\x00WEBPVP"),
ct: "image/webp",
},
&exactSig{[]byte("\x00\x00\x01\x00"), "image/vnd.microsoft.icon"},
&maskedSig{
mask: []byte("\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF"),
pat: []byte("RIFF\x00\x00\x00\x00WAVE"),
ct: "audio/wave",
},
&maskedSig{
mask: []byte("\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF"),
pat: []byte("FORM\x00\x00\x00\x00AIFF"),
ct: "audio/aiff",
},
&maskedSig{
mask: []byte("\xFF\xFF\xFF\xFF"),
pat: []byte(".snd"),
ct: "audio/basic",
},
&maskedSig{
mask: []byte("\xFF\xFF\xFF\xFF\xFF"),
pat: []byte("OggS\x00"),
ct: "application/ogg",
},
&maskedSig{
mask: []byte("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"),
pat: []byte("MThd\x00\x00\x00\x06"),
ct: "audio/midi",
},
&maskedSig{
mask: []byte("\xFF\xFF\xFF"),
pat: []byte("ID3"),
ct: "audio/mpeg",
},
&maskedSig{
mask: []byte("\xFF\xFF\xFF\xFF\x00\x00\x00\x00\xFF\xFF\xFF\xFF"),
pat: []byte("RIFF\x00\x00\x00\x00AVI "),
ct: "video/avi",
},
// Fonts
&maskedSig{
// 34 NULL bytes followed by the string "LP"
pat: []byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x4C\x50"),
// 34 NULL bytes followed by \xF\xF
mask: []byte("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF"),
ct: "application/vnd.ms-fontobject",
},
&exactSig{[]byte("\x00\x01\x00\x00"), "application/font-ttf"},
&exactSig{[]byte("OTTO"), "application/font-off"},
&exactSig{[]byte("ttcf"), "application/font-cff"},
&exactSig{[]byte("wOFF"), "application/font-woff"},
&exactSig{[]byte("\x1A\x45\xDF\xA3"), "video/webm"},
&exactSig{[]byte("\x52\x61\x72\x20\x1A\x07\x00"), "application/x-rar-compressed"},
&exactSig{[]byte("\x50\x4B\x03\x04"), "application/zip"},
&exactSig{[]byte("\x1F\x8B\x08"), "application/x-gzip"},
mp4Sig{},
textSig{}, // should be last
}
type exactSig struct {
sig []byte
ct string
}
func (e *exactSig) match(data []byte, firstNonWS int) string {
if bytes.HasPrefix(data, e.sig) {
return e.ct
}
return ""
}
type maskedSig struct {
mask, pat []byte
skipWS bool
ct string
}
func (m *maskedSig) match(data []byte, firstNonWS int) string {
// pattern matching algorithm section 6
// https://mimesniff.spec.whatwg.org/#pattern-matching-algorithm
if m.skipWS {
data = data[firstNonWS:]
}
if len(m.pat) != len(m.mask) {
return ""
}
if len(data) < len(m.mask) {
return ""
}
for i, mask := range m.mask {
db := data[i] & mask
if db != m.pat[i] {
return ""
}
}
return m.ct
}
type htmlSig []byte
func (h htmlSig) match(data []byte, firstNonWS int) string {
data = data[firstNonWS:]
if len(data) < len(h)+1 {
return ""
}
for i, b := range h {
db := data[i]
if 'A' <= b && b <= 'Z' {
db &= 0xDF
}
if b != db {
return ""
}
}
// Next byte must be space or right angle bracket.
if db := data[len(h)]; db != ' ' && db != '>' {
return ""
}
return "text/html; charset=utf-8"
}
var mp4ftype = []byte("ftyp")
var mp4 = []byte("mp4")
type mp4Sig struct{}
func (mp4Sig) match(data []byte, firstNonWS int) string {
// https://mimesniff.spec.whatwg.org/#signature-for-mp4
// c.f. section 6.2.1
if len(data) < 12 {
return ""
}
boxSize := int(binary.BigEndian.Uint32(data[:4]))
if boxSize%4 != 0 || len(data) < boxSize {
return ""
}
if !bytes.Equal(data[4:8], mp4ftype) {
return ""
}
for st := 8; st < boxSize; st += 4 {
if st == 12 {
// minor version number
continue
}
if bytes.Equal(data[st:st+3], mp4) {
return "video/mp4"
}
}
return ""
}
type textSig struct{}
func (textSig) match(data []byte, firstNonWS int) string {
// c.f. section 5, step 4.
for _, b := range data[firstNonWS:] {
switch {
case b <= 0x08,
b == 0x0B,
0x0E <= b && b <= 0x1A,
0x1C <= b && b <= 0x1F:
return ""
}
}
return "text/plain; charset=utf-8"
}

View File

@@ -0,0 +1,99 @@
package http
import (
"go-common/app/admin/main/upload/model"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/binding"
)
// ping check server ok.
func ping(c *bm.Context) {
if err := uaSvc.Ping(c); err != nil {
c.Error = err
c.AbortWithStatus(503)
}
}
func add(c *bm.Context) {
var err error
ap := &model.AddParam{}
if err = c.BindWith(ap, binding.FormPost); err != nil {
return
}
c.JSON(nil, uaSvc.Add(c, ap))
}
func list(c *bm.Context) {
var (
err error
)
lp := &model.ListParam{}
if err = c.Bind(lp); err != nil {
return
}
c.JSON(uaSvc.List(c, lp))
}
func deleteFile(c *bm.Context) {
var (
err error
ok bool
adminID interface{}
)
dp := new(model.DeleteParam)
if adminID, ok = c.Get("uid"); !ok {
c.JSON(nil, ecode.UserNotExist)
return
}
dp.AdminID = adminID.(int64)
if err = c.Bind(dp); err != nil {
return
}
c.JSON(nil, uaSvc.Delete(c, dp))
}
func deleteRawFile(c *bm.Context) {
var (
err error
)
dp := new(model.DeleteRawParam)
if err = c.Bind(dp); err != nil {
return
}
c.JSON(nil, uaSvc.DeleteRaw(c, dp))
}
func deleteFileV2(c *bm.Context) {
var (
adminID interface{}
err error
ok bool
)
dp := new(model.DeleteV2Param)
if adminID, ok = c.Get("uid"); !ok {
c.JSON(nil, ecode.UserNotExist)
return
}
dp.AdminID = adminID.(int64)
if err = c.Bind(dp); err != nil {
return
}
if err = uaSvc.DeleteV2(c, dp); err != nil {
log.Error("deleteFileV2 error(%v)", err)
}
c.JSON(nil, err)
}
func multiList(c *bm.Context) {
var (
err error
)
lp := &model.MultiListParam{}
if err = c.Bind(lp); err != nil {
return
}
c.JSON(uaSvc.MultiList(c, lp))
}