3
\$\begingroup\$

api.js

'use strict';
const http = require('http');

module.exports = url => {
  const options = {
    host: url,
    method: 'HEAD',
    path: '/'
  };
  const req = http.request(options);
  req.end();
  const promise = new Promise((resolve, reject) => {
    let connected = false;
    req.on('response', res => {
      connected = res.statusCode < 500;
      resolve(connected);
    });

    req.on('error', err => {
      reject(err);
    });
  });
  return promise;
};

The most confusing part for me is which status codes should be considered a valid candidate? apart from that any comments regarding code are welcome.

\$\endgroup\$
  • \$\begingroup\$ My proxy answers 403 for non existing sites such as shbrtze.com \$\endgroup\$ – Bruno Costa Jul 15 '16 at 10:30
  • \$\begingroup\$ It seems that my code is throwing error for unavailable sites too instead this should be transparent to the client and should get false instead. \$\endgroup\$ – CodeYogi Jul 15 '16 at 11:20
4
\$\begingroup\$

When the server does not exists it seems node throws an EIO error.

Now you need to make a decision, you can either reject the promise or resolve with false. From an usage point of view I would say I would prefer to resolve it false unless I need to know why the server is unavailable.

I am assuming that you just want to know if it is available or not, thus it doesn't make sense to reject the promise ever.

Your module also doesn't support Urls, in the form of

scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]

In order to support that you must parse the parameter with the existing URL module.

In order to support both the URL and the URN you can check if the protocol was specified

var http = require('http');
var url = require("url");
var Promise = require('promise');

module.exports = function (uri) {
  var address = url.parse(uri); 
  var parts = uri.split('/');
  var options = {
    host: address.protocol != null ? address.host : parts[0],
    method: 'HEAD',
    path: address.protocol != null ? address.pathname : parts.slice(1).join('/')
  };
  var req = http.request(options);
  req.end();
  var promise = new Promise(function (resolve, reject) {
    var connected = false;
    req.on('response', function (res) {
      connected = res.statusCode < 500;
      resolve(connected);
    });

    req.on('error', function (err) {
      resolve(false);
    });
  });
  return promise;
};

module.exports("http://httpstat.us/200").then(function(isAvailable){
    console.log(isAvailable);
});
\$\endgroup\$
  • \$\begingroup\$ LGTM, but I want that the user can type httpstat.us and still get the result, while using url module its not possible(I tried that), wdyt? \$\endgroup\$ – CodeYogi Jul 15 '16 at 14:50
  • \$\begingroup\$ @CodeYogi FML that is what I think, I wish that urlwould support that, but I guess they didn't support because the scheme/protocol is not specified. Look at the edited answer \$\endgroup\$ – Bruno Costa Jul 15 '16 at 15:17
  • \$\begingroup\$ What if no url is provided? and is 500 status check is enough? \$\endgroup\$ – CodeYogi Jul 15 '16 at 15:30
  • \$\begingroup\$ @CodeYogi Seems that the promise is rejected as expected (with empty string) and even with my proxy it seems there still was a request to a DNS check that resulted in the EIO error. So it seems status codes < 500 are enough. \$\endgroup\$ – Bruno Costa Jul 15 '16 at 15:56
  • \$\begingroup\$ IMHO I think its better to raise error if url is not present rather than let it fail silently, here is the [repo ](github.com/vivekimsit/is-site-up) which is online now, feel free to make any changes there. \$\endgroup\$ – CodeYogi Jul 15 '16 at 18:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.