Giter Site home page Giter Site logo

sindresorhus / is-online Goto Github PK

View Code? Open in Web Editor NEW
1.2K 25.0 90.0 89 KB

Check if the internet connection is up

License: MIT License

JavaScript 91.87% TypeScript 8.13%
internet internet-connection nodejs javascript browser connectivity detect network online ping

is-online's Introduction

is-online

Check if the internet connection is up

Works in Node.js and the browser (with a bundler).

In the browser, there is already navigator.onLine, but it's useless as it only tells you if there's a local connection, and not whether the internet is accessible.

Install

npm install is-online

Usage

import isOnline from 'is-online';

console.log(await isOnline());
//=> true

API

isOnline(options?)

options

Type: object

timeout

Type: number
Default: 5000

Milliseconds to wait for a server to respond.

ipVersion

Type: number
Values: 4 | 6
Default: 4

The Internet Protocol version to use.

This is an advanced option that is usually not necessary to be set, but it can prove useful to specifically assert IPv6 connectivity.

How it works

The following checks are run in parallel:

  • Retrieve icanhazip.com (or ipify.org as fallback) via HTTPS.
  • Query myip.opendns.com and o-o.myaddr.l.google.com DNS entries. (Node.js only)
  • Retrieve Apple's Captive Portal test page (this is what iOS does). (Node.js only)

When any check succeeds, the returned Promise is resolved to true.

Proxy support

To make it work through proxies, you need to set up global-agent.

Maintainers

Related

is-online's People

Contributors

bendingbender avatar coclauso avatar johno avatar kevva avatar moox avatar nuno-morais avatar richienb avatar schneiderl avatar silverwind avatar sindresorhus avatar yupkey avatar zce avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

is-online's Issues

Improve accuracy - node version

Instead of trying to resolve common domain names, I'd suggest instead opening a socket to domain:80 and check if the handshake completes. This should be more reliable in a network with an local caching DNS server, where your main internet line could go down while you still receive correct DNS answers.

Alternatively, if you like to keep using DNS, I'd recommend resolving the root zone recursively for a more reliable check. Something equivalent to dig +trace NS should do, thought I don't think node's dns does support recursive queries yet.

Watch when is online or offline

Is there a watcher that I can use when the connection is down or up? I thought it would be good to ask you before implementing the setTimeout() to manually send request on every second.

Pseudo-sync approach?

Beforehand I'd like to thank you for the package.

My all huge code doesn't make any sense without Internet, thus I just exit if there is no internet.
I understand that the paradigm of nodejs is all async, but do I really need to insert all my code into the enclosure of then ?

I'm not that versed on promises but this approach is not working

const isOnline = require('is-online');
let online = await isOnline();
console.log(online);
var online = await isOnline();
                   ^^^^^^^^

SyntaxError: Unexpected identifier
    at createScript (vm.js:74:10)
    at Object.runInThisContext (vm.js:116:10)
    at Module._compile (module.js:533:28)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Function.Module.runMain (module.js:605:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:575:3

My node version: v8.0.0

Thank you

Import using Webpack

I am trying to import isOnline and unable to do so.
I am trying the following:
import { isOnline } from 'is-online';
Am i missing anything?

IPv6 support for the DNS lookup

The node version currently only tries to contact the root servers over IPv4. It would be nice if IPv6 would be used as a fallback if IPv4 is unavailable.

roots("AAAA") can be used to retrieve an array of IPv6 addresses of the root servers. Unfortunately, I don't have pure IPv6 available from my ISP, so I can't test reliably.

Problem using is-online behind a proxy

Our app is using is-online and is running behind a http proxy.
It seems that the request that calls Apple captive portal is done directly on internet and not through the proxy so the request fails.
Do you confirm that is-online can not be used behind a proxy ?

is there a support to determine whether the network connection changed?

Hi,
Is there any support to test whether the network connection changed.

Lets say i am connected to a wired connection and change my connection to wifi. Is there a way to detect it.

I know Chrome has navigator.connection.onchange but is there a cross browser and platform (mobile browsers) solution ?

Thanks.

Timeout of 1000ms seems too low

I get intermittent false from isOnline even though I'm online through my WIFI.

After debugging, the culprit was the global timeout of 1000ms which seems kind of low, especially for unreliable connections such as wireless ones. Perhaps make this higher or customizable?

npm tarball missing index.js for version 5.1.0

When I npm install version 5.1.0, it is missing the index.js file. The file is there in version 5.0.1

➜  tmp  npm install [email protected]                                                                                                                                          [19:52:17]
[email protected] node_modules/is-online
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected])
➜  tmp  ls node_modules/is-online                                                                                                                                            [19:52:20]
browser.js    hostnames.js  license       node_modules/ package.json  readme.md
➜  tmp  npm install [email protected]                                                                                                                                          [19:51:39]
[email protected] node_modules/is-online
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected] ([email protected], [email protected], [email protected], [email protected], [email protected])
➜  tmp  ls node_modules/is-online                                                                                                                                            [19:51:51]
browser.js    hostnames.js  index.js      license       node_modules/ package.json  readme.md

