Browse Source

优化代码结构

master
Sydonian 2 months ago
parent
commit
59f6887b88
1 changed files with 89 additions and 3 deletions
  1. +89
    -3
      sdks/sdks.go

+ 89
- 3
sdks/sdks.go View File

@@ -2,6 +2,7 @@ package sdks

import (
"bytes"
"crypto/sha256"
"fmt"
"io"
"mime"
@@ -12,6 +13,7 @@ import (

"github.com/google/go-querystring/query"
"gitlink.org.cn/cloudream/common/consts/errorcode"
"gitlink.org.cn/cloudream/common/pkgs/iterator"
"gitlink.org.cn/cloudream/common/utils/http2"
"gitlink.org.cn/cloudream/common/utils/io2"
"gitlink.org.cn/cloudream/common/utils/serder"
@@ -86,6 +88,8 @@ type RequestBody interface {
Length() int64
// 将内部值变成一个流,用于发送请求
IntoStream() io.ReadCloser
// 计算Sha256哈希,如果不方便计算,则返回nil
Hash() []byte
}

type StringBody struct {
@@ -100,6 +104,11 @@ func (s *StringBody) IntoStream() io.ReadCloser {
return io.NopCloser(bytes.NewReader([]byte(s.Value)))
}

func (s *StringBody) Hash() []byte {
hash := sha256.Sum256([]byte(s.Value))
return hash[:]
}

type BytesBody struct {
Value []byte
}
@@ -112,6 +121,11 @@ func (b *BytesBody) IntoStream() io.ReadCloser {
return io.NopCloser(bytes.NewReader(b.Value))
}

func (b *BytesBody) Hash() []byte {
hash := sha256.Sum256(b.Value)
return hash[:]
}

type StreamBody struct {
Stream io.ReadCloser
LengthHint int64 // 长度提示,如果长度未知,可以设置为-1
@@ -125,6 +139,10 @@ func (s *StreamBody) IntoStream() io.ReadCloser {
return s.Stream
}

func (s *StreamBody) Hash() []byte {
return nil
}

type APIRequest interface {
MakeParam() *RequestParam
}
@@ -157,7 +175,12 @@ func MakeQueryParam(method string, path string, q any) *RequestParam {
}
}

func MakeMultipartParam(method string, path string, info any, stream io.ReadCloser) *RequestParam {
type UploadFileInfo struct {
FileName string
File io.ReadCloser
}

func MakeUploadParam(method string, path string, info any, file UploadFileInfo) *RequestParam {
data, err := serder.ObjectToJSONEx(info)
if err != nil {
// 开发人员应该保证param是可序列化的
@@ -168,19 +191,20 @@ func MakeMultipartParam(method string, path string, info any, stream io.ReadClos
mw := multipart.NewWriter(pw)
go func() {
defer mw.Close()

err := mw.WriteField("info", string(data))
if err != nil {
pw.CloseWithError(err)
return
}

fw, err := mw.CreateFormFile("file", "file")
fw, err := mw.CreateFormFile("file", file.FileName)
if err != nil {
pw.CloseWithError(err)
return
}

_, err = io.Copy(fw, stream)
_, err = io.Copy(fw, file.File)
if err != nil {
pw.CloseWithError(err)
return
@@ -201,6 +225,68 @@ func MakeMultipartParam(method string, path string, info any, stream io.ReadClos
}
}

type MultiUploadIter = iterator.Iterator[UploadFileInfo]

func MakeMultiUploadParam(method string, path string, info any, files MultiUploadIter) *RequestParam {
data, err := serder.ObjectToJSONEx(info)
if err != nil {
// 开发人员应该保证param是可序列化的
panic(err)
}

pr, pw := io.Pipe()
mw := multipart.NewWriter(pw)

go func() {
defer mw.Close()

err := mw.WriteField("info", string(data))
if err != nil {
pw.CloseWithError(err)
return
}

for {
file, err := files.MoveNext()
if err == iterator.ErrNoMoreItem {
break
}
if err != nil {
pw.CloseWithError(fmt.Errorf("opening file: %w", err))
return
}

w, err := mw.CreateFormFile("files", url.PathEscape(file.FileName))
if err != nil {
file.File.Close()
pw.CloseWithError(fmt.Errorf("create form file failed, err: %w", err))
return
}

_, err = io.Copy(w, file.File)
if err != nil {
file.File.Close()
pw.CloseWithError(err)
return
}
file.File.Close()
}
}()

headers := http.Header{}
headers.Set("Content-Type", fmt.Sprintf("%s;boundary=%s", http2.ContentTypeMultiPart, mw.Boundary()))

return &RequestParam{
Method: method,
Path: path,
Header: headers,
Body: &StreamBody{
Stream: pr,
LengthHint: -1,
},
}
}

type APIResponse interface {
ParseResponse(resp *http.Response) error
}


Loading…
Cancel
Save