aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasily <JustAMan@users.noreply.github.com>2019-02-16 03:22:12 +0300
committerGitHub <noreply@github.com>2019-02-16 03:22:12 +0300
commitb7ae044e653859b9190783e38e720d5c13a13098 (patch)
treed7ab62a67bc7b45c73d98418b7edee05b7818ad1
parent7cc69f30c4519db4162acfbc4d056ae34e6ca6ef (diff)
parent18e1d03a89b7fe3ddba925f81b153d0f0cd1973c (diff)
Merge pull request #885 from Bond-009/warn
More warning fixes
-rw-r--r--Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs2
-rw-r--r--Jellyfin.Drawing.Skia/SkiaEncoder.cs2
-rw-r--r--Jellyfin.Server/CoreAppHost.cs7
-rw-r--r--Jellyfin.Server/Jellyfin.Server.csproj3
-rw-r--r--Jellyfin.Server/Program.cs48
-rw-r--r--Jellyfin.Server/SocketSharp/RequestMono.cs152
-rw-r--r--Jellyfin.Server/SocketSharp/SharpWebSocket.cs44
-rw-r--r--Jellyfin.Server/SocketSharp/WebSocketSharpListener.cs61
-rw-r--r--Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs27
-rw-r--r--Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs20
-rw-r--r--jellyfin.ruleset8
11 files changed, 212 insertions, 162 deletions
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
index 4eff9252e..d74cf3be2 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
@@ -94,7 +94,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
var now = DateTime.UtcNow;
- var _ = StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
+ _ = StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token);
//OpenedMediaSource.Protocol = MediaProtocol.File;
//OpenedMediaSource.Path = tempFile;
diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs
index dc714ed18..5060476ba 100644
--- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs
+++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs
@@ -282,7 +282,7 @@ namespace Jellyfin.Drawing.Skia
var bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height, !requiresTransparencyHack);
// decode
- var _ = codec.GetPixels(bitmap.Info, bitmap.GetPixels());
+ _ = codec.GetPixels(bitmap.Info, bitmap.GetPixels());
origin = codec.EncodedOrigin;
diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs
index a486c2a47..126cb467f 100644
--- a/Jellyfin.Server/CoreAppHost.cs
+++ b/Jellyfin.Server/CoreAppHost.cs
@@ -18,6 +18,8 @@ namespace Jellyfin.Server
public override bool CanSelfRestart => StartupOptions.RestartPath != null;
+ protected override bool SupportsDualModeSockets => true;
+
protected override void RestartInternal() => Program.Restart();
protected override IEnumerable<Assembly> GetAssembliesWithPartsInternal()
@@ -27,8 +29,6 @@ namespace Jellyfin.Server
protected override void ShutdownInternal() => Program.Shutdown();
- protected override bool SupportsDualModeSockets => true;
-
protected override IHttpListener CreateHttpListener()
=> new WebSocketSharpListener(
Logger,
@@ -39,7 +39,6 @@ namespace Jellyfin.Server
CryptographyProvider,
SupportsDualModeSockets,
FileSystemManager,
- EnvironmentInfo
- );
+ EnvironmentInfo);
}
}
diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj
index fe1397bcb..bd670df52 100644
--- a/Jellyfin.Server/Jellyfin.Server.csproj
+++ b/Jellyfin.Server/Jellyfin.Server.csproj
@@ -5,11 +5,14 @@
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+ <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<PropertyGroup>
<!-- We need C# 7.1 for async main-->
<LangVersion>latest</LangVersion>
+ <!-- Disable documentation warnings (for now) -->
+ <NoWarn>SA1600;CS1591</NoWarn>
</PropertyGroup>
<ItemGroup>
diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs
index 2c177290e..ac5aab460 100644
--- a/Jellyfin.Server/Program.cs
+++ b/Jellyfin.Server/Program.cs
@@ -57,13 +57,28 @@ namespace Jellyfin.Server
errs => Task.FromResult(0)).ConfigureAwait(false);
}
+ public static void Shutdown()
+ {
+ if (!_tokenSource.IsCancellationRequested)
+ {
+ _tokenSource.Cancel();
+ }
+ }
+
+ public static void Restart()
+ {
+ _restartOnShutdown = true;
+
+ Shutdown();
+ }
+
private static async Task StartApp(StartupOptions options)
{
ServerApplicationPaths appPaths = CreateApplicationPaths(options);
// $JELLYFIN_LOG_DIR needs to be set for the logger configuration manager
Environment.SetEnvironmentVariable("JELLYFIN_LOG_DIR", appPaths.LogDirectoryPath);
- await CreateLogger(appPaths);
+ await CreateLogger(appPaths).ConfigureAwait(false);
_logger = _loggerFactory.CreateLogger("Main");
AppDomain.CurrentDomain.UnhandledException += (sender, e)
@@ -76,6 +91,7 @@ namespace Jellyfin.Server
{
return; // Already shutting down
}
+
e.Cancel = true;
_logger.LogInformation("Ctrl+C, shutting down");
Environment.ExitCode = 128 + 2;
@@ -89,6 +105,7 @@ namespace Jellyfin.Server
{
return; // Already shutting down
}
+
_logger.LogInformation("Received a SIGTERM signal, shutting down");
Environment.ExitCode = 128 + 15;
Shutdown();
@@ -102,7 +119,7 @@ namespace Jellyfin.Server
SQLitePCL.Batteries_V2.Init();
// Allow all https requests
- ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; });
+ ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; } );
var fileSystem = new ManagedFileSystem(_loggerFactory, environmentInfo, null, appPaths.TempDirectory, true);
@@ -115,18 +132,18 @@ namespace Jellyfin.Server
new NullImageEncoder(),
new NetworkManager(_loggerFactory, environmentInfo)))
{
- await appHost.Init(new ServiceCollection());
+ await appHost.Init(new ServiceCollection()).ConfigureAwait(false);
appHost.ImageProcessor.ImageEncoder = GetImageEncoder(fileSystem, appPaths, appHost.LocalizationManager);
- await appHost.RunStartupTasks();
+ await appHost.RunStartupTasks().ConfigureAwait(false);
// TODO: read input for a stop command
try
{
// Block main thread until shutdown
- await Task.Delay(-1, _tokenSource.Token);
+ await Task.Delay(-1, _tokenSource.Token).ConfigureAwait(false);
}
catch (TaskCanceledException)
{
@@ -146,7 +163,7 @@ namespace Jellyfin.Server
/// for everything else the XDG approach is followed:
/// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
/// </summary>
- /// <param name="options"></param>
+ /// <param name="options">StartupOptions</param>
/// <returns>ServerApplicationPaths</returns>
private static ServerApplicationPaths CreateApplicationPaths(StartupOptions options)
{
@@ -308,6 +325,7 @@ namespace Jellyfin.Server
await rscstr.CopyToAsync(fstr).ConfigureAwait(false);
}
}
+
var configuration = new ConfigurationBuilder()
.SetBasePath(appPaths.ConfigurationDirectoryPath)
.AddJsonFile("logging.json")
@@ -335,7 +353,7 @@ namespace Jellyfin.Server
}
}
- public static IImageEncoder GetImageEncoder(
+ private static IImageEncoder GetImageEncoder(
IFileSystem fileSystem,
IApplicationPaths appPaths,
ILocalizationManager localizationManager)
@@ -376,26 +394,12 @@ namespace Jellyfin.Server
{
return MediaBrowser.Model.System.OperatingSystem.BSD;
}
+
throw new Exception($"Can't resolve OS with description: '{osDescription}'");
}
}
}
- public static void Shutdown()
- {
- if (!_tokenSource.IsCancellationRequested)
- {
- _tokenSource.Cancel();
- }
- }
-
- public static void Restart()
- {
- _restartOnShutdown = true;
-
- Shutdown();
- }
-
private static void StartNewInstance(StartupOptions options)
{
_logger.LogInformation("Starting new instance");
diff --git a/Jellyfin.Server/SocketSharp/RequestMono.cs b/Jellyfin.Server/SocketSharp/RequestMono.cs
index a8ba4cdb5..24cf994ea 100644
--- a/Jellyfin.Server/SocketSharp/RequestMono.cs
+++ b/Jellyfin.Server/SocketSharp/RequestMono.cs
@@ -13,7 +13,7 @@ namespace Jellyfin.Server.SocketSharp
{
internal static string GetParameter(string header, string attr)
{
- int ap = header.IndexOf(attr);
+ int ap = header.IndexOf(attr, StringComparison.Ordinal);
if (ap == -1)
{
return null;
@@ -82,9 +82,7 @@ namespace Jellyfin.Server.SocketSharp
}
else
{
- //
// We use a substream, as in 2.x we will support large uploads streamed to disk,
- //
var sub = new HttpPostedFile(e.Filename, e.ContentType, input, e.Start, e.Length);
files[e.Name] = sub;
}
@@ -127,8 +125,12 @@ namespace Jellyfin.Server.SocketSharp
public string Authorization => string.IsNullOrEmpty(request.Headers["Authorization"]) ? null : request.Headers["Authorization"];
- protected bool validate_cookies, validate_query_string, validate_form;
- protected bool checked_cookies, checked_query_string, checked_form;
+ protected bool validate_cookies { get; set; }
+ protected bool validate_query_string { get; set; }
+ protected bool validate_form { get; set; }
+ protected bool checked_cookies { get; set; }
+ protected bool checked_query_string { get; set; }
+ protected bool checked_form { get; set; }
private static void ThrowValidationException(string name, string key, string value)
{
@@ -138,8 +140,12 @@ namespace Jellyfin.Server.SocketSharp
v = v.Substring(0, 16) + "...\"";
}
- string msg = string.Format("A potentially dangerous Request.{0} value was " +
- "detected from the client ({1}={2}).", name, key, v);
+ string msg = string.Format(
+ CultureInfo.InvariantCulture,
+ "A potentially dangerous Request.{0} value was detected from the client ({1}={2}).",
+ name,
+ key,
+ v);
throw new Exception(msg);
}
@@ -179,6 +185,7 @@ namespace Jellyfin.Server.SocketSharp
for (int idx = 1; idx < len; idx++)
{
char next = val[idx];
+
// See http://secunia.com/advisories/14325
if (current == '<' || current == '\xff1c')
{
@@ -256,6 +263,7 @@ namespace Jellyfin.Server.SocketSharp
value.Append((char)c);
}
}
+
if (c == -1)
{
AddRawKeyValue(form, key, value);
@@ -271,6 +279,7 @@ namespace Jellyfin.Server.SocketSharp
key.Append((char)c);
}
}
+
if (c == -1)
{
AddRawKeyValue(form, key, value);
@@ -308,6 +317,7 @@ namespace Jellyfin.Server.SocketSharp
result.Append(key);
result.Append('=');
}
+
result.Append(pair.Value);
}
@@ -429,13 +439,13 @@ namespace Jellyfin.Server.SocketSharp
real = position + d;
break;
default:
- throw new ArgumentException(nameof(origin));
+ throw new ArgumentException("Unknown SeekOrigin value", nameof(origin));
}
long virt = real - offset;
if (virt < 0 || virt > Length)
{
- throw new ArgumentException();
+ throw new ArgumentException("Invalid position", nameof(d));
}
position = s.Seek(real, SeekOrigin.Begin);
@@ -491,11 +501,6 @@ namespace Jellyfin.Server.SocketSharp
public Stream InputStream => stream;
}
- private class Helpers
- {
- public static readonly CultureInfo InvariantCulture = CultureInfo.InvariantCulture;
- }
-
internal static class StrUtils
{
public static bool StartsWith(string str1, string str2, bool ignore_case)
@@ -533,12 +538,17 @@ namespace Jellyfin.Server.SocketSharp
public class Element
{
- public string ContentType;
- public string Name;
- public string Filename;
- public Encoding Encoding;
- public long Start;
- public long Length;
+ public string ContentType { get; set; }
+
+ public string Name { get; set; }
+
+ public string Filename { get; set; }
+
+ public Encoding Encoding { get; set; }
+
+ public long Start { get; set; }
+
+ public long Length { get; set; }
public override string ToString()
{
@@ -547,15 +557,23 @@ namespace Jellyfin.Server.SocketSharp
}
}
+ private const byte LF = (byte)'\n';
+
+ private const byte CR = (byte)'\r';
+
private Stream data;
+
private string boundary;
- private byte[] boundary_bytes;
+
+ private byte[] boundaryBytes;
+
private byte[] buffer;
- private bool at_eof;
+
+ private bool atEof;
+
private Encoding encoding;
- private StringBuilder sb;
- private const byte LF = (byte)'\n', CR = (byte)'\r';
+ private StringBuilder sb;
// See RFC 2046
// In the case of multipart entities, in which one or more different
@@ -570,18 +588,48 @@ namespace Jellyfin.Server.SocketSharp
public HttpMultipart(Stream data, string b, Encoding encoding)
{
this.data = data;
- //DB: 30/01/11: cannot set or read the Position in HttpListener in Win.NET
- //var ms = new MemoryStream(32 * 1024);
- //data.CopyTo(ms);
- //this.data = ms;
-
boundary = b;
- boundary_bytes = encoding.GetBytes(b);
- buffer = new byte[boundary_bytes.Length + 2]; // CRLF or '--'
+ boundaryBytes = encoding.GetBytes(b);
+ buffer = new byte[boundaryBytes.Length + 2]; // CRLF or '--'
this.encoding = encoding;
sb = new StringBuilder();
}
+ public Element ReadNextElement()
+ {
+ if (atEof || ReadBoundary())
+ {
+ return null;
+ }
+
+ var elem = new Element();
+ string header;
+ while ((header = ReadHeaders()) != null)
+ {
+ if (StrUtils.StartsWith(header, "Content-Disposition:", true))
+ {
+ elem.Name = GetContentDispositionAttribute(header, "name");
+ elem.Filename = StripPath(GetContentDispositionAttributeWithEncoding(header, "filename"));
+ }
+ else if (StrUtils.StartsWith(header, "Content-Type:", true))
+ {
+ elem.ContentType = header.Substring("Content-Type:".Length).Trim();
+ elem.Encoding = GetEncoding(elem.ContentType);
+ }
+ }
+
+ long start = data.Position;
+ elem.Start = start;
+ long pos = MoveToNextBoundary();
+ if (pos == -1)
+ {
+ return null;
+ }
+
+ elem.Length = pos - start;
+ return elem;
+ }
+
private string ReadLine()
{
// CRLF or LF are ok as line endings.
@@ -600,6 +648,7 @@ namespace Jellyfin.Server.SocketSharp
{
break;
}
+
got_cr = b == CR;
sb.Append((char)b);
}
@@ -769,7 +818,7 @@ namespace Jellyfin.Server.SocketSharp
return -1;
}
- if (!CompareBytes(boundary_bytes, buffer))
+ if (!CompareBytes(boundaryBytes, buffer))
{
state = 0;
data.Position = retval + 2;
@@ -785,7 +834,7 @@ namespace Jellyfin.Server.SocketSharp
if (buffer[bl - 2] == '-' && buffer[bl - 1] == '-')
{
- at_eof = true;
+ atEof = true;
}
else if (buffer[bl - 2] != CR || buffer[bl - 1] != LF)
{
@@ -800,6 +849,7 @@ namespace Jellyfin.Server.SocketSharp
c = data.ReadByte();
continue;
}
+
data.Position = retval + 2;
if (got_cr)
{
@@ -818,42 +868,6 @@ namespace Jellyfin.Server.SocketSharp
return retval;
}
- public Element ReadNextElement()
- {
- if (at_eof || ReadBoundary())
- {
- return null;
- }
-
- var elem = new Element();
- string header;
- while ((header = ReadHeaders()) != null)
- {
- if (StrUtils.StartsWith(header, "Content-Disposition:", true))
- {
- elem.Name = GetContentDispositionAttribute(header, "name");
- elem.Filename = StripPath(GetContentDispositionAttributeWithEncoding(header, "filename"));
- }
- else if (StrUtils.StartsWith(header, "Content-Type:", true))
- {
- elem.ContentType = header.Substring("Content-Type:".Length).Trim();
- elem.Encoding = GetEncoding(elem.ContentType);
- }
- }
-
- long start = 0;
- start = data.Position;
- elem.Start = start;
- long pos = MoveToNextBoundary();
- if (pos == -1)
- {
- return null;
- }
-
- elem.Length = pos - start;
- return elem;
- }
-
private static string StripPath(string path)
{
if (path == null || path.Length == 0)
diff --git a/Jellyfin.Server/SocketSharp/SharpWebSocket.cs b/Jellyfin.Server/SocketSharp/SharpWebSocket.cs
index f371cb25a..6eee4cd12 100644
--- a/Jellyfin.Server/SocketSharp/SharpWebSocket.cs
+++ b/Jellyfin.Server/SocketSharp/SharpWebSocket.cs
@@ -24,6 +24,7 @@ namespace Jellyfin.Server.SocketSharp
private TaskCompletionSource<bool> _taskCompletionSource = new TaskCompletionSource<bool>();
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
+ private bool _disposed = false;
public SharpWebSocket(SocketHttpListener.WebSocket socket, ILogger logger)
{
@@ -40,9 +41,9 @@ namespace Jellyfin.Server.SocketSharp
_logger = logger;
WebSocket = socket;
- socket.OnMessage += socket_OnMessage;
- socket.OnClose += socket_OnClose;
- socket.OnError += socket_OnError;
+ socket.OnMessage += OnSocketMessage;
+ socket.OnClose += OnSocketClose;
+ socket.OnError += OnSocketError;
WebSocket.ConnectAsServer();
}
@@ -52,29 +53,22 @@ namespace Jellyfin.Server.SocketSharp
return _taskCompletionSource.Task;
}
- void socket_OnError(object sender, SocketHttpListener.ErrorEventArgs e)
+ private void OnSocketError(object sender, SocketHttpListener.ErrorEventArgs e)
{
_logger.LogError("Error in SharpWebSocket: {Message}", e.Message ?? string.Empty);
- //Closed?.Invoke(this, EventArgs.Empty);
+
+ // Closed?.Invoke(this, EventArgs.Empty);
}
- void socket_OnClose(object sender, SocketHttpListener.CloseEventArgs e)
+ private void OnSocketClose(object sender, SocketHttpListener.CloseEventArgs e)
{
_taskCompletionSource.TrySetResult(true);
Closed?.Invoke(this, EventArgs.Empty);
}
- void socket_OnMessage(object sender, SocketHttpListener.MessageEventArgs e)
+ private void OnSocketMessage(object sender, SocketHttpListener.MessageEventArgs e)
{
- //if (!string.IsNullOrEmpty(e.Data))
- //{
- // if (OnReceive != null)
- // {
- // OnReceive(e.Data);
- // }
- // return;
- //}
if (OnReceiveBytes != null)
{
OnReceiveBytes(e.RawData);
@@ -117,6 +111,7 @@ namespace Jellyfin.Server.SocketSharp
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
/// <summary>
@@ -125,16 +120,23 @@ namespace Jellyfin.Server.SocketSharp
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool dispose)
{
+ if (_disposed)
+ {
+ return;
+ }
+
if (dispose)
{
- WebSocket.OnMessage -= socket_OnMessage;
- WebSocket.OnClose -= socket_OnClose;
- WebSocket.OnError -= socket_OnError;
+ WebSocket.OnMessage -= OnSocketMessage;
+ WebSocket.OnClose -= OnSocketClose;
+ WebSocket.OnError -= OnSocketError;
_cancellationTokenSource.Cancel();
WebSocket.Close();
}
+
+ _disposed = true;
}
/// <summary>
@@ -142,11 +144,5 @@ namespace Jellyfin.Server.SocketSharp
/// </summary>
/// <value>The receive action.</value>
public Action<byte[]> OnReceiveBytes { get; set; }
-
- /// <summary>
- /// Gets or sets the on receive.
- /// </summary>
- /// <value>The on receive.</value>
- public Action<string> OnReceive { get; set; }
}
}
diff --git a/Jellyfin.Server/SocketSharp/WebSocketSharpListener.cs b/Jellyfin.Server/SocketSharp/WebSocketSharpListener.cs
index a44343ab2..58c4d38a2 100644
--- a/Jellyfin.Server/SocketSharp/WebSocketSharpListener.cs
+++ b/Jellyfin.Server/SocketSharp/WebSocketSharpListener.cs
@@ -34,9 +34,16 @@ namespace Jellyfin.Server.SocketSharp
private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource();
private CancellationToken _disposeCancellationToken;
- public WebSocketSharpListener(ILogger logger, X509Certificate certificate, IStreamHelper streamHelper,
- INetworkManager networkManager, ISocketFactory socketFactory, ICryptoProvider cryptoProvider,
- bool enableDualMode, IFileSystem fileSystem, IEnvironmentInfo environment)
+ public WebSocketSharpListener(
+ ILogger logger,
+ X509Certificate certificate,
+ IStreamHelper streamHelper,
+ INetworkManager networkManager,
+ ISocketFactory socketFactory,
+ ICryptoProvider cryptoProvider,
+ bool enableDualMode,
+ IFileSystem fileSystem,
+ IEnvironmentInfo environment)
{
_logger = logger;
_certificate = certificate;
@@ -61,7 +68,9 @@ namespace Jellyfin.Server.SocketSharp
public void Start(IEnumerable<string> urlPrefixes)
{
if (_listener == null)
+ {
_listener = new HttpListener(_logger, _cryptoProvider, _socketFactory, _networkManager, _streamHelper, _fileSystem, _environment);
+ }
_listener.EnableDualMode = _enableDualMode;
@@ -83,15 +92,18 @@ namespace Jellyfin.Server.SocketSharp
private void ProcessContext(HttpListenerContext context)
{
- var _ = Task.Run(async () => await InitTask(context, _disposeCancellationToken));
+ _ = Task.Run(async () => await InitTask(context, _disposeCancellationToken).ConfigureAwait(false));
}
private static void LogRequest(ILogger logger, HttpListenerRequest request)
{
var url = request.Url.ToString();
- logger.LogInformation("{0} {1}. UserAgent: {2}",
- request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod, url, request.UserAgent ?? string.Empty);
+ logger.LogInformation(
+ "{0} {1}. UserAgent: {2}",
+ request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod,
+ url,
+ request.UserAgent ?? string.Empty);
}
private Task InitTask(HttpListenerContext context, CancellationToken cancellationToken)
@@ -201,7 +213,7 @@ namespace Jellyfin.Server.SocketSharp
}
catch (ObjectDisposedException)
{
- //TODO Investigate and properly fix.
+ // TODO: Investigate and properly fix.
}
catch (Exception ex)
{
@@ -223,38 +235,39 @@ namespace Jellyfin.Server.SocketSharp
public Task Stop()
{
_disposeCancellationTokenSource.Cancel();
-
- if (_listener != null)
- {
- _listener.Close();
- }
+ _listener?.Close();
return Task.CompletedTask;
}
+ /// <summary>
+ /// Releases the unmanaged resources and disposes of the managed resources used.
+ /// </summary>
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
private bool _disposed;
- private readonly object _disposeLock = new object();
+
+ /// <summary>
+ /// Releases the unmanaged resources and disposes of the managed resources used.
+ /// </summary>
+ /// <param name="disposing">Whether or not the managed resources should be disposed</param>
protected virtual void Dispose(bool disposing)
{
- if (_disposed) return;
-
- lock (_disposeLock)
+ if (_disposed)
{
- if (_disposed) return;
-
- if (disposing)
- {
- Stop();
- }
+ return;
+ }
- //release unmanaged resources here...
- _disposed = true;
+ if (disposing)
+ {
+ Stop().GetAwaiter().GetResult();
}
+
+ _disposed = true;
}
}
}
diff --git a/Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs b/Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs
index ebeb18ea0..cbce7d457 100644
--- a/Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs
+++ b/Jellyfin.Server/SocketSharp/WebSocketSharpRequest.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Text;
using Emby.Server.Implementations.HttpServer;
@@ -24,7 +25,7 @@ namespace Jellyfin.Server.SocketSharp
this.request = httpContext.Request;
this.response = new WebSocketSharpResponse(logger, httpContext.Response, this);
- //HandlerFactoryPath = GetHandlerPathIfAny(UrlPrefixes[0]);
+ // HandlerFactoryPath = GetHandlerPathIfAny(UrlPrefixes[0]);
}
private static string GetHandlerPathIfAny(string listenerUrl)
@@ -41,7 +42,7 @@ namespace Jellyfin.Server.SocketSharp
}
var startHostUrl = listenerUrl.Substring(pos + "://".Length);
- var endPos = startHostUrl.IndexOf('/');
+ var endPos = startHostUrl.IndexOf('/', StringComparison.Ordinal);
if (endPos == -1)
{
return null;
@@ -69,9 +70,11 @@ namespace Jellyfin.Server.SocketSharp
public string UserHostAddress => request.UserHostAddress;
- public string XForwardedFor => string.IsNullOrEmpty(request.Headers["X-Forwarded-For"]) ? null : request.Headers["X-Forwarded-For"];
+ public string XForwardedFor
+ => string.IsNullOrEmpty(request.Headers["X-Forwarded-For"]) ? null : request.Headers["X-Forwarded-For"];
- public int? XForwardedPort => string.IsNullOrEmpty(request.Headers["X-Forwarded-Port"]) ? (int?)null : int.Parse(request.Headers["X-Forwarded-Port"]);
+ public int? XForwardedPort
+ => string.IsNullOrEmpty(request.Headers["X-Forwarded-Port"]) ? (int?)null : int.Parse(request.Headers["X-Forwarded-Port"], CultureInfo.InvariantCulture);
public string XForwardedProtocol => string.IsNullOrEmpty(request.Headers["X-Forwarded-Proto"]) ? null : request.Headers["X-Forwarded-Proto"];
@@ -107,6 +110,7 @@ namespace Jellyfin.Server.SocketSharp
switch (crlf)
{
case 0:
+ {
if (c == '\r')
{
crlf = 1;
@@ -121,29 +125,39 @@ namespace Jellyfin.Server.SocketSharp
{
throw new ArgumentException("net_WebHeaderInvalidControlChars");
}
+
break;
+ }
case 1:
+ {
if (c == '\n')
{
crlf = 2;
break;
}
+
throw new ArgumentException("net_WebHeaderInvalidCRLFChars");
+ }
case 2:
+ {
if (c == ' ' || c == '\t')
{
crlf = 0;
break;
}
+
throw new ArgumentException("net_WebHeaderInvalidCRLFChars");
+ }
}
}
+
if (crlf != 0)
{
throw new ArgumentException("net_WebHeaderInvalidCRLFChars");
}
+
return name;
}
@@ -156,6 +170,7 @@ namespace Jellyfin.Server.SocketSharp
return true;
}
}
+
return false;
}
@@ -343,6 +358,7 @@ namespace Jellyfin.Server.SocketSharp
this.pathInfo = System.Net.WebUtility.UrlDecode(pathInfo);
this.pathInfo = NormalizePathInfo(pathInfo, mode);
}
+
return this.pathInfo;
}
}
@@ -444,7 +460,7 @@ namespace Jellyfin.Server.SocketSharp
public string ContentType => request.ContentType;
- public Encoding contentEncoding;
+ private Encoding contentEncoding;
public Encoding ContentEncoding
{
get => contentEncoding ?? request.ContentEncoding;
@@ -502,6 +518,7 @@ namespace Jellyfin.Server.SocketSharp
i++;
}
}
+
return httpFiles;
}
}
diff --git a/Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs b/Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs
index cabc96b23..56e5c73d6 100644
--- a/Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs
+++ b/Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs
@@ -13,12 +13,12 @@ using HttpListenerResponse = SocketHttpListener.Net.HttpListenerResponse;
using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse;
using IRequest = MediaBrowser.Model.Services.IRequest;
-
namespace Jellyfin.Server.SocketSharp
{
public class WebSocketSharpResponse : IHttpResponse
{
private readonly ILogger _logger;
+
private readonly HttpListenerResponse _response;
public WebSocketSharpResponse(ILogger logger, HttpListenerResponse response, IRequest request)
@@ -30,7 +30,9 @@ namespace Jellyfin.Server.SocketSharp
}
public IRequest Request { get; private set; }
+
public Dictionary<string, object> Items { get; private set; }
+
public object OriginalResponse => _response;
public int StatusCode
@@ -51,7 +53,7 @@ namespace Jellyfin.Server.SocketSharp
set => _response.ContentType = value;
}
- //public ICookies Cookies { get; set; }
+ public QueryParamCollection Headers => _response.Headers;
public void AddHeader(string name, string value)
{
@@ -64,8 +66,6 @@ namespace Jellyfin.Server.SocketSharp
_response.AddHeader(name, value);
}
- public QueryParamCollection Headers => _response.Headers;
-
public string GetHeader(string name)
{
return _response.Headers[name];
@@ -114,9 +114,9 @@ namespace Jellyfin.Server.SocketSharp
public void SetContentLength(long contentLength)
{
- //you can happily set the Content-Length header in Asp.Net
- //but HttpListener will complain if you do - you have to set ContentLength64 on the response.
- //workaround: HttpListener throws "The parameter is incorrect" exceptions when we try to set the Content-Length header
+ // you can happily set the Content-Length header in Asp.Net
+ // but HttpListener will complain if you do - you have to set ContentLength64 on the response.
+ // workaround: HttpListener throws "The parameter is incorrect" exceptions when we try to set the Content-Length header
_response.ContentLength64 = contentLength;
}
@@ -147,15 +147,12 @@ namespace Jellyfin.Server.SocketSharp
{
sb.Append($";domain={cookie.Domain}");
}
- //else if (restrictAllCookiesToDomain != null)
- //{
- // sb.Append($";domain={restrictAllCookiesToDomain}");
- //}
if (cookie.Secure)
{
sb.Append(";Secure");
}
+
if (cookie.HttpOnly)
{
sb.Append(";HttpOnly");
@@ -164,7 +161,6 @@ namespace Jellyfin.Server.SocketSharp
return sb.ToString();
}
-
public bool SendChunked
{
get => _response.SendChunked;
diff --git a/jellyfin.ruleset b/jellyfin.ruleset
index 0f8c9aa02..4381349ca 100644
--- a/jellyfin.ruleset
+++ b/jellyfin.ruleset
@@ -3,11 +3,19 @@
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
<!-- disable warning SA1101: Prefix local calls with 'this.' -->
<Rule Id="SA1101" Action="None" />
+ <!-- disable warning SA1130: Use lambda syntax -->
+ <Rule Id="SA1130" Action="None" />
<!-- disable warning SA1200: 'using' directive must appear within a namespace declaration -->
<Rule Id="SA1200" Action="None" />
<!-- disable warning SA1309: Fields must not begin with an underscore -->
<Rule Id="SA1309" Action="None" />
+ <!-- disable warning SA1512: Single-line comments must not be followed by blank line -->
+ <Rule Id="SA1512" Action="None" />
<!-- disable warning SA1633: The file header is missing or not located at the top of the file -->
<Rule Id="SA1633" Action="None" />
</Rules>
+ <Rules AnalyzerId="Microsoft.CodeAnalysis.FxCopAnalyzers" RuleNamespace="Microsoft.Design">
+ <!-- disable warning CA1054: Change the type of parameter url from string to System.Uri -->
+ <Rule Id="CA1054" Action="None" />
+ </Rules>
</RuleSet>