diff --git a/s3/s3.go b/s3/s3.go index 3f4cafb9c5b9ea5ab104bafbbedc84dc609730df..0f7a3823e4575473ac9ea511b04612a30fc14d5d 100644 --- a/s3/s3.go +++ b/s3/s3.go @@ -32,8 +32,9 @@ type S3UploadSettings struct { RetrieveSignedUrl bool ExpiryDuration *time.Duration // Used to set expiry datetime of download links. NB: does not affect deletion of object from S3 bucket. AddContentDisposition bool - FileName string - GenerateFileNameFromParts bool // Whether the file extension needs to be specified. If true, supply FilePrefix and FileExt. + FileName string // Used to specify the file name (excluding path) for content disposition; if FilePath is not present, it is used as the object key as well. + FilePath string // The complete file path (including name) used for the object key in S3. + GenerateFileNameFromParts bool // Whether the file extension needs to be specified. If true, supply FilePrefix and FileExt. Adds a UUID between the prefix and the extension. FilePrefix string // Required when GenerateFileNameFromParts is true FileExt string // Required when GenerateFileNameFromParts is true } @@ -154,22 +155,35 @@ func (s SessionWithHelpers) UploadWithSettings(data []byte, bucket, fileName str // UploadWithSettingsRevised can be renamed to UploadWithSettings once original function has been deprecated. func (s SessionWithHelpers) UploadWithSettingsRevised(data []byte, bucket string, settings S3UploadSettings) (S3UploadResponse, error) { - var fileName, uploadUrl string + var fileName, filePath, uploadUrl string + // fileName is used as the object key in S3 if settings.FileName != "" { fileName = settings.FileName } + if settings.GenerateFileNameFromParts { fileName = fmt.Sprintf("%s_%s.%s", settings.FilePrefix, uuid.New().String(), settings.FileExt) } + if settings.FilePath != "" { + filePath = settings.FilePath + } else { + filePath = fileName + } + + // Uploaded objects require a key + if fileName == "" { + return S3UploadResponse{}, errors.Error("no file name supplied for upload") + } + if settings.MimeType == "" { settings.MimeType = getTypeForFilename(fileName) } putInput := &s3.PutObjectInput{ Bucket: aws.String(bucket), - Key: aws.String(fileName), + Key: aws.String(filePath), ContentType: aws.String(string(settings.MimeType)), Body: bytes.NewReader(data), } @@ -187,14 +201,9 @@ func (s SessionWithHelpers) UploadWithSettingsRevised(data []byte, bucket string if settings.RetrieveSignedUrl { var headers map[string]string - fileNameHeader := fileName - if settings.FileName != "" { - fileNameHeader = settings.FileName - } - if settings.AddContentDisposition { headers = map[string]string{ - "content-disposition": "attachment; filename=\"" + fileNameHeader + "\"", + "content-disposition": "attachment; filename=\"" + fileName + "\"", } } @@ -202,7 +211,8 @@ func (s SessionWithHelpers) UploadWithSettingsRevised(data []byte, bucket string if settings.ExpiryDuration != nil { downloadUrlExpiry = *settings.ExpiryDuration } - uploadUrl, err = s.GetSignedDownloadURL(bucket, fileName, downloadUrlExpiry, headers) + + uploadUrl, err = s.GetSignedDownloadURL(bucket, filePath, downloadUrlExpiry, headers) if err != nil { return S3UploadResponse{}, err }