DNS resolutions overflow UV pool

Issuehunt badges

I found situation when using is-online gives negative consequences on my system.

Preconditions

  • your network is offline
  • you use is-online periodically by timer

What will happen

is-online uses domain name for network checking, it means DNS resolution will be done first. Since network is actually offline, DNS resolution is becoming very long operation, which will block thread of UV pool. Since we run it on regular basis (in my case I ran it every 5 seconds), your UV pool overflows after some time. By default UV pool size is 4.
After UV pool is overflown, all UV operations will be queued (like fs.* functions), which may cause significant delays of their execution. In my case after 20 minutes of operation, queue increased to 50-70 operations, which gave me almost never ending new operations (like fs.readFile or any other).

I'd suggest avoid DNS resolution here (in my project I implemented 8.8.8.8:53 connection instead) or cancel DNS resolution requests when timeout happens.

Information about UV pool can be found here
https://www.future-processing.pl/blog/on-problems-with-threads-in-node-js/


IssueHunt Summary

lukks lukks has been rewarded.

Backers (Total: $30.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

onetime called multiple times

In index.js from line 56, on connect cb(null, true) is called, the socket is closed and next is called with an error, which leads (if i understood it correctly) to the call of cb(null, false).
Since in line 17 cb = onetime(cb) is called we get two calls of onetime which leads to an error.

socket.connect(80, domain, function () {
                    cb(null, true);
                    socket.end();
                    next(new Error()); // skip to end
                });
            }, function () {
                cb(null, false);
            });

Over Corporate Proxy

Iam behind proxy corporative.
I can use npm for install package fine using proxy corporate.

but when i run:

is-online

return

Offline

Some idea?

[package.json tags] - consider adding "no" to the tags list

I searched for "no internet" among packages and this package didn't turn up in the npm search results. There is keyword "internet" in package.json but there is not keyword "no". Please consider adding keyword "no" to package.json tags list. Maybe it will help others to find this package.

verison ^6.0.0 doesnt seem to resolve the promise it gives

i noticed my code broke after updating to 6.0.0, turns out 5.2.0 works fine,
6.0.0 and newer never resolve the promise it now throws "Error: Not running"

# node
> let i = require( './' )
undefined
> i( {}, function(err,status){
... console.log( err, status )
... })
Promise { <pending> }
> Error: Not running
    at Socket._healthCheck (dgram.js:527:11)
    at Socket.close (dgram.js:421:8)
    at Timeout.setTimeout [as _onTimeout] (C:\Software\Clerk Systems\updater\node_modules\is-online\index.js:48:15)
    at ontimeout (timers.js:365:14)
    at tryOnTimeout (timers.js:237:5)
    at Timer.listOnTimeout (timers.js:207:5)
>

Setting different hostnames

I am trying to pass hostnames to isOnline(), using isOnline({hostnames: ["http://www.google.com"]}), but it is always using the hostnames listed on hostnames.js file, ignoring the hostnames I passed when call isOnline()

