Skip to content

Commit

Permalink
Make fPutObject automatically detect content-type (#765)
Browse files Browse the repository at this point in the history
Also correct fput-object.js example

Fixes #763
  • Loading branch information
kaankabalak authored and kannappanr committed Apr 23, 2019
1 parent 095fb32 commit fad89ff
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 2 deletions.
8 changes: 7 additions & 1 deletion examples/fput-object.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,15 @@ var s3Client = new Minio.Client({
secretKey: 'YOUR-SECRETACCESSKEY'
})

var metaData = {
'Content-Type': 'application/octet-stream',
'X-Amz-Meta-Testing': 1234,
'example': 5678
}

// Put a file in bucket my-bucketname.
var file = 'my-testfile'
s3Client.fPutObject('my-bucketname', 'my-objectname', file, 'application/octet-stream', function(e) {
s3Client.fPutObject('my-bucketname', 'my-objectname', file, metaData, function(e) {
if (e) {
return console.log(e)
}
Expand Down
15 changes: 15 additions & 0 deletions src/main/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,21 @@ export function readableStream(data) {
s.push(null)
return s
}

// Process metadata to insert appropriate value to `content-type` attribute
export function insertContentType(metaData, filePath) {
// check if content-type attribute present in metaData
for (var key in metaData) {
if (key.toLowerCase() === 'content-type') {
return metaData
}
}
// if `content-type` attribute is not present in metadata,
// then infer it from the extension in filePath
metaData['content-type'] = probeContentType(filePath)
return metaData
}

// Function prepends metadata with the appropriate prefix if it is not already on
export function prependXAMZMeta(metaData) {
var newMetadata = Object.assign({}, metaData)
Expand Down
5 changes: 4 additions & 1 deletion src/main/minio.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { extractMetadata, prependXAMZMeta, isValidPrefix, isValidEndpoint, isVal
uriEscape, uriResourceEscape, isBoolean, isFunction, isNumber,
isString, isObject, isArray, isValidDate, pipesetup,
readableStream, isReadableStream, isVirtualHostStyle,
makeDateLong, promisify } from './helpers.js'
insertContentType, makeDateLong, promisify } from './helpers.js'

import { signV4, presignSignatureV4, postPresignSignatureV4 } from './signing.js'

Expand Down Expand Up @@ -877,6 +877,9 @@ export class Client {
throw new TypeError('metaData should be of type "object"')
}

// Inserts correct `content-type` attribute based on metaData and filePath
insertContentType(metaData, filePath)

//Updates metaData to have the correct prefix if needed
metaData = prependXAMZMeta(metaData)
var size
Expand Down
47 changes: 47 additions & 0 deletions src/test/functional/functional-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,53 @@ describe('functional tests', function() {
client.fPutObject(bucketName, _100kbObjectName, tmpFileUpload,done)
})

step(`statObject(bucketName, objectName, cb)_bucketName:${bucketName}, objectName:${_100kbObjectName}_`, done => {
client.statObject(bucketName, _100kbObjectName, (e, stat) => {
if (e) return done(e)
// As metadata is not provided and there is no file extension,
// we default to 'application/octet-stream' as per `probeContentType` function
if (stat.metaData && stat.metaData['content-type'] !== 'application/octet-stream') {
return done(new Error('content-type mismatch'))
}
done()
})
})

var tmpFileUploadWithExt = `${tmpDir}/${_100kbObjectName}.txt`
step(`fPutObject(bucketName, objectName, filePath, metaData, callback)_bucketName:${bucketName}, objectName:${_100kbObjectName}, filePath: ${tmpFileUploadWithExt}, metaData:${metaData}_`, done => {
fs.writeFileSync(tmpFileUploadWithExt, _100kb)
client.fPutObject(bucketName, _100kbObjectName, tmpFileUploadWithExt, metaData, done)
})

step(`statObject(bucketName, objectName, cb)_bucketName:${bucketName}, objectName:${_100kbObjectName}_`, done => {
client.statObject(bucketName, _100kbObjectName, (e, stat) => {
if (e) return done(e)
// As metadata is provided, even though we have an extension,
// the `content-type` should be equal what was declared on the metadata
if (stat.metaData && stat.metaData['content-type'] !== 'text/html') {
return done(new Error('content-type mismatch'))
} else if (!stat.metaData) {
return done(new Error('no metadata present'))
}
done()
})
})

step(`fPutObject(bucketName, objectName, filePath, metaData, callback)_bucketName:${bucketName}, objectName:${_100kbObjectName}, filePath: ${tmpFileUploadWithExt}_`, done => {
fs.writeFileSync(tmpFileUploadWithExt, _100kb)
client.fPutObject(bucketName, _100kbObjectName, tmpFileUploadWithExt, done)
})

step(`statObject(bucketName, objectName, cb)_bucketName:${bucketName}, objectName:${_100kbObjectName}_`, done => {
client.statObject(bucketName, _100kbObjectName, (e, stat) => {
if (e) return done(e)
// As metadata is not provided but we have a file extension,
// we need to infer `content-type` from the file extension
if (stat.metaData && stat.metaData['content-type'] !== 'text/plain') return done(new Error('content-type mismatch'))
done()
})
})

step(`putObject(bucketName, objectName, stream, size, metaData, callback)_bucketName:${bucketName}, objectName:${_100kbObjectName}, stream:100kb, size:${_100kb.length}, metaData:${metaData}_`, done => {
var stream = readableStream(_100kb)
client.putObject(bucketName, _100kbObjectName, stream, _100kb.length, metaData, done)
Expand Down

0 comments on commit fad89ff

Please sign in to comment.