Обнаружен AccessDenied при использовании UploadPartCopy для MultiPartUpload в Golang - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь использовать S3 MultipartUpload для объединения файлов в корзину S3.Если у вас есть несколько файлов> 5 МБ (последний файл может быть меньше), вы можете объединить их в S3 в больший файл.По сути, это эквивалентно использованию cat для объединения файлов.Когда я пытаюсь сделать это в Go, я получаю:

An error occurred (AccessDenied) when calling the UploadPartCopy operation: Access Denied

Код выглядит примерно так:

mpuOut, err := s3CreateMultipartUpload(&S3.CreateMultipartUploadInput{
    Bucket: aws.String(bucket),
    Key:    aws.String(concatenatedFile),
})
if err != nil {
    return err
}

var ps []*S3.CompletedPart
for i, part := range parts { // parts is a list of paths to things in s3
    partNumber := int64(i) + 1
    upOut, err := s3UploadPartCopy(&S3.UploadPartCopyInput{
        Bucket:     aws.String(bucket),
        CopySource: aws.String(part),
        Key:        aws.String(concatenatedFile),
        UploadId:   aws.String(*mpuOut.UploadId),
        PartNumber: aws.Int64(partNumber),
    })
    if err != nil {
        return err // <- fails here
    }
    ps = append(ps, &S3.CompletedPart{
        ETag:       s3Out.CopyPartResult.ETag,
        PartNumber: aws.Int64(int64(i)),
    })
}

_, err = s3CompleteMultipartUpload(&S3.CompleteMultipartUploadInput{
    Bucket:          aws.String(bucket),
    Key:             aws.String(concatenatedFile),
    MultipartUpload: &S3.CompletedMultipartUpload{Parts: ps},
    UploadId:        aws.String(*mpuOut.UploadId),
})
if err != nil {
    return err
}

_, err = s3CompleteMultipartUpload(&S3.CompleteMultipartUploadInput{
    Bucket:          aws.String(bucket),
    Key:             aws.String(concatenatedFile),
    MultipartUpload: &S3.CompletedMultipartUpload{Parts: ps},
    UploadId:        aws.String(*mpuOut.UploadId),
})
if err != nil {
    return err
}

Когда он работает, он дуетс ошибкой выше.Разрешения на ведро широко открыты.Есть идеи?

1 Ответ

0 голосов
/ 08 июня 2018

Хорошо, проблема в том, что когда вы выполняете UploadPartCopy для параметра CopySource, вы не просто используете путь в корзине s3.Вы должны поместить имя в начале пути, даже если оно находится в том же ведре.Сумасшедший

mpuOut, err := s3CreateMultipartUpload(&S3.CreateMultipartUploadInput{
    Bucket: aws.String(bucket),
    Key:    aws.String(concatenatedFile),
})
if err != nil {
    return err
}

var ps []*S3.CompletedPart
for i, part := range parts { // parts is a list of paths to things in s3
    partNumber := int64(i) + 1
    upOut, err := s3UploadPartCopy(&S3.UploadPartCopyInput{
        Bucket:     aws.String(bucket),
        CopySource: aws.String(fmt.Sprintf("%s/%s", bucket, part), // <- ugh
        Key:        aws.String(concatenatedFile),
        UploadId:   aws.String(*mpuOut.UploadId),
        PartNumber: aws.Int64(partNumber),
    })
    if err != nil {
        return err
    }
    ps = append(ps, &S3.CompletedPart{
        ETag:       s3Out.CopyPartResult.ETag,
        PartNumber: aws.Int64(int64(i)),
    })
}

_, err = s3CompleteMultipartUpload(&S3.CompleteMultipartUploadInput{
    Bucket:          aws.String(bucket),
    Key:             aws.String(concatenatedFile),
    MultipartUpload: &S3.CompletedMultipartUpload{Parts: ps},
    UploadId:        aws.String(*mpuOut.UploadId),
})
if err != nil {
    return err
}

_, err = s3CompleteMultipartUpload(&S3.CompleteMultipartUploadInput{
    Bucket:          aws.String(bucket),
    Key:             aws.String(concatenatedFile),
    MultipartUpload: &S3.CompletedMultipartUpload{Parts: ps},
    UploadId:        aws.String(*mpuOut.UploadId),
})
if err != nil {
    return err
}

Это просто потратило около часа моей жизни, поэтому я решил, что постараюсь спасти кого-то еще от неприятностей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...