mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
added automatic ipv6 ipv4 detection
This commit is contained in:
@@ -7,9 +7,11 @@ cardsCacheCapacity: 100
|
|||||||
# Listen for incoming connections
|
# Listen for incoming connections
|
||||||
listen: false
|
listen: false
|
||||||
# Enables IPv6 and/or IPv4 protocols. Need to have at least one enabled!
|
# Enables IPv6 and/or IPv4 protocols. Need to have at least one enabled!
|
||||||
|
# - Use option "auto" to automatically detect support
|
||||||
|
# - Use "enabled" or "disabled" to enable or disabled each protocol
|
||||||
protocol:
|
protocol:
|
||||||
ipv4: true
|
ipv4: auto
|
||||||
ipv6: false
|
ipv6: auto
|
||||||
# Prefers IPv6 for DNS. Enable this on ISPs that don't have issues with IPv6
|
# Prefers IPv6 for DNS. Enable this on ISPs that don't have issues with IPv6
|
||||||
dnsPreferIPv6: false
|
dnsPreferIPv6: false
|
||||||
# The hostname that autorun opens.
|
# The hostname that autorun opens.
|
||||||
|
89
server.js
89
server.js
@@ -4,6 +4,7 @@
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import http from 'node:http';
|
import http from 'node:http';
|
||||||
import https from 'node:https';
|
import https from 'node:https';
|
||||||
|
import os from 'os';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import util from 'node:util';
|
import util from 'node:util';
|
||||||
import net from 'node:net';
|
import net from 'node:net';
|
||||||
@@ -133,8 +134,8 @@ const DEFAULT_CSRF_DISABLED = false;
|
|||||||
const DEFAULT_BASIC_AUTH = false;
|
const DEFAULT_BASIC_AUTH = false;
|
||||||
const DEFAULT_PER_USER_BASIC_AUTH = false;
|
const DEFAULT_PER_USER_BASIC_AUTH = false;
|
||||||
|
|
||||||
const DEFAULT_ENABLE_IPV6 = false;
|
const DEFAULT_ENABLE_IPV6 = "auto";
|
||||||
const DEFAULT_ENABLE_IPV4 = true;
|
const DEFAULT_ENABLE_IPV4 = "auto";
|
||||||
|
|
||||||
const DEFAULT_PREFER_IPV6 = false;
|
const DEFAULT_PREFER_IPV6 = false;
|
||||||
|
|
||||||
@@ -149,11 +150,11 @@ const DEFAULT_PROXY_BYPASS = [];
|
|||||||
|
|
||||||
const cliArguments = yargs(hideBin(process.argv))
|
const cliArguments = yargs(hideBin(process.argv))
|
||||||
.usage('Usage: <your-start-script> <command> [options]')
|
.usage('Usage: <your-start-script> <command> [options]')
|
||||||
.option('enableIPv6', {
|
.option('string', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: null,
|
default: null,
|
||||||
describe: `Enables IPv6.\n[config default: ${DEFAULT_ENABLE_IPV6}]`,
|
describe: `Enables IPv6.\n[config default: ${DEFAULT_ENABLE_IPV6}]`,
|
||||||
}).option('enableIPv4', {
|
}).option('string', {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: null,
|
default: null,
|
||||||
describe: `Enables IPv4.\n[config default: ${DEFAULT_ENABLE_IPV4}]`,
|
describe: `Enables IPv4.\n[config default: ${DEFAULT_ENABLE_IPV4}]`,
|
||||||
@@ -280,7 +281,7 @@ if (dnsPreferIPv6) {
|
|||||||
console.log('Preferring IPv4 for DNS resolution');
|
console.log('Preferring IPv4 for DNS resolution');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!enableIPv6 && !enableIPv4) {
|
if (enableIPv6 == "disabled" && enableIPv4 == "disabled") {
|
||||||
console.error('error: You can\'t disable all internet protocols: at least IPv6 or IPv4 must be enabled.');
|
console.error('error: You can\'t disable all internet protocols: at least IPv6 or IPv4 must be enabled.');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
@@ -365,6 +366,28 @@ function getSessionCookieAge() {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getHasIP() {
|
||||||
|
let hasIPv6 = false;
|
||||||
|
let hasIPv4 = false;
|
||||||
|
const interfaces = os.networkInterfaces();
|
||||||
|
|
||||||
|
for (const iface of Object.values(interfaces)) {
|
||||||
|
if (iface === undefined) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for (const info of iface) {
|
||||||
|
if (info.family === 'IPv6') {
|
||||||
|
hasIPv6 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.family === 'IPv4') {
|
||||||
|
hasIPv4 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [hasIPv6, hasIPv4];
|
||||||
|
}
|
||||||
|
|
||||||
app.use(cookieSession({
|
app.use(cookieSession({
|
||||||
name: getCookieSessionName(),
|
name: getCookieSessionName(),
|
||||||
sameSite: 'strict',
|
sameSite: 'strict',
|
||||||
@@ -685,18 +708,18 @@ const preSetupTasks = async function () {
|
|||||||
* Gets the hostname to use for autorun in the browser.
|
* Gets the hostname to use for autorun in the browser.
|
||||||
* @returns {string} The hostname to use for autorun
|
* @returns {string} The hostname to use for autorun
|
||||||
*/
|
*/
|
||||||
function getAutorunHostname() {
|
function getAutorunHostname(useIPv6, useIPv4) {
|
||||||
if (autorunHostname === 'auto') {
|
if (autorunHostname === 'auto') {
|
||||||
if (enableIPv6 && enableIPv4) {
|
if (useIPv6 && useIPv4) {
|
||||||
if (avoidLocalhost) return '[::1]';
|
if (avoidLocalhost) return '[::1]';
|
||||||
return 'localhost';
|
return 'localhost';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableIPv6) {
|
if (useIPv6) {
|
||||||
return '[::1]';
|
return '[::1]';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableIPv4) {
|
if (useIPv4) {
|
||||||
return '127.0.0.1';
|
return '127.0.0.1';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -709,10 +732,10 @@ function getAutorunHostname() {
|
|||||||
* @param {boolean} v6Failed If the server failed to start on IPv6
|
* @param {boolean} v6Failed If the server failed to start on IPv6
|
||||||
* @param {boolean} v4Failed If the server failed to start on IPv4
|
* @param {boolean} v4Failed If the server failed to start on IPv4
|
||||||
*/
|
*/
|
||||||
const postSetupTasks = async function (v6Failed, v4Failed) {
|
const postSetupTasks = async function (v6Failed, v4Failed, useIPv6, useIPv4) {
|
||||||
const autorunUrl = new URL(
|
const autorunUrl = new URL(
|
||||||
(cliArguments.ssl ? 'https://' : 'http://') +
|
(cliArguments.ssl ? 'https://' : 'http://') +
|
||||||
(getAutorunHostname()) +
|
(getAutorunHostname(useIPv6, useIPv4)) +
|
||||||
(':') +
|
(':') +
|
||||||
((autorunPortOverride >= 0) ? autorunPortOverride : server_port),
|
((autorunPortOverride >= 0) ? autorunPortOverride : server_port),
|
||||||
);
|
);
|
||||||
@@ -725,11 +748,11 @@ const postSetupTasks = async function (v6Failed, v4Failed) {
|
|||||||
|
|
||||||
let logListen = 'SillyTavern is listening on';
|
let logListen = 'SillyTavern is listening on';
|
||||||
|
|
||||||
if (enableIPv6 && !v6Failed) {
|
if (useIPv6 && !v6Failed) {
|
||||||
logListen += color.green(' IPv6: ' + tavernUrlV6.host);
|
logListen += color.green(' IPv6: ' + tavernUrlV6.host);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableIPv4 && !v4Failed) {
|
if (useIPv4 && !v4Failed) {
|
||||||
logListen += color.green(' IPv4: ' + tavernUrl.host);
|
logListen += color.green(' IPv4: ' + tavernUrl.host);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,13 +828,13 @@ function logSecurityAlert(message) {
|
|||||||
* @param {boolean} v6Failed If the server failed to start on IPv6
|
* @param {boolean} v6Failed If the server failed to start on IPv6
|
||||||
* @param {boolean} v4Failed If the server failed to start on IPv4
|
* @param {boolean} v4Failed If the server failed to start on IPv4
|
||||||
*/
|
*/
|
||||||
function handleServerListenFail(v6Failed, v4Failed) {
|
function handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4) {
|
||||||
if (v6Failed && !enableIPv4) {
|
if (v6Failed && !useIPv4) {
|
||||||
console.error(color.red('fatal error: Failed to start server on IPv6 and IPv4 disabled'));
|
console.error(color.red('fatal error: Failed to start server on IPv6 and IPv4 disabled'));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v4Failed && !enableIPv6) {
|
if (v4Failed && !useIPv6) {
|
||||||
console.error(color.red('fatal error: Failed to start server on IPv4 and IPv6 disabled'));
|
console.error(color.red('fatal error: Failed to start server on IPv4 and IPv6 disabled'));
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
@@ -856,13 +879,13 @@ function createHttpServer(url) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startHTTPorHTTPS() {
|
async function startHTTPorHTTPS(useIPv6, useIPv4) {
|
||||||
let v6Failed = false;
|
let v6Failed = false;
|
||||||
let v4Failed = false;
|
let v4Failed = false;
|
||||||
|
|
||||||
const createFunc = cliArguments.ssl ? createHttpsServer : createHttpServer;
|
const createFunc = cliArguments.ssl ? createHttpsServer : createHttpServer;
|
||||||
|
|
||||||
if (enableIPv6) {
|
if (useIPv6) {
|
||||||
try {
|
try {
|
||||||
await createFunc(tavernUrlV6);
|
await createFunc(tavernUrlV6);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -873,7 +896,7 @@ async function startHTTPorHTTPS() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableIPv4) {
|
if (useIPv4) {
|
||||||
try {
|
try {
|
||||||
await createFunc(tavernUrl);
|
await createFunc(tavernUrl);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -888,10 +911,32 @@ async function startHTTPorHTTPS() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function startServer() {
|
async function startServer() {
|
||||||
const [v6Failed, v4Failed] = await startHTTPorHTTPS();
|
let useIPv6 = (enableIPv6 == "enabled")
|
||||||
|
let useIPv4 = (enableIPv4 == "enabled")
|
||||||
|
|
||||||
handleServerListenFail(v6Failed, v4Failed);
|
const [hasIPv6, hasIPv4] = await getHasIP()
|
||||||
postSetupTasks(v6Failed, v4Failed);
|
if (enableIPv6 == "auto") {
|
||||||
|
useIPv6 = hasIPv6;
|
||||||
|
if (useIPv6) {
|
||||||
|
console.log("IPv6 support detected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableIPv4 == "auto") {
|
||||||
|
useIPv4 = hasIPv4;
|
||||||
|
if (useIPv4) {
|
||||||
|
console.log("IPv4 support detected")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!useIPv6 && !useIPv4) {
|
||||||
|
console.log("No IPv6 and no IPv4 enabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
const [v6Failed, v4Failed] = await startHTTPorHTTPS(useIPv6, useIPv4);
|
||||||
|
|
||||||
|
handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4);
|
||||||
|
postSetupTasks(v6Failed, v4Failed, useIPv6, useIPv4);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function verifySecuritySettings() {
|
async function verifySecuritySettings() {
|
||||||
|
Reference in New Issue
Block a user