I wish to upload files in the form of a stream into Azure Storage but I don’t want to use Azure SDK
instead I want to do it in a more generic way using REST API
and not BlobServiceClient
.
Is there a way to do so? The reference links for the same can be found here:
But the links mentioned here propose a solution using Azure SDK
. I want to do it without Azure SDK
Here’s the code:
const CryptoJS = require("crypto-js"); const request = require("request"); const fs = require("fs"); const account = process.env.ACCOUNT_NAME || ""; const key = process.env.ACCOUNT_KEY || ""; const containerName = "demo"; const blobName = "dummyfile.txt"; var strTime = new Date().toUTCString(); // read file to Stream var filePath = `${__dirname}/README.md`; const readStream = fs.createReadStream(filePath); var stat = fs.statSync(filePath); string_params = { verb: "PUT", "Content-Encoding": "", "Content-Language": "", "Content-Length": stat.size, "Content-MD5": "", "Content-Type": "application/octet-stream", Date: "", "If-Modified-Since": "", "If-Match": "", "If-None-Match": "", "If-Unmodified-Since": "", Range: "", CanonicalizedHeaders: "x-ms-blob-type:BlockBlobnx-ms-date:" + strTime + "nx-ms-version:" + "2020-04-08n", CanonicalizedResource: `/${account}/${containerName}/${blobName}`, }; var strToSign = `${string_params["verb"]}n${string_params["Content-Encoding"]}n${string_params["Content-Language"]}n${string_params["Content-Length"]}n${string_params["Content-MD5"]}n${string_params["Content-Type"]}n${string_params["Date"]}n${string_params["If-Modified-Since"]}n${string_params["If-Match"]}n${string_params["If-None-Match"]}n${string_params["If-Unmodified-Since"]}n${string_params["Range"]}n${string_params["CanonicalizedHeaders"]}${string_params["CanonicalizedResource"]}`; var secret = CryptoJS.enc.Base64.parse(key); var hash = CryptoJS.HmacSHA256(strToSign, secret); var hashInBase64 = CryptoJS.enc.Base64.stringify(hash); var auth = `SharedKey ${account}:` + hashInBase64; const options = { url: `https://${account}.blob.core.windows.net/${containerName}/${blobName}`, headers: { Authorization: auth, "x-ms-blob-type": "BlockBlob", "x-ms-date": strTime, "x-ms-version": "2020-04-08", "Content-Type": "application/octet-stream", "Content-Length": stat.size, }, body: readStream, }; function callback(error, response, body) { console.log(response.statusCode); console.log(response.statusMessage); if (!error && response.statusCode == 200) { console.log(error); console.log(response); console.log(body); } } request.put(options, callback);
The error which I am getting is:
TypeError: Cannot read property 'statusCode' of undefined
Edit: The problem was solved by Pamela’s code + the issue I found was there’s was an error in initializing .env
variables.
Answer
You could use Put Blob Rest API to upload a stream. There is a sample using node.js.
const CryptoJS = require("crypto-js"); const request = require("request"); const fs = require('fs'); const account = "account-name"; const key = "account-key"; var strTime = new Date().toUTCString(); var filePath = 'your-file-path'; const readStream = fs.createReadStream(filePath); var stat = fs.statSync(filePath); string_params = { 'verb': 'PUT', 'Content-Encoding': '', 'Content-Language': '', 'Content-Length': stat.size, 'Content-MD5': '', 'Content-Type': 'application/octet-stream', 'Date': '', 'If-Modified-Since': '', 'If-Match': '', 'If-None-Match': '', 'If-Unmodified-Since': '', 'Range': '', 'CanonicalizedHeaders': 'x-ms-blob-type:BlockBlobnx-ms-date:' + strTime + 'nx-ms-version:' + '2020-04-08n', 'CanonicalizedResource': `/${account}/containername/myblob` } var strToSign = `${string_params['verb']}n${string_params['Content-Encoding']}n${string_params['Content-Language']}n${string_params['Content-Length']}n${string_params['Content-MD5']}n${string_params['Content-Type']}n${string_params['Date']}n${string_params['If-Modified-Since']}n${string_params['If-Match']}n${string_params['If-None-Match']}n${string_params['If-Unmodified-Since']}n${string_params['Range']}n${string_params['CanonicalizedHeaders']}${string_params['CanonicalizedResource']}` console.log(strToSign); var secret = CryptoJS.enc.Base64.parse(key); var hash = CryptoJS.HmacSHA256(strToSign, secret); var hashInBase64 = CryptoJS.enc.Base64.stringify(hash); var auth = `SharedKey ${account}:` + hashInBase64; console.log(auth) const options = { url: `https://${account}.blob.core.windows.net/containername/myblob`, headers: { Authorization: auth, 'x-ms-blob-type': 'BlockBlob', "x-ms-date": strTime, "x-ms-version": "2020-04-08", 'Content-Type': "application/octet-stream", 'Content-Length': stat.size }, body: readStream }; function callback(error, response, body) { console.log(response.statusCode); console.log(response.statusMessage); if (!error && response.statusCode == 200) { console.log(error); console.log(response); console.log(body); } } request.put(options, callback);