0

Using the standard request module, we can run the following script to check a file's MIME type;

var request = require('request');
var url = "http://www.somedomain.com/somepicture.jpg";
var magic = {
    jpg: 'ffd8ffe0',
    png: '89504e47',
    gif: '47494638'
};
var options = {
    method: 'GET',
    url: url,
    encoding: null // keeps the body as buffer
};

request(options, function (err, response, body) {
    if(!err && response.statusCode == 200){
        var magicNumberInBody = body.toString('hex',0,4);
        if (magicNumberInBody == magic.jpg || 
            magicNumberInBody == magic.png ||
            magicNumberInBody == magic.gif) {
            console.log("It's an image!");
            return true;
        }
    }
});

Which is pretty self-explanatory. However, when working with node.js and relying on Promises, how can we carry out the above? I've attempted to install and use request-promise, and wrote up the following script;

return rp("http://www.somedomain.com/somepicture.jpg")
            .then((response) => {
                var magicNumberInBody = response.toString('hex',0,4);
                console.log(magicNumberInBody);
                if (magicNumberInBody == magic.jpg ||
                    magicNumberInBody == magic.png ||
                    magicNumberInBody == magic.gif) {
                    console.log("It's an image!");
                    return true;
                }

However, for anything that's not html/txt based, request-promise seems to just return with the raw binary.

Would anyone know how I can change the above data into something meaningful, which I can easily use to identify if the MIME type is jpg/png/gif?

Eoghan
  • 1,720
  • 2
  • 17
  • 35

2 Answers2

2

You have to use the resolveWithFullResponse option:

rp({
  uri: "http://www.somedomain.com/somepicture.jpg",
  resolveWithFullResponse: true
}).then(res => {
  console.log(res.headers['content-type'])
})
martriay
  • 5,632
  • 3
  • 29
  • 39
  • Thanks, I've gotten more usable data from this, but still no way to run the actual above script. res.headers['content-type'] just returns back with "content-type': 'application/octet-stream" for images. I need to view the actual MIME type. – Eoghan Aug 17 '16 at 21:23
  • sorry bud, that's a whole other problem and you can't do much about it, see: https://stackoverflow.com/questions/9707204/how-handling-images-mime-type-application-octet-stream – martriay Aug 17 '16 at 22:50
0

I do a head request first

      // Download
      return Image._head($, $(image).attr('src'))
        .then((filename) => {
          return Image._download($, filename)
        })
        .then((code) => {
          return $
        })


  // Request
  Request.head(options)
    .then((data) => {
      console.log(data)
      // Get the content type
      // const type = data['content-type']
      // let ext = ''

      // // Extract extension
      // if (type === 'image/jpeg' || type === 'image/pjpeg') {
      //   ext = 'jpg'
      // } else if (type === 'image/png') {
      //   ext = 'png'
      // } else if (type === 'image/gif') {
      //   ext = 'gif'
      // }

      // Get filename
      let filename = null
      const disposition = data['content-disposition']

      if (disposition && disposition.indexOf('inline') !== -1) {
        var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
        var matches = filenameRegex.exec(disposition)
        if (matches != null && matches[1]) {
          filename = matches[1].replace(/['"]/g, '')
        }
      }

      // Path
      // const path = Path.join('./resources/images', `${filename}`)

      // console.log('content-type:', data.headers['content-type'])
      // console.log('content-length:', data.headers['content-length'])
      // console.log('content-disposition:', data.headers['content-disposition'])
      console.log('filename:', filename)

      // resolve(data.html)
      resolve(filename)
    })
    .catch((error) => {
      resolve(new Error(`${error} - Instagram - ${src}`))
    })

Then another request to actually download the file.

Hope this helps in some way

Ian Warner
  • 1,058
  • 13
  • 32