Skip to content

Commit

Permalink
feat: add request cancelation in browser implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
stropitek committed Oct 31, 2020
1 parent f9e667f commit fdb9f7e
Showing 1 changed file with 42 additions and 29 deletions.
71 changes: 42 additions & 29 deletions browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ const isIp = require('is-ip');

const defaults = {
timeout: 5000
};
};

const urls = {
const urls = {
v4: [
'https://ipv4.icanhazip.com/',
'https://api.ipify.org/'
Expand All @@ -16,42 +16,55 @@ const urls = {
]
};

const sendXhr = async (url, options, version) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.addEventListener('error', reject, {once: true});
xhr.addEventListener('timeout', reject, {once: true});
const sendXhr = (url, options, version) => {
const xhr = new XMLHttpRequest();
let _resolve;
const promise = new Promise((resolve, reject) => {
_resolve = resolve;
xhr.addEventListener('error', reject, { once: true });
xhr.addEventListener('timeout', reject, { once: true });

xhr.addEventListener('load', () => {
const ip = xhr.responseText.trim();
xhr.addEventListener('load', () => {
const ip = xhr.responseText.trim();

if (!ip || !isIp[version](ip)) {
reject();
return;
}
if (!ip || !isIp[version](ip)) {
reject();
return;
}

resolve(ip);
resolve(ip);
}, {once: true});

xhr.open('GET', url);
xhr.timeout = options.timeout;
xhr.send();
xhr.open('GET', url);
xhr.timeout = options.timeout;
xhr.send();
});
};
promise.cancel = () => {
_resolve();
xhr.abort();
}
return promise;
};

const queryHttps = async (version, options) => {
let ip;
const urls_ = [].concat.apply(urls[version], options.fallbackUrls || []);
for (const url of urls_) {
const queryHttps = (version, options) => {
let request;
const promise = (async function () {
const urls_ = [].concat.apply(urls[version], options.fallbackUrls || []);
for (const url of urls_) {
try {
// eslint-disable-next-line no-await-in-loop
ip = await sendXhr(url, options, version);
return ip;
// eslint-disable-next-line no-await-in-loop
request = sendXhr(url, options, version);
const ip = await request;
return ip;
} catch (_) {}
}

throw new Error('Couldn\'t find your IP');
};
}
throw new Error("Couldn't find your IP");
})();
promise.cancel = () => {
request.cancel();
};
return promise;
};

module.exports.v4 = options => queryHttps('v4', {...defaults, ...options});

Expand Down

0 comments on commit fdb9f7e

Please # to comment.