3

With nodejs, I am using the following code to connect to a camera via digest auth and download the image data.

var request = require('request')

var options = {
    'url': uri,
    'auth': {
        'user': user,
        'pass': pass,
        'sendImmediately': false
    }
};

var request = request.get(options, function (error, response, body) {
    if (!error && response.statusCode == 200) {

        console.log('response :>> ', response);
        const filename = "picture.jpg"
        // const fileContents = Buffer.from(resp.body._readableState.buffer.head, 'base64')
        const fileContents = Buffer.from(body)
        // fs.writeFile(filename, fileContents, (err) => {
        fs.writeFileSync(filename, fileContents, (err) => {
            if (err) return console.error(err)
            console.log('file saved to ', filename)
            return body
        })
    }
    else {
        console.log('Code : ' + response.statusCode)
        console.log('error : ' + error)
        console.log('body : ' + body)
    }
});

This creates a ~360kb file or so -- roughly 2x the expected size of the image when downloaded via a browser. It also does not open in an image editing software or anything -- it's not creating a valid jpg.

When writing the body to the console, it looks like a bunch of this: Console output

I'm unsure how to turn this data into an image file that I can write to the filesystem. Help?

Update: I have changed the buffer.from to try 'binary', 'utf-8', 'utf8', 'base64url' and 'base64'... to no avail.

The response does come back with a content type of 'image/jpeg; charset="UTF-8"' but the created file is still invalid.

Update #2: This question: nodejs convert image between buffer and string taught me that once a jpg gets sent to UTF8, you can't go back to a valid jpg.... so then I started wondering if I could request in a different encoding. Turns out, Request allows an optional encoding parameter. (sad to see it's deprecated needlessly... but with 20 million a week downloading it, I don't think it's going anywhere)

So changing my options to:

var options = {
    'url': uri,
    'encoding': 'binary',
    'auth': {
        'user': user,
        'pass': pass,
        'sendImmediately': false
    }
};

and my buffer creation to this: const fileContents = Buffer.from(body, 'binary')

matched everything up.

lowcrawler
  • 6,777
  • 9
  • 37
  • 79
  • 1
    Does this question help? https://stackoverflow.com/questions/43487543/writing-binary-data-using-node-js-fs-writefile-to-create-an-image-file – sean-7777 Mar 23 '22 at 22:51
  • The problem is I'm not getting a normal string I can 'strip off the front' of like in the accepted answer. I'm not starting with 'plain text'. I'll re-read to ensure I'm not missing something from that question. – lowcrawler Mar 23 '22 at 22:54
  • Maybe just use `Buffer.from` directly? `fs.writeFile('pic.jpeg', Buffer.from(img_data, "img_type_here"));` – sean-7777 Mar 23 '22 at 22:57
  • Also, the image will not render in terminal. Try opening the actual file. – sean-7777 Mar 23 '22 at 22:58
  • Note the post above - I'm trying to save the file so I can open it. With the given code, it creates an invalid file. – lowcrawler Mar 23 '22 at 23:38
  • The first question that comes to my mind is: which picture format does the URL provide? That's all that really matters... If the server behind the URL you are requesting provides data in png format encoded in base64, there is no point in trying to decode it any other way. So, do you have the specs of the output data? – Ben Mar 24 '22 at 08:23

1 Answers1

0

Hell of a coaster ride. Thanks, Man. @lowcrawler

I had to save the REST API response into a vRO package file using nodejs, which I just couldn't right, making me scratch my head badly. But after reading your comment and hit and trail, I made it finally. Thanks again.

var request = require('request');
var fs = require('fs');
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;
var options = {
  'method': 'GET',
  'encoding': 'binary',
  'url': 'https://vro_fqdn/vco/api/packages/gitlab_vro_credential_store_confs?exportConfigurationAttributeValues=true&exportGlobalTags=true&exportVersionHistory=true&exportConfigSecureStringAttributeValues=false&allowedOperations=vef&exportExtensionData=false',
  'headers': {
    'Accept': 'application/zip',
    'Authorization': 'Basic eDIxMzxxxxxxxxxxxx5sb2NhbDpBdWcjMjAyMw=='
  }
};
request(options, function (error, response, body) {
  if (error) throw new Error(error);
  console.log(response.body);
  fs.writeFile("packageName.package",  Buffer.from(body, 'binary'), function(err){
    if (err) throw err;
    console.log("success");
    });
});