You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
3.3 KiB
149 lines
3.3 KiB
package upyun
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
type FormUploadConfig struct {
|
|
LocalPath string
|
|
SaveKey string
|
|
ExpireAfterSec int64
|
|
NotifyUrl string
|
|
Apps []map[string]interface{}
|
|
Options map[string]interface{}
|
|
}
|
|
|
|
type FormUploadResp struct {
|
|
Code int `json:"code"`
|
|
Msg string `json:"message"`
|
|
Url string `json:"url"`
|
|
Timestamp int64 `json:"time"`
|
|
ImgWidth int `json:"image-width"`
|
|
ImgHeight int `json:"image-height"`
|
|
ImgFrames int `json:"image-frames"`
|
|
ImgType string `json:"image-type"`
|
|
Sign string `json:"sign"`
|
|
Taskids []string `json:"task_ids"`
|
|
}
|
|
|
|
func (config *FormUploadConfig) Format() {
|
|
if config.Options == nil {
|
|
config.Options = make(map[string]interface{})
|
|
}
|
|
if config.SaveKey != "" {
|
|
config.Options["save-key"] = config.SaveKey
|
|
}
|
|
if config.NotifyUrl != "" {
|
|
config.Options["notify-url"] = config.NotifyUrl
|
|
}
|
|
if config.ExpireAfterSec > 0 {
|
|
config.Options["expiration"] = time.Now().Unix() + config.ExpireAfterSec
|
|
}
|
|
if len(config.Apps) > 0 {
|
|
config.Options["apps"] = config.Apps
|
|
}
|
|
}
|
|
|
|
func (up *UpYun) FormUpload(config *FormUploadConfig) (*FormUploadResp, error) {
|
|
config.Format()
|
|
config.Options["bucket"] = up.Bucket
|
|
|
|
args, err := json.Marshal(config.Options)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
policy := base64ToStr(args)
|
|
|
|
formValues := make(map[string]string)
|
|
formValues["policy"] = policy
|
|
formValues["file"] = config.LocalPath
|
|
|
|
if up.deprecated {
|
|
formValues["signature"] = up.MakeFormAuth(policy)
|
|
} else {
|
|
sign := &UnifiedAuthConfig{
|
|
Method: "POST",
|
|
Uri: "/" + up.Bucket,
|
|
Policy: policy,
|
|
}
|
|
if v, ok := config.Options["date"]; ok {
|
|
sign.DateStr = v.(string)
|
|
}
|
|
if v, ok := config.Options["content-md5"]; ok {
|
|
sign.ContentMD5 = v.(string)
|
|
}
|
|
formValues["authorization"] = up.MakeUnifiedAuth(sign)
|
|
}
|
|
|
|
endpoint := up.doGetEndpoint("v0.api.upyun.com")
|
|
url := fmt.Sprintf("http://%s/%s", endpoint, up.Bucket)
|
|
resp, err := up.doFormRequest(url, formValues)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
b, err := ioutil.ReadAll(resp.Body)
|
|
resp.Body.Close()
|
|
|
|
if err != nil {
|
|
return nil, errorOperation("form read body", err)
|
|
}
|
|
|
|
var r FormUploadResp
|
|
err = json.Unmarshal(b, &r)
|
|
return &r, err
|
|
}
|
|
|
|
func (up *UpYun) doFormRequest(url string, formValues map[string]string) (*http.Response, error) {
|
|
formBody := &bytes.Buffer{}
|
|
formWriter := multipart.NewWriter(formBody)
|
|
defer formWriter.Close()
|
|
|
|
for k, v := range formValues {
|
|
if k != "file" {
|
|
formWriter.WriteField(k, v)
|
|
}
|
|
}
|
|
|
|
boundary := formWriter.Boundary()
|
|
bdBuf := bytes.NewBufferString(fmt.Sprintf("\r\n--%s--\r\n", boundary))
|
|
|
|
fpath := formValues["file"]
|
|
fd, err := os.Open(fpath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer fd.Close()
|
|
|
|
fInfo, err := fd.Stat()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
_, err = formWriter.CreateFormFile("file", filepath.Base(fpath))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
headers := map[string]string{
|
|
"Content-Type": "multipart/form-data; boundary=" + boundary,
|
|
"Content-Length": fmt.Sprint(formBody.Len() + int(fInfo.Size()) + bdBuf.Len()),
|
|
}
|
|
|
|
body := io.MultiReader(formBody, fd, bdBuf)
|
|
resp, err := up.doHTTPRequest("POST", url, headers, body)
|
|
if err != nil {
|
|
return nil, errorOperation("form", err)
|
|
}
|
|
return resp, nil
|
|
}
|