|
@@ -0,0 +1,148 @@
|
|
|
+package filesdk
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "encoding/json"
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "io/ioutil"
|
|
|
+ "mime/multipart"
|
|
|
+ "net/http"
|
|
|
+ "strings"
|
|
|
+ "sync"
|
|
|
+)
|
|
|
+
|
|
|
+var (
|
|
|
+ persistent = "fs/api/v1/files/persistent" //文件持久化路径
|
|
|
+ upload = "fs/api/v1/files" // 文件上传api路径
|
|
|
+)
|
|
|
+
|
|
|
+type persistentStruct struct {
|
|
|
+ Hash string `json:"hash"`
|
|
|
+}
|
|
|
+
|
|
|
+type Config struct {
|
|
|
+ Host string
|
|
|
+}
|
|
|
+
|
|
|
+type ConfigHandle struct {
|
|
|
+ Host string
|
|
|
+}
|
|
|
+
|
|
|
+var (
|
|
|
+ once sync.Once
|
|
|
+ internalHandle *ConfigHandle
|
|
|
+)
|
|
|
+
|
|
|
+func (c *Config) Init() {
|
|
|
+ //代码运行中需要的时候执行,且只执行一次
|
|
|
+ once.Do(func() {
|
|
|
+ internalHandle = &ConfigHandle{
|
|
|
+ Host: c.Host,
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// GetHandle get handle
|
|
|
+func GetHandle() *ConfigHandle {
|
|
|
+ return internalHandle
|
|
|
+}
|
|
|
+
|
|
|
+//HandlePersistent 设置文件持久化
|
|
|
+func (c *ConfigHandle) HandlePersistent(hash string) error {
|
|
|
+ if hash == "" {
|
|
|
+ return errors.New("缺少请求参数")
|
|
|
+ }
|
|
|
+ param := persistentStruct{
|
|
|
+ Hash: hash,
|
|
|
+ }
|
|
|
+ s, err := json.Marshal(param)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ url := fmt.Sprintf("%s/%s", c.Host, persistent)
|
|
|
+ reqBody := strings.NewReader(string(s))
|
|
|
+ req, err := http.NewRequest(http.MethodPut, url, reqBody)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ req.Header.Set("Content-type", "application/json")
|
|
|
+ client := &http.Client{}
|
|
|
+ response, err := client.Do(req)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ _, err = ioutil.ReadAll(response.Body)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+type FileInfo struct {
|
|
|
+ URL string `json:"url"`
|
|
|
+ Name string `json:"name"`
|
|
|
+ Hash string `json:"hash"`
|
|
|
+ Size int64 `json:"size"`
|
|
|
+}
|
|
|
+
|
|
|
+// Upload 文件上传
|
|
|
+// headers 参数支持:FILE-EXPIRE,FILE-HASH
|
|
|
+func (c *ConfigHandle) Upload(fileName string, bucket string, headers map[string]string, fileData []byte) (*FileInfo, error) {
|
|
|
+ if len(fileData) == 0 {
|
|
|
+ return nil, errors.New("非法文件")
|
|
|
+ }
|
|
|
+ fileBytes := &bytes.Buffer{}
|
|
|
+ writer := multipart.NewWriter(fileBytes)
|
|
|
+ part, err := writer.CreateFormFile("fileData", fileName)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ if _, err = part.Write(fileData); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ baseUrlField, err := writer.CreateFormField("base_url")
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ _, err = baseUrlField.Write([]byte(bucket))
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ formKey, err := writer.CreateFormField("form_key")
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ _, err = formKey.Write([]byte("fileData"))
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ err = writer.Close()
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ url := fmt.Sprintf("%s/%s", c.Host, upload)
|
|
|
+ req, err := http.NewRequest("POST", url, fileBytes)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ req.Header.Set("Content-type", writer.FormDataContentType())
|
|
|
+ for k, v := range headers {
|
|
|
+ req.Header.Set(k, v)
|
|
|
+ }
|
|
|
+ client := &http.Client{}
|
|
|
+ response, err := client.Do(req)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ resp, err := ioutil.ReadAll(response.Body)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ var result *FileInfo
|
|
|
+ if err = json.Unmarshal(resp, &result); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return result, nil
|
|
|
+}
|