| 428 | } |
| 429 | |
| 430 | func (d *BaiduNetdisk) uploadSlice(ctx context.Context, uploadUrl string, params map[string]string, fileName string, file *io.SectionReader) error { |
| 431 | b := bytes.NewBuffer(make([]byte, 0, bytes.MinRead)) |
| 432 | mw := multipart.NewWriter(b) |
| 433 | _, err := mw.CreateFormFile("file", fileName) |
| 434 | if err != nil { |
| 435 | return err |
| 436 | } |
| 437 | headSize := b.Len() |
| 438 | err = mw.Close() |
| 439 | if err != nil { |
| 440 | return err |
| 441 | } |
| 442 | head := bytes.NewReader(b.Bytes()[:headSize]) |
| 443 | tail := bytes.NewReader(b.Bytes()[headSize:]) |
| 444 | rateLimitedRd := driver.NewLimitedUploadStream(ctx, io.MultiReader(head, file, tail)) |
| 445 | |
| 446 | req, err := http.NewRequestWithContext(ctx, http.MethodPost, uploadUrl+"/rest/2.0/pcs/superfile2", rateLimitedRd) |
| 447 | if err != nil { |
| 448 | return err |
| 449 | } |
| 450 | query := req.URL.Query() |
| 451 | for k, v := range params { |
| 452 | query.Set(k, v) |
| 453 | } |
| 454 | req.URL.RawQuery = query.Encode() |
| 455 | req.Header.Set("Content-Type", mw.FormDataContentType()) |
| 456 | req.ContentLength = int64(b.Len()) + file.Size() |
| 457 | |
| 458 | client := net.NewHttpClient() |
| 459 | if d.UploadSliceTimeout > 0 { |
| 460 | client.Timeout = time.Second * time.Duration(d.UploadSliceTimeout) |
| 461 | } else { |
| 462 | client.Timeout = DEFAULT_UPLOAD_SLICE_TIMEOUT |
| 463 | } |
| 464 | resp, err := client.Do(req) |
| 465 | if err != nil { |
| 466 | return err |
| 467 | } |
| 468 | defer resp.Body.Close() |
| 469 | b.Reset() |
| 470 | _, err = b.ReadFrom(resp.Body) |
| 471 | if err != nil { |
| 472 | return err |
| 473 | } |
| 474 | body := b.Bytes() |
| 475 | respStr := string(body) |
| 476 | log.Debugln(respStr) |
| 477 | lower := strings.ToLower(respStr) |
| 478 | // 合并 uploadid 过期检测逻辑 |
| 479 | if strings.Contains(lower, "uploadid") && |
| 480 | (strings.Contains(lower, "invalid") || strings.Contains(lower, "expired") || strings.Contains(lower, "not found")) { |
| 481 | return ErrUploadIDExpired |
| 482 | } |
| 483 | |
| 484 | errCode := utils.Json.Get(body, "error_code").ToInt() |
| 485 | errNo := utils.Json.Get(body, "errno").ToInt() |
| 486 | if errCode != 0 || errNo != 0 { |
| 487 | return errs.NewErr(errs.StreamIncomplete, "error uploading to baidu, response=%s", respStr) |