I am using it on electron too, so I need to pass hostnames as options to be able to use http or https on requests that check internet, because without this the lib automatically does the requests using file://

Cancel outstanding HTTP requests on DNS success

Issuehunt badges

Adding this issue here so we don't forget about it.

Details in #39 (comment), it' currently blocked by sindresorhus/got#274.


IssueHunt Summary

lukks lukks has been rewarded.

Backers (Total: $40.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

running tests fails

somehow the tests wont start

# npm i
# npm test

> [email protected] test C:\<somedir>\is-online
> xo && ava test.js


  1 exception

  × Couldn't find any files to test

npm ERR! Test failed.  See above for more details.

I'm getting 'undefined'

I have a electron app where I'm trying to check if a connection is availible. I've done it like in your readme but the console logs always undefined.
I have also tried your is-reachable with the google example, but same result.

Repeat until success

Hi, i need a little help with this.

I am doing it this way:

isOnline(function(err, online){
    console.log(online);
    if( online )
        initPage()
});

I turn off my connection and run the program, I turn it back on half way through. And it returns this:

[4640:1128/234236:WARNING:dns_config_service_win.cc(653)] Failed to read DnsConfig.
[4640:1128/234237:INFO:CONSOLE(449)] ""false"", source: file:///C:/Alpha/js/common.js (449)
[4640:1128/234241:WARNING:dns_config_service_win.cc(653)] Failed to read DnsConfig.
[4640:1128/234246:WARNING:dns_config_service_win.cc(653)] Failed to read DnsConfig.
[4640:1128/234251:WARNING:dns_config_service_win.cc(653)] Failed to read DnsConfig.
[4640:1128/234256:WARNING:dns_config_service_win.cc(653)] Failed to read DnsConfig.
[4640:1128/234301:WARNING:dns_config_service_win.cc(653)] Failed to read DnsConfig.
[4640:1128/234306:WARNING:dns_config_service_win.cc(653)] Failed to read DnsConfig.
[4640:1128/234311:WARNING:dns_config_service_win.cc(653)] Failed to read DnsConfig.
[4640:1128/234316:WARNING:dns_config_service_win.cc(653)] Failed to read DnsConfig.
[4640:1128/234321:WARNING:dns_config_service_win.cc(653)] Failed to read DnsConfig.
[Finished in 47.6s]

And I close the program.

So my question is: does the script keep trying to get a connection or should i do it? Because it only returned the status once.

native-dns throwing when offline

Try turning off your connection then running the tests or the binary.

/Users/sindresorhus/dev/is-online/node_modules/native-dns/lib/platform.js:166
      throw err;
            ^
Error: ENOENT, open '/etc/resolv.conf'

@silverwind This kinda looks like a native-dns bug. Thoughts?

DoD root server timing out

Not sure if there is anything to do about this, but I'm getting false negatives because the Department of Defense root server always times out. Not sure if this is unique to my location or network setup, but I thought it was worth mentioning. Maybe add an option to specify the root server for more consistency?

Traceroute output

192.112.36.4 is from United States (US) in region North America
Input: g.root-servers.net
canonical name: g.root-servers.net
Registered Domain: root-servers.net

TraceRoute from Network-Tools.com to 192.112.36.4 [g.root-servers.net]
Hop (ms)    (ms)    (ms)             IP Address Host name
1     0       0       0          206.123.64.217   -  
2     0       0       0          64.124.196.225  xe-4-2-0.er2.dfw2.us.above.net  
3     1       1       1          64.125.13.210    -  
4     6       6       6          67.14.13.218    iah-edge-18.inet.qwest.net  
5     10      10      10         63.158.243.46   63-158-243-46.dia.static.qwest.net  
6     Timed out       Timed out       Timed out               -  
7     Timed out       Timed out       Timed out               -  
8     Timed out       Timed out       Timed out               -  
9     Timed out       Timed out       Timed out               -  
10    Timed out       Timed out       Timed out               -  
11    Timed out       Timed out       Timed out               -  
12    Timed out       Timed out       Timed out               -  
13    Timed out       Timed out       Timed out               -  
14    Timed out       Timed out       Timed out               -  
15    Timed out       Timed out       Timed out               -  
16    Timed out       Timed out       Timed out               -  
17    Timed out       Timed out       Timed out               -  
18    Timed out       Timed out       Timed out               -  
19    Timed out       Timed out       Timed out               -  
Trace aborted.

Incompatibility with create-react-app

This is followup to PR sindresorhus/ip-regex#12

sindresorhus/ip-regex is in dependency chain of this package
sindresorhus/public-ip > sindresorhus/is-ip > sindresorhus/ip-regex

In PR you wrote that this sindresorhus/ip-regex is targeted for node (which i totally understand) and same probably goes for sindresorhus/is-ip, but this package and sindresorhus/public-ip are targeted also for browser.

Right now you can't use this package or sindresorhus/public-ip in scenario with webpack + uglifyjs without explicitly setting up babel for this modules or using babel-engine-plugin like you suggested in PR.

Problem is when you have React app build using https://github.com/facebookincubator/create-react-app
where by default you can't change webpack without ejecting whole configuration.

More details here

Ejecting while configuration only to use one module is a bit overkill in my opinion.

So my question is do you have any other idea how this module could be useable with react-scripts without making this package (and packages in dependency chain) published with es2015 versions ?

Or could you at least improve README with info that it requires babel-engine-plugin to work with uglifyjs@2?

bundle has 1 warnings

When I import is-online I get this warning on console:

[HMR] bundle has 1 warnings
    ./node_modules/keyv/src/index.js
    18:14-40 Critical dependency: the request of a dependency is an expression

dgram.js error after upgrading to version 6.0.0

Node version : v6.9.1 (tried v6.9.2 too)

Doing :

isOnline().then(online => {
    // ...
  })
dgram.js:530
    throw new Error('Not running'); // error message from dgram_legacy.js
    ^

Error: Not running
    at Socket._healthCheck (dgram.js:530:11)
    at Socket.close (dgram.js:424:8)
    at Timeout.setTimeout (/Users/sylvain/git/gd-cli/node_modules/is-online/index.js:48:15)
    at ontimeout (timers.js:365:14)
    at tryOnTimeout (timers.js:237:5)
    at Timer.listOnTimeout (timers.js:207:5)

In Electron, it is not working

In electron, I am getting 404 becuase url it makes is:

GET file://www.google.com/favicon.ico?1484028202894 net::ERR_FILE_NOT_FOUND
GET file://www.cloudflare.com/favicon.ico?1484028202894 net::ERR_FILE_NOT_FOUND
GET file://www.baidu.com/favicon.ico?1484028202894 net::ERR_FILE_NOT_FOUND
GET file://www.yandex.ru/favicon.ico?1484028202894 net::ERR_FILE_NOT_FOUND

Option to disable plain http calls to Apple servers

Plain http calls are something I very rarely do nowadays. While the call to the Apple servers is unsignificant, I still prefer not sending plain http requests to Apple at all. I'd be so happy if there were an option to disable servers. Also sending https requests to Apple would be a good improvement too.

Return promises

Since we have access to most ES6 features nowadays, would it be possible to return a promise instead of callback?

Will have a look at the code soon and check if it's anything I could do as a PR.

5.1.0 is broken on node

Running npm install is-online (installs 5.1.0)

and then running:

var isOnline = require('is-online');

isOnline(function(err, online) {
    console.log(online);
    //=> true
});

As per the example -- doesn't work.

If you run npm install [email protected] it works fine.

A better way to detect dns intercepting

DNS version queries might be a even better way to detect routers which intercept DNS, even when they respond with the source IP of the queried nameserver. If we send a query for version.bind with class CHAOS and type TXT, most DNS servers respond with a certain string (which is not specific to bind, despite its name):

$ dig +short @ns3.cloudmark.com version.bind chaos txt
"none"

With DNS intercepting in place, the query ought to return either a different string or an error like NOTIMP / SERVFAIL (seen on ns1.google.com/8.8.8.8) status codes. Here's an example:

 $ dig +short @ns3.cloudmark.com version.bind chaos txt
"dnsmasq-2.73"

What we need is a IP address of a nameserver that is guaranteed to always return a certain string we can test for. Unfortunately, the root servers are not suitable as they apparently return a wide range of different strings which ought to get changed at some point. The best candidate seems to be the c root which sports a static versionless string:

$ dig +short @c.root-servers.net version.bind chaos txt
"c-root"

Can anyone think of other suitable nameserver?

When calling isOnline((err, online) => {}), err is true/false and online is undefined

I'm just now testing out this tool, and it's working great so far! I am running into one quirk though.

To test, my code looks something like this, and I'm toggling my Wifi on/off to test the responses:

isOnline((err, online) => {
  console.log('err', err);
  console.log('online', online);
});

For me, err is true/false depending on network connectivity and online is always undefined. Could this be due to some new behavior in ES6/7? Is the first parameter from the callback discarded if it's null? Or maybe the order of err and online was reversed. I'm not sure if there was a change in code that wasn't replicated in the docs, or what.

If the docs are in fact outdated, or if online will be undefined if err is null, then I could submit a PR with a fix.


EDIT: Just saw this note under the Browser API section in the readme:

Same as above except the callback doesn't have an error parameter.

Test URL `https://ipv4.icanhazip.com/` is not working.

Problem

Test URL https://ipv4.icanhazip.com/ is not currently working.
Reported on - 2019-06-24T11:01:04.450Z

Suggestion

I think if your server to test url is down then you should redirect request to another test url to check internet connectivity.

Object has no method 'equals' - [email protected]

Running default example produces error msg:

var isOnline = require('is-online');

isOnline(function(err, online) {
    console.log(online);
    //=> true
});
/tag/node_modules/is-online/index.js:38
        if (msg.slice(0, 2).equals(transactionID) && rinfo.address === server) {
                            ^
TypeError: Object �� has no method 'equals'
    at Socket.<anonymous> (/tag/node_modules/is-online/index.js:38:23)
    at Socket.emit (events.js:98:17)
    at UDP.onMessage (dgram.js:440:8)

Not supporting when npm run build

Hello,

I utilized in my sample application, when i start using "npm start" it is working fine. But when i try to build using "npm run build" showing error like Missing( > ) with UglifyJs. Could you please let me know how to resolve this issue.
Thanks in advance.

Switch from querying "com" to ""

As discussed in #4, we should switch from querying the "com" zone to querying "" once this is resolved:

tjfontaine/native-dns-packet#13

"" is the root domain name, to which the root servers answer with an authorative answer for themselves. This should further improve the reliabilty of this check for cases where the "com" zone is not replicated.

Failing on node 8.0.0

Node 8.0.0 is not that ancient and it breaks on the spread syntax for objects (ECMAScript 2018).
This node version does not support spread syntax.

We should take care of backward compatibility.

/home/travis/build/jfoclpf/autocosts/node_modules/is-online/index.js:22
		...options
		^^^
SyntaxError: Unexpected token ...
    at createScript (vm.js:74:10)
    at Object.runInThisContext (vm.js:116:10)
    at Module._compile (module.js:533:28)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Module.require (module.js:513:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/home/travis/build/jfoclpf/autocosts/commons.js:105:18)

It fails on line 22 of index.js

module.exports = options => {
	options = {
		timeout: 5000,
		version: 'v4',
		...options
	};

Can't we use Object.assign to merge the options?

module.exports = options => {
	options = Object.assign(
		{
			timeout: 5000,
			version: 'v4'
		},
		options || {},
	);

I tested and it works

Support for showing internet connectivity through proxy servers

Currently, if I run this from the CLI, and am behind a HTTP/HTTPS proxy, then, it returns offline. Although, I can access internet through the browser, and using the HTTP protocol from the CLI. (I have exported the http_proxy and https_proxy ENV variables)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.