fix(upload): 分片用 multipart 字段 chunk、路由顺序与串行上传
- 前端 FormData+chunk,避免 raw body 被中间层断连 - Gin 分片路由置于 POST .../assets 之前 - 分片并发降为 1 Made-with: Cursor
This commit is contained in:
@@ -215,7 +215,7 @@ func MultipartUploadStatus(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
// PutMultipartChunk 上传单个分片(二进制 body,长度须与分片大小一致)。路由同时注册 POST 与 PUT,建议客户端用 POST。
|
||||
// PutMultipartChunk 上传单个分片。支持 multipart 字段 chunk(推荐)或 application/octet-stream 原始 body;路由同时注册 POST 与 PUT。
|
||||
func PutMultipartChunk(c *gin.Context) {
|
||||
siteID := c.Param("site_id")
|
||||
uploadID := c.Param("upload_id")
|
||||
@@ -252,7 +252,38 @@ func PutMultipartChunk(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "创建临时文件失败"})
|
||||
return
|
||||
}
|
||||
n, err := io.Copy(f, io.LimitReader(c.Request.Body, expected+1))
|
||||
|
||||
ct := strings.ToLower(c.GetHeader("Content-Type"))
|
||||
var src io.Reader
|
||||
if strings.HasPrefix(ct, "multipart/form-data") {
|
||||
// 与整文件上传一致走 multipart,避免部分网关对 raw POST body 断连
|
||||
fh, err := c.FormFile("chunk")
|
||||
if err != nil {
|
||||
_ = f.Close()
|
||||
_ = os.Remove(tmp)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "请使用表单字段 chunk 上传分片"})
|
||||
return
|
||||
}
|
||||
if fh.Size > 0 && fh.Size != expected {
|
||||
_ = f.Close()
|
||||
_ = os.Remove(tmp)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "分片大小不符"})
|
||||
return
|
||||
}
|
||||
part, err := fh.Open()
|
||||
if err != nil {
|
||||
_ = f.Close()
|
||||
_ = os.Remove(tmp)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "打开分片失败"})
|
||||
return
|
||||
}
|
||||
defer part.Close()
|
||||
src = part
|
||||
} else {
|
||||
src = c.Request.Body
|
||||
}
|
||||
|
||||
n, err := io.Copy(f, io.LimitReader(src, expected+1))
|
||||
_ = f.Close()
|
||||
if err != nil {
|
||||
_ = os.Remove(tmp)
|
||||
|
||||
Reference in New Issue
Block a user