feat: ota
This commit is contained in:
@@ -26,7 +26,12 @@ func Nacos(conf zrpc.RpcClientConf) zrpc.Client {
|
||||
return zrpc.MustNewClient(cliConf,
|
||||
zrpc.WithDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())),
|
||||
zrpc.WithDialOption(grpc.WithUnaryInterceptor(request.UserClientInterceptor)),
|
||||
zrpc.WithDialOption(grpc.WithDefaultCallOptions(grpc.WaitForReady(true))),
|
||||
zrpc.WithDialOption(grpc.WithDefaultCallOptions(
|
||||
grpc.WaitForReady(true),
|
||||
// 上传文件经 base64 后可达 ~170MB+,需大于默认 4MB
|
||||
grpc.MaxCallRecvMsgSize(256<<20),
|
||||
grpc.MaxCallSendMsgSize(256<<20),
|
||||
)),
|
||||
zrpc.WithDialOption(grpc.WithConnectParams(grpc.ConnectParams{
|
||||
MinConnectTimeout: 2 * time.Second,
|
||||
})),
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
package request
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"lone-services/bff/internal/response"
|
||||
"lone-services/pkg/oss"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
ossUploadAPIPath = "/api/v3/chore/oss/upload"
|
||||
formFileField = "file"
|
||||
maxUploadMemory = oss.MaxUploadBytes
|
||||
)
|
||||
|
||||
func FormUploadMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost || r.URL.Path != ossUploadAPIPath {
|
||||
next(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
ct := r.Header.Get("Content-Type")
|
||||
ctrl := &response.BaseController{}
|
||||
if !strings.HasPrefix(strings.ToLower(ct), "multipart/form-data") {
|
||||
ctrl.Error(w, response.Define(response.ErrorMissingParams, "请使用 multipart/form-data 上传,字段名为 file"))
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseMultipartForm(int64(maxUploadMemory)); err != nil {
|
||||
ctrl.Error(w, response.Define(response.ErrorMissingParams, "解析上传文件失败"))
|
||||
return
|
||||
}
|
||||
file, header, err := r.FormFile(formFileField)
|
||||
if err != nil {
|
||||
ctrl.Error(w, response.Define(response.ErrorMissingParams, "请上传文件,字段名为 file"))
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
content, err := io.ReadAll(io.LimitReader(file, int64(maxUploadMemory)+1))
|
||||
if err != nil || len(content) == 0 {
|
||||
ctrl.Error(w, response.Define(response.ErrorMissingParams, "文件内容不能为空"))
|
||||
return
|
||||
}
|
||||
if len(content) > maxUploadMemory {
|
||||
ctrl.Error(w, response.Define(response.ErrorMissingParams, "文件过大,最大 128MB"))
|
||||
return
|
||||
}
|
||||
|
||||
filename := filepath.Base(header.Filename)
|
||||
if filename == "." || filename == "" {
|
||||
filename = "file"
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(map[string]string{
|
||||
"filename": filename,
|
||||
"content": base64.StdEncoding.EncodeToString(content),
|
||||
})
|
||||
if err != nil {
|
||||
ctrl.Fail(w)
|
||||
return
|
||||
}
|
||||
|
||||
r.Body = io.NopCloser(bytes.NewReader(payload))
|
||||
r.ContentLength = int64(len(payload))
|
||||
r.Header.Set("Content-Type", "application/json")
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user