pull/885/head
Bond-009 5 years ago
parent 2cb747651b
commit 8b04fe7633

@ -13,7 +13,7 @@ namespace Jellyfin.Server.SocketSharp
{ {
internal static string GetParameter(string header, string attr) internal static string GetParameter(string header, string attr)
{ {
int ap = header.IndexOf(attr); int ap = header.IndexOf(attr, StringComparison.Ordinal);
if (ap == -1) if (ap == -1)
{ {
return null; return null;
@ -140,8 +140,12 @@ namespace Jellyfin.Server.SocketSharp
v = v.Substring(0, 16) + "...\""; v = v.Substring(0, 16) + "...\"";
} }
string msg = string.Format("A potentially dangerous Request.{0} value was " + string msg = string.Format(
"detected from the client ({1}={2}).", name, key, v); CultureInfo.InvariantCulture,
"A potentially dangerous Request.{0} value was detected from the client ({1}={2}).",
name,
key,
v);
throw new Exception(msg); throw new Exception(msg);
} }
@ -258,6 +262,7 @@ namespace Jellyfin.Server.SocketSharp
value.Append((char)c); value.Append((char)c);
} }
} }
if (c == -1) if (c == -1)
{ {
AddRawKeyValue(form, key, value); AddRawKeyValue(form, key, value);
@ -273,6 +278,7 @@ namespace Jellyfin.Server.SocketSharp
key.Append((char)c); key.Append((char)c);
} }
} }
if (c == -1) if (c == -1)
{ {
AddRawKeyValue(form, key, value); AddRawKeyValue(form, key, value);
@ -310,6 +316,7 @@ namespace Jellyfin.Server.SocketSharp
result.Append(key); result.Append(key);
result.Append('='); result.Append('=');
} }
result.Append(pair.Value); result.Append(pair.Value);
} }
@ -493,11 +500,6 @@ namespace Jellyfin.Server.SocketSharp
public Stream InputStream => stream; public Stream InputStream => stream;
} }
private class Helpers
{
public static readonly CultureInfo InvariantCulture = CultureInfo.InvariantCulture;
}
internal static class StrUtils internal static class StrUtils
{ {
public static bool StartsWith(string str1, string str2, bool ignore_case) public static bool StartsWith(string str1, string str2, bool ignore_case)
@ -535,12 +537,17 @@ namespace Jellyfin.Server.SocketSharp
public class Element public class Element
{ {
public string ContentType; public string ContentType { get; set; }
public string Name;
public string Filename; public string Name { get; set; }
public Encoding Encoding;
public long Start; public string Filename { get; set; }
public long Length;
public Encoding Encoding { get; set; }
public long Start { get; set; }
public long Length { get; set; }
public override string ToString() public override string ToString()
{ {
@ -597,6 +604,7 @@ namespace Jellyfin.Server.SocketSharp
{ {
break; break;
} }
got_cr = b == CR; got_cr = b == CR;
sb.Append((char)b); sb.Append((char)b);
} }
@ -797,6 +805,7 @@ namespace Jellyfin.Server.SocketSharp
c = data.ReadByte(); c = data.ReadByte();
continue; continue;
} }
data.Position = retval + 2; data.Position = retval + 2;
if (got_cr) if (got_cr)
{ {

@ -24,6 +24,7 @@ namespace Jellyfin.Server.SocketSharp
private TaskCompletionSource<bool> _taskCompletionSource = new TaskCompletionSource<bool>(); private TaskCompletionSource<bool> _taskCompletionSource = new TaskCompletionSource<bool>();
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private bool _disposed = false;
public SharpWebSocket(SocketHttpListener.WebSocket socket, ILogger logger) public SharpWebSocket(SocketHttpListener.WebSocket socket, ILogger logger)
{ {
@ -40,9 +41,9 @@ namespace Jellyfin.Server.SocketSharp
_logger = logger; _logger = logger;
WebSocket = socket; WebSocket = socket;
socket.OnMessage += socket_OnMessage; socket.OnMessage += OnSocketMessage;
socket.OnClose += socket_OnClose; socket.OnClose += OnSocketClose;
socket.OnError += socket_OnError; socket.OnError += OnSocketError;
WebSocket.ConnectAsServer(); WebSocket.ConnectAsServer();
} }
@ -52,21 +53,21 @@ namespace Jellyfin.Server.SocketSharp
return _taskCompletionSource.Task; 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); _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); _taskCompletionSource.TrySetResult(true);
Closed?.Invoke(this, EventArgs.Empty); Closed?.Invoke(this, EventArgs.Empty);
} }
void socket_OnMessage(object sender, SocketHttpListener.MessageEventArgs e) private void OnSocketMessage(object sender, SocketHttpListener.MessageEventArgs e)
{ {
if (OnReceiveBytes != null) if (OnReceiveBytes != null)
{ {
@ -110,6 +111,7 @@ namespace Jellyfin.Server.SocketSharp
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);
GC.SuppressFinalize(this);
} }
/// <summary> /// <summary>
@ -118,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> /// <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) protected virtual void Dispose(bool dispose)
{ {
if (_disposed)
{
return;
}
if (dispose) if (dispose)
{ {
WebSocket.OnMessage -= socket_OnMessage; WebSocket.OnMessage -= OnSocketMessage;
WebSocket.OnClose -= socket_OnClose; WebSocket.OnClose -= OnSocketClose;
WebSocket.OnError -= socket_OnError; WebSocket.OnError -= OnSocketError;
_cancellationTokenSource.Cancel(); _cancellationTokenSource.Cancel();
WebSocket.Close(); WebSocket.Close();
} }
_disposed = true;
} }
/// <summary> /// <summary>

@ -34,9 +34,16 @@ namespace Jellyfin.Server.SocketSharp
private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource(); private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource();
private CancellationToken _disposeCancellationToken; private CancellationToken _disposeCancellationToken;
public WebSocketSharpListener(ILogger logger, X509Certificate certificate, IStreamHelper streamHelper, public WebSocketSharpListener(
INetworkManager networkManager, ISocketFactory socketFactory, ICryptoProvider cryptoProvider, ILogger logger,
bool enableDualMode, IFileSystem fileSystem, IEnvironmentInfo environment) X509Certificate certificate,
IStreamHelper streamHelper,
INetworkManager networkManager,
ISocketFactory socketFactory,
ICryptoProvider cryptoProvider,
bool enableDualMode,
IFileSystem fileSystem,
IEnvironmentInfo environment)
{ {
_logger = logger; _logger = logger;
_certificate = certificate; _certificate = certificate;
@ -61,7 +68,9 @@ namespace Jellyfin.Server.SocketSharp
public void Start(IEnumerable<string> urlPrefixes) public void Start(IEnumerable<string> urlPrefixes)
{ {
if (_listener == null) if (_listener == null)
{
_listener = new HttpListener(_logger, _cryptoProvider, _socketFactory, _networkManager, _streamHelper, _fileSystem, _environment); _listener = new HttpListener(_logger, _cryptoProvider, _socketFactory, _networkManager, _streamHelper, _fileSystem, _environment);
}
_listener.EnableDualMode = _enableDualMode; _listener.EnableDualMode = _enableDualMode;
@ -90,8 +99,11 @@ namespace Jellyfin.Server.SocketSharp
{ {
var url = request.Url.ToString(); var url = request.Url.ToString();
logger.LogInformation("{0} {1}. UserAgent: {2}", logger.LogInformation(
request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod, url, request.UserAgent ?? string.Empty); "{0} {1}. UserAgent: {2}",
request.IsWebSocketRequest ? "WS" : "HTTP " + request.HttpMethod,
url,
request.UserAgent ?? string.Empty);
} }
private Task InitTask(HttpListenerContext context, CancellationToken cancellationToken) private Task InitTask(HttpListenerContext context, CancellationToken cancellationToken)

@ -42,7 +42,7 @@ namespace Jellyfin.Server.SocketSharp
} }
var startHostUrl = listenerUrl.Substring(pos + "://".Length); var startHostUrl = listenerUrl.Substring(pos + "://".Length);
var endPos = startHostUrl.IndexOf('/'); var endPos = startHostUrl.IndexOf('/', StringComparison.Ordinal);
if (endPos == -1) if (endPos == -1)
{ {
return null; return null;
@ -110,6 +110,7 @@ namespace Jellyfin.Server.SocketSharp
switch (crlf) switch (crlf)
{ {
case 0: case 0:
{
if (c == '\r') if (c == '\r')
{ {
crlf = 1; crlf = 1;
@ -124,23 +125,31 @@ namespace Jellyfin.Server.SocketSharp
{ {
throw new ArgumentException("net_WebHeaderInvalidControlChars"); throw new ArgumentException("net_WebHeaderInvalidControlChars");
} }
break; break;
}
case 1: case 1:
{
if (c == '\n') if (c == '\n')
{ {
crlf = 2; crlf = 2;
break; break;
} }
throw new ArgumentException("net_WebHeaderInvalidCRLFChars"); throw new ArgumentException("net_WebHeaderInvalidCRLFChars");
}
case 2: case 2:
{
if (c == ' ' || c == '\t') if (c == ' ' || c == '\t')
{ {
crlf = 0; crlf = 0;
break; break;
} }
throw new ArgumentException("net_WebHeaderInvalidCRLFChars"); throw new ArgumentException("net_WebHeaderInvalidCRLFChars");
}
} }
} }
@ -349,6 +358,7 @@ namespace Jellyfin.Server.SocketSharp
this.pathInfo = System.Net.WebUtility.UrlDecode(pathInfo); this.pathInfo = System.Net.WebUtility.UrlDecode(pathInfo);
this.pathInfo = NormalizePathInfo(pathInfo, mode); this.pathInfo = NormalizePathInfo(pathInfo, mode);
} }
return this.pathInfo; return this.pathInfo;
} }
} }
@ -508,6 +518,7 @@ namespace Jellyfin.Server.SocketSharp
i++; i++;
} }
} }
return httpFiles; return httpFiles;
} }
} }

Loading…
Cancel
Save