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.9.16 to 0.10.0

lib/actions/AbortCopyBlob.js

0

lib/actions/CopyBlob.js

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

@@ -29,3 +29,11 @@ 'use strict';

response.addHttpProperty(N.CONTENT_LENGTH, response.proxy.original.size);
response.addHttpProperty(N.COPY_ID, response.proxy.original.copyId);
response.addHttpProperty(N.COPY_STATUS, response.proxy.original.copyStatus);
response.addHttpProperty(N.COPY_COMPLETION_TIME, response.proxy.original.copyCompletionTime);
response.addHttpProperty(N.COPY_STATUS_DESCRIPTION, response.proxy.original.copyStatusDescription);
response.addHttpProperty(N.COPY_PROGRESS, response.proxy.original.copyProgress);
response.addHttpProperty(N.COPY_SOURCE, response.proxy.original.copySource);
response.addHttpProperty(N.INCREMENTAL_COPY, response.proxy.original.incrementalCopy);
response.addHttpProperty(N.SEQUENCE_NUMBER, response.proxy.original.sequenceNumber);
response.addHttpProperty(N.BLOB_COMMITTED_BLOCK_COUNT, response.proxy.original[N.BLOB_COMMITTED_BLOCK_COUNT]);
res.set(response.httpProps);

@@ -32,0 +40,0 @@ res.status(200).send();

3

lib/Constants.js

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

APPEND_BLOCK: 'AppendBlock',
COPY_BLOB: 'CopyBlob'
COPY_BLOB: 'CopyBlob',
ABORT_COPY_BLOB: 'AbortCopyBlob'
}

@@ -84,0 +85,0 @@ }

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

// We prepend a specific character to guarantee unique ids.
// This is neccessary since otherwise snapshot IDs could overlap with blob IDs could overlap with page IDs, ....
// This is neccessary since otherwise snapshot IDs could overlap with block IDs could overlap with block-/append-/page-blob IDs.
blobId(containerName, blobName) {

@@ -56,0 +56,0 @@ return Buffer.from(`A${containerName}${blobName}`, 'utf8').toString('base64');

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

PendingCopyOperation: new ErrorCode('PendingCopyOperation', 409, 'There is currently a pending copy operation.'),
NoPendingCopyOperation: new ErrorCode('NoPendingCopyOperation', 409, 'There is currently no pending copy operation.'),
InvalidBlockList: new ErrorCode('InvalidBlockList', 400, 'The specified block list is invalid.')
}

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

snapshotBlob = require('./../actions/SnapshotBlob'),
copyBlob = require('./../actions/CopyBlob');
copyBlob = require('./../actions/CopyBlob'),
abortCopyBlob = require('./../actions/AbortCopyBlob');

@@ -38,6 +39,3 @@

