App-proxyforurl
view release on metacpan or search on metacpan
script/proxyforurl view on Meta::CPAN
async dnsDomainLevels(host) {
const m = host.match(/\./g);
return m ? m.length : 0;
}
async dnsResolve(host) {
const body = new FormData();
body.append('host', host);
const res = await fetch(this.basePath + '/v1/gethostbyname', {method: 'POST', body});
const text = await res.text();
if (res.status >= 500) throw 'dnsResolve() FAIL ' + (text || res.status);
return text;
}
async isInNet(ip, net, mask) {
// Ex: Turn 255.255.255.0 into 24
if (mask.match(/\./)) mask = Math.round(mask.split('.').reduce((c, o) => c - Math.log2(256 - o), 32));
const body = new FormData();
body.append('ip', ip);
body.append('net', net);
body.append('mask', mask);
const res = await fetch(this.basePath + '/v1/is-in-net', {method: 'POST', body});
const text = await res.text();
if (res.status >= 500) throw 'isInNet() FAIL ' + (text || res.status);
return parseInt(text, 10) ? true : false;
}
async isResolvable(host) {
return await this.dnsResolve(host) ? true : false;
}
async isPlainHostName(str) {
return str.match(/\./) ? false : true;
}
async localHostOrDomainIs(host, str) {
return str.match(/^\./) ? dnsDomainIs(host, str) : host === str ? true : host === host.split('.')[0];
}
async myIpAddress() {
return this.myIpAddressInput.value || this.remoteAddress || '127.0.0.1';
}
async shExpMatch(host, re) {
return host.match(new RegExp(re.replace(/\*/, '.*?'), 'i')) ? true : false;
}
async timeRange() {
return true;
}
async weekdayRange() {
return true;
}
_animate(start) {
const method = start ? 'setAttribute' : 'removeAttribute';
setTimeout(() => {
this.form.querySelector('button')[method]('aria-busy', true);
}, (start ? 1 : 350));
}
async _init() {
const res = await fetch(this.basePath + '/v1/template');
const text = await res.text();
if (!this.rulesInput.value) this.rulesInput.value = text;
const yourIp = text.match(/Your IP: (\S+)/) || [];
this.remoteAddress = yourIp[1] || '127.0.0.1';
this.myIpAddressInput.placeholder = this.remoteAddress;
this.myIpAddressInput.value = this.remoteAddress;
}
async _wrap(func) {
const args = [].slice.call(arguments, 1);
const res = await this[func].apply(this, args);
this.log(func, args, res);
return res;
}
}
@@ template.html.ep
// Your IP: <%= $c->tx->remote_address %>
function FindProxyForURL(url, host) {
// our local URLs from the domains below example.com don't need a proxy:
if (shExpMatch(host, "*.example.com")) return "DIRECT";
if (isPlainHostName(host)) return "DIRECT";
if (localHostOrDomainIs(host, "www.example.com")) return "PROXY local.proxy:8080";
if (!isResolvable(host)) return "SOCKS4 example.com:1080";
if (dnsDomainLevels(host) === 4) return "SOCKS4 example.com:1081";
alert("Checking other rules...");
alert(myIpAddress());
// URLs within this network are accessed through
// port 8080 on fastproxy.example.com:
if (isInNet(host, "10.0.0.0", "255.255.248.0")) return "PROXY fastproxy.example.com:8080";
if (dnsDomainIs(host, "le.com")) return "PROXY proxy2.example.com:8888";
// All other requests go through port 8080 of proxy.example.com.
// should that fail to respond, go directly to the WWW:
return "PROXY proxy.example.com:8080; DIRECT";
}
( run in 0.773 second using v1.01-cache-2.11-cpan-39bf76dae61 )