feat: link mac client to shared gateway proxy
This commit is contained in:
@@ -21,6 +21,10 @@ import {
|
||||
readClientSettings,
|
||||
writeClientSettings,
|
||||
} from "./clientSettings.js";
|
||||
import {
|
||||
buildSharedProxyInfo,
|
||||
checkSharedProxyGateway,
|
||||
} from "./sharedProxy.js";
|
||||
import { matchRoute, detectRuleConflicts } from "./routeMatcher.js";
|
||||
import { tcpPing, resolveHost } from "./ping.js";
|
||||
|
||||
@@ -722,6 +726,36 @@ async function applySelectedServer(selectedTag) {
|
||||
});
|
||||
}
|
||||
|
||||
async function applyClientSharedProxy() {
|
||||
const clientSettings = readClientSettings();
|
||||
if (!clientSettings.sharedProxyEnabled || !clientSettings.sharedProxy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const generated = buildGatewayConfig(
|
||||
{ outbounds: [], customRules: [] },
|
||||
"",
|
||||
);
|
||||
writeSingboxConfig(generated);
|
||||
await startSingbox();
|
||||
pushLog(
|
||||
"info",
|
||||
`Mac client uses shared gateway proxy ${clientSettings.sharedProxy.host}:${clientSettings.sharedProxy.port}`,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
async function applyClientDirectProxy() {
|
||||
const generated = buildGatewayConfig(
|
||||
{ outbounds: [], customRules: [] },
|
||||
"",
|
||||
);
|
||||
writeSingboxConfig(generated);
|
||||
await startSingbox();
|
||||
pushLog("info", "Mac client routes local proxy directly");
|
||||
return true;
|
||||
}
|
||||
|
||||
function handleLogsStream(req, res) {
|
||||
res.writeHead(200, {
|
||||
"content-type": "text/event-stream; charset=utf-8",
|
||||
@@ -756,6 +790,20 @@ async function handleApi(req, res) {
|
||||
return sendJson(res, 200, publicState());
|
||||
}
|
||||
|
||||
if (req.method === "GET" && req.url === "/api/shared-proxy") {
|
||||
return sendJson(
|
||||
res,
|
||||
200,
|
||||
buildSharedProxyInfo({
|
||||
appMode: settings.appMode,
|
||||
proxyPort: settings.proxyPort,
|
||||
running: Boolean(singboxProcess),
|
||||
hostHeader: req.headers.host,
|
||||
sharedProxyHost: settings.sharedProxyHost,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (req.method === "GET" && req.url === "/api/config") {
|
||||
const config = readSingboxConfig();
|
||||
return sendJson(res, 200, { success: true, config });
|
||||
@@ -947,12 +995,48 @@ async function handleApi(req, res) {
|
||||
const clientSettings = writeClientSettings(body.clientSettings || body);
|
||||
const prevState = readJson(settings.statePath, {});
|
||||
|
||||
if (
|
||||
settings.appMode === "client" &&
|
||||
prevState.selectedTag &&
|
||||
readJson(settings.subscriptionCachePath, null)?.config
|
||||
) {
|
||||
await applySelectedServer(prevState.selectedTag);
|
||||
if (settings.appMode === "client") {
|
||||
if (clientSettings.sharedProxyEnabled) {
|
||||
await applyClientSharedProxy();
|
||||
} else if (clientSettings.homeBypassEnabled) {
|
||||
await applyClientDirectProxy();
|
||||
} else if (
|
||||
prevState.selectedTag &&
|
||||
readJson(settings.subscriptionCachePath, null)?.config
|
||||
) {
|
||||
await applySelectedServer(prevState.selectedTag);
|
||||
} else {
|
||||
await stopSingbox();
|
||||
removeSingboxConfig();
|
||||
}
|
||||
}
|
||||
|
||||
return sendJson(res, 200, {
|
||||
success: true,
|
||||
clientSettings,
|
||||
singboxRunning: Boolean(singboxProcess),
|
||||
});
|
||||
}
|
||||
|
||||
if (req.method === "POST" && req.url === "/api/client-settings/shared-proxy/check") {
|
||||
const body = await readBody(req);
|
||||
const url = String(body.url || "").trim();
|
||||
if (!url) {
|
||||
return sendJson(res, 400, {
|
||||
success: false,
|
||||
error: "Укажите адрес gateway",
|
||||
});
|
||||
}
|
||||
|
||||
const patch = await checkSharedProxyGateway(url);
|
||||
const clientSettings = writeClientSettings({
|
||||
...readClientSettings(),
|
||||
...patch,
|
||||
homeBypassEnabled: false,
|
||||
});
|
||||
|
||||
if (settings.appMode === "client") {
|
||||
await applyClientSharedProxy();
|
||||
}
|
||||
|
||||
return sendJson(res, 200, {
|
||||
@@ -1348,6 +1432,14 @@ async function handleApi(req, res) {
|
||||
error: "selectedTag обязателен",
|
||||
});
|
||||
|
||||
if (settings.appMode === "client") {
|
||||
writeClientSettings({
|
||||
...readClientSettings(),
|
||||
homeBypassEnabled: false,
|
||||
sharedProxyEnabled: false,
|
||||
});
|
||||
}
|
||||
|
||||
await applySelectedServer(selectedTag);
|
||||
return sendJson(res, 200, {
|
||||
success: true,
|
||||
|
||||
Reference in New Issue
Block a user