Skip to content

Instantly share code, notes, and snippets.

@DonMartin76
Last active October 14, 2018 09:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DonMartin76/4bae63c886c8dc2dbf2d1c09ac92d8d0 to your computer and use it in GitHub Desktop.
Save DonMartin76/4bae63c886c8dc2dbf2d1c09ac92d8d0 to your computer and use it in GitHub Desktop.
Snippet in node.js to download a file from an Azure Files SMB Share using the REST API
'use strict';
// Uses request: npm install --save request
const request = require('request');
const fs = require('fs');
const crypto = require('crypto');
const dummyLog = function (s) {
console.log(s);
}
const debug = dummyLog, info = dummyLog, error = dummyLog;
const x_ms_version = '2018-03-28';
function downloadFromStorage(storageName, storageKey, shareName, filePath, outFilePath, callback) {
debug(`downloadFromStorage(${shareName}, ${filePath})`);
const mediaPath = `${shareName}${filePath}`;
const mediaUri = `https://${storageName}.file.core.windows.net/${mediaPath}`;
const x_ms_date = (new Date()).toUTCString();
const canonicalizedResource = `/${storageName}/${mediaPath}`;
const headers = {
'x-ms-date': x_ms_date,
'x-ms-version': x_ms_version
};
const canonicalizedHeaders = makeCanonicalizedHeaders(headers);
// SharedKeyLite
const stringToSign = `GET\n\n\n\n${canonicalizedHeaders}${canonicalizedResource}`;
debug(stringToSign);
const secret = Buffer.from(storageKey, 'base64');
const hmac256 = crypto.createHmac('sha256', secret);
hmac256.update(stringToSign, 'utf-8');
const sig = hmac256.digest('base64');
headers.Authorization = `SharedKeyLite ${storageName}:${sig}`;
request.get({
uri: mediaUri,
headers: headers
})
.on('response', function (res) {
debug(`GET ${mediaPath} responding with ${res.statusCode}, Content-Type ${res.headers['content-type']}`);
if (res.statusCode === 200) {
res.pipe(fs.createWriteStream(outFilePath))
.on('finish', function () {
info(`Downloaded ${mediaPath} on the fly.`);
return callback(null);
});
} else {
return callback(makeError(res.statusCode, `Could not download ${mediaPath} (status code ${res.statusCode})`));
}
})
.on('error', function (err) {
error(err);
return callback(makeError(500, `An error occurred while downloading ${mediaPath}`));
});
}
function makeCanonicalizedHeaders(headers) {
let first = true;
let c = '';
for (let h in headers) {
if (!h.startsWith('x-ms-'))
continue;
c += `${h}:${headers[h]}\n`;
}
return c;
}
function makeError(status, message, innerError) {
const err = new Error(message);
err.status = status;
if (innerError)
err.innerError = innerError;
return err;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment