测试修复文件上传 bug
This commit is contained in:
@@ -70,8 +70,18 @@ func (s *Storage) PutObject(ctx context.Context, key string, reader io.Reader, s
|
||||
}
|
||||
_, err := s.client.PutObject(ctx, s.bucket, key, reader, size, minio.PutObjectOptions{
|
||||
ContentType: contentType,
|
||||
UserMetadata: metadata,
|
||||
UserMetadata: sanitizeObjectMetadata(metadata),
|
||||
})
|
||||
if isNoSuchBucketError(err) && rewindReader(reader) == nil {
|
||||
s.markBucketNotReady()
|
||||
if readyErr := s.ensureBucketReady(ctx); readyErr != nil {
|
||||
return readyErr
|
||||
}
|
||||
_, err = s.client.PutObject(ctx, s.bucket, key, reader, size, minio.PutObjectOptions{
|
||||
ContentType: contentType,
|
||||
UserMetadata: sanitizeObjectMetadata(metadata),
|
||||
})
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -120,6 +130,48 @@ func (s *Storage) ensureBucketReady(ctx context.Context) error {
|
||||
return s.ensureBucket(ctx)
|
||||
}
|
||||
|
||||
func (s *Storage) markBucketNotReady() {
|
||||
s.bucketMu.Lock()
|
||||
defer s.bucketMu.Unlock()
|
||||
s.bucketReady = false
|
||||
}
|
||||
|
||||
func isNoSuchBucketError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
errResp := minio.ToErrorResponse(err)
|
||||
if errResp.Code == "NoSuchBucket" {
|
||||
return true
|
||||
}
|
||||
return strings.Contains(strings.ToLower(err.Error()), "bucket does not exist")
|
||||
}
|
||||
|
||||
func rewindReader(reader io.Reader) error {
|
||||
seeker, ok := reader.(io.Seeker)
|
||||
if !ok {
|
||||
return fmt.Errorf("reader cannot rewind")
|
||||
}
|
||||
_, err := seeker.Seek(0, io.SeekStart)
|
||||
return err
|
||||
}
|
||||
|
||||
func sanitizeObjectMetadata(metadata map[string]string) map[string]string {
|
||||
if len(metadata) == 0 {
|
||||
return nil
|
||||
}
|
||||
sanitized := make(map[string]string, len(metadata))
|
||||
for key, value := range metadata {
|
||||
key = strings.TrimSpace(key)
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
// MinIO/S3 用户元数据会作为 HTTP header 发送,值统一转义为 ASCII,避免中文文件名导致上传失败。
|
||||
sanitized[key] = url.QueryEscape(value)
|
||||
}
|
||||
return sanitized
|
||||
}
|
||||
|
||||
func normalizeEndpoint(raw string) (string, bool, error) {
|
||||
parsed, err := url.Parse(raw)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user