fix: support for IPv6 address literals in HOST env var (#2614)

Co-authored-by: fallenbagel <[email protected]>
This commit is contained in:
Kyle Ouellette
2026-07-22 20:49:11 +08:00
committed by GitHub
co-authored by fallenbagel
parent bf5323faf4
commit 0adbf50b5c
8 changed files with 41 additions and 17 deletions
+1
View File
@@ -71,6 +71,7 @@
"mime": "^4.1.0",
"nanoid": "^5.1.7",
"next": "16.2.6",
"ip-address": "^10.2.0",
"node-cache": "5.1.2",
"node-gyp": "12.2.0",
"node-schedule": "2.1.1",
+9
View File
@@ -110,6 +110,9 @@ importers:
humanize-duration:
specifier: ^3.33.2
version: 3.33.2
ip-address:
specifier: ^10.2.0
version: 10.2.0
js-yaml:
specifier: ^4.1.1
version: 4.1.1
@@ -4868,6 +4871,10 @@ packages:
resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==}
engines: {node: '>= 12'}
[email protected]:
resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==}
engines: {node: '>= 12'}
[email protected]:
resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==}
engines: {node: '>= 12'}
@@ -13283,6 +13290,8 @@ snapshots:
[email protected]: {}
[email protected]: {}
[email protected]:
dependencies:
jsbn: 1.1.0
+10 -2
View File
@@ -267,19 +267,27 @@ app
const port = Number(process.env.PORT) || 5055;
const host = process.env.HOST;
let httpServer;
if (host) {
server.listen(port, host, () => {
httpServer = server.listen(port, host, () => {
logger.info(`Server ready on ${host} port ${port}`, {
label: 'Server',
});
});
} else {
server.listen(port, () => {
httpServer = server.listen(port, () => {
logger.info(`Server ready on port ${port}`, {
label: 'Server',
});
});
}
httpServer.on('error', (err) => {
logger.error('Failed to start server', {
label: 'Server',
message: err.message,
});
process.exit(1);
});
})
.catch((err) => {
logger.error(err.stack);
+3 -6
View File
@@ -11,6 +11,7 @@ import type { User } from '@app/hooks/useUser';
import { Permission, useUser } from '@app/hooks/useUser';
import '@app/styles/globals.css';
import { polyfillIntl } from '@app/utils/polyfillIntl';
import { getHostAndPort } from '@app/utils/urlHelper';
import '@fontsource-variable/inter';
import { MediaServerType } from '@server/constants/server';
import type { PublicSettingsResponse } from '@server/interfaces/api/settingsInterfaces';
@@ -266,9 +267,7 @@ CoreApp.getInitialProps = async (initialProps) => {
if (ctx.res) {
// Check if app is initialized and redirect if necessary
const response = await axios.get<PublicSettingsResponse>(
`http://${process.env.HOST || 'localhost'}:${
process.env.PORT || 5055
}/api/v1/settings/public`
`http://${getHostAndPort()}/api/v1/settings/public`
);
currentSettings = response.data;
@@ -286,9 +285,7 @@ CoreApp.getInitialProps = async (initialProps) => {
try {
// Attempt to get the user by running a request to the local api
const response = await axios.get<User>(
`http://${process.env.HOST || 'localhost'}:${
process.env.PORT || 5055
}/api/v1/auth/me`,
`http://${getHostAndPort()}/api/v1/auth/me`,
{
headers:
ctx.req && ctx.req.headers.cookie
@@ -1,4 +1,5 @@
import CollectionDetails from '@app/components/CollectionDetails';
import { getHostAndPort } from '@app/utils/urlHelper';
import type { Collection } from '@server/models/Collection';
import axios from 'axios';
import type { GetServerSideProps, NextPage } from 'next';
@@ -15,9 +16,7 @@ export const getServerSideProps: GetServerSideProps<
CollectionPageProps
> = async (ctx) => {
const response = await axios.get<Collection>(
`http://${process.env.HOST || 'localhost'}:${
process.env.PORT || 5055
}/api/v1/collection/${ctx.query.collectionId}`,
`http://${getHostAndPort()}/api/v1/collection/${ctx.query.collectionId}`,
{
headers: ctx.req?.headers?.cookie
? { cookie: ctx.req.headers.cookie }
+2 -3
View File
@@ -1,4 +1,5 @@
import MovieDetails from '@app/components/MovieDetails';
import { getHostAndPort } from '@app/utils/urlHelper';
import type { MovieDetails as MovieDetailsType } from '@server/models/Movie';
import axios from 'axios';
import type { GetServerSideProps, NextPage } from 'next';
@@ -15,9 +16,7 @@ export const getServerSideProps: GetServerSideProps<MoviePageProps> = async (
ctx
) => {
const response = await axios.get<MovieDetailsType>(
`http://${process.env.HOST || 'localhost'}:${
process.env.PORT || 5055
}/api/v1/movie/${ctx.query.movieId}`,
`http://${getHostAndPort()}/api/v1/movie/${ctx.query.movieId}`,
{
headers: ctx.req?.headers?.cookie
? { cookie: ctx.req.headers.cookie }
+2 -3
View File
@@ -1,4 +1,5 @@
import TvDetails from '@app/components/TvDetails';
import { getHostAndPort } from '@app/utils/urlHelper';
import type { TvDetails as TvDetailsType } from '@server/models/Tv';
import axios from 'axios';
import type { GetServerSideProps, NextPage } from 'next';
@@ -15,9 +16,7 @@ export const getServerSideProps: GetServerSideProps<TvPageProps> = async (
ctx
) => {
const response = await axios.get<TvDetailsType>(
`http://${process.env.HOST || 'localhost'}:${
process.env.PORT || 5055
}/api/v1/tv/${ctx.query.tvId}`,
`http://${getHostAndPort()}/api/v1/tv/${ctx.query.tvId}`,
{
headers: ctx.req?.headers?.cookie
? { cookie: ctx.req.headers.cookie }
+12
View File
@@ -0,0 +1,12 @@
import { Address6 } from 'ip-address';
export function getHostAndPort(): string {
let host = process.env.HOST || 'localhost';
if (Address6.isValid(host)) {
// If host is an IPv6 literal it needs to be placed in square brackets
host = `[${host}]`;
}
const port = Number(process.env.PORT) || 5055;
return `${host}:${port}`;
}