Comparing version 0.4.9 to 0.4.11
'use strict'; | ||
const storageManager = require('./../StorageManager'), | ||
Blob = require('./../model/Blob'); | ||
Blob = require('./../model/Blob'), | ||
ResponseHeader = require('./../model/ResponseHeader'); | ||
@@ -11,6 +12,6 @@ class CreateBlockBlob { | ||
process(req, res, containerName, blobName) { | ||
const blob = new Blob(blobName, req.headers); | ||
const blob = new Blob(blobName, req.headers, 'BlockBlob'); | ||
storageManager.createBlockBlob(containerName, blob, req.body) | ||
.then((result) => { | ||
this._addResponseHeaders(res, result) | ||
res.set(new ResponseHeader(result, null, { 'x-ms-request-server-encrypted': false })); | ||
res.status(201).send(); | ||
@@ -31,14 +32,4 @@ }) | ||
} | ||
_addResponseHeaders(res, props) { | ||
res.set({ | ||
'ETag': props.ETag, | ||
'Last-Modified': props.lastModified, | ||
'x-ms-version': '2011-08-18', | ||
'x-ms-request-server-encrypted': false, | ||
'Content-MD5': props.md5 | ||
}); | ||
} | ||
} | ||
module.exports = new CreateBlockBlob(); |
'use strict'; | ||
const storageManager = require('./../StorageManager'), | ||
Container = require('./../model/Container'); | ||
Container = require('./../model/Container'), | ||
ResponseHeader = require('./../model/ResponseHeader'); | ||
@@ -13,4 +14,4 @@ class CreateContainer { | ||
storageManager.createContainer(container) | ||
.then((result) => { | ||
this._addResponseHeaders(res, container.httpProps) | ||
.then(() => { | ||
res.set(new ResponseHeader(container.httpProps)); | ||
res.status(200).send(); | ||
@@ -28,12 +29,4 @@ }) | ||
} | ||
_addResponseHeaders(res, props) { | ||
res.set({ | ||
'ETag': props.ETag, | ||
'Last-Modified': props.lastModified, | ||
'x-ms-version': '2011-08-18', | ||
}); | ||
} | ||
} | ||
module.exports = new CreateContainer(); |
'use strict'; | ||
const storageManager = require('./../StorageManager'); | ||
const storageManager = require('./../StorageManager'), | ||
ResponseHeader = require('./../model/ResponseHeader'); | ||
@@ -11,3 +12,4 @@ class DeleteBlob { | ||
storageManager.deleteBlob(container, blob) | ||
.then((result) => { | ||
.then(() => { | ||
res.set(new ResponseHeader()); | ||
res.status(202).send(); | ||
@@ -24,10 +26,4 @@ }) | ||
} | ||
_addResponseHeaders(res) { | ||
res.set({ | ||
'x-ms-version': '2011-08-18' | ||
}); | ||
} | ||
} | ||
module.exports = new DeleteBlob(); |
'use strict'; | ||
const storageManager = require('./../StorageManager'), | ||
Container = require('./../model/Container'); | ||
Container = require('./../model/Container'), | ||
ResponseHeader = require('./../model/ResponseHeader'); | ||
class DeleteContainer { | ||
@@ -13,2 +15,3 @@ constructor() { | ||
.then((result) => { | ||
res.set(new ResponseHeader()); | ||
res.status(200).send(); | ||
@@ -15,0 +18,0 @@ }) |
@@ -6,2 +6,3 @@ 'use strict'; | ||
request = require('request'), | ||
ResponseHeader = require('./../model/ResponseHeader'), | ||
path = require('path'); | ||
@@ -35,8 +36,4 @@ | ||
.on('response', (staticResponse) => { | ||
this._addResponseHeader(res, result, result.httpProps, result.metaProps); | ||
if (range) { | ||
res.writeHead(206); | ||
} else { | ||
res.writeHead(200); | ||
} | ||
res.set(new ResponseHeader(result.httpProps, result.metaProps, { 'Accept-Ranges': 'bytes' })); | ||
(range) ? res.writeHead(206) : res.writeHead(200); | ||
}) | ||
@@ -68,17 +65,2 @@ .pipe(res); | ||
_addResponseHeader(res, result, httpProps, metaProps) { | ||
const header = {}; | ||
Object.keys(metaProps).forEach((key) => { | ||
header[key] = metaProps[key]; | ||
}); | ||
header.ETag = result.ETag; | ||
header['Content-Encoding'] = httpProps['Content-Encoding']; | ||
header['Content-Type'] = httpProps['Content-Type']; | ||
header['x-ms-version'] = '2013-08-15'; | ||
header['Last-Modified'] = httpProps['Last-Modified']; | ||
header['Content-MD5'] = httpProps['Content-MD5']; | ||
header['Accept-Ranges'] = 'bytes'; | ||
res.set(header); | ||
} | ||
_addRequestHeader(url, range) { | ||
@@ -85,0 +67,0 @@ const request = {}; |
'use strict'; | ||
const storageManager = require('./../StorageManager'); | ||
const storageManager = require('./../StorageManager'), | ||
ResponseHeader = require('./../model/ResponseHeader'); | ||
@@ -12,3 +13,3 @@ class GetBlobMetadata { | ||
.then((result) => { | ||
this._setResponseHeader(res, result); | ||
res.set(new ResponseHeader(result.httpProps, result.metaProps)); | ||
res.status(200).send(); | ||
@@ -27,17 +28,4 @@ }) | ||
} | ||
_setResponseHeader(res, result) { | ||
const httpProps = result.httpProps; | ||
const metaProps = result.metaProps; | ||
const respHeader = {}; | ||
respHeader['Last-Modified'] = httpProps['Last-Modified']; | ||
respHeader.ETag = httpProps.ETag; | ||
respHeader['x-ms-version'] = '2011-08-18'; | ||
Object.keys(metaProps).forEach((key) => { | ||
respHeader[`x-ms-meta-${key}`] = metaProps[key]; | ||
}); | ||
res.set(respHeader); | ||
} | ||
} | ||
module.exports = new GetBlobMetadata(); |
@@ -5,2 +5,3 @@ 'use strict'; | ||
js2xmlparser = require('js2xmlparser'), | ||
ResponseHeader = require('./../model/ResponseHeader'), | ||
Model = require('./../model/BlockListXmlModel'); | ||
@@ -19,23 +20,11 @@ | ||
const xml = this._transformToXml(result.blocks, blockListType); | ||
this._addHeader(res, result.parentBlob); | ||
res.set(new ResponseHeader(result.parentBlob.http_props, null, { 'x-ms-blob-content-length': result.parentBlob.size, 'Content-Type': 'application/xml' })); | ||
res.status(200).send(xml); | ||
}) | ||
.catch((e) => { | ||
// A read operation cannot leave DB and disk storage in an inconsistent state, | ||
// thus we do not abort the process by re-throwing an error. | ||
res.status(500).send(); | ||
console.error(e); | ||
throw e; | ||
}); | ||
} | ||
_addHeader(res, parentBlob) { | ||
const httpProps = parentBlob.http_props; | ||
res.set({ | ||
'Last-Modified': httpProps.lastModified, | ||
'ETag': httpProps.ETag, | ||
'Content-Type': httpProps['Content-Type'] || 'application/xml', // as per spec | ||
'x-ms-blob-content-length': parentBlob.size | ||
}); | ||
} | ||
_transformToXml(blockList, blockListType) { | ||
@@ -46,3 +35,3 @@ let model = new Model.BlockList(blockListType); | ||
model.committedblocks.block.push(new Model.Block(block.blockId, block.size)); | ||
} else if(!block.committed && (blockListType === 'uncommitted' || blockListType === 'all')) { | ||
} else if (!block.committed && (blockListType === 'uncommitted' || blockListType === 'all')) { | ||
model.uncommittedblocks.block.push(new Model.Block(block.blockId, block.size)); | ||
@@ -49,0 +38,0 @@ } |
@@ -5,2 +5,3 @@ 'use strict'; | ||
js2xmlparser = require("js2xmlparser"), | ||
ResponseHeader = require('./../model/ResponseHeader'), | ||
model = require('./../model/BlobListXmlModel'); | ||
@@ -19,2 +20,3 @@ | ||
const xmlDoc = js2xmlparser.parse('EnumerationResults', transformedModel); | ||
res.set(new ResponseHeader()); | ||
res.status(200).send(xmlDoc); | ||
@@ -51,3 +53,3 @@ }) | ||
(queryParams.marker === undefined) ? delete xmlBlobListModel.marker : xmlBlobListModel.marker = marker; | ||
for(let blob of blobList) { | ||
for (let blob of blobList) { | ||
let modelBlob = new model.Blob(blob.name); | ||
@@ -60,7 +62,7 @@ xmlBlobListModel.blobs.blob.push(modelBlob); | ||
} | ||
modelBlob.properties['Last-Modified'] = blob.http_props.lastModified; | ||
modelBlob.properties['Last-Modified'] = blob.http_props['Last-Modified']; | ||
modelBlob.properties.ETag = blob.http_props.ETag; | ||
modelBlob.properties['Content-Type'] = blob.http_props['Content-Type']; | ||
modelBlob.properties['Content-Encoding'] = blob.http_props['Content-Encoding']; | ||
modelBlob.properties['Content-MD5'] = blob.http_props.ContentMD5; | ||
modelBlob.properties['Content-MD5'] = blob.http_props['Content-MD5']; | ||
} | ||
@@ -76,3 +78,3 @@ return xmlBlobListModel; | ||
blobModel.metadata[key] = value; | ||
}); | ||
}); | ||
} | ||
@@ -79,0 +81,0 @@ } |
'use strict'; | ||
const storageManager = require('./../StorageManager'), | ||
js2xmlparser = require("js2xmlparser"), | ||
model = require('./../model/ContainerListXmlModel'); | ||
js2xmlparser = require("js2xmlparser"), | ||
ResponseHeader = require('./../model/ResponseHeader'), | ||
model = require('./../model/ContainerListXmlModel'); | ||
class ListContainers { | ||
constructor(){ | ||
constructor() { | ||
} | ||
@@ -13,8 +14,8 @@ | ||
const prefix = req.query.prefix || '', | ||
maxresults = req.query.maxresults || "5000", | ||
includeMetadata = (req.query.include === 'metadata') ? true : false, | ||
marker = req.query.marker || ''; | ||
maxresults = req.query.maxresults || "5000", | ||
includeMetadata = (req.query.include === 'metadata') ? true : false, | ||
marker = req.query.marker || ''; | ||
storageManager.listContainer(prefix, maxresults) | ||
.then((containers) => { | ||
this._addResponseHeaders(res); | ||
res.set(new ResponseHeader()); | ||
let transformedModel = this._transformContainerList(containers, includeMetadata, prefix, maxresults, marker); | ||
@@ -36,3 +37,3 @@ let xmlDoc = js2xmlparser.parse('EnumerationResults', transformedModel); | ||
delete xmlContainerListModel.nextMarker; | ||
for(let container of containers) { | ||
for (let container of containers) { | ||
let modelContainer = new model.Container(container.name); | ||
@@ -56,3 +57,3 @@ xmlContainerListModel.containers.container.push(modelContainer); | ||
modelContainer.metadata[key] = value; | ||
}); | ||
}); | ||
} | ||
@@ -59,0 +60,0 @@ |
'use strict'; | ||
const storageManager = require('./../StorageManager'), | ||
ResponseHeader = require('./../model/ResponseHeader'), | ||
Blob = require('./../model/Blob'); | ||
@@ -31,3 +32,3 @@ | ||
.then((result) => { | ||
this._addResponseHeaders(res, result); | ||
res.set(new ResponseHeader(result, null, { 'x-ms-request-server-encrypted': false })); | ||
res.status(201).send(); | ||
@@ -44,14 +45,4 @@ }) | ||
} | ||
_addResponseHeaders(res, props) { | ||
res.set({ | ||
'ETag': props.ETag, | ||
'Last-Modified': props.lastModified, | ||
'Content-MD5': props['Content-MD5'], | ||
'x-ms-request-server-encrypted': false, | ||
'x-ms-version': '2011-08-18', | ||
}); | ||
} | ||
} | ||
module.exports = new PutBlock(); |
@@ -6,2 +6,3 @@ 'use strict'; | ||
BbPromise = require('bluebird'), | ||
ResponseHeader = require('./../model/ResponseHeader'), | ||
xml2jsAsync = BbPromise.promisify(require('xml2js').parseString), | ||
@@ -15,3 +16,3 @@ md5 = require('md5'); | ||
process(req, res, containerName, blobName, xmlDoc) { | ||
const blob = new Blob(blobName, req.headers); | ||
const blob = new Blob(blobName, req.headers); | ||
let md5RequestBody; | ||
@@ -22,20 +23,20 @@ BbPromise.try(() => { | ||
}) | ||
.then((blocklist) => { | ||
return storageManager.putBlockList(containerName, blob, blocklist) | ||
}) | ||
.then((response) => { | ||
response.contentMD5 = md5RequestBody; | ||
this._addResponseHeaders(res, response); | ||
res.status(201).send(); | ||
}) | ||
.catch((e) => { | ||
if (e.code === 'ENOENT') { | ||
res.status(404).send(); | ||
} else if (e.code === 'xml') { | ||
res.status(400).send('UnsupportedXmlNode'); | ||
} else { | ||
res.status(500).send(); | ||
throw e; | ||
} | ||
}); | ||
.then((blocklist) => { | ||
return storageManager.putBlockList(containerName, blob, blocklist) | ||
}) | ||
.then((response) => { | ||
response['Content-MD5'] = md5RequestBody; | ||
res.set(new ResponseHeader(response, null, { 'x-ms-request-server-encrypted': false })); | ||
res.status(201).send(); | ||
}) | ||
.catch((e) => { | ||
if (e.code === 'ENOENT') { | ||
res.status(404).send(); | ||
} else if (e.code === 'xml') { | ||
res.status(400).send('UnsupportedXmlNode'); | ||
} else { | ||
res.status(500).send(); | ||
throw e; | ||
} | ||
}); | ||
} | ||
@@ -64,14 +65,4 @@ | ||
} | ||
_addResponseHeaders(res, props) { | ||
res.set({ | ||
'ETag': props.ETag, | ||
'Last-Modified': props.lastModified, | ||
'Content-MD5': props.contentMD5, | ||
'x-ms-request-server-encrypted': false, | ||
'x-ms-version': '2011-08-18', | ||
}); | ||
} | ||
} | ||
module.exports = new PutBlockList(); |
'use strict'; | ||
const storageManager = require('./../StorageManager'), | ||
ResponseHeader = require('./../model/ResponseHeader'), | ||
Blob = require('./../model/Blob'); | ||
@@ -14,3 +15,3 @@ | ||
.then((result) => { | ||
res.set(result); | ||
res.set(new ResponseHeader(result)); | ||
res.status(200).send(); | ||
@@ -17,0 +18,0 @@ }) |
@@ -6,4 +6,5 @@ 'use strict'; | ||
class Blob extends StorageItem { | ||
constructor(name, httpHeader) { | ||
constructor(name, httpHeader, blobType) { | ||
super(name, httpHeader); | ||
this.httpProps['x-ms-blob-type'] = blobType || 'BlockBlob'; | ||
} | ||
@@ -10,0 +11,0 @@ } |
@@ -11,3 +11,5 @@ 'use strict'; | ||
setBlobMetadataHandler = require('./../api/SetBlobMetadata'), | ||
getBlobMetadataHandler = require('./../api/GetBlobMetadata'); | ||
getBlobMetadataHandler = require('./../api/GetBlobMetadata'), | ||
setBlobPropertiesHandler = require('./../api/SetBlobProperties'), | ||
getBlobPropertiesHandler = require('./../api/GetBlobProperties'); | ||
@@ -33,2 +35,6 @@ /* | ||
}) | ||
.head((req, res) => { | ||
// Get Blob Properties | ||
getBlobPropertiesHandler.process(req, res, req.params.container, req.params.blob); | ||
}) | ||
.post((req, res) => { | ||
@@ -47,4 +53,6 @@ }) | ||
setBlobMetadataHandler.process(req, res, req.params.container, req.params.blob); | ||
} | ||
else { | ||
} else if (req.query.comp === 'properties') { | ||
// Set Blob Properties | ||
setBlobPropertiesHandler.process(req, res, req.params.container, req.params.blob); | ||
} else { | ||
res.status(500).send('Not supported yet. Azurite only supports Block Blobs.'); | ||
@@ -51,0 +59,0 @@ } |
@@ -88,3 +88,3 @@ 'use strict'; | ||
blob.httpProps['Content-MD5'] = targetMD5; | ||
response.md5 = targetMD5; | ||
response['Content-MD5'] = targetMD5; | ||
if (sourceMD5) { | ||
@@ -119,3 +119,3 @@ if (targetMD5 !== sourceMD5) { | ||
response.ETag = newBlob.meta.revision; | ||
response.lastModified = blob.httpProps.lastModified; | ||
response['Last-Modified'] = blob.httpProps['Last-Modified']; | ||
} else { | ||
@@ -128,6 +128,4 @@ const updateBlob = blobResult[0]; | ||
response.ETag = updateBlob.meta.revision; | ||
response.lastModified = blob.httpProps.lastModified; | ||
response['Last-Modified'] = blob.httpProps['Last-Modified']; | ||
} | ||
}) | ||
.then(() => { | ||
return response; | ||
@@ -162,3 +160,3 @@ }); | ||
response.metaProps = blob.meta_props; | ||
response.ETag = blob.meta.revision; | ||
response.httpProps.ETag = blob.meta.revision; | ||
return response; | ||
@@ -249,3 +247,3 @@ }) | ||
response.ETag = newBlob.meta.revision; | ||
response.lastModified = options.blob.httpProps['Last-Modified']; | ||
response['Last-Modified'] = options.blob.httpProps['Last-Modified']; | ||
} else { | ||
@@ -258,3 +256,3 @@ const updateBlob = blobResult[0]; | ||
response.ETag = updateBlob.meta.revision; | ||
response.lastModified = options.blob.httpProps['Last-Modified']; | ||
response['Last-Modified'] = options.blob.httpProps['Last-Modified']; | ||
} | ||
@@ -298,3 +296,3 @@ return response; | ||
response.ETag = updateBlob.meta.revision; | ||
response.lastModified = blob.httpProps.lastModified; | ||
response['Last-Modified'] = blob.httpProps['Last-Modified']; | ||
}) | ||
@@ -350,19 +348,5 @@ .then(() => { | ||
return BbPromise.try(() => { | ||
const coll = this.db.getCollection(containerName); | ||
if (!coll) { | ||
const err = new Error('Container does not exist.'); | ||
err.code = 'NO_CONTAINER'; | ||
throw err; | ||
} | ||
const result = coll.chain() | ||
.find({ name: blob.name }) | ||
.data(); | ||
if (result.length === 0) { | ||
const err = new Error('Blob does not exist.'); | ||
err.code = 'NO_BLOB'; | ||
throw err; | ||
} | ||
const blobToUpdate = result[0]; | ||
const res = this._getCollectionAndBlob(containerName, blob.name), | ||
coll = res.coll, | ||
blobToUpdate = res.blob; | ||
blobToUpdate.meta_props = blob.metaProps; | ||
@@ -380,20 +364,7 @@ blobToUpdate.http_props['Last-Modified'] = blob.httpProps['Last-Modified']; | ||
return BbPromise.try(() => { | ||
const coll = this.db.getCollection(containerName); | ||
if (!coll) { | ||
const err = new Error('Container does not exist.'); | ||
err.code = 'NO_CONTAINER'; | ||
throw err; | ||
} | ||
const result = coll.chain() | ||
.find({ name: blobName }) | ||
.data(); | ||
if (result.length === 0) { | ||
const err = new Error('Blob does not exist.'); | ||
err.code = 'NO_BLOB'; | ||
throw err; | ||
} | ||
const httpProps = result[0].http_props; | ||
const metaProps = result[0].meta_props; | ||
httpProps.ETag = result[0].meta.revision; | ||
const res = this._getCollectionAndBlob(containerName, blobName), | ||
blob = res.blob, | ||
httpProps = blob.http_props, | ||
metaProps = blob.meta_props; | ||
httpProps.ETag = blob.meta.revision; | ||
return { | ||
@@ -406,2 +377,43 @@ httpProps: httpProps, | ||
setBlobProperties(containerName, blob) { | ||
return BbPromise.try(() => { | ||
const res = this._getCollectionAndBlob(containerName, blob.name), | ||
blobToUpdate = res.blob, | ||
coll = res.coll; | ||
blobToUpdate.http_props = blob.httpProps; | ||
coll.update(blobToUpdate); | ||
return { | ||
'Last-Modified': blobToUpdate.http_props['Last-Modified'], | ||
ETag: blobToUpdate.meta.revision | ||
}; | ||
}); | ||
} | ||
getBlobProperties(containerName, blobName) { | ||
// For block blobs return values are equal in Azurite | ||
return this.getBlobMetadata(containerName, blobName); | ||
} | ||
_getCollectionAndBlob(containerName, blobName) { | ||
const coll = this.db.getCollection(containerName); | ||
if (!coll) { | ||
const err = new Error('Container does not exist.'); | ||
err.code = 'NO_CONTAINER'; | ||
throw err; | ||
} | ||
const result = coll.chain() | ||
.find({ name: blobName }) | ||
.data(); | ||
if (result.length === 0) { | ||
const err = new Error('Blob does not exist.'); | ||
err.code = 'NO_BLOB'; | ||
throw err; | ||
} | ||
return { | ||
coll: coll, | ||
blob: result[0] | ||
}; | ||
} | ||
_buildBlockListQuery(containerName, blobName, blockListType) { | ||
@@ -408,0 +420,0 @@ let query = { |
{ | ||
"name": "azurite", | ||
"version": "0.4.9", | ||
"version": "0.4.11", | ||
"description": "A lightweight server clone of Azure Blob Storage that simulates most of the commands supported by it with minimal dependencies.", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -78,6 +78,6 @@ # Azurite | ||
## Get Blob Properties | ||
## Get Blob Properties [DONE] | ||
Returns all system properties and user-defined metadata on the blob. | ||
## Set Blob Properties | ||
## Set Blob Properties [DONE] | ||
Sets system properties defined for an existing blob. | ||
@@ -84,0 +84,0 @@ |
@@ -115,3 +115,3 @@ const chai = require('chai'), | ||
e.should.have.status(404); | ||
}); | ||
}); | ||
}); | ||
@@ -124,5 +124,36 @@ it('should fail to get metadata of a blob in a non-existant container', () => { | ||
e.should.have.status(404); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('Blob Properties', () => { | ||
it('should successfully set all system properties', () => { | ||
return chai.request(url) | ||
.put(`${urlPath}/${containerName}/${blobName}`) | ||
.set('x-ms-blob-cache-control', 'true') | ||
.set('x-ms-blob-content-type', 'ContentType') | ||
.set('x-ms-blob-content-md5', 'ContentMD5') | ||
.set('x-ms-blob-content-encoding', 'ContentEncoding') | ||
.set('x-ms-blob-content-language', 'ContentLanguage') | ||
.query({ comp: 'properties' }) | ||
.then((res) => { | ||
res.should.have.status(200); | ||
}); | ||
}); | ||
it('should get all previously set system properties', () => { | ||
return chai.request(url) | ||
.head(`${urlPath}/${containerName}/${blobName}`) | ||
.then((res) => { | ||
res.should.have.status(200); | ||
res.should.have.header('ETag'); | ||
res.should.have.header('Last-Modified'); | ||
res.should.have.header('Content-Type', 'ContentType'); | ||
res.should.have.header('Content-Encoding', 'ContentEncoding'); | ||
res.should.have.header('Content-MD5', 'ContentMD5'); | ||
res.should.have.header('Content-Language', 'ContentLanguage'); | ||
res.should.have.header('Cache-Control', 'true'); | ||
res.should.have.header('x-ms-blob-type', 'BlockBlob'); | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -15,2 +15,5 @@ 'use strict'; | ||
expect(item.httpProps).to.have.property('Content-Encoding', 'utf8'); | ||
expect(item.httpProps).to.not.have.property('Content-MD5'); | ||
expect(item.httpProps).to.not.have.property('Content-Language'); | ||
expect(item.httpProps).to.not.have.property('Cache-Control'); | ||
expect(item.metaProps).to.be.empty; | ||
@@ -17,0 +20,0 @@ }); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
73506
38
1592