0

I'm trying to upload images from a url to the server safely.

var http = require('http');
var fs = require('fs');
var path = require('path')

var download = function(url, dest, filename, cb) {
    var file = fs.createWriteStream(dest + "/" + filename + path.extname(url));

    var request = http.get(url, function(response) {
        response.pipe(file);
        file.on('error', function(err) {
            console.log(err.message);
            file.end();
        });
        file.on('finish', function() {
            file.close(cb);
        });
    }).on('error', function(err) { // Handle errors
        fs.unlink(dest);
        if (cb) cb(err.message);
    });
}

var url = "https://vignette.wikia.nocookie.net/spongebob/images/d/d7/SpongeBob_stock_art.png";

download(url, 'downloadedAssets/imgs', 'spongebob', function onComplete(err) {
    if (err) {
        console.log(err.message);
    } else {
        console.log('image uploaded to server');
    }
});

Which crashes the server

TypeError [ERR_INVALID_PROTOCOL]: Protocol "https:" not supported. Expected "http:"

I understand I can't upload https files, but why does it crash the server instead of executing file.on('error') then ending the file.

I also tried try/catch and same thing

2 Answers 2

2

It crashes at http.get(url,function(){..}) because you are using http module. You need to use https module to do the get request to a https url.

const https = require('https');

https.get('https://encrypted.google.com/', (res) => {
  console.log('statusCode:', res.statusCode);
  console.log('headers:', res.headers);

  res.on('data', (d) => {
    process.stdout.write(d);
  });

}).on('error', (e) => {
  console.error(e);
});

You can use request module which support both http and https. From the doc:

Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.const request = require('request');

const options = {
  url: 'https://api.github.com/repos/request/request',
  headers: {
    'User-Agent': 'request'
  }
};

function callback(error, response, body) {
  if (!error && response.statusCode == 200) {
    const info = JSON.parse(body);
    console.log(info.stargazers_count + " Stars");
    console.log(info.forks_count + " Forks");
  }
}

request(options, callback);

Or to use Promises out of the box, use axios.

Sign up to request clarification or add additional context in comments.

1 Comment

ohh I see. Thanks! What if I want the user to be able to upload both http and https. Should I just rewrite the .get call for each of them, or is there a more efficient way to do that?
1

fs.createWriteStream is working absolutely fine so it is not throwing exceptions or errors.

The error is coming from http.get() method because you are trying to access 'https' using http module. Put debugger in http.get() module, you will definitely get error thrown.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.