mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
fix: session capabilities using disposed HTTP context
- Extract AccessToken from auth response before background task - Create new HeaderDictionary with token instead of using Request.Headers - Prevents ObjectDisposedException when HTTP context is disposed - Session capabilities now work correctly for all clients Note: WebSocket support for external tracks already implemented via JellyfinSessionManager.EnsureSessionAsync and WebSocketProxyMiddleware
This commit is contained in:
@@ -1838,43 +1838,62 @@ public class JellyfinController : ControllerBase
|
||||
{
|
||||
var responseJson = result.RootElement.GetRawText();
|
||||
|
||||
// On successful auth, post session capabilities in background
|
||||
// On successful auth, extract access token and post session capabilities in background
|
||||
if (statusCode == 200)
|
||||
{
|
||||
_logger.LogInformation("Authentication successful, posting session capabilities in background");
|
||||
_logger.LogInformation("Authentication successful");
|
||||
|
||||
// Don't await - do this in background so we return auth response immediately
|
||||
_ = Task.Run(async () =>
|
||||
// Extract access token from response for session capabilities
|
||||
string? accessToken = null;
|
||||
if (result.RootElement.TryGetProperty("AccessToken", out var tokenEl))
|
||||
{
|
||||
try
|
||||
accessToken = tokenEl.GetString();
|
||||
}
|
||||
|
||||
// Post session capabilities in background if we have a token
|
||||
if (!string.IsNullOrEmpty(accessToken))
|
||||
{
|
||||
// Capture token in closure - don't use Request.Headers (will be disposed)
|
||||
var token = accessToken;
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
_logger.LogInformation("🔧 Posting session capabilities after authentication");
|
||||
var capabilities = new
|
||||
try
|
||||
{
|
||||
PlayableMediaTypes = new[] { "Audio" },
|
||||
SupportedCommands = Array.Empty<string>(),
|
||||
SupportsMediaControl = false,
|
||||
SupportsPersistentIdentifier = true,
|
||||
SupportsSync = false
|
||||
};
|
||||
|
||||
var capabilitiesJson = JsonSerializer.Serialize(capabilities);
|
||||
var (capResult, capStatus) = await _proxyService.PostJsonAsync("Sessions/Capabilities/Full", capabilitiesJson, Request.Headers);
|
||||
|
||||
if (capStatus == 204 || capStatus == 200)
|
||||
{
|
||||
_logger.LogInformation("✓ Session capabilities posted after auth ({StatusCode})", capStatus);
|
||||
_logger.LogDebug("🔧 Posting session capabilities after authentication");
|
||||
|
||||
// Build auth header with the new token
|
||||
var authHeaders = new HeaderDictionary
|
||||
{
|
||||
["X-Emby-Token"] = token
|
||||
};
|
||||
|
||||
var capabilities = new
|
||||
{
|
||||
PlayableMediaTypes = new[] { "Audio" },
|
||||
SupportedCommands = Array.Empty<string>(),
|
||||
SupportsMediaControl = false,
|
||||
SupportsPersistentIdentifier = true,
|
||||
SupportsSync = false
|
||||
};
|
||||
|
||||
var capabilitiesJson = JsonSerializer.Serialize(capabilities);
|
||||
var (capResult, capStatus) = await _proxyService.PostJsonAsync("Sessions/Capabilities/Full", capabilitiesJson, authHeaders);
|
||||
|
||||
if (capStatus == 204 || capStatus == 200)
|
||||
{
|
||||
_logger.LogDebug("✓ Session capabilities posted after auth ({StatusCode})", capStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogDebug("⚠ Session capabilities returned {StatusCode} after auth", capStatus);
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning("⚠ Session capabilities returned {StatusCode} after auth", capStatus);
|
||||
_logger.LogDebug(ex, "Failed to post session capabilities after auth");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to post session capabilities after auth");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user