actions[req.azuriteOperation](req.azuriteRequest, res);
// Refactor me: Move this to bin/azurite (exception needs to carry res object), and handle entire exception handling there
}).catch((e) => {
// e.res = res;
// throw e;
res.status(e.statusCode || 500).send(e.message);

@@ -151,2 +149,6 @@ if (!e.statusCode) throw e;

copyBlob.process(request, res);
}
actions[Operations.Blob.ABORT_COPY_BLOB] = (request, res) => {
abortCopyBlob.process(request, res);
}

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

BlockListValidation = require('./../validation/BlockList'),
AbortCopyValidation = require('./../validation/AbortCopy'),
CopyStatusValidation = require('./../validation/CopyStatus');

@@ -43,3 +44,3 @@

BbPromise.try(() => {
if (req.azuriteOperation === undefined || req.azuriteOperation === Operations.Blob.COPY_BLOB) {
if (req.azuriteOperation === undefined /*|| req.azuriteOperation === Operations.Blob.COPY_BLOB*/) {
res.status(501).send('Not Implemented yet.');

@@ -277,7 +278,21 @@ return;

validations[Operations.Blob.COPY_BLOB] = (request, valContext) => {
// Source Validation
const sourceBlobProxy = sm._getCopySourceProxy(request);
const ret = sm._getCollectionAndContainer((request.copySourceName()).sourceContainerName),
sourceContainerProxy = ret.containerProxy;
valContext
.run(ContainerExistsVal, { containerProxy: sourceContainerProxy })
.run(BlobExistsVal, { blobProxy: sourceBlobProxy });
// Target Validation
valContext
.run(ContainerExistsVal)
.run(BlobExistsVal)
.run(CompatibleBlobTypeVal, { request: { entityType: sourceBlobProxy.original.entityType } })
.run(ConditionalRequestHeadersVal, { usage: Usage.Write })
.run(CopyStatusValidation);
}
validations[Operations.Blob.ABORT_COPY_BLOB] = (request, valContext) => {
valContext
.run(AbortCopyValidation);
}
'use strict';
const crypto = require('crypto'),
url = require('url'),
EntityType = require('./../Constants').StorageEntityType,

@@ -26,2 +27,3 @@ BlockListType = require('./../Constants').BlockListType,

this.snapshot = false;
this.copyId = req.query.copyid;
// Per default, all (block) blobs will be set to committed by EntityGenerator

@@ -65,20 +67,27 @@ this.commit = true;

/**
* Return the blob's URI of Azurite's internal file system location.
*
* @memberof AzuriteBlobRequest
*/
copySourceUrl() {
copySourceName() {
if (this.httpProps[N.COPY_SOURCE === undefined]) {
throw new InternalAzuriteError('Request: copySourceUrl was called without copy-source header set.')
}
let uri;
const source = this.httpProps[N.COPY_SOURCE];
// Same Storage account
if (source.includes('http://127.0.0.1/devstoreaccount1/')) {
source = source.replace('http://127.0.0.1/devstoreaccount1/', '');
uri = env.diskStorageUri(this);
let source = this.httpProps[N.COPY_SOURCE];
if (source.includes('http://127.0.0.1:10000/devstoreaccount1/')) {
source = source.replace('http://127.0.0.1:10000/devstoreaccount1/', '');
} else { // format: /accountName/containerName/blobName
// TODO
}
return result;
source = url.parse(source).pathname; // we ignore query params
const parts = source.split('/'),
containerName = parts[0];
parts.splice(0, 1);
const blobName = decodeURIComponent(parts.join('/')); // // unicode characters in http headers are encoded!
const query = url.parse(blobName).query
let date = undefined;
if (query !== null && query !== '') {
date = query.split('=')[1]
}
return {
sourceContainerName: containerName,
sourceBlobName: blobName,
date: date
};
}

@@ -85,0 +94,0 @@ }

@@ -44,3 +44,6 @@ 'use strict';

COPY_ID: 'x-ms-copy-id',
COPY_STATUS_DESCRIPTION: 'x-ms-copy-status-description',
COPY_PROGRESS: 'x-ms-copy-progress',
INCREMENTAL_COPY: 'x-ms-incremental-copy',
COPY_DESTINATION_SNAPSHOT: 'x-ms-copy-destination-snapshot',
// Append Blob specific attributes

@@ -47,0 +50,0 @@ BLOB_CONDITION_MAX_SIZE: 'x-ms-blob-condition-maxsize',

@@ -62,3 +62,6 @@ 'use strict';

req.azuriteOperation = Operations.Blob.SET_BLOB_PROPERTIES;
} else if (req.headers['x-ms-copy-source'] !== undefined) {
} else if (req.query.comp === 'copy') {
req.azuriteOperation = Operations.Blob.ABORT_COPY_BLOB;
}
else if (req.headers['x-ms-copy-source'] !== undefined) {
req.azuriteOperation = Operations.Blob.COPY_BLOB;

@@ -65,0 +68,0 @@ } else {

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

blobProxy = this._createOrUpdateBlob(coll, request);
this._clearCopyMetaData(blobProxy);
return fs.outputFile(request.uri, request.body, { encoding: request.httpProps[N.CONTENT_ENCODING] })

@@ -178,3 +179,3 @@ .then(() => {

});
}
}
const coll = this.db.getCollection(request.containerName);

@@ -263,2 +264,3 @@ const blobs = coll.chain()

blobProxy.original.size = totalSize;
this._clearCopyMetaData(blobProxy);
coll.update(blobProxy.release());

@@ -313,2 +315,3 @@ resolve(new AzuriteResponse({ proxy: blobProxy }));

request.httpProps[N.CONTENT_MD5] ? blobProxy.original.md5 = request.httpProps[N.CONTENT_MD5] : request.calculateContentMd5();
this._clearCopyMetaData(blobProxy);
coll.update(blobProxy.release());

@@ -565,31 +568,42 @@ const response = new AzuriteResponse({ proxy: blobProxy });

copyBlob(request) {
const source = request.copySourceUrl();
const sourceProxy = this._getCopySourceProxy(request);
let from = null,
to = null;
// TODO: from local storage format is http://127.0.0.1:10000/devstoreaccount1/<container>/<blob>
// which is identical to external format => fix
if (source.type === 'external') {
from = req({ url: source.uri });
}
if (source.type === 'internal') {
from = fs.createReadStream(source.uri);
// TODO: if blob type is block also copy committed blocks
}
to = fs.createWriteStream(env.diskStorageUri(request));
from = fs.createReadStream(sourceProxy.original.uri);
// TODO: if blob type is block also copy committed blocks
to = fs.createWriteStream(env.diskStorageUri(request.id));
from.pipe(to);
const { coll, blobProxySource } = this._getCollectionAndBlob(request.containerName, request.blobName);
const blobProxyDestination = StorageEntityGenerator.clone(blobProxySource);
const coll = this.db.getCollection(request.containerName),
blobProxyDestination = this._createOrUpdateBlob(coll, request),
copyId = uuidv4();
blobProxyDestination.original.copyStatus = CopyStatus.PENDING;
const copyId = uuidv4();
blobProxyDestination.original.copyStatusDescription = '';
blobProxyDestination.original.copyId = copyId;
CopyOperationsManager.add(copyId, from, to, env.diskStorageUri(request));
CopyOperationsManager.add(copyId, from, to, env.diskStorageUri(request.id));
let bytesCopied = 0;
to.on('finish', () => {
if (blobProxyDestination.original.copyStatus !== CopyStatus.FAILED) {
blobProxyDestination.original.completionTime = new Date().toGMTString();
blobProxyDestination.original.copyCompletionTime = new Date().toGMTString();
blobProxyDestination.original.copyStatus = CopyStatus.SUCCESS;
if (Object.keys(request.metaProps).length > 0) {
blobProxyDestination.original.metaProps = request.metaProps;
delete blobProxyDestination.original.copyStatusDescription;
blobProxyDestination.original.copySource = sourceProxy.original.uri;
const { sourceContainerName, sourceBlobName } = request.copySourceName();
// encode blobname in case there are unicode characters which are not supported by http headers per default
blobProxyDestination.original.copySource = `http://localhost/devstoreaccount1/${sourceContainerName}/${encodeURIComponent(sourceBlobName)}`;
blobProxyDestination.original.incrementalCopy = false;
blobProxyDestination.original.size = sourceProxy.original.size;
blobProxyDestination.original.entityType = sourceProxy.original.entityType;
blobProxyDestination.original.md5 = sourceProxy.original.md5;
blobProxyDestination.original.metaProps = (Object.keys(request.metaProps).length > 0)
? request.metaProps
: sourceProxy.original.metaProps;
if (sourceProxy.original.entityType === StorageEntityType.PageBlob) {
blobProxyDestination.original.sequenceNumber = sourceProxy.original.sequenceNumber;
}
if (sourceProxy.original.entityType === StorageEntityType.AppendBlob) {
blobProxyDestination[N.BLOB_COMMITTED_BLOCK_COUNT] = sourceProxy.original[N.BLOB_COMMITTED_BLOCK_COUNT];
}
CopyOperationsManager.clear(copyId);

@@ -599,4 +613,9 @@ coll.update(blobProxyDestination.release());

});
from.on('data', (chunk) => {
bytesCopied += chunk.length;
blobProxyDestination.original.copyProgress = `${bytesCopied}/${sourceProxy.original.size}`;
});
to.on('error', (err) => {
blobProxyDestination.original.copyStatus = CopyStatus.FAILED;
blobProxyDestination.original.copyStatusDescription = err.message;
blobProxyDestination.original.completionTime = new Date().toGMTString();

@@ -611,2 +630,9 @@ CopyOperationsManager.clear(copyId);

abortCopyBlob(request) {
return CopyOperationsManager.cancel(request.copyId)
.then(() => {
return new AzuriteResponse();
});
}
_createOrUpdateBlob(coll, request) {

@@ -694,4 +720,33 @@ const blob = coll.chain().find({ 'id': { '$eq': request.id } }).data();

}
_getCopySourceProxy(request) {
// const { sourceContainerName, sourceBlobName, date } = request.copySourceName();
const resp = request.copySourceName(),
sourceContainerName = resp.sourceContainerName,
sourceBlobName = resp.sourceBlobName,
date = resp.date;
if (date !== undefined) {
const { coll, blobProxy } = this._getCollectionAndBlob(sourceContainerName, env.snapshotId(sourceContainerName, sourceBlobName, date));
if (blobProxy) {
return blobProxy;
}
}
const { coll, blobProxy } = this._getCollectionAndBlob(sourceContainerName, env.blobId(sourceContainerName, sourceBlobName));
if (blobProxy) {
return blobProxy;
}
}
_clearCopyMetaData(proxy) {
delete proxy.original.copyId;
delete proxy.original.copyStatus;
delete proxy.original.copyCompletionTime;
delete proxy.original.copyStatusDescription;
delete proxy.original.copyProgress;
delete proxy.original.copySource;
delete proxy.original.incrementalCopy;
delete proxy.original.copyDestinationSnapshot;
}
}
module.exports = new StorageManager;

@@ -6,9 +6,7 @@ 'use strict';

* Since the validation is synchronous / single-threaded we can be certain about the exact state of the entire
* application after @see ValidationContext exits.
* application before and after @see ValidationContext exits.
*
* In case a validation fails an according @see AzuriteException is thrown which is then expected
* to be processed by the responsible API Handler.
* In case a validation fails an according @see AzuriteException is thrown which is then processed
* by the validation middleware module middleware/validation.js
*
* A validation module should only need the Azurite request object and the container/blob-proxy1
*
* @class ValidationContext

@@ -15,0 +13,0 @@ */

{
"name": "azurite",
"version": "0.9.16",
"version": "0.10.0",
"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": {

@@ -186,6 +186,6 @@ # Azurite

- Copy Blob [IN-PROGRESS]
- Copy Blob [DONE]
Copies a source blob to a destination blob in this storage account or in another storage account.
- Abort Copy Blob [TODO]
- Abort Copy Blob [DONE]
Aborts a pending Copy Blob operation, and leaves a destination blob with zero length and full metadata.

@@ -192,0 +192,0 @@

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