Skip to content

Commit

Permalink
feat(client): add Upload func
Browse files Browse the repository at this point in the history
  • Loading branch information
bububa committed Jul 30, 2021
1 parent c29b8ab commit 9d1e9c3
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 2 deletions.
73 changes: 73 additions & 0 deletions core/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"strings"

"github.com/bububa/kwai-marketing-api/core/internal/debug"
"github.com/bububa/kwai-marketing-api/model"
Expand Down Expand Up @@ -50,6 +53,11 @@ func (c *SDKClient) GetUrl(req model.GetRequest) string {
return fmt.Sprintf("%s/%s?%s", BASE_URL, req.Url(), req.Encode())
}

// UploadUrl post multipart/form-data请求地址
func (c *SDKClient) UploadUrl(req model.UploadRequest) string {
return fmt.Sprintf("%s/%s", BASE_URL, req.Url())
}

// Post execute post api request
func (c *SDKClient) Post(accessToken string, req model.PostRequest, resp interface{}) error {
var reqResp model.BaseResponse
Expand Down Expand Up @@ -88,6 +96,71 @@ func (c *SDKClient) Get(accessToken string, req model.GetRequest, resp interface
return nil
}

// Upload multipart/form-data post
func (c *SDKClient) Upload(accessToken string, req model.UploadRequest, resp interface{}) error {
var buf bytes.Buffer
mw := multipart.NewWriter(&buf)
params := req.Encode()
mp := make(map[string]string, len(params))
for _, v := range params {
var (
fw io.Writer
r io.Reader
err error
)
if v.Reader != nil {
if fw, err = mw.CreateFormFile(v.Key, v.Value); err != nil {
return err
}
r = v.Reader
mp[v.Key] = fmt.Sprintf("@%s", v.Value)
} else {
if fw, err = mw.CreateFormField(v.Key); err != nil {
return err
}
r = strings.NewReader(v.Value)
mp[v.Key] = v.Value
}
if _, err = io.Copy(fw, r); err != nil {
return err

}
}
mw.Close()
reqUrl := c.UploadUrl(req)
debug.PrintPostMultipartRequest(reqUrl, mp, c.debug)
httpReq, err := http.NewRequest("POST", reqUrl, &buf)
if err != nil {
return err
}
httpReq.Header.Add("Content-Type", mw.FormDataContentType())
if accessToken != "" {
httpReq.Header.Add("Access-Token", accessToken)
}

httpResp, err := http.DefaultClient.Do(httpReq)
if err != nil {
return err
}
defer httpResp.Body.Close()
var reqResp model.BaseResponse
err = debug.DecodeJSONHttpResponse(httpResp.Body, &reqResp, c.debug)
if err != nil {
debug.PrintError(err, c.debug)
return err
}
if reqResp.IsError() {
return reqResp
}
if resp != nil {
err = json.Unmarshal(reqResp.Data, resp)
if err != nil {
return err
}
}
return nil
}

// post data through api
func (c *SDKClient) post(accessToken string, reqUrl string, reqBytes []byte, resp interface{}) error {
debug.PrintPostJSONRequest(reqUrl, reqBytes, c.debug)
Expand Down
12 changes: 10 additions & 2 deletions core/internal/debug/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,19 @@ func PrintPostJSONRequest(url string, body []byte, debug bool) {
}

// PrintPostMultipartRequest debug print post multipart request
func PrintPostMultipartRequest(url string, body []byte, debug bool) {
func PrintPostMultipartRequest(url string, mp map[string]string, debug bool) {
if !debug {
return
}
log.Println("[DEBUG] [API] multipart/form-data POST", url)
body, _ := json.Marshal(mp)
const format = "[DEBUG] [API] multipart/form-data POST %s\n" +
"http request body:\n%s\n"

buf := bytes.NewBuffer(make([]byte, 0, len(body)+1024))
if err := json.Indent(buf, body, "", " "); err == nil {
body = buf.Bytes()
}
log.Printf(format, url, body)
}

// DecodeJSONHttpResponse decode http json response with debug
Expand Down
19 changes: 19 additions & 0 deletions model/request.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package model

import "io"

// PostRequest request interface for post
type PostRequest interface {
Url() string
Expand All @@ -11,3 +13,20 @@ type GetRequest interface {
Url() string
Encode() string
}

// UploadField multipart/form-data post request field struct
type UploadField struct {
// Key field key
Key string
// Value field value
Value string
// Reader upload file reader
Reader io.Reader
}

// UploadRequest multipart/form-data reqeust interface
type UploadRequest interface {
Url() string
// Encode encode request to UploadFields
Encode() []UploadField
}

0 comments on commit 9d1e9c3

Please sign in to comment.