mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-24 05:27:30 +01:00
Merge branch 'master' into dev
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" Condition="'$(TgsTestNoSdk)' != 'true'" />
|
||||
<!-- Usage: Dependency mocking for tests -->
|
||||
<!-- Pinned: Be VERY careful about updating https://github.com/moq/moq/issues/1372 -->
|
||||
<PackageReference Include="Moq" Version="4.20.69" />
|
||||
<PackageReference Include="Moq" Version="4.20.70" />
|
||||
<!-- Usage: MSTest execution -->
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
|
||||
<!-- Usage: MSTest asserts etc... -->
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<!-- Usage: HTTP constants reference -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
|
||||
<!-- Usage: Decoding the 'nbf' property of JWTs -->
|
||||
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="7.0.3" />
|
||||
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="7.1.2" />
|
||||
<!-- Usage: Primary JSON library -->
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<!-- Usage: Data model annotating -->
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Usage: Connecting to SignalR hubs in API -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.1" />
|
||||
<!-- Usage: Using target JSON serializer for API -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -518,6 +518,7 @@ namespace Tgstation.Server.Host.Components
|
||||
}
|
||||
|
||||
IBridgeHandler? bridgeHandler = null;
|
||||
var loggedDelay = false;
|
||||
for (var i = 0; bridgeHandler == null && i < 30; ++i)
|
||||
{
|
||||
// There's a miniscule time period where we could potentially receive a bridge request and not have the registration ready when we launch DD
|
||||
@@ -525,7 +526,15 @@ namespace Tgstation.Server.Host.Components
|
||||
Task delayTask = Task.CompletedTask;
|
||||
lock (bridgeHandlers)
|
||||
if (!bridgeHandlers.TryGetValue(accessIdentifier, out bridgeHandler))
|
||||
{
|
||||
if (!loggedDelay)
|
||||
{
|
||||
logger.LogTrace("Received bridge request with unregistered access identifier \"{aid}\". Waiting up to 3 seconds for it to be registered...", accessIdentifier);
|
||||
loggedDelay = true;
|
||||
}
|
||||
|
||||
delayTask = asyncDelayer.Delay(TimeSpan.FromMilliseconds(100), cancellationToken);
|
||||
}
|
||||
|
||||
await delayTask;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,12 @@ namespace Tgstation.Server.Host.Controllers
|
||||
/// <summary>
|
||||
/// If the content of bridge requests and responses should be logged.
|
||||
/// </summary>
|
||||
internal static bool LogContent { get; set; }
|
||||
static bool LogContent => logContentDisableCounter == 0;
|
||||
|
||||
/// <summary>
|
||||
/// Counter which, if not zero, indicates content logging should be disabled.
|
||||
/// </summary>
|
||||
static uint logContentDisableCounter;
|
||||
|
||||
/// <summary>
|
||||
/// Static counter for the number of requests processed.
|
||||
@@ -54,12 +59,14 @@ namespace Tgstation.Server.Host.Controllers
|
||||
readonly ILogger<BridgeController> logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes static members of the <see cref="BridgeController"/> class.
|
||||
/// Temporarily disable content logging. Must be followed up with a call to <see cref="ReenableContentLogging"/>.
|
||||
/// </summary>
|
||||
static BridgeController()
|
||||
{
|
||||
LogContent = true;
|
||||
}
|
||||
internal static void TemporarilyDisableContentLogging() => Interlocked.Increment(ref logContentDisableCounter);
|
||||
|
||||
/// <summary>
|
||||
/// Reenable content logging. Must be preceeded with a call to <see cref="TemporarilyDisableContentLogging"/>.
|
||||
/// </summary>
|
||||
internal static void ReenableContentLogging() => Interlocked.Decrement(ref logContentDisableCounter);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BridgeController"/> class.
|
||||
@@ -87,16 +94,16 @@ namespace Tgstation.Server.Host.Controllers
|
||||
[AllowAnonymous]
|
||||
public async ValueTask<IActionResult> Process([FromQuery] string data, CancellationToken cancellationToken)
|
||||
{
|
||||
// Nothing to see here
|
||||
var remoteIP = Request.HttpContext.Connection.RemoteIpAddress;
|
||||
if (remoteIP == null || !IPAddress.IsLoopback(remoteIP))
|
||||
{
|
||||
logger.LogTrace("Rejecting remote bridge request from {remoteIP}", remoteIP);
|
||||
return Forbid();
|
||||
}
|
||||
|
||||
using (LogContext.PushProperty(SerilogContextHelper.BridgeRequestIterationContextProperty, Interlocked.Increment(ref requestsProcessed)))
|
||||
{
|
||||
// Nothing to see here
|
||||
var remoteIP = Request.HttpContext.Connection.RemoteIpAddress;
|
||||
if (remoteIP == null || !IPAddress.IsLoopback(remoteIP))
|
||||
{
|
||||
logger.LogTrace("Rejecting remote bridge request from {remoteIP}", remoteIP);
|
||||
return Forbid();
|
||||
}
|
||||
|
||||
BridgeParameters? request;
|
||||
try
|
||||
{
|
||||
@@ -106,6 +113,9 @@ namespace Tgstation.Server.Host.Controllers
|
||||
{
|
||||
if (LogContent)
|
||||
logger.LogWarning(ex, "Error deserializing bridge request: {badJson}", data);
|
||||
else
|
||||
logger.LogWarning(ex, "Error deserializing bridge request!");
|
||||
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
@@ -113,11 +123,16 @@ namespace Tgstation.Server.Host.Controllers
|
||||
{
|
||||
if (LogContent)
|
||||
logger.LogWarning("Error deserializing bridge request: {badJson}", data);
|
||||
else
|
||||
logger.LogWarning("Error deserializing bridge request!");
|
||||
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
if (LogContent)
|
||||
logger.LogTrace("Bridge Request: {json}", data);
|
||||
else
|
||||
logger.LogTrace("Bridge Request");
|
||||
|
||||
var response = await bridgeDispatcher.ProcessBridgeRequest(request, cancellationToken);
|
||||
if (response == null)
|
||||
|
||||
@@ -76,21 +76,21 @@
|
||||
<!-- Usage: git interop -->
|
||||
<PackageReference Include="LibGit2Sharp" Version="0.29.0" />
|
||||
<!-- Usage: JWT injection into HTTP pipeline -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.1" />
|
||||
<!-- Usage: Support ""legacy"" Newotonsoft.Json in HTTP pipeline. The rest of our codebase uses Newtonsoft. -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.1" />
|
||||
<!-- Usage: Using target JSON serializer for API -->
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="8.0.1" />
|
||||
<!-- Usage: Database ORM -->
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.1" />
|
||||
<!-- Usage: Automatic migration generation using command line -->
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.1">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<!-- Usage: Sqlite ORM plugin -->
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.1" />
|
||||
<!-- Usage: MSSQL ORM plugin -->
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.1" />
|
||||
<!-- Usage: POSIX support for syscalls, signals, and symlinks -->
|
||||
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||
<!-- Usage: YAML config plugin -->
|
||||
@@ -98,7 +98,7 @@
|
||||
<!-- Usage: PostgresSQL ORM plugin -->
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
|
||||
<!-- Usage: GitHub.com interop -->
|
||||
<PackageReference Include="Octokit" Version="9.0.0" />
|
||||
<PackageReference Include="Octokit" Version="9.1.0" />
|
||||
<!-- Usage: MYSQL/MariaDB ORM plugin -->
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.0-beta.2" />
|
||||
<!-- Usage: Discord interop -->
|
||||
@@ -119,8 +119,6 @@
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.5.0" />
|
||||
<!-- Usage: Windows authentication plugin allowing searching for users by name -->
|
||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="8.0.0" />
|
||||
<!-- Usage: JWT plugin needed to undo some Microsoft meddling in the HTTP pipeline -->
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.0.3" />
|
||||
<!-- Usage: Identifying owning user of Windows Process objects -->
|
||||
<PackageReference Include="System.Management" Version="8.0.0" />
|
||||
<!-- Usage: Temporary resolution to compatibility issues with EFCore 7 and .NET 8 -->
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Tgstation.Server.Tests.Live
|
||||
&& !((exception is BadHttpRequestException) && logMessage.Contains("Unexpected end of request content.")) // canceled request
|
||||
&& !logMessage.StartsWith("Error disconnecting connection ")
|
||||
&& !(logMessage.StartsWith("An exception occurred while iterating over the results of a query for context type") && (exception is OperationCanceledException || exception?.InnerException is OperationCanceledException))
|
||||
&& !(logMessage.StartsWith("An error occurred using the connection to database ") && (exception is OperationCanceledException || exception?.InnerException is OperationCanceledException))
|
||||
&& !(logMessage.Contains("An error occurred using the connection to database ") && (exception == null || (exception is OperationCanceledException || exception?.InnerException is OperationCanceledException)))
|
||||
&& !(logMessage.StartsWith("Error when dispatching 'OnConnectedAsync' on hub") && (exception is OperationCanceledException || exception?.InnerException is OperationCanceledException))
|
||||
&& !(logMessage.StartsWith("An exception occurred in the database while saving changes for context type") && (exception is OperationCanceledException || exception?.InnerException is OperationCanceledException)))
|
||||
|| (logLevel == LogLevel.Critical && logMessage != "DropDatabase configuration option set! Dropping any existing database..."))
|
||||
|
||||
@@ -893,7 +893,7 @@ namespace Tgstation.Server.Tests.Live.Instance
|
||||
{
|
||||
// first check the bridge limits
|
||||
var bridgeTestsTcs = new TaskCompletionSource();
|
||||
BridgeController.LogContent = false;
|
||||
BridgeController.TemporarilyDisableContentLogging();
|
||||
using (var loggerFactory = LoggerFactory.Create(builder =>
|
||||
{
|
||||
builder.AddConsole();
|
||||
@@ -914,7 +914,7 @@ namespace Tgstation.Server.Tests.Live.Instance
|
||||
await bridgeTestsTcs.Task.WaitAsync(cancellationToken);
|
||||
}
|
||||
|
||||
BridgeController.LogContent = true;
|
||||
BridgeController.ReenableContentLogging();
|
||||
|
||||
// Time for DD to revert the bridge access identifier change
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
|
||||
|
||||
@@ -61,6 +61,16 @@ namespace Tgstation.Server.Tests.Live
|
||||
static readonly Lazy<ushort> mainDDPort = new(() => FreeTcpPort(odDDPort.Value, odDMPort.Value, compatDMPort.Value, compatDDPort.Value));
|
||||
static readonly Lazy<ushort> mainDMPort = new(() => FreeTcpPort(odDDPort.Value, odDMPort.Value, compatDMPort.Value, compatDDPort.Value, mainDDPort.Value));
|
||||
|
||||
static void InitializePorts()
|
||||
{
|
||||
_ = odDMPort.Value;
|
||||
_ = odDDPort.Value;
|
||||
_ = compatDMPort.Value;
|
||||
_ = compatDDPort.Value;
|
||||
_ = mainDDPort.Value;
|
||||
_ = mainDMPort.Value;
|
||||
}
|
||||
|
||||
readonly ServerClientFactory clientFactory = new (new ProductHeaderValue(Assembly.GetExecutingAssembly().GetName().Name, Assembly.GetExecutingAssembly().GetName().Version.ToString()));
|
||||
|
||||
public static List<System.Diagnostics.Process> GetEngineServerProcessesOnPort(EngineType engineType, ushort? port)
|
||||
@@ -162,7 +172,8 @@ namespace Tgstation.Server.Tests.Live
|
||||
}
|
||||
catch
|
||||
{
|
||||
l.Stop();
|
||||
using (l)
|
||||
l.Stop();
|
||||
throw;
|
||||
}
|
||||
|
||||
@@ -172,10 +183,9 @@ namespace Tgstation.Server.Tests.Live
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach(var l in listeners)
|
||||
{
|
||||
l.Stop();
|
||||
}
|
||||
foreach (var l in listeners)
|
||||
using (l)
|
||||
l.Stop();
|
||||
}
|
||||
|
||||
Console.WriteLine($"Allocated port: {result}");
|
||||
@@ -1238,6 +1248,8 @@ namespace Tgstation.Server.Tests.Live
|
||||
using (var currentProcess = System.Diagnostics.Process.GetCurrentProcess())
|
||||
Assert.AreEqual(ProcessPriorityClass.Normal, currentProcess.PriorityClass);
|
||||
|
||||
InitializePorts();
|
||||
|
||||
var maximumTestMinutes = TestingUtils.RunningInGitHubActions ? 90 : 20;
|
||||
using var hardCancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(maximumTestMinutes));
|
||||
var hardCancellationToken = hardCancellationTokenSource.Token;
|
||||
|
||||
Reference in New Issue
Block a user