mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-12-10 10:10:14 +02:00
Add socks proxy support to proxy feature
- Socks proxy support implemented. - Monitor proxy agent create flow refactored and moved under proxy class. Thanks for suggestion @thomasleveil
This commit is contained in:
parent
9e27acb511
commit
8078d0618d
@ -1,6 +1,4 @@
|
|||||||
const https = require("https");
|
const https = require("https");
|
||||||
const HttpProxyAgent = require("http-proxy-agent");
|
|
||||||
const HttpsProxyAgent = require("https-proxy-agent");
|
|
||||||
const dayjs = require("dayjs");
|
const dayjs = require("dayjs");
|
||||||
const utc = require("dayjs/plugin/utc");
|
const utc = require("dayjs/plugin/utc");
|
||||||
let timezone = require("dayjs/plugin/timezone");
|
let timezone = require("dayjs/plugin/timezone");
|
||||||
@ -13,6 +11,7 @@ const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalCli
|
|||||||
const { R } = require("redbean-node");
|
const { R } = require("redbean-node");
|
||||||
const { BeanModel } = require("redbean-node/dist/bean-model");
|
const { BeanModel } = require("redbean-node/dist/bean-model");
|
||||||
const { Notification } = require("../notification");
|
const { Notification } = require("../notification");
|
||||||
|
const { Proxy } = require("../proxy");
|
||||||
const { demoMode } = require("../config");
|
const { demoMode } = require("../config");
|
||||||
const version = require("../../package.json").version;
|
const version = require("../../package.json").version;
|
||||||
const apicache = require("../modules/apicache");
|
const apicache = require("../modules/apicache");
|
||||||
@ -204,31 +203,13 @@ class Monitor extends BeanModel {
|
|||||||
const proxy = await R.load("proxy", this.proxy_id);
|
const proxy = await R.load("proxy", this.proxy_id);
|
||||||
|
|
||||||
if (proxy && proxy.active) {
|
if (proxy && proxy.active) {
|
||||||
const httpProxyAgentOptions = {
|
const { httpAgent, httpsAgent } = Proxy.createAgents(proxy, {
|
||||||
protocol: proxy.protocol,
|
httpsAgentOptions: httpsAgentOptions,
|
||||||
host: proxy.host,
|
});
|
||||||
port: proxy.port,
|
|
||||||
};
|
|
||||||
const httpsProxyAgentOptions = {
|
|
||||||
...httpsAgentOptions,
|
|
||||||
protocol: proxy.protocol,
|
|
||||||
hostname: proxy.host,
|
|
||||||
port: proxy.port,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (proxy.auth) {
|
|
||||||
httpProxyAgentOptions.auth = `${proxy.username}:${proxy.password}`;
|
|
||||||
httpsProxyAgentOptions.auth = `${proxy.username}:${proxy.password}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
debug(`[${this.name}] HTTP options: ${JSON.stringify({
|
|
||||||
"http": httpProxyAgentOptions,
|
|
||||||
"https": httpsProxyAgentOptions,
|
|
||||||
})}`);
|
|
||||||
|
|
||||||
options.proxy = false;
|
options.proxy = false;
|
||||||
options.httpAgent = new HttpProxyAgent(httpProxyAgentOptions);
|
options.httpAgent = httpAgent;
|
||||||
options.httpsAgent = new HttpsProxyAgent(httpsProxyAgentOptions);
|
options.httpsAgent = httpsAgent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
const { R } = require("redbean-node");
|
const { R } = require("redbean-node");
|
||||||
|
const HttpProxyAgent = require("http-proxy-agent");
|
||||||
|
const HttpsProxyAgent = require("https-proxy-agent");
|
||||||
|
const SocksProxyAgent = require("socks-proxy-agent");
|
||||||
|
const { debug } = require("../src/util");
|
||||||
|
|
||||||
class Proxy {
|
class Proxy {
|
||||||
|
|
||||||
|
static SUPPORTED_PROXY_PROTOCOLS = ["http", "https", "socks", "socks5", "socks4"]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves and updates given proxy entity
|
* Saves and updates given proxy entity
|
||||||
*
|
*
|
||||||
@ -25,8 +31,11 @@ class Proxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure given proxy protocol is supported
|
// Make sure given proxy protocol is supported
|
||||||
if (!["http", "https"].includes(proxy.protocol)) {
|
if (!this.SUPPORTED_PROXY_PROTOCOLS.includes(proxy.protocol)) {
|
||||||
throw new Error(`Unsupported proxy protocol "${proxy.protocol}. Supported protocols are http and https."`);
|
throw new Error(`
|
||||||
|
Unsupported proxy protocol "${proxy.protocol}.
|
||||||
|
Supported protocols are ${this.SUPPORTED_PROXY_PROTOCOLS.join(", ")}."`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When proxy is default update deactivate old default proxy
|
// When proxy is default update deactivate old default proxy
|
||||||
@ -73,6 +82,68 @@ class Proxy {
|
|||||||
// Delete proxy from list
|
// Delete proxy from list
|
||||||
await R.trash(bean);
|
await R.trash(bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create HTTP and HTTPS agents related with given proxy bean object
|
||||||
|
*
|
||||||
|
* @param proxy proxy bean object
|
||||||
|
* @param options http and https agent options
|
||||||
|
* @return {{httpAgent: Agent, httpsAgent: Agent}}
|
||||||
|
*/
|
||||||
|
static createAgents(proxy, options) {
|
||||||
|
const { httpAgentOptions, httpsAgentOptions } = options || {};
|
||||||
|
let agent;
|
||||||
|
let httpAgent;
|
||||||
|
let httpsAgent;
|
||||||
|
|
||||||
|
const proxyOptions = {
|
||||||
|
protocol: proxy.protocol,
|
||||||
|
host: proxy.host,
|
||||||
|
port: proxy.port,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (proxy.auth) {
|
||||||
|
proxyOptions.auth = `${proxy.username}:${proxy.password}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(`Proxy Options: ${JSON.stringify(proxyOptions)}`);
|
||||||
|
debug(`HTTP Agent Options: ${JSON.stringify(httpAgentOptions)}`);
|
||||||
|
debug(`HTTPS Agent Options: ${JSON.stringify(httpsAgentOptions)}`);
|
||||||
|
|
||||||
|
switch (proxy.protocol) {
|
||||||
|
case "http":
|
||||||
|
case "https":
|
||||||
|
httpAgent = new HttpProxyAgent({
|
||||||
|
...httpAgentOptions || {},
|
||||||
|
...proxyOptions
|
||||||
|
});
|
||||||
|
|
||||||
|
httpsAgent = new HttpsProxyAgent({
|
||||||
|
...httpsAgentOptions || {},
|
||||||
|
...proxyOptions,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "socks":
|
||||||
|
case "socks5":
|
||||||
|
case "socks4":
|
||||||
|
agent = new SocksProxyAgent({
|
||||||
|
...httpAgentOptions,
|
||||||
|
...httpsAgentOptions,
|
||||||
|
...proxyOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
httpAgent = agent;
|
||||||
|
httpsAgent = agent;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: throw new Error(`Unsupported proxy protocol provided. ${proxy.protocol}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
httpAgent,
|
||||||
|
httpsAgent
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
<select id="proxy-protocol" v-model="proxy.protocol" class="form-select">
|
<select id="proxy-protocol" v-model="proxy.protocol" class="form-select">
|
||||||
<option value="https">HTTPS</option>
|
<option value="https">HTTPS</option>
|
||||||
<option value="http">HTTP</option>
|
<option value="http">HTTP</option>
|
||||||
|
<option value="socks">SOCKS</option>
|
||||||
|
<option value="socks5">SOCKS v5</option>
|
||||||
|
<option value="socks4">SOCKS v4</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
|
|
||||||
<ul class="list-group mb-3" style="border-radius: 1rem;">
|
<ul class="list-group mb-3" style="border-radius: 1rem;">
|
||||||
<li v-for="(proxy, index) in $root.proxyList" :key="index" class="list-group-item">
|
<li v-for="(proxy, index) in $root.proxyList" :key="index" class="list-group-item">
|
||||||
{{ proxy.host }}<span v-if="proxy.default === true" class="badge bg-primary ms-2">{{ $t("Default") }}</span><br>
|
{{ proxy.host }}:{{ proxy.port }} ({{ proxy.protocol }})
|
||||||
|
<span v-if="proxy.default === true" class="badge bg-primary ms-2">{{ $t("Default") }}</span><br>
|
||||||
<a href="#" @click="$refs.proxyDialog.show(proxy.id)">{{ $t("Edit") }}</a>
|
<a href="#" @click="$refs.proxyDialog.show(proxy.id)">{{ $t("Edit") }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -237,7 +237,7 @@
|
|||||||
<input :id="`proxy-${proxy.id}`" v-model="monitor.proxyId" :value="proxy.id" name="proxy" class="form-check-input" type="radio">
|
<input :id="`proxy-${proxy.id}`" v-model="monitor.proxyId" :value="proxy.id" name="proxy" class="form-check-input" type="radio">
|
||||||
|
|
||||||
<label class="form-check-label" :for="`proxy-${proxy.id}`">
|
<label class="form-check-label" :for="`proxy-${proxy.id}`">
|
||||||
{{ proxy.host }}
|
{{ proxy.host }}:{{ proxy.port }} ({{ proxy.protocol }})
|
||||||
<a href="#" @click="$refs.proxyDialog.show(proxy.id)">{{ $t("Edit") }}</a>
|
<a href="#" @click="$refs.proxyDialog.show(proxy.id)">{{ $t("Edit") }}</a>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user