Node.js - Simple HTTP web request for GET and POST

A simple asyncronous Node.js script for sending HTTP requests.

// Web request
const sendRequest = async function(url, opt) {
  opt = opt ? opt : {};
  const parsedUrl = require("url").parse(url);
  let headers = opt.headers ? opt.headers : {};
  headers["Content-length"] = opt.body ? opt.body.length : 0;
  const options = {
    hostname: parsedUrl.hostname,
    port: opt.port ? opt.port : (parsedUrl.port != null ? parseInt(parsedUrl.port) : (parsedUrl.protocol == "https:" ? 443 : 80)),
    path: parsedUrl.path,
    method: opt.method ? opt.method : "GET",
    headers: headers,
    timeout: typeof opt.timeout == "number" ? opt.timeout : 30000
  };
  let response = await new Promise(function(res, err) {
    let completed = false;
    let request = require(parsedUrl.protocol == "https:" ? "https" : "http").request(options, function(response) {
      let responseText = [];
      response.on("data", function(d) {
        responseText.push(d);
      });
      response.on("end", function() {
        completed = true;
        response.responseText = Buffer.concat(responseText);
        if (!opt.buffer) {
          response.responseText = response.responseText.toString("utf-8");
        }
        res(response);
      });
    });
    request.on("error", function(error) {
      completed = true;
      if (!opt.silent) {
        console.error(`sendRequest Error: ${error.message}`);
      }
      err(error);
    });
    request.write(opt.body ? opt.body : "");
    request.end();
    if (options.timeout > 0) {
      setTimeout(function() {
        if (completed) {
          return;
        }
        request.destroy(new Error(`Timed out (${options.timeout} ms).`));
      }, options.timeout);
    }
  });
  if (response.statusCode == 301 || response.statusCode == 302) {
    let redirectUrl;
    const locationParsed = require("url").parse(response.headers.location);
    if (response.headers.location) {
      if (locationParsed.protocol && locationParsed.host) {
        redirectUrl = locationParsed.href;
      } else if (locationParsed.path) {
        if (locationParsed.path[0] == "/") {
          redirectUrl = `${parsedUrl.protocol}//${parsedUrl.host}${locationParsed.path}`;
        } else {
          redirectUrl = `${parsedUrl.protocol}//${parsedUrl.host}${parsedUrl.path.replace(/^([^?]*\/).*$/,"$1")}${locationParsed.path}`;
        }
      } else {
        throw new Error(`Redirect location header invalid: ${response.headers.location}`);
      }
    } else {
      throw new Error(`Redirect location header missing: ${response.headers.location}`);
    }
    const newOpt = {...JSON.parse(JSON.stringify(opt)),...{method: "GET"}};
    delete newOpt.body;
    return await sendRequest(redirectUrl, newOpt);
  }
  return response;
};

Simple use within an async function.

(async function() {
  
  const res = await sendRequest("https://example.com");
  
  console.log(res.responseText);
  
})();

More options.

(async function() {
  
  const res = await sendRequest("http://example.com", {
    headers: {
      Key: "Value"
    },
    port: 8000,
    method: "POST",
    body: "Some payload"
  });
  
  console.log(res.responseText);
  
})();