1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-04-18 07:24:17 +03:00

Config: Updated DB host to handle ipv6

Can be set via the square bracket format.
For #5464
This commit is contained in:
Dan Brown 2025-03-15 20:32:57 +00:00
parent 94b1cffa2d
commit 4f5ad171ac
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
4 changed files with 44 additions and 14 deletions

View File

@ -56,6 +56,7 @@ APP_PROXIES=null
# Database details
# Host can contain a port (localhost:3306) or a separate DB_PORT option can be used.
# An ipv6 address can be used via the square bracket format ([::1]).
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=database_database

View File

@ -40,12 +40,16 @@ if (env('REDIS_SERVERS', false)) {
// MYSQL
// Split out port from host if set
$mysql_host = env('DB_HOST', 'localhost');
$mysql_host_exploded = explode(':', $mysql_host);
$mysql_port = env('DB_PORT', 3306);
if (count($mysql_host_exploded) > 1) {
$mysql_host = $mysql_host_exploded[0];
$mysql_port = intval($mysql_host_exploded[1]);
$mysqlHost = env('DB_HOST', 'localhost');
$mysqlHostExploded = explode(':', $mysqlHost);
$mysqlPort = env('DB_PORT', 3306);
$mysqlHostIpv6 = str_starts_with($mysqlHost, '[');
if ($mysqlHostIpv6 && str_contains($mysqlHost, ']:')) {
$mysqlHost = implode(':', array_slice($mysqlHostExploded, 0, -1));
$mysqlPort = intval(end($mysqlHostExploded));
} else if (!$mysqlHostIpv6 && count($mysqlHostExploded) > 1) {
$mysqlHost = $mysqlHostExploded[0];
$mysqlPort = intval($mysqlHostExploded[1]);
}
return [
@ -61,12 +65,12 @@ return [
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => $mysql_host,
'host' => $mysqlHost,
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'port' => $mysql_port,
'port' => $mysqlPort,
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
// Prefixes are only semi-supported and may be unstable
@ -88,7 +92,7 @@ return [
'database' => 'bookstack-test',
'username' => env('MYSQL_USER', 'bookstack-test'),
'password' => env('MYSQL_PASSWORD', 'bookstack-test'),
'port' => $mysql_port,
'port' => $mysqlPort,
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',

View File

@ -118,7 +118,7 @@ abstract class TestCase extends BaseTestCase
* Database config is juggled so the value can be restored when
* parallel testing are used, where multiple databases exist.
*/
protected function runWithEnv(string $name, $value, callable $callback)
protected function runWithEnv(string $name, $value, callable $callback, bool $handleDatabase = true)
{
Env::disablePutenv();
$originalVal = $_SERVER[$name] ?? null;
@ -132,13 +132,17 @@ abstract class TestCase extends BaseTestCase
$database = config('database.connections.mysql_testing.database');
$this->refreshApplication();
DB::purge();
config()->set('database.connections.mysql_testing.database', $database);
DB::beginTransaction();
if ($handleDatabase) {
DB::purge();
config()->set('database.connections.mysql_testing.database', $database);
DB::beginTransaction();
}
$callback();
DB::rollBack();
if ($handleDatabase) {
DB::rollBack();
}
if (is_null($originalVal)) {
unset($_SERVER[$name]);

View File

@ -160,6 +160,27 @@ class ConfigTest extends TestCase
$this->assertTrue($isMailTlsRequired());
}
public function test_mysql_host_parsed_as_expected()
{
$cases = [
'127.0.0.1' => ['127.0.0.1', 3306],
'127.0.0.1:3307' => ['127.0.0.1', 3307],
'a.example.com' => ['a.example.com', 3306],
'a.example.com:3307' => ['a.example.com', 3307],
'[::1]' => ['[::1]', 3306],
'[::1]:123' => ['[::1]', 123],
'[2001:db8:3c4d:0015:0000:0000:1a2f]' => ['[2001:db8:3c4d:0015:0000:0000:1a2f]', 3306],
'[2001:db8:3c4d:0015:0000:0000:1a2f]:4567' => ['[2001:db8:3c4d:0015:0000:0000:1a2f]', 4567],
];
foreach ($cases as $host => [$expectedHost, $expectedPort]) {
$this->runWithEnv("DB_HOST", $host, function () use ($expectedHost, $expectedPort) {
$this->assertEquals($expectedHost, config("database.connections.mysql.host"));
$this->assertEquals($expectedPort, config("database.connections.mysql.port"));
}, false);
}
}
/**
* Set an environment variable of the given name and value
* then check the given config key to see if it matches the given result.