Last active
October 14, 2018 09:53
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'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