aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/HttpServer
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/HttpServer')
-rw-r--r--Emby.Server.Implementations/HttpServer/WebSocketConnection.cs36
-rw-r--r--Emby.Server.Implementations/HttpServer/WebSocketManager.cs13
2 files changed, 48 insertions, 1 deletions
diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
index 373b0994a6..6dc6d9d289 100644
--- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
+++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
@@ -1,5 +1,7 @@
using System;
using System.Buffers;
+using System.Collections.Generic;
+using System.Globalization;
using System.IO.Pipelines;
using System.Net;
using System.Net.WebSockets;
@@ -7,6 +9,7 @@ using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
+using Emby.Server.Implementations.Localization;
using Jellyfin.Extensions.Json;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Net.WebSocketMessages;
@@ -69,6 +72,17 @@ namespace Emby.Server.Implementations.HttpServer
/// <inheritdoc />
public IPAddress? RemoteEndPoint { get; }
+ /// <summary>
+ /// Gets or initializes the culture fallback chain captured from the
+ /// <c>Accept-Language</c> header of the upgrade request.
+ /// </summary>
+ public IReadOnlyList<string>? RequestCultureFallback { get; init; }
+
+ /// <summary>
+ /// Gets or initializes the UI culture name captured from the upgrade request.
+ /// </summary>
+ public string? RequestUICulture { get; init; }
+
/// <inheritdoc />
public Func<WebSocketMessageInfo, Task>? OnReceive { get; set; }
@@ -82,6 +96,28 @@ namespace Emby.Server.Implementations.HttpServer
public WebSocketState State => _socket.State;
/// <inheritdoc />
+ public void ApplyRequestCulture()
+ {
+ if (RequestCultureFallback is not null)
+ {
+ LocalizationManager.RequestCultureFallback = RequestCultureFallback;
+ }
+
+ if (!string.IsNullOrEmpty(RequestUICulture))
+ {
+ try
+ {
+ CultureInfo.CurrentUICulture = CultureInfo.GetCultureInfo(RequestUICulture);
+ }
+ catch (CultureNotFoundException)
+ {
+ // Jellyfin culture codes (e.g. "es_419") aren't always valid .NET cultures —
+ // skip setting CurrentUICulture; RequestCultureFallback above carries the chain.
+ }
+ }
+ }
+
+ /// <inheritdoc />
public async Task SendAsync(OutboundWebSocketMessage message, CancellationToken cancellationToken)
{
var json = JsonSerializer.SerializeToUtf8Bytes(message, _jsonOptions);
diff --git a/Emby.Server.Implementations/HttpServer/WebSocketManager.cs b/Emby.Server.Implementations/HttpServer/WebSocketManager.cs
index cb5b3993b8..3b5f6d1d09 100644
--- a/Emby.Server.Implementations/HttpServer/WebSocketManager.cs
+++ b/Emby.Server.Implementations/HttpServer/WebSocketManager.cs
@@ -4,9 +4,11 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Net.WebSockets;
using System.Threading.Tasks;
+using Emby.Server.Implementations.Localization;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Net;
using Microsoft.AspNetCore.Http;
@@ -48,13 +50,22 @@ namespace Emby.Server.Implementations.HttpServer
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);
+ // Capture the culture context set by AcceptLanguageMiddleware so it can be
+ // restored both when processing incoming messages and when periodic
+ // listeners produce server-initiated payloads on background tasks.
var connection = new WebSocketConnection(
_loggerFactory.CreateLogger<WebSocketConnection>(),
webSocket,
authorizationInfo,
context.GetNormalizedRemoteIP())
{
- OnReceive = ProcessWebSocketMessageReceived
+ RequestCultureFallback = LocalizationManager.RequestCultureFallback,
+ RequestUICulture = CultureInfo.CurrentUICulture.Name
+ };
+ connection.OnReceive = result =>
+ {
+ connection.ApplyRequestCulture();
+ return ProcessWebSocketMessageReceived(result);
};
await using (connection.ConfigureAwait(false))
{