diff --git a/s3/s3.go b/s3/s3.go index 3f4cafb9c5b9ea5ab104bafbbedc84dc609730df..dee365b31e3b0a092961352d5de6656c4cc82da1 100644 --- a/s3/s3.go +++ b/s3/s3.go @@ -28,14 +28,14 @@ type S3UploadResponse struct { } type S3UploadSettings struct { - MimeType MIMEType - 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. - FilePrefix string // Required when GenerateFileNameFromParts is true - FileExt string // Required when GenerateFileNameFromParts is true + MimeType MIMEType + 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 + FilePath string + FileName string + FileExt string + InsertUUID bool } // Duration constants @@ -154,22 +154,39 @@ 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 fullFileName, uploadUrl string - if settings.FileName != "" { - fileName = settings.FileName + uuidString := "" + if settings.InsertUUID { + uuidString = fmt.Sprintf("_%s", uuid.New().String()) } - if settings.GenerateFileNameFromParts { - fileName = fmt.Sprintf("%s_%s.%s", settings.FilePrefix, uuid.New().String(), settings.FileExt) + + if len(settings.FileExt) > 0 { + if settings.FileExt[0] != '.' { + settings.FileExt = fmt.Sprintf(".%s", settings.FileExt) + } + } + + if len(settings.FilePath) > 0 { + if settings.FilePath[len(settings.FilePath)-1] != '/' { + settings.FilePath = fmt.Sprintf("%s/", settings.FilePath) + } + } + + fullFileName = fmt.Sprintf("%s%s%s%s", settings.FilePath, settings.FileName, uuidString, settings.FileExt) + + // Uploaded objects require a key + if fullFileName == "" { + return S3UploadResponse{}, errors.Error("no file name supplied for upload") } if settings.MimeType == "" { - settings.MimeType = getTypeForFilename(fileName) + settings.MimeType = getTypeForFilename(fullFileName) } putInput := &s3.PutObjectInput{ Bucket: aws.String(bucket), - Key: aws.String(fileName), + Key: aws.String(fullFileName), ContentType: aws.String(string(settings.MimeType)), Body: bytes.NewReader(data), } @@ -187,14 +204,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": fmt.Sprintf("attachment; filename=\"%s.%s\"", settings.FileName, settings.FileExt), } } @@ -202,7 +214,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, fullFileName, downloadUrlExpiry, headers) if err != nil { return S3UploadResponse{}, err } @@ -213,7 +226,7 @@ func (s SessionWithHelpers) UploadWithSettingsRevised(data []byte, bucket string response := S3UploadResponse{ URL: uploadUrl, - Filename: fileName, + Filename: fullFileName, Bucket: bucket, FileSize: fileSizeInBytes, }