fixed broken ipv6 on linux, and weird implementation in general

19eae8cb49177fedf4ce245d9334ef6c4d64f5f8

BPplays <andymalbp@gmail.com>

1 files changed, +25 -9Showing whitespace changes
server.js+25 -9
@@ -28,7 +28,6 @@ import multer from 'multer';
28import responseTime from 'response-time';28import responseTime from 'response-time';
29import helmet from 'helmet';29import helmet from 'helmet';
30import bodyParser from 'body-parser';30import bodyParser from 'body-parser';
31import { getMatch, IPMatch, IPSubnetwork, IPRange, matches } from 'ip-matching';
3231
33// net related library imports32// net related library imports
34import fetch from 'node-fetch';33import fetch from 'node-fetch';
@@ -70,6 +69,7 @@ import {
70 removeColorFormatting,69 removeColorFormatting,
71 getSeparator,70 getSeparator,
72 stringToBool,71 stringToBool,
72 urlHostnameToIPv6,
73} from './src/util.js';73} from './src/util.js';
74import { UPLOADS_DIRECTORY } from './src/constants.js';74import { UPLOADS_DIRECTORY } from './src/constants.js';
75import { ensureThumbnailCache } from './src/endpoints/thumbnails.js';75import { ensureThumbnailCache } from './src/endpoints/thumbnails.js';
@@ -388,14 +388,14 @@ async function getHasIP() {
388 let hasIPv4 = false;388 let hasIPv4 = false;
389 let hasIPv4Local = false;389 let hasIPv4Local = false;
390 const interfaces = os.networkInterfaces();390 const interfaces = os.networkInterfaces();
391 const linkLocalV6 = getMatch('fe80::/10');
392391
393 for (const iface of Object.values(interfaces)) {392 for (const iface of Object.values(interfaces)) {
394 if (iface === undefined) {393 if (iface === undefined) {
395 continue;394 continue;
396 }395 }
397 for (const info of iface) {396 for (const info of iface) {
398 if (info.family === 'IPv6' && !linkLocalV6.matches(info.address)) {397 //! change this if you ever add configurable addresses to bind to
398 if (info.family === 'IPv6') {
399 hasIPv6 = true;399 hasIPv6 = true;
400 if (info.internal === true) {400 if (info.internal === true) {
401 hasIPv6Local = true;401 hasIPv6Local = true;
@@ -878,7 +878,7 @@ function handleServerListenFail(v6Failed, v4Failed, useIPv6, useIPv4) {
878 * @returns {Promise<void>} A promise that resolves when the server is listening878 * @returns {Promise<void>} A promise that resolves when the server is listening
879 * @throws {Error} If the server fails to start879 * @throws {Error} If the server fails to start
880 */880 */
881function createHttpsServer(url) {881function createHttpsServer(url, ipVersion) {
882 return new Promise((resolve, reject) => {882 return new Promise((resolve, reject) => {
883 const server = https.createServer(883 const server = https.createServer(
884 {884 {
@@ -887,7 +887,15 @@ function createHttpsServer(url) {
887 }, app);887 }, app);
888 server.on('error', reject);888 server.on('error', reject);
889 server.on('listening', resolve);889 server.on('listening', resolve);
890 server.listen(Number(url.port || 443), url.hostname);890
891 let host = url.hostname
892 if (ipVersion === 6) host = urlHostnameToIPv6(url.hostname);
893 server.listen({
894 host: host,
895 port: Number(url.port || 443),
896 // see https://nodejs.org/api/net.html#serverlisten for why ipv6Only is used
897 ipv6Only: true,
898 });
891 });899 });
892}900}
893901
@@ -897,12 +905,20 @@ function createHttpsServer(url) {
897 * @returns {Promise<void>} A promise that resolves when the server is listening905 * @returns {Promise<void>} A promise that resolves when the server is listening
898 * @throws {Error} If the server fails to start906 * @throws {Error} If the server fails to start
899 */907 */
900function createHttpServer(url) {908function createHttpServer(url, ipVersion) {
901 return new Promise((resolve, reject) => {909 return new Promise((resolve, reject) => {
902 const server = http.createServer(app);910 const server = http.createServer(app);
903 server.on('error', reject);911 server.on('error', reject);
904 server.on('listening', resolve);912 server.on('listening', resolve);
905 server.listen(Number(url.port || 80), url.hostname);913
914 let host = url.hostname
915 if (ipVersion === 6) host = urlHostnameToIPv6(url.hostname);
916 server.listen({
917 host: host,
918 port: Number(url.port || 80),
919 // see https://nodejs.org/api/net.html#serverlisten for why ipv6Only is used
920 ipv6Only: true,
921 });
906 });922 });
907}923}
908924
@@ -914,7 +930,7 @@ async function startHTTPorHTTPS(useIPv6, useIPv4) {
914930
915 if (useIPv6) {931 if (useIPv6) {
916 try {932 try {
917 await createFunc(tavernUrlV6);933 await createFunc(tavernUrlV6, 6);
918 } catch (error) {934 } catch (error) {
919 console.error('non-fatal error: failed to start server on IPv6');935 console.error('non-fatal error: failed to start server on IPv6');
920 console.error(error);936 console.error(error);
@@ -925,7 +941,7 @@ async function startHTTPorHTTPS(useIPv6, useIPv4) {
925941
926 if (useIPv4) {942 if (useIPv4) {
927 try {943 try {
928 await createFunc(tavernUrl);944 await createFunc(tavernUrl, 4);
929 } catch (error) {945 } catch (error) {
930 console.error('non-fatal error: failed to start server on IPv4');946 console.error('non-fatal error: failed to start server on IPv4');
931 console.error(error);947 console.error(error);