Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

azurite

Package Overview
Dependencies
Maintainers
1
Versions
156
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

azurite - npm Package Compare versions

Comparing version 0.4.7 to 0.4.8

.travis.yml

37

lib/api/CreateBlockBlob.js
'use strict';
const storageManager = require('./../StorageManager'),
BlobHttpProperties = require('./../model/BlobHttpProperties');
Blob = require('./../model/Blob');

@@ -10,6 +10,5 @@ class CreateBlockBlob {

process(req, res, container, blob) {
const httpProps = this._buildHttpProps(req.headers);
const metaProps = this._buildMetaProps(req.headers);
storageManager.createBlockBlob(container, blob, req.body, httpProps, metaProps)
process(req, res, containerName, blobName) {
const blob = new Blob(blobName, req.headers);
storageManager.createBlockBlob(containerName, blob, req.body)
.then((result) => {

@@ -21,9 +20,6 @@ this._addResponseHeaders(res, result)

if (e.code === 'ENOENT') {
console.error(`Container ${container} does not exist.`);
res.status(404).send();
} else if (e.code === 'EACCES') {
console.error(`Azurite failed to create blob in local file system due to missing permissions.`);
res.status(404).send();
} else if (e.name === 'md5') {
console.error(e.message);
res.status(400).send(e.message);

@@ -37,25 +33,2 @@ } else {

_buildHttpProps(httpHeader) {
return new BlobHttpProperties(
null, // ETag will be overwritten by most recent value in DB if this is an update of an existing blob
null,
// x-ms-* attributes have precedence over according HTTP-Headers
httpHeader['x-ms-blob-content-type'] || httpHeader['Content-Type'] || 'application/octet-stream',
httpHeader['x-ms-blob-content-encoding'] || httpHeader['Content-Encoding'] || 'utf8',
httpHeader['x-ms-blob-content-language'] || httpHeader['Content-Language'],
httpHeader['x-ms-blob-content-md5'] || httpHeader['Content-MD5'],
httpHeader['x-ms-blob-cache-control'] || httpHeader['Cache-Control']);
}
_buildMetaProps(httpHeader) {
let metaProps = {};
Object.keys(httpHeader).forEach((key) => {
const value = httpHeader[key];
if (key.indexOf('x-ms-meta-') !== -1) {
metaProps[key] = value;
}
});
return metaProps;
}
_addResponseHeaders(res, props) {

@@ -68,3 +41,3 @@ res.set({

'Content-MD5': props.md5
});
});
}

@@ -71,0 +44,0 @@ }

'use strict';
const storageManager = require('./../StorageManager'),
Container = require('./../model/Container'),
ContainerHttpProperties = require('./../model/ContainerHttpProperties');
Container = require('./../model/Container');

@@ -11,9 +10,7 @@ class CreateContainer {

process(req, res) {
const containerName = req.params.container;
let containerModel = this._buildContainerModel(req, containerName);
storageManager.createContainer(containerModel)
process(req, res, containerName) {
const container = new Container(containerName, req.headers)
storageManager.createContainer(container)
.then((result) => {
console.log(`Successfully created container "${containerName}"`);
this._addResponseHeaders(res, containerModel.httpProps)
this._addResponseHeaders(res, container.httpProps)
res.status(200).send();

@@ -23,3 +20,2 @@ })

if (e.code === "EEXIST") {
console.error(`Container ${containerName} already exists.`);
res.status(409).send();

@@ -34,17 +30,2 @@ } else {

_buildContainerModel(req, containerName) {
let optional = {};
if(req.headers['x-ms-blob-public-access']) {
optional.access = req.headers['x-ms-blob-public-access'];
}
let container = new Container(containerName, new ContainerHttpProperties(), {}, optional);
Object.keys(req.headers).forEach((key) => {
let value = req.headers[key];
if (key.indexOf('x-ms-meta') !== -1) {
container.metaProps[key] = value;
}
});
return container;
}
_addResponseHeaders(res, props) {

@@ -51,0 +32,0 @@ res.set({

@@ -12,3 +12,2 @@ 'use strict';

.then((result) => {
console.log(`Successfully deleted ${container}/${blob}`);
res.status(202).send();

@@ -18,3 +17,2 @@ })

if (e.code === "ENOENT") {
console.error(`Blob ${container}/${blob} does not exist.`);
res.status(404).send('BlobNotFound');

@@ -21,0 +19,0 @@ } else {

'use strict';
const storageManager = require('./../StorageManager');
const storageManager = require('./../StorageManager'),
Container = require('./../model/Container');

@@ -9,7 +10,5 @@ class DeleteContainer {

process(req, res) {
const containerName = req.params.container
process(req, res, containerName) {
storageManager.deleteContainer(containerName)
.then((result) => {
console.log(`Successfully deleted container "${containerName}"`);
res.status(200).send();

@@ -19,3 +18,2 @@ })

if (e.code === "ENOENT") {
console.error(`Container ${containerName} does not exist.`);
res.status(404).send();

@@ -22,0 +20,0 @@ } else {

@@ -75,4 +75,4 @@ 'use strict';

header['x-ms-version'] = '2013-08-15';
header['Last-Modified'] = httpProps.lastModified;
header['Content-MD5'] = httpProps.ContentMD5;
header['Last-Modified'] = httpProps['Last-Modified'];
header['Content-MD5'] = httpProps['Content-MD5'];
header['Accept-Ranges'] = 'bytes';

@@ -79,0 +79,0 @@ res.set(header);

@@ -0,0 +0,0 @@ 'use strict';

@@ -0,0 +0,0 @@ 'use strict';

@@ -5,3 +5,3 @@ 'use strict';

js2xmlparser = require("js2xmlparser"),
model = require('./../model/ContainerList');
model = require('./../model/ContainerListXmlModel');

@@ -25,3 +25,2 @@ class ListContainers {

.catch((e) => {
console.error('ListContainers operation failed.\n' + JSON.stringify(e));
res.status(500).send();

@@ -55,3 +54,2 @@ });

let value = metaProps[key];
key = key.replace('x-ms-meta-', '');
key = 'metadata-' + key;

@@ -58,0 +56,0 @@ modelContainer.metadata[key] = value;

'use strict';
const storageManager = require('./../StorageManager'),
BlobHttpProperties = require('./../model/BlobHttpProperties');
Blob = require('./../model/Blob');

@@ -12,11 +12,6 @@ class PutBlock {

blockId: blockId,
contentLength: req.headers['content-length'],
contentLength: req.headers['content-length'] || req.headers['Content-Length'],
fileName: `${containerName}-${blobName}-${blockId}`,
parent: `${containerName}-${blobName}`,
httpProps: new BlobHttpProperties(null,
null,
null,
req.headers['x-ms-blob-content-encoding'] || 'utf8',
null,
req.headers['content-mD5'])
blob: new Blob(blobName, req.headers)
}

@@ -43,2 +38,5 @@ // Content-Length is required. The length of the block content in bytes.

res.status(400).send(e.message);
} else {
res.status(500).send();
throw e;
}

@@ -45,0 +43,0 @@ });

'use strict';
const storageManager = require('./../StorageManager'),
BlobHttpProperties = require('./../model/BlobHttpProperties'),
Blob = require('./../model/Blob'),
BbPromise = require('bluebird'),

@@ -14,29 +14,26 @@ xml2jsAsync = BbPromise.promisify(require('xml2js').parseString),

process(req, res, containerName, blobName, xmlDoc) {
let httpProps;
let metaProps;
const blob = new Blob(blobName, req.headers);
let md5RequestBody;
BbPromise.try(() => {
httpProps = this._buildHttpProps(req.headers);
metaProps = this._buildMetaProps(req.headers);
md5RequestBody = md5(xmlDoc);
return this._deserializeBlockList(xmlDoc)
})
.then((blocklist) => {
return storageManager.putBlockList(containerName, blobName, blocklist, httpProps, metaProps)
})
.then((response) => {
response.contentMD5 = md5RequestBody;
this._addResponseHeaders(res, response);
res.status(201).send();
})
.catch((e) => {
if (e.code === 'xml') {
res.status(400).send('UnsupportedXmlNode');
} else if (e.code === 'ENOENT'){
res.status(400).send('InvalidBlockList');
} else {
res.status(500).send();
throw e;
}
});
.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;
}
});
}

@@ -75,27 +72,4 @@

}
_buildHttpProps(httpHeader) {
return new BlobHttpProperties(
null, // ETag will be overwritten by most recent value in DB if this is an update of an existing blob
null,
// x-ms-* attributes have precedence over according HTTP-Headers
httpHeader['x-ms-blob-content-type'] || httpHeader['Content-Type'] || 'application/octet-stream',
httpHeader['x-ms-blob-content-encoding'] || httpHeader['Content-Encoding'] || 'utf8',
httpHeader['x-ms-blob-content-language'] || httpHeader['Content-Language'],
httpHeader['x-ms-blob-content-md5'] || httpHeader['Content-MD5'],
httpHeader['x-ms-blob-cache-control'] || httpHeader['Cache-Control']);
}
_buildMetaProps(httpHeader) {
let metaProps = {};
Object.keys(httpHeader).forEach((key) => {
const value = httpHeader[key];
if (key.indexOf('x-ms-meta-') !== -1) {
metaProps[key] = value;
}
});
return metaProps;
}
}
module.exports = new PutBlockList();

@@ -10,2 +10,3 @@ 'use strict';

fs = BbPromise.promisifyAll(require("fs")),
morgan = require('morgan'),
cli = require('./cli');

@@ -15,3 +16,3 @@

BbPromise.onPossiblyUnhandledRejection((err) => {
console.log('**PANIC** Something unexpected happened! Emulator may be in an inconsistent state!');
console.error('**PANIC** Something unexpected happened! Emulator may be in an inconsistent state!');
process.stderr.write(err.stack);

@@ -24,2 +25,3 @@ process.abort();

constructor() {
this.server;
}

@@ -34,6 +36,5 @@

let app = express();
app.use((req, res, next) => {
// TODO: Log sensible information about the request
next();
});
if (!env.silent) {
app.use(morgan('dev'));
}
app.use(bodyParser.raw({

@@ -48,9 +49,17 @@ inflate: true,

require('./routes/BlobRoute')(app);
app.listen(env.port, () => {
cli.asciiGreeting();
this.server = app.listen(env.port, () => {
if (!env.silent) {
cli.asciiGreeting();
}
});
});
}
close() {
return BbPromise.try(() => {
this.server.close();
})
}
}
module.exports = Azurite;

@@ -0,0 +0,0 @@ 'use strict';

@@ -14,7 +14,8 @@ 'use strict';

init(options) {
if (initialized) {
return;
if (initialized && !options.overwrite) {
return BbPromise.resolve();
}
initialized = true;
this.azuriteRootPath = options.l || options.location || './';
this.silent = options.s || options.silent;
this.dbName = '__azurite_db__.json';

@@ -21,0 +22,0 @@ this.localStoragePath = path.join(this.azuriteRootPath, '__blobstorage__');

@@ -0,0 +0,0 @@ 'use strict';

@@ -0,0 +0,0 @@ 'use strict';

'use strict';
class Container {
constructor(name, props, metaProps, optional) {
this.name = name;
this.httpProps = props || {};
this.metaProps = metaProps || {};
if (optional) {
this.access = optional.access || 'private'
}
const StorageItem = require('./StorageItem');
class Container extends StorageItem {
constructor(name, httpHeader) {
super(name, httpHeader);
this.access = httpHeader['x-ms-blob-public-access'] || 'private';
}

@@ -12,0 +10,0 @@ }

@@ -0,0 +0,0 @@ 'use strict';

@@ -9,3 +9,4 @@ 'use strict';

putBlockListHandler = require('./../api/PutBlockList'),
getBlockListHandler = require('./../api/GetBlockList');
getBlockListHandler = require('./../api/GetBlockList'),
setBlobMetadataHandler = require('./../api/SetBlobMetadata');

@@ -32,6 +33,4 @@ /*

const blobType = req.headers['x-ms-blob-type'];
// PUT Block
if (req.query.comp === 'block') {
putBlockHandler.process(req, res, req.params.container, req.params.blob, req.query.blockid);
// PUT Blob
} else if (req.query.comp === 'blocklist') {

@@ -41,3 +40,7 @@ putBlockListHandler.process(req, res, req.params.container, req.params.blob, req.body);

createBlockBlobHandler.process(req, res, req.params.container, req.params.blob);
} else {
} else if (req.query.comp === 'metadata') {
// Set Blob Metadata
setBlobMetadataHandler.process(req, res, req.params.container, req.params.blob);
}
else {
res.status(500).send('Not supported yet. Azurite only supports Block Blobs.');

@@ -44,0 +47,0 @@ }

@@ -31,5 +31,5 @@ 'use strict';

if (req.query.restype === 'container') {
deleteContainerHandler.process(req, res);
deleteContainerHandler.process(req, res, req.params.container);
}
});
}

@@ -9,4 +9,3 @@ 'use strict';

md5 = require('md5'),
CombinedStream = require('combined-stream'),
BlobHttpProperties = require('./model/BlobHttpProperties');
CombinedStream = require('combined-stream');

@@ -81,11 +80,11 @@ const CONTAINERS_COL_NAME = 'Containers',

createBlockBlob(container, blobName, body, httpProps, metaProps) {
createBlockBlob(container, blob, body) {
let containerPath = path.join(env.localStoragePath, container);
let blobPath = path.join(containerPath, blobName);
let blobPath = path.join(containerPath, blob.name);
let response = {};
const targetMD5 = md5(body);
httpProps.ContentMD5 = targetMD5;
return fs.statAsync(containerPath)
.then((stat) => {
const sourceMD5 = httpProps['Content-MD5'];
const sourceMD5 = blob.httpProps['Content-MD5'];
blob.httpProps['Content-MD5'] = targetMD5;
response.md5 = targetMD5;

@@ -102,3 +101,3 @@ if (sourceMD5) {

// Container exists, otherwise fs.statAsync throws error
return fs.outputFileAsync(blobPath, body, { encoding: httpProps['Content-Encoding'] });
return fs.outputFileAsync(blobPath, body, { encoding: blob.httpProps['Content-Encoding'] });
})

@@ -111,3 +110,3 @@ .then(() => {

const blobResult = coll.chain()
.find({ 'name': { '$eq': blobName } })
.find({ 'name': { '$eq': blob.name } })
.data();

@@ -117,17 +116,17 @@

const newBlob = coll.insert({
name: blobName,
http_props: httpProps,
meta_props: metaProps,
name: blob.name,
http_props: blob.httpProps,
meta_props: blob.metaProps,
size: body.length
});
response.ETag = newBlob.meta.revision;
response.lastModified = httpProps.lastModified;
response.lastModified = blob.httpProps.lastModified;
} else {
const updateBlob = blobResult[0];
updateBlob.http_props = httpProps;
updateBlob.meta_props = metaProps;
updateBlob.http_props = blob.httpProps;
updateBlob.meta_props = blob.metaProps;
updateBlob.size = body.length;
coll.update(updateBlob);
response.ETag = updateBlob.meta.revision;
response.lastModified = httpProps.lastModified;
response.lastModified = blob.httpProps.lastModified;
}

@@ -208,6 +207,5 @@ })

if (blobResult.length === 0) {
const httpProps = new BlobHttpProperties();
coll.insert({
name: blobName,
http_props: httpProps,
http_props: options.blob.httpProps,
committed: false,

@@ -219,3 +217,3 @@ size: 0

// Checking MD5 in case 'Content-MD5' header was set.
const sourceMD5 = options.httpProps['Content-MD5'];
const sourceMD5 = options.blob.httpProps['Content-MD5'];
const targetMD5 = md5(body);

@@ -234,3 +232,3 @@ response['Content-MD5'] = targetMD5;

const blockPath = path.join(env.commitsPath, options.fileName);
return fs.outputFileAsync(blockPath, body, { encoding: options.httpProps['Content-Encoding'] });
return fs.outputFileAsync(blockPath, body, { encoding: options.blob.httpProps['Content-Encoding'] });
})

@@ -249,17 +247,17 @@ .then(() => {

parent: options.parent,
http_props: options.httpProps,
http_props: options.blob.httpProps,
size: body.length, // in bytes
committed: false
});
response.ETag = newBlob.meta.revision;
response.lastModified = options.httpProps.lastModified;
response.lastModified = options.blob.httpProps['Last-Modified'];
} else {
const updateBlob = blobResult[0];
updateBlob.http_props = options.httpProps;
updateBlob.http_props = options.blob.httpProps;
updateBlob.size = body.length;
updatedBlob.committed = false;
updateBlob.committed = false;
coll.update(updateBlob);
response.ETag = updateBlob.meta.revision;
response.lastModified = options.httpProps.lastModified;
response.lastModified = options.blob.httpProps['Last-Modified'];
}

@@ -270,27 +268,37 @@ return response;

putBlockList(containerName, blobName, blockList, httpProps, metaProps) {
putBlockList(containerName, blob, blockList) {
const response = {};
let blocks = [];
return BbPromise.try(() => {
const combinedStream = CombinedStream.create();
let promises = [];
for (const block of blockList) {
const blockName = `${containerName}-${blobName}-${block.id}`;
const blockName = `${containerName}-${blob.name}-${block.id}`;
const blockPath = path.join(env.commitsPath, blockName);
combinedStream.append(fs.createReadStream(blockPath));
blocks.push(blockPath);
promises.push(fs.statAsync(blockPath));
}
const blobPath = path.join(env.localStoragePath, containerName, blobName);
combinedStream.pipe(fs.createWriteStream(blobPath));
// In case a block does not exists this will throw
return BbPromise.all(promises);
})
.then(() => {
const combinedStream = CombinedStream.create();
for (const block of blocks) {
combinedStream.append(fs.createReadStream(block));
}
const blobPath = path.join(env.localStoragePath, containerName, blob.name);
combinedStream.pipe(fs.createWriteStream(blobPath));
const coll = this.db.getCollection(containerName);
const blobResult = coll.chain()
.find({ 'name': { '$eq': blobName } })
.data();
const coll = this.db.getCollection(containerName);
const blobResult = coll.chain()
.find({ 'name': { '$eq': blob.name } })
.data();
// Blob must exist in DB since preceding calls to "PUT Block"
const updateBlob = blobResult[0];
updateBlob.http_props = httpProps;
updateBlob.meta_props = metaProps;
coll.update(updateBlob);
response.ETag = updateBlob.meta.revision;
response.lastModified = httpProps.lastModified;
})
// Blob must exist in DB since preceding calls to "PUT Block"
const updateBlob = blobResult[0];
updateBlob.http_props = blob.httpProps;
updateBlob.meta_props = blob.metaProps;
coll.update(updateBlob);
response.ETag = updateBlob.meta.revision;
response.lastModified = blob.httpProps.lastModified;
})
.then(() => {

@@ -301,3 +309,3 @@ // Set Blocks in DB to committed = true, delete blocks not in BlockList

const blocks = coll.chain()
.find({ parent: `${containerName}-${blobName}` })
.find({ parent: `${containerName}-${blob.name}` })
.data();

@@ -321,3 +329,3 @@ for (const block of blocks) {

getBlockList(containerName, blobName, blockListType) {
let response ={};
let response = {};
return fs.statAsync(path.join(env.localStoragePath, containerName))

@@ -341,6 +349,35 @@ .then(() => {

response.parentBlob = parentBlob[0];
return response;
return response;
});
}
setBlobMetadata(containerName, blob) {
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];
blobToUpdate.meta_props = blob.metaProps;
blobToUpdate.http_props['Last-Modified'] = blob.httpProps['Last-Modified'];
coll.update(blobToUpdate);
return {
ETag: blobToUpdate.meta.revision,
'Last-Modified': blobToUpdate.http_props['Last-Modified']
};
});
}
_buildBlockListQuery(containerName, blobName, blockListType) {

@@ -347,0 +384,0 @@ let query = {

{
"name": "azurite",
"version": "0.4.7",
"version": "0.4.8",
"description": "A lightweight server clone of Azure Blob Storage that simulates most of the commands supported by it with minimal dependencies.",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"pretest": "npm run clean",
"test": "cross-env AZURITE_LOCATION=azurite-testdrive mocha --timeout 10000",
"start": "bin/azurite -l azurite-testdrive",
"clean": "rimraf azurite-testdrive"
},

@@ -45,5 +48,14 @@ "engines": {

"minimist": "^1.2.0",
"morgan": "^1.7.0",
"request": "^2.79.0",
"xml2js": "^0.4.17"
},
"devDependencies": {
"chai": "^3.5.0",
"chai-http": "^3.0.0",
"cross-env": "^3.1.3",
"mocha": "^3.2.0",
"request-promise": "^4.1.1",
"rimraf": "^2.5.4"
}
}
# Azurite
[![npm version](https://badge.fury.io/js/azurite.svg)](https://badge.fury.io/js/azurite)
[![license](https://img.shields.io/github/license/mashape/apistatus.svg?maxAge=2592000)]()
[![Build Status](https://travis-ci.org/arafato/azurite.svg?branch=master)](https://travis-ci.org/arafato/azurite)

@@ -14,8 +15,7 @@ A lightweight server clone of Azure Blob Storage that simulates most of the commands supported by it with minimal dependencies.

Standard Emulator Connection String:
DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;
AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;
BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;
TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;
QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;
You do not need to provide an account key.
# REST APIs

@@ -22,0 +22,0 @@ https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/blob-service-rest-api

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc