docs: function get(address, contentType, redirs = 0, tries = 0) {
      return new Promise((fulfill, reject) => {
          const { host, path } = url.parse(address);
          const options = {
              headers: { 'User-Agent': 'peerio-updater/1.0' },
              timeout: REQUEST_TIMEOUT,
              host,
              path
          };
          const req = https.get(options, res => {
              if (res.statusCode === 404) {
                  reject(new Error(`Not found: ${address}`));
                  return;
              }
              if (res.statusCode >= 300 && res.statusCode < 400 && res.headers['location']) {
                  res.resume();
                  if (redirs >= MAX_REDIRECTS) {
                      reject(new Error('Too many redirects'));
                      return;
                  }
                  let location = res.headers['location']; // always string according to Node docs
                  if (!/^https?:/.test(location)) {
                      location = url.resolve(address, location);
                  }
                  if (!location.startsWith('https:')) {
                      reject(new Error(`Unsafe redirect to ${location}`));
                      return;
                  }
                  fulfill(get(location, contentType, redirs + 1, tries));
                  return;
              }
              if (res.statusCode !== 200) {
                  res.resume();
                  if (tries < MAX_RETRIES) {
                      fulfill(waitBeforeRetry(tries).then(() =>
                          get(address, contentType, 0, tries + 1))
                      );
                  } else {
                      reject(new Error(`Request failed with status ${res.statusCode}`));
                  }
                  return;
              }
              if (contentType) {
                  let got = res.headers['content-type'] || '';
                  // Strip anything after ';' (e.g. application/json; charset=utf8)
                  const semicolon = got.indexOf(';')
                  if (semicolon >= 0) got = got.substring(0, semicolon);
                  if (contentType !== got) {
                      res.resume();
                      reject(new Error(`Unexpected content type: ${got}`));
                      return;
                  }
              }
              fulfill(res);
          });
  
          const handleError = err => {
              if (tries < MAX_RETRIES) {
                  fulfill(waitBeforeRetry(tries).then(() =>
                      get(address, contentType, 0, tries + 1))
                  );
              } else {
                  reject(new Error(`Request failed: ${err.message}`));
              }
          };
  
          req.on('error', handleError);
          req.on('timeout', () => {
              req.abort();
              handleError(new Error('Request timed out'));
          });
      });
  }