diff --git a/src/Unosquare.Labs.EmbedIO/Modules/StaticFilesModule.cs b/src/Unosquare.Labs.EmbedIO/Modules/StaticFilesModule.cs index dd4bb370b..b0714afb1 100644 --- a/src/Unosquare.Labs.EmbedIO/Modules/StaticFilesModule.cs +++ b/src/Unosquare.Labs.EmbedIO/Modules/StaticFilesModule.cs @@ -95,9 +95,11 @@ public StaticFilesModule( _virtualPaths = new VirtualPaths(Path.GetFullPath(fileSystemPath), useDirectoryBrowser); UseGzip = true; -#if DEBUG // When debugging, disable RamCache +#if DEBUG + // When debugging, disable RamCache UseRamCache = false; -#else // Otherwise, enable it by default +#else + // Otherwise, enable it by default UseRamCache = true; #endif DefaultDocument = DefaultDocumentName; diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/HttpBase.cs b/src/Unosquare.Labs.EmbedIO/System.Net/HttpBase.cs index 8d0d821ea..cfcc9316d 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/HttpBase.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/HttpBase.cs @@ -157,34 +157,30 @@ private static async Task ReadEntityBodyAsync(Stream stream, string leng ? await stream.ReadBytesAsync((int) len, ct) : null; } - - private static bool EqualsWith(int value, char c, Action action) - { - action(value); - return value == c - 0; - } - + private static string[] ReadHeaders(Stream stream) { var buff = new List(); var cnt = 0; - - void Add(int i) + + bool EqualsWith(int i, char c) { if (i == -1) throw new EndOfStreamException("The header cannot be read from the data source."); buff.Add((byte) i); cnt++; + + return i == c - 0; } var read = false; while (cnt < HeadersMaxLength) { - if (EqualsWith(stream.ReadByte(), '\r', Add) && - EqualsWith(stream.ReadByte(), '\n', Add) && - EqualsWith(stream.ReadByte(), '\r', Add) && - EqualsWith(stream.ReadByte(), '\n', Add)) + if (EqualsWith(stream.ReadByte(), '\r') && + EqualsWith(stream.ReadByte(), '\n') && + EqualsWith(stream.ReadByte(), '\r') && + EqualsWith(stream.ReadByte(), '\n')) { read = true; break; diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/HttpListener.cs b/src/Unosquare.Labs.EmbedIO/System.Net/HttpListener.cs index 7dfe4887a..dcf486f26 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/HttpListener.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/HttpListener.cs @@ -234,14 +234,11 @@ internal void RegisterContext(HttpListenerContext context) throw new Exception("Unable to register context"); } - internal void UnregisterContext(HttpListenerContext context) - { - _ctxQueue.TryRemove(context.Id, out var removedContext); - } + internal void UnregisterContext(HttpListenerContext context) => _ctxQueue.TryRemove(context.Id, out var _); internal void AddConnection(HttpConnection cnc) => _connections[cnc] = cnc; - internal void RemoveConnection(HttpConnection cnc) => _connections.TryRemove(cnc, out var instance); + internal void RemoveConnection(HttpConnection cnc) => _connections.TryRemove(cnc, out var _); private void Close(bool closeExisting) { diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerRequest.cs b/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerRequest.cs index dda6104f9..b00638cea 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerRequest.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerRequest.cs @@ -48,7 +48,7 @@ namespace Unosquare.Net /// public sealed class HttpListenerRequest { - private static readonly byte[] _100Continue = Encoding.UTF8.GetBytes("HTTP/1.1 100 Continue\r\n\r\n"); + private static readonly byte[] HttpStatus100 = Encoding.UTF8.GetBytes("HTTP/1.1 100 Continue\r\n\r\n"); private static readonly char[] Separators = { ' ' }; private readonly HttpListenerContext _context; @@ -419,7 +419,7 @@ internal void FinishInitialization() if (string.Compare(Headers["Expect"], "100-continue", StringComparison.OrdinalIgnoreCase) == 0) { - _context.Connection.GetResponseStream().InternalWrite(_100Continue, 0, _100Continue.Length); + _context.Connection.GetResponseStream().InternalWrite(HttpStatus100, 0, HttpStatus100.Length); } } diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/HttpSysSettings.cs b/src/Unosquare.Labs.EmbedIO/System.Net/HttpSysSettings.cs deleted file mode 100644 index 9a2ec2b09..000000000 --- a/src/Unosquare.Labs.EmbedIO/System.Net/HttpSysSettings.cs +++ /dev/null @@ -1,10 +0,0 @@ -#if !NET47 -namespace Unosquare.Net -{ - internal static class HttpSysSettings - { - public const bool EnableNonUtf8 = true; - public const bool FavorUtf8 = true; - } -} -#endif \ No newline at end of file diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/NetExtensions.cs b/src/Unosquare.Labs.EmbedIO/System.Net/NetExtensions.cs index 57758051c..402482cb6 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/NetExtensions.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/NetExtensions.cs @@ -70,11 +70,7 @@ internal static string Unquote(this string str) return str.Trim(); } - - internal static bool IsData(this byte opcode) => opcode == 0x1 || opcode == 0x2; - - internal static bool IsData(this Opcode opcode) => opcode == Opcode.Text || opcode == Opcode.Binary; - + internal static byte[] InternalToByteArray(this ushort value, Endianness order) { var bytes = BitConverter.GetBytes(value); @@ -92,33 +88,7 @@ internal static byte[] InternalToByteArray(this ulong value, Endianness order) return bytes; } - - internal static bool IsControl(this byte opcode) => opcode > 0x7 && opcode < 0x10; - - internal static bool IsReserved(this CloseStatusCode code) - { - return code == CloseStatusCode.Undefined || - code == CloseStatusCode.NoStatus || - code == CloseStatusCode.Abnormal || - code == CloseStatusCode.TlsHandshakeFailure; - } - - /// - /// Converts the order of the specified array of to the host byte order. - /// - /// - /// An array of converted from . - /// - /// - /// An array of to convert. - /// - /// - /// One of the enum values, specifies the byte order of - /// . - /// - /// - /// is . - /// + internal static byte[] ToHostOrder(this byte[] source, Endianness sourceOrder) { if (source == null) @@ -126,42 +96,14 @@ internal static byte[] ToHostOrder(this byte[] source, Endianness sourceOrder) return source.Length > 1 && !sourceOrder.IsHostOrder() ? source.Reverse().ToArray() : source; } - - /// - /// Determines whether the specified is host (this computer - /// architecture) byte order. - /// - /// - /// true if is host byte order; otherwise, false. - /// - /// - /// One of the enum values, to test. - /// + internal static bool IsHostOrder(this Endianness order) { // true: !(true ^ true) or !(false ^ false) // false: !(true ^ false) or !(false ^ true) return !(BitConverter.IsLittleEndian ^ (order == Endianness.Little)); } - - /// - /// Tries to create a for WebSocket with - /// the specified . - /// - /// - /// true if a is successfully created; otherwise, false. - /// - /// - /// A that represents a WebSocket URL to try. - /// - /// - /// When this method returns, a that represents a WebSocket URL, - /// or if is invalid. - /// - /// - /// When this method returns, a that represents an error message, - /// or if is valid. - /// + internal static bool TryCreateWebSocketUri( this string uriString, out Uri result, out string message) { @@ -211,20 +153,7 @@ internal static bool TryCreateWebSocketUri( internal static bool IsToken(this string value) => value.All(c => c >= 0x20 && c < 0x7f && !Tspecials.Contains(c)); - - /// - /// Gets the collection of the HTTP cookies from the specified HTTP . - /// - /// - /// A that receives a collection of the HTTP cookies. - /// - /// - /// A that contains a collection of the HTTP headers. - /// - /// - /// true if is a collection of the response headers; - /// otherwise, false. - /// + internal static CookieCollection GetCookies(this NameValueCollection headers, bool response) { var name = response ? "Set-Cookie" : Headers.Cookie; @@ -242,42 +171,11 @@ internal static string ToExtensionString(this CompressionMethod method, params s return parameters == null || parameters.Length == 0 ? m : $"{m}; {string.Join("; ", parameters)}"; } - - /// - /// Determines whether the specified contains the entry with - /// the specified both and . - /// - /// - /// true if contains the entry with both - /// and ; otherwise, false. - /// - /// - /// A to test. - /// - /// - /// A that represents the key of the entry to find. - /// - /// - /// A that represents the value of the entry to find. - /// + internal static bool Contains(this NameValueCollection collection, string name, string value) => collection[name]?.Split(Strings.CommaSplitChar) .Any(val => val.Trim().Equals(value, StringComparison.OrdinalIgnoreCase)) == true; - - /// - /// Determines whether the specified contains any of characters in - /// the specified array of . - /// - /// - /// true if contains any of ; - /// otherwise, false. - /// - /// - /// A to test. - /// - /// - /// An array of that contains characters to find. - /// + internal static bool Contains(this string value, params char[] chars) => chars?.Length == 0 || (!string.IsNullOrEmpty(value) && value.IndexOfAny(chars) > -1); diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/PayloadData.cs b/src/Unosquare.Labs.EmbedIO/System.Net/PayloadData.cs index eb9756418..77e9dd0fd 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/PayloadData.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/PayloadData.cs @@ -37,7 +37,7 @@ namespace Unosquare.Net internal class PayloadData : IEnumerable { - public static readonly ulong MaxLength; + public static readonly ulong MaxLength = long.MaxValue; private readonly byte[] _data; private readonly long _length; @@ -46,11 +46,6 @@ internal class PayloadData : IEnumerable private string _reason; private bool _reasonSet; - static PayloadData() - { - MaxLength = Int64.MaxValue; - } - internal PayloadData() { _code = 1005; @@ -136,15 +131,9 @@ internal string Reason } } - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public IEnumerator GetEnumerator() - { - return ((IEnumerable)_data).GetEnumerator(); - } + public IEnumerator GetEnumerator() => ((IEnumerable)_data).GetEnumerator(); public override string ToString() => BitConverter.ToString(_data); diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/WebSocket.cs b/src/Unosquare.Labs.EmbedIO/System.Net/WebSocket.cs index 84bc1a6df..957b2b333 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/WebSocket.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/WebSocket.cs @@ -92,9 +92,9 @@ public class WebSocket : IDisposable /// Represents the random number generator used internally. /// internal static readonly RandomNumberGenerator RandomNumber = RandomNumberGenerator.Create(); - + private const string Guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - + private readonly Action _message; private readonly bool _client; private readonly object _forState = new object(); @@ -165,7 +165,7 @@ public WebSocket(string url) IsSecure = _uri.Scheme == "wss"; #endif _waitTime = TimeSpan.FromSeconds(5); - _forMessageEventQueue = ((ICollection) _messageEventQueue).SyncRoot; + _forMessageEventQueue = ((ICollection)_messageEventQueue).SyncRoot; _validator = new WebSocketValidator(this); } @@ -183,7 +183,7 @@ internal WebSocket(WebSocketContext context) _forMessageEventQueue = ((ICollection)_messageEventQueue).SyncRoot; _validator = new WebSocketValidator(this); } - + /// /// Occurs when the WebSocket connection has been closed. /// @@ -203,7 +203,7 @@ internal WebSocket(WebSocketContext context) /// Occurs when the WebSocket connection has been established. /// public event EventHandler OnOpen; - + /// /// Gets or sets the compression method used to compress a message on the WebSocket connection. /// @@ -513,7 +513,7 @@ public async Task CloseAsync(CloseStatusCode code = CloseStatusCode.Undefined, s return; } - var send = !code.IsReserved(); + var send = !IsOpcodeReserved(code); await InternalCloseAsync(new CloseEventArgs(code, reason), send, send, ct: ct); } @@ -669,7 +669,7 @@ public void SetCookie(Cookie cookie) CookieCollection.Add(cookie); } } - + /// public void Dispose() { @@ -795,6 +795,14 @@ private static HttpResponse CreateHandshakeFailureResponse(HttpStatusCode code) return ret; } + private static bool IsOpcodeReserved(CloseStatusCode code) + { + return code == CloseStatusCode.Undefined || + code == CloseStatusCode.NoStatus || + code == CloseStatusCode.Abnormal || + code == CloseStatusCode.TlsHandshakeFailure; + } + // As server private async Task AcceptHandshakeAsync() { @@ -992,7 +1000,7 @@ private void Fatal(string message, Exception exception = null) private void Fatal(string message, CloseStatusCode code) { // TODO: Wait? - InternalCloseAsync(new CloseEventArgs(code, message), !code.IsReserved(), false).Wait(); + InternalCloseAsync(new CloseEventArgs(code, message), !IsOpcodeReserved(code), false).Wait(); } private void Message() @@ -1561,7 +1569,7 @@ private async Task SetClientStream() #endif } #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously - + private void StartReceiving() { if (_messageEventQueue.Count > 0) diff --git a/src/Unosquare.Labs.EmbedIO/System.Net/WebSocketFrame.cs b/src/Unosquare.Labs.EmbedIO/System.Net/WebSocketFrame.cs index f44a3360f..6aeebac70 100644 --- a/src/Unosquare.Labs.EmbedIO/System.Net/WebSocketFrame.cs +++ b/src/Unosquare.Labs.EmbedIO/System.Net/WebSocketFrame.cs @@ -133,7 +133,7 @@ internal WebSocketFrame( Fin fin, Opcode opcode, PayloadData payloadData, bool compressed = false, bool mask = true) { Fin = fin; - Rsv1 = opcode.IsData() && compressed ? Rsv.On : Rsv.Off; + Rsv1 = IsOpcodeData(opcode) && compressed ? Rsv.On : Rsv.Off; Rsv2 = Rsv.Off; Rsv3 = Rsv.Off; Opcode = opcode; @@ -385,11 +385,11 @@ private static WebSocketFrame ProcessHeader(byte[] header) var err = !Enum.IsDefined(typeof(Opcode), opcode) ? "An unsupported opcode." - : !opcode.IsData() && rsv1 == Rsv.On + : !IsOpcodeData(opcode) && rsv1 == Rsv.On ? "A non data frame is compressed." - : opcode.IsControl() && fin == Fin.More + : IsOpcodeControl(opcode) && fin == Fin.More ? "A control frame is fragmented." - : opcode.IsControl() && payloadLen > 125 + : IsOpcodeControl(opcode) && payloadLen > 125 ? "A control frame has a long payload length." : null; @@ -408,6 +408,12 @@ private static WebSocketFrame ProcessHeader(byte[] header) }; } + private static bool IsOpcodeData(Opcode opcode) => opcode == Opcode.Text || opcode == Opcode.Binary; + + private static bool IsOpcodeData(byte opcode) => opcode == 0x1 || opcode == 0x2; + + private static bool IsOpcodeControl(byte opcode) => opcode > 0x7 && opcode < 0x10; + private static async Task ReadExtendedPayloadLengthAsync(Stream stream, WebSocketFrame frame) { var len = frame.ExtendedPayloadLengthCount; diff --git a/src/Unosquare.Labs.EmbedIO/Unosquare.Labs.EmbedIO.csproj b/src/Unosquare.Labs.EmbedIO/Unosquare.Labs.EmbedIO.csproj index de57c40b4..2e1818538 100644 --- a/src/Unosquare.Labs.EmbedIO/Unosquare.Labs.EmbedIO.csproj +++ b/src/Unosquare.Labs.EmbedIO/Unosquare.Labs.EmbedIO.csproj @@ -1,7 +1,7 @@ - A tiny, cross-platform, module based, MIT-licensed web server. Supporting NET FX, NET Core, NET Standard and MONO. + A tiny, cross-platform, module based, MIT-licensed web server. Supporting NET Framework, Net Core, and Mono. Copyright © Unosquare 2013-2018 EmbedIO Web Server Unosquare @@ -11,7 +11,7 @@ EmbedIO ..\..\StyleCop.Analyzers.ruleset Full - 1.2.0 + 1.13.0 EmbedIO Unosquare https://raw.githubusercontent.com/unosquare/embedio/master/LICENSE @@ -28,7 +28,7 @@ All - + diff --git a/test/Unosquare.Labs.EmbedIO.Tests/Unosquare.Labs.EmbedIO.Tests.csproj b/test/Unosquare.Labs.EmbedIO.Tests/Unosquare.Labs.EmbedIO.Tests.csproj index 883dd6286..64ce419c7 100644 --- a/test/Unosquare.Labs.EmbedIO.Tests/Unosquare.Labs.EmbedIO.Tests.csproj +++ b/test/Unosquare.Labs.EmbedIO.Tests/Unosquare.Labs.EmbedIO.Tests.csproj @@ -22,7 +22,7 @@ All - +