implemented check for hotel/ISP paywall

This commit is contained in:
tigerbot 2017-06-20 15:33:45 -06:00
parent aea4725fb0
commit e901f1679b
1 changed files with 91 additions and 0 deletions

View File

@ -63,6 +63,81 @@ module.exports.create = function (deps, conf) {
});
}
function checkPaywall() {
var PromiseA = require('bluebird');
var testDomains = [
'daplie.com'
, 'duckduckgo.com'
, 'google.com'
, 'amazon.com'
, 'facebook.com'
, 'msn.com'
, 'yahoo.com'
];
// While this is not being developed behind a paywall the current idea is that
// a paywall will either manipulate DNS queries to point to the paywall gate,
// or redirect HTTP requests to the paywall gate. So we check for both and
// hope we can detect most hotel/ISP paywalls out there in the world.
return PromiseA.resolve()
.then(function () {
var dns = PromiseA.promisifyAll(require('dns'));
var proms = testDomains.map(function (dom) {
return dns.resolve6Async(dom)
.catch(function (err) {
if (err.code === 'ENODATA') {
return dns.resolve4Async(dom);
} else {
return PromiseA.reject(err);
}
})
.then(function (result) {
return result[0];
});
});
return PromiseA.all(proms).then(function (addrs) {
var unique = addrs.filter(function (value, ind, self) {
return value && self.indexOf(value) === ind;
});
// It is possible some walls might have exceptions that leave some of the domains
// we test alone, so we might have more than one unique address even behind an
// active paywall.
return unique.length < addrs.length;
});
})
.then(function (paywall) {
if (paywall) {
return paywall;
}
var request = deps.request.defaults({
followRedirect: false
, headers: {
connection: 'close'
}
});
var proms = testDomains.map(function (dom) {
return request('https://'+dom).then(function (resp) {
if (resp.statusCode >= 300 && resp.statusCode < 400) {
return resp.headers.location;
} else {
return 'https://'+dom;
}
});
});
return PromiseA.all(proms).then(function (urls) {
var unique = urls.filter(function (value, ind, self) {
return value && self.indexOf(value) === ind;
});
return unique.length < urls.length;
});
})
;
}
return {
init: function (req, res) {
if (handleCors(req, res, 'POST')) {
@ -233,6 +308,22 @@ module.exports.create = function (deps, conf) {
});
});
}
, paywall_check: function (req, res) {
if (handleCors(req, res, 'GET')) {
return;
}
isAuthorized(req, res, function () {
res.setHeader('Content-Type', 'application/json;');
checkPaywall().then(function (paywall) {
res.end(JSON.stringify({paywall: paywall}));
}, function (err) {
err.message = err.message || err.toString();
res.statusCode = 500;
res.end(JSON.stringify({error: {message: err.message, code: err.code}}));
});
});
}
, _api: api
};
};