diff --git a/EonaCat.Network.Tester/Program.cs b/EonaCat.Network.Tester/Program.cs index 89d2019..960a218 100644 --- a/EonaCat.Network.Tester/Program.cs +++ b/EonaCat.Network.Tester/Program.cs @@ -66,8 +66,7 @@ internal class Program StartServer(serverUri, certificatePath, certificatePassword, requiredPassword); // Start the client in the main thread - _client = new WSClient(clientUri); - _client.SSL.Certificates.Add(new X509Certificate(certificatePath, certificatePassword)); + _client = new WSClient(clientUri, new X509Certificate(certificatePath, certificatePassword)); _client.OnConnect += (sender, e) => Console.WriteLine($"Connected to server"); _client.OnMessageReceived += (sender, e) => Console.WriteLine($"Received message from server: {e.Data}"); _client.OnDisconnect += (sender, e) => Console.WriteLine($"Disconnected from server: {e.Code} : {e.Reason}"); diff --git a/EonaCat.Network/Constants.cs b/EonaCat.Network/Constants.cs index ae9cd07..aefcc4c 100644 --- a/EonaCat.Network/Constants.cs +++ b/EonaCat.Network/Constants.cs @@ -1,11 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace EonaCat.Network +namespace EonaCat.Network { internal class Constants { - public static string Version { get; set; } = "1.1.2"; + public static string Version { get; set; } = "1.1.4"; } -} +} \ No newline at end of file diff --git a/EonaCat.Network/EonaCat.Network.csproj b/EonaCat.Network/EonaCat.Network.csproj index 0ac9510..d9a3590 100644 --- a/EonaCat.Network/EonaCat.Network.csproj +++ b/EonaCat.Network/EonaCat.Network.csproj @@ -16,9 +16,9 @@ EonaCat, Network, .NET Standard, EonaCatHelpers, Jeroen, Saey, Protocol, Quic, UDP, TCP, Web, Server EonaCat Networking library with Quic, TCP, UDP, WebSockets and a Webserver - 1.1.3 - 1.1.3 - 1.1.3 + 1.1.4 + 1.1.4 + 1.1.4 icon.png diff --git a/EonaCat.Network/System/Quic/Connections/ConnectionPool.cs b/EonaCat.Network/System/Quic/Connections/ConnectionPool.cs index 1cf9caf..c458f2c 100644 --- a/EonaCat.Network/System/Quic/Connections/ConnectionPool.cs +++ b/EonaCat.Network/System/Quic/Connections/ConnectionPool.cs @@ -1,7 +1,6 @@ using EonaCat.Quic.Infrastructure; using EonaCat.Quic.Infrastructure.Settings; using EonaCat.Quic.InternalInfrastructure; -using System; using System.Collections.Generic; namespace EonaCat.Quic.Connections diff --git a/EonaCat.Network/System/Quic/Connections/QuicConnection.cs b/EonaCat.Network/System/Quic/Connections/QuicConnection.cs index 5b5cf23..d2a1a7e 100644 --- a/EonaCat.Network/System/Quic/Connections/QuicConnection.cs +++ b/EonaCat.Network/System/Quic/Connections/QuicConnection.cs @@ -9,7 +9,6 @@ using EonaCat.Quic.Infrastructure.Packets; using EonaCat.Quic.Infrastructure.Settings; using EonaCat.Quic.InternalInfrastructure; using EonaCat.Quic.Streams; -using System; using System.Collections.Generic; namespace EonaCat.Quic.Connections diff --git a/EonaCat.Network/System/Quic/Context/QuicStreamContext.cs b/EonaCat.Network/System/Quic/Context/QuicStreamContext.cs index 19316ec..d6c9ee0 100644 --- a/EonaCat.Network/System/Quic/Context/QuicStreamContext.cs +++ b/EonaCat.Network/System/Quic/Context/QuicStreamContext.cs @@ -1,5 +1,4 @@ using EonaCat.Quic.Streams; -using System; namespace EonaCat.Quic.Context { diff --git a/EonaCat.Network/System/Quic/Helpers/StreamId.cs b/EonaCat.Network/System/Quic/Helpers/StreamId.cs index 8259ae4..53623b8 100644 --- a/EonaCat.Network/System/Quic/Helpers/StreamId.cs +++ b/EonaCat.Network/System/Quic/Helpers/StreamId.cs @@ -1,6 +1,4 @@ -using System; - -namespace EonaCat.Quic.Helpers +namespace EonaCat.Quic.Helpers { // This file is part of the EonaCat project(s) which is released under the Apache License. // See the LICENSE file or go to https://EonaCat.com/License for full license details. diff --git a/EonaCat.Network/System/Quic/Infrastructure/ErrorCodes.cs b/EonaCat.Network/System/Quic/Infrastructure/ErrorCodes.cs index cf96230..5c42dbd 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/ErrorCodes.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/ErrorCodes.cs @@ -1,6 +1,4 @@ -using System; - -namespace EonaCat.Quic.Infrastructure +namespace EonaCat.Quic.Infrastructure { // This file is part of the EonaCat project(s) which is released under the Apache License. // See the LICENSE file or go to https://EonaCat.com/License for full license details. diff --git a/EonaCat.Network/System/Quic/Infrastructure/Frames/ConnectionCloseFrame.cs b/EonaCat.Network/System/Quic/Infrastructure/Frames/ConnectionCloseFrame.cs index c240d1d..244cca8 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/Frames/ConnectionCloseFrame.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/Frames/ConnectionCloseFrame.cs @@ -1,5 +1,4 @@ using EonaCat.Quic.Helpers; -using System; using System.Collections.Generic; namespace EonaCat.Quic.Infrastructure.Frames diff --git a/EonaCat.Network/System/Quic/Infrastructure/Frames/DataBlockedFrame.cs b/EonaCat.Network/System/Quic/Infrastructure/Frames/DataBlockedFrame.cs index 0944672..c3917ff 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/Frames/DataBlockedFrame.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/Frames/DataBlockedFrame.cs @@ -1,5 +1,4 @@ using EonaCat.Quic.Helpers; -using System; using System.Collections.Generic; namespace EonaCat.Quic.Infrastructure.Frames diff --git a/EonaCat.Network/System/Quic/Infrastructure/Frames/MaxStreamDataFrame.cs b/EonaCat.Network/System/Quic/Infrastructure/Frames/MaxStreamDataFrame.cs index e760c0c..1fd5fb1 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/Frames/MaxStreamDataFrame.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/Frames/MaxStreamDataFrame.cs @@ -1,5 +1,4 @@ using EonaCat.Quic.Helpers; -using System; using System.Collections.Generic; namespace EonaCat.Quic.Infrastructure.Frames diff --git a/EonaCat.Network/System/Quic/Infrastructure/Frames/MaxStreamsFrame.cs b/EonaCat.Network/System/Quic/Infrastructure/Frames/MaxStreamsFrame.cs index 6c394a7..fc3be9a 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/Frames/MaxStreamsFrame.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/Frames/MaxStreamsFrame.cs @@ -1,5 +1,4 @@ using EonaCat.Quic.Helpers; -using System; using System.Collections.Generic; namespace EonaCat.Quic.Infrastructure.Frames diff --git a/EonaCat.Network/System/Quic/Infrastructure/Frames/StreamDataBlockedFrame.cs b/EonaCat.Network/System/Quic/Infrastructure/Frames/StreamDataBlockedFrame.cs index d8606e5..9ee1e97 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/Frames/StreamDataBlockedFrame.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/Frames/StreamDataBlockedFrame.cs @@ -1,5 +1,4 @@ using EonaCat.Quic.Helpers; -using System; using System.Collections.Generic; namespace EonaCat.Quic.Infrastructure.Frames diff --git a/EonaCat.Network/System/Quic/Infrastructure/Frames/StreamFrame.cs b/EonaCat.Network/System/Quic/Infrastructure/Frames/StreamFrame.cs index 4170d28..464f2ef 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/Frames/StreamFrame.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/Frames/StreamFrame.cs @@ -1,5 +1,4 @@ using EonaCat.Quic.Helpers; -using System; using System.Collections.Generic; namespace EonaCat.Quic.Infrastructure.Frames diff --git a/EonaCat.Network/System/Quic/Infrastructure/NumberSpace.cs b/EonaCat.Network/System/Quic/Infrastructure/NumberSpace.cs index 749852d..00f0a9d 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/NumberSpace.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/NumberSpace.cs @@ -1,6 +1,4 @@ -using System; - -namespace EonaCat.Quic.Infrastructure +namespace EonaCat.Quic.Infrastructure { // This file is part of the EonaCat project(s) which is released under the Apache License. // See the LICENSE file or go to https://EonaCat.com/License for full license details. diff --git a/EonaCat.Network/System/Quic/Infrastructure/PacketProcessing/PacketCreator.cs b/EonaCat.Network/System/Quic/Infrastructure/PacketProcessing/PacketCreator.cs index 9d5fad6..5b073f8 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/PacketProcessing/PacketCreator.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/PacketProcessing/PacketCreator.cs @@ -1,7 +1,6 @@ using EonaCat.Quic.Helpers; using EonaCat.Quic.Infrastructure.Frames; using EonaCat.Quic.Infrastructure.Packets; -using System; namespace EonaCat.Quic.Infrastructure.PacketProcessing { diff --git a/EonaCat.Network/System/Quic/Infrastructure/PacketType.cs b/EonaCat.Network/System/Quic/Infrastructure/PacketType.cs index 7d27293..941ac59 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/PacketType.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/PacketType.cs @@ -1,6 +1,4 @@ -using System; - -namespace EonaCat.Quic.Infrastructure +namespace EonaCat.Quic.Infrastructure { // This file is part of the EonaCat project(s) which is released under the Apache License. // See the LICENSE file or go to https://EonaCat.com/License for full license details. diff --git a/EonaCat.Network/System/Quic/Infrastructure/Packets/InitialPacket.cs b/EonaCat.Network/System/Quic/Infrastructure/Packets/InitialPacket.cs index edcf2bd..af04a67 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/Packets/InitialPacket.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/Packets/InitialPacket.cs @@ -1,5 +1,4 @@ using EonaCat.Quic.Helpers; -using System; using System.Collections.Generic; namespace EonaCat.Quic.Infrastructure.Packets diff --git a/EonaCat.Network/System/Quic/Infrastructure/Packets/Packet.cs b/EonaCat.Network/System/Quic/Infrastructure/Packets/Packet.cs index 49d3625..6387c2d 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/Packets/Packet.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/Packets/Packet.cs @@ -2,7 +2,6 @@ using EonaCat.Quic.Infrastructure.Exceptions; using EonaCat.Quic.Infrastructure.Frames; using EonaCat.Quic.Infrastructure.Settings; -using System; using System.Collections.Generic; namespace EonaCat.Quic.Infrastructure.Packets diff --git a/EonaCat.Network/System/Quic/Infrastructure/Settings/QuicVersion.cs b/EonaCat.Network/System/Quic/Infrastructure/Settings/QuicVersion.cs index a3548e7..af7422d 100644 --- a/EonaCat.Network/System/Quic/Infrastructure/Settings/QuicVersion.cs +++ b/EonaCat.Network/System/Quic/Infrastructure/Settings/QuicVersion.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace EonaCat.Quic.Infrastructure.Settings { diff --git a/EonaCat.Network/System/Sockets/Web/CloseStatusCode.cs b/EonaCat.Network/System/Sockets/Web/CloseStatusCode.cs index 01ffeae..9763359 100644 --- a/EonaCat.Network/System/Sockets/Web/CloseStatusCode.cs +++ b/EonaCat.Network/System/Sockets/Web/CloseStatusCode.cs @@ -5,6 +5,51 @@ namespace EonaCat.Network { public enum CloseStatusCode : ushort { + //1000: Normal Closure + //Indicates a normal closure, meaning that the purpose for which the connection was established has been fulfilled. + + //1001: Going Away + //The endpoint is going away, such as a server going down or a browser tab is closing. + + //1002: Protocol Error + //Indicates that the endpoint is terminating the connection due to a protocol error. + + //1003: Unsupported Data + //Indicates that the endpoint is terminating the connection because it received data that it cannot process. + + //1005: No Status Received + //Reserved. It indicates that no status code was received. + + //1006: Abnormal Closure + //Reserved. It is a reserved value and should not be set as a status code in a Close control frame by an endpoint. + + //1007: Invalid frame payload data + //Indicates that an endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the message. + + //1008: Policy Violation + //Indicates that an endpoint is terminating the connection because it has received a message that violates its policy. + + //1009: Message Too Big + //Indicates that an endpoint is terminating the connection because it has received a message that is too big for it to process. + + //1010: Missing Extension + //Indicates that an endpoint is terminating the connection because it has received a message that requires negotiation of an extension, and the client did not offer that extension. + + //1011: Internal Error + //Indicates that a server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request. + + //1012: Service Restart + //Reserved. It indicates that the service is restarting. + + //1013: Try Again Later + //Reserved. It indicates that the server is temporarily unable to process the request. + + //1014: Bad Gateway + //Reserved. It indicates that an intermediate server failed to fulfill a request. + + //1015: TLS Handshake Failure + //Reserved. It indicates that the connection was closed due to a failure to perform a TLS handshake. + Normal = 1000, Away = 1001, @@ -25,10 +70,16 @@ namespace EonaCat.Network TooBig = 1009, - MandatoryExtension = 1010, + MissingExtension = 1010, ServerError = 1011, + ServiceRestart = 1012, + + TryAgainLater = 1013, + + BadGateway = 1014, + TlsHandshakeFailure = 1015 } } \ No newline at end of file diff --git a/EonaCat.Network/System/Sockets/Web/Core/Authentication/AuthenticationChallenge.cs b/EonaCat.Network/System/Sockets/Web/Core/Authentication/AuthenticationChallenge.cs index 4c4ba68..ad9eaf9 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Authentication/AuthenticationChallenge.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Authentication/AuthenticationChallenge.cs @@ -41,6 +41,7 @@ namespace EonaCat.Network : base(scheme, parameters) { } + /// /// Gets the domain for Digest authentication. /// @@ -104,49 +105,32 @@ namespace EonaCat.Network return string.Format($"Basic realm=\"{{0}}\"", Parameters["realm"]); } - /// - /// Gets the Digest authentication string representation of the authentication challenge. - /// - /// A string representing the Digest authentication challenge. internal override string ToDigestString() { var output = new StringBuilder(DIGEST_SIZE); + var realm = Parameters["realm"]; + var nonce = Parameters["nonce"]; - var domain = Parameters["domain"]; - if (domain != null) + if (realm != null) { - output.AppendFormat($"Digest realm=\"{Parameters["realm"]}\", domain=\"{domain}\", nonce=\"{Parameters["nonce"]}\""); - } - else - { - output.AppendFormat($"Digest realm=\"{Parameters["realm"]}\", nonce=\"{Parameters["nonce"]}\""); - } + output.AppendFormat("Digest realm=\"{0}\", nonce=\"{1}\"", realm, nonce); - var opaque = Parameters["opaque"]; - if (opaque != null) - { - output.AppendFormat($", opaque=\"{opaque}\""); - } - - var stale = Parameters["stale"]; - if (stale != null) - { - output.AppendFormat($", stale={stale}"); - } - - var algorithm = Parameters["algorithm"]; - if (algorithm != null) - { - output.AppendFormat($", algorithm={algorithm}"); - } - - var qop = Parameters["qop"]; - if (qop != null) - { - output.AppendFormat($", qop=\"{qop}\""); + AppendIfNotNull(output, "domain", Parameters["domain"]); + AppendIfNotNull(output, "opaque", Parameters["opaque"]); + AppendIfNotNull(output, "stale", Parameters["stale"]); + AppendIfNotNull(output, "algorithm", Parameters["algorithm"]); + AppendIfNotNull(output, "qop", Parameters["qop"]); } return output.ToString(); } + + private static void AppendIfNotNull(StringBuilder output, string key, string value) + { + if (value != null) + { + output.AppendFormat(", {0}=\"{1}\"", key, value); + } + } } } \ No newline at end of file diff --git a/EonaCat.Network/System/Sockets/Web/Core/Authentication/AuthenticationResponse.cs b/EonaCat.Network/System/Sockets/Web/Core/Authentication/AuthenticationResponse.cs index 10d14c6..64ccdf0 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Authentication/AuthenticationResponse.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Authentication/AuthenticationResponse.cs @@ -72,6 +72,7 @@ namespace EonaCat.Network : base(scheme, parameters) { } + /// /// Gets the cnonce value for Digest authentication. /// @@ -108,6 +109,7 @@ namespace EonaCat.Network internal uint NonceCount => _nonceCount < uint.MaxValue ? _nonceCount : 0; + /// /// Converts the authentication response to an identity. /// diff --git a/EonaCat.Network/System/Sockets/Web/Core/Chunks/ChunkStream.cs b/EonaCat.Network/System/Sockets/Web/Core/Chunks/ChunkStream.cs index 4fa478b..0ba330c 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Chunks/ChunkStream.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Chunks/ChunkStream.cs @@ -63,6 +63,7 @@ namespace EonaCat.Network /// Gets the web headers associated with the chunk stream. /// internal WebHeaderCollection Headers { get; } + /// /// Reads a specified amount of data from the chunk stream. /// @@ -159,6 +160,7 @@ namespace EonaCat.Network return nread; } + private InputChunkState SeekCrLf(byte[] buffer, ref int offset, int length) { if (!_gotChunck) @@ -316,6 +318,7 @@ namespace EonaCat.Network return InputChunkState.End; } + private void Write(byte[] buffer, ref int offset, int length) { if (_state == InputChunkState.End) diff --git a/EonaCat.Network/System/Sockets/Web/Core/Collections/WebHeaderCollection.cs b/EonaCat.Network/System/Sockets/Web/Core/Collections/WebHeaderCollection.cs index 0e0ca9b..6a872ed 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Collections/WebHeaderCollection.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Collections/WebHeaderCollection.cs @@ -19,6 +19,7 @@ namespace EonaCat.Network [ComVisible(true)] public class WebHeaderCollection : NameValueCollection, ISerializable { + private const int BUFFER_SIZE = 65535; private static readonly Dictionary _headers; private readonly bool _internallyUsed; private HttpHeaderType _state; @@ -136,10 +137,12 @@ namespace EonaCat.Network throw new ArgumentException(ex.Message, nameof(serializationInfo), ex); } } + public override string[] AllKeys => base.AllKeys; public override int Count => base.Count; public override KeysCollection Keys => base.Keys; internal HttpHeaderType State => _state; + public string this[HttpRequestHeader header] { get @@ -165,6 +168,7 @@ namespace EonaCat.Network Add(header, value); } } + public static bool IsRestricted(string headerName) { return isRestricted(CheckName(headerName), false); @@ -462,7 +466,7 @@ namespace EonaCat.Network } value = value.Trim(); - if (value.Length > 65535) + if (value.Length > BUFFER_SIZE) { throw new ArgumentOutOfRangeException(nameof(value), "Greater than 65,535 characters."); } @@ -517,6 +521,7 @@ namespace EonaCat.Network { base.Add(name, CheckValue(value)); } + private void CheckRestricted(string name) { if (!_internallyUsed && isRestricted(name, true)) @@ -544,6 +549,7 @@ namespace EonaCat.Network "This collection has already been used to store the response headers."); } } + private void DoWithCheckingState( Action action, string name, string value, bool setState) { @@ -578,6 +584,7 @@ namespace EonaCat.Network CheckRestricted(name); action(name, CheckValue(value)); } + private void removeWithoutCheckingName(string name, string unuse) { CheckRestricted(name); diff --git a/EonaCat.Network/System/Sockets/Web/Core/Context/HttpListenerWSContext.cs b/EonaCat.Network/System/Sockets/Web/Core/Context/HttpListenerWSContext.cs index 1375c36..543fcfe 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Context/HttpListenerWSContext.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Context/HttpListenerWSContext.cs @@ -84,6 +84,7 @@ namespace EonaCat.Network /// Gets the stream of the underlying TCP connection. /// internal Stream Stream => _context.Connection.Stream; + /// public override string ToString() { diff --git a/EonaCat.Network/System/Sockets/Web/Core/Context/TcpListenerWSContext.cs b/EonaCat.Network/System/Sockets/Web/Core/Context/TcpListenerWSContext.cs index e359cc9..6d53f66 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Context/TcpListenerWSContext.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Context/TcpListenerWSContext.cs @@ -29,6 +29,7 @@ namespace EonaCat.Network private NameValueCollection _queryString; private WebRequest _request; private IPrincipal _user; + /// /// Initializes a new instance of the class. /// @@ -130,6 +131,7 @@ namespace EonaCat.Network /// Gets the stream of the underlying TCP connection. /// internal Stream Stream { get; } + /// public override string ToString() { diff --git a/EonaCat.Network/System/Sockets/Web/Core/Cookies/Cookie.cs b/EonaCat.Network/System/Sockets/Web/Core/Cookies/Cookie.cs index 0a513be..2419fdb 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Cookies/Cookie.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Cookies/Cookie.cs @@ -332,6 +332,7 @@ namespace EonaCat.Network } internal int[] Ports => _ports; + /// public override bool Equals(object comparand) { @@ -414,7 +415,7 @@ namespace EonaCat.Network internal string ToResponseString() { return _name.Length > 0 - ? (_version == 0 ? toResponseStringVersion0() : toResponseStringVersion1()) + ? (_version == 0 ? ToResponseStringVersion0() : ToResponseStringVersion1()) : string.Empty; } @@ -493,7 +494,7 @@ namespace EonaCat.Network return true; } - private string toResponseStringVersion0() + private string ToResponseStringVersion0() { var output = new StringBuilder(64); output.AppendFormat("{0}={1}", _name, _value); @@ -530,7 +531,7 @@ namespace EonaCat.Network return output.ToString(); } - private string toResponseStringVersion1() + private string ToResponseStringVersion1() { var output = new StringBuilder(64); output.AppendFormat("{0}={1}; Version={2}", _name, _value, _version); diff --git a/EonaCat.Network/System/Sockets/Web/Core/Cookies/CookieCollection.cs b/EonaCat.Network/System/Sockets/Web/Core/Cookies/CookieCollection.cs index 6b5be1f..14b0ee8 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Cookies/CookieCollection.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Cookies/CookieCollection.cs @@ -16,7 +16,7 @@ namespace EonaCat.Network public class CookieCollection : ICollection, IEnumerable { private readonly List _list; - private object _sync; + private object _locker; /// /// Initializes a new instance of the class. @@ -26,7 +26,6 @@ namespace EonaCat.Network _list = new List(); } - /// /// Gets the number of cookies in the collection. /// @@ -45,7 +44,7 @@ namespace EonaCat.Network /// /// Gets an object that can be used to synchronize access to the collection. /// - public object SyncRoot => _sync ??= ((ICollection)_list).SyncRoot; + public object SyncRoot => _locker ??= ((ICollection)_list).SyncRoot; internal IList List => _list; @@ -62,6 +61,7 @@ namespace EonaCat.Network return list; } } + /// /// Gets or sets the cookie at the specified index. /// @@ -105,6 +105,7 @@ namespace EonaCat.Network return null; } } + /// /// Adds the specified cookie to the collection, updating it if it already exists. /// diff --git a/EonaCat.Network/System/Sockets/Web/Core/Cookies/CookieException.cs b/EonaCat.Network/System/Sockets/Web/Core/Cookies/CookieException.cs index 1ef28f4..ccd19b1 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Cookies/CookieException.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Cookies/CookieException.cs @@ -49,6 +49,7 @@ namespace EonaCat.Network : base(serializationInfo, streamingContext) { } + /// /// Populates a with the data needed to serialize the exception. /// diff --git a/EonaCat.Network/System/Sockets/Web/Core/Endpoints/EndPointListener.cs b/EonaCat.Network/System/Sockets/Web/Core/Endpoints/EndPointListener.cs index 84bab1c..d624e99 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Endpoints/EndPointListener.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Endpoints/EndPointListener.cs @@ -26,6 +26,7 @@ namespace EonaCat.Network private List _all; // host == '+' private Dictionary _prefixes; private List _unhandled; // host == '*' + static EndPointListener() { _defaultCertFolderPath = diff --git a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpConnection.cs b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpConnection.cs index 3487ed6..42b604b 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpConnection.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpConnection.cs @@ -618,6 +618,7 @@ namespace EonaCat.Network _position = 0; _requestBuffer = new MemoryStream(); } + private void UnregisterContext() { if (!_contextRegistered) diff --git a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpHeaderInfo.cs b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpHeaderInfo.cs index 25c380d..e2a2788 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpHeaderInfo.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpHeaderInfo.cs @@ -48,6 +48,7 @@ namespace EonaCat.Network /// Gets a value indicating whether the header is multi-value in a response. /// internal bool IsMultiValueInResponse => (Type & HttpHeaderType.MultiValueInResponse) == HttpHeaderType.MultiValueInResponse; + /// /// Gets a value indicating whether the header is multi-value. /// diff --git a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListener.cs b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListener.cs index 09d10ab..adc7e25 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListener.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListener.cs @@ -32,6 +32,7 @@ namespace EonaCat.Network private string _realm; private SSLConfigServer _sslConfig; private Func _userCredFinder; + static HttpListener() { _defaultRealm = "SECRET AREA"; @@ -60,6 +61,7 @@ namespace EonaCat.Network } public static bool IsSupported => true; + /// /// Gets or sets a value indicating whether the server accepts every /// handshake request without checking the request URI. @@ -147,6 +149,7 @@ namespace EonaCat.Network } public bool IsListening => _listening; + public HttpListenerPrefixCollection Prefixes { get @@ -217,6 +220,7 @@ namespace EonaCat.Network internal bool IsDisposed { get; private set; } internal bool ReuseAddress { get; set; } + /// /// Aborts the listener and releases all resources associated with it. /// @@ -400,14 +404,14 @@ namespace EonaCat.Network throw new HttpListenerException(995); } - var ctx = GetContextFromQueue(); - if (ctx == null) + var context = GetContextFromQueue(); + if (context == null) { _waitQueue.Add(asyncResult); } else { - asyncResult.Complete(ctx, true); + asyncResult.Complete(context, true); } return asyncResult; @@ -630,10 +634,10 @@ namespace EonaCat.Network return null; } - var ctx = contextQueue[0]; + var context = contextQueue[0]; contextQueue.RemoveAt(0); - return ctx; + return context; } } } \ No newline at end of file diff --git a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerAsyncResult.cs b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerAsyncResult.cs index 384e0b1..0def279 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerAsyncResult.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerAsyncResult.cs @@ -12,7 +12,7 @@ namespace EonaCat.Network internal class HttpListenerAsyncResult : IAsyncResult { private readonly AsyncCallback _callback; - private readonly object _sync; + private readonly object _locker; private bool _completed; private HttpListenerContext _context; private Exception _exception; @@ -27,7 +27,7 @@ namespace EonaCat.Network { _callback = callback; AsyncState = state; - _sync = new object(); + _locker = new object(); } /// @@ -42,7 +42,7 @@ namespace EonaCat.Network { get { - lock (_sync) + lock (_locker) { return _waitHandle ??= new ManualResetEvent(_completed); } @@ -61,7 +61,7 @@ namespace EonaCat.Network { get { - lock (_sync) + lock (_locker) { return _completed; } @@ -77,6 +77,7 @@ namespace EonaCat.Network /// Gets or sets a value indicating whether the asynchronous operation is in progress. /// internal bool InGet { get; set; } + /// /// Completes the asynchronous operation with the specified exception. /// @@ -129,7 +130,7 @@ namespace EonaCat.Network // Private method to complete the asynchronous operation private static void complete(HttpListenerAsyncResult asyncResult) { - lock (asyncResult._sync) + lock (asyncResult._locker) { asyncResult._completed = true; diff --git a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerContext.cs b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerContext.cs index c8c0463..b725dee 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerContext.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerContext.cs @@ -64,6 +64,7 @@ namespace EonaCat.Network /// Gets or sets the associated with the context. /// internal HttpListener Listener { get; set; } + /// /// Accepts a WebSocket connection with the specified protocol. /// diff --git a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerException.cs b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerException.cs index fe8610e..a4cd719 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerException.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerException.cs @@ -47,6 +47,7 @@ namespace EonaCat.Network : base(serializationInfo, streamingContext) { } + /// /// Gets the Win32 error code associated with this exception. /// diff --git a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerResponse.cs b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerResponse.cs index d99e046..3f97e31 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerResponse.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpListenerResponse.cs @@ -294,7 +294,6 @@ namespace EonaCat.Network } } - internal bool CloseConnection { get; set; } internal bool HeadersSent { get; set; } diff --git a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpStreamAsyncResult.cs b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpStreamAsyncResult.cs index 8f25045..3f726bf 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpStreamAsyncResult.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpStreamAsyncResult.cs @@ -9,7 +9,7 @@ namespace EonaCat.Network internal class HttpStreamAsyncResult : IAsyncResult { private readonly AsyncCallback _callback; - private readonly object _sync; + private readonly object _locker; private bool _isCompleted; private ManualResetEvent _waitHandle; @@ -17,15 +17,16 @@ namespace EonaCat.Network { _callback = callback; AsyncState = state; - _sync = new object(); + _locker = new object(); } public object AsyncState { get; } + public WaitHandle AsyncWaitHandle { get { - lock (_sync) + lock (_locker) { return _waitHandle ??= new ManualResetEvent(_isCompleted); } @@ -33,11 +34,12 @@ namespace EonaCat.Network } public bool CompletedSynchronously => SyncRead == Count; + public bool IsCompleted { get { - lock (_sync) + lock (_locker) { return _isCompleted; } @@ -55,9 +57,10 @@ namespace EonaCat.Network internal int Offset { get; set; } internal int SyncRead { get; set; } + internal void Complete() { - lock (_sync) + lock (_locker) { if (_isCompleted) { diff --git a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpUtility.cs b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpUtility.cs index a37f4b5..7da87d7 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Http/HttpUtility.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Http/HttpUtility.cs @@ -15,8 +15,9 @@ namespace EonaCat.Network internal sealed class HttpUtility { private static readonly char[] _hexChars = "0123456789abcdef".ToCharArray(); - private static readonly object _sync = new object(); + private static readonly object _locker = new object(); private static Dictionary _entities; + public static string HtmlAttributeEncode(string s) { if (s == null || s.Length == 0 || !s.Contains('&', '"', '<', '>')) @@ -1212,7 +1213,7 @@ namespace EonaCat.Network private static Dictionary getEntities() { - lock (_sync) + lock (_locker) { if (_entities == null) { @@ -1234,6 +1235,7 @@ namespace EonaCat.Network ? c - 'A' + 10 : -1; } + private static bool notEncoded(char c) { return c == '!' || diff --git a/EonaCat.Network/System/Sockets/Web/Core/Logger.cs b/EonaCat.Network/System/Sockets/Web/Core/Logger.cs index d53ce58..938d3e2 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Logger.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Logger.cs @@ -5,7 +5,6 @@ using EonaCat.Logger.SplunkServer; using EonaCat.Logger.Syslog; using System; using System.Collections.Generic; -using System.Numerics; namespace EonaCat.Network { @@ -26,10 +25,11 @@ namespace EonaCat.Network internal class Logger { private static readonly LogManager _logManager; + static Logger() { - _logManager = new LogManager(new LoggerSettings { RemoveMessagePrefix = true }); - _logManager.OnException += _logManager_OnException; + _logManager = new LogManager(new LoggerSettings()); + _logManager.OnException += LogManager_OnException; } internal static bool DisableConsole { get; set; } @@ -37,6 +37,7 @@ namespace EonaCat.Network internal static bool IsLoggingEnabled { get; set; } internal static string LoggingDirectory { get; private set; } private static bool HasBeenSetup { get; set; } + internal static void AddGrayLogServer(string hostname, int port) { _logManager.Settings.GrayLogServers.Add(new GrayLogServer(hostname, port)); @@ -69,6 +70,16 @@ namespace EonaCat.Network internal static void Error(Exception exception, string message = null, bool isCriticalException = false, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null) { + if (!IsLoggingEnabled) + { + return; + } + + if (DisableConsole) + { + writeToConsole = false; + } + if (!HasBeenSetup) { Setup(); @@ -86,6 +97,16 @@ namespace EonaCat.Network internal static void Error(string message = null, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, string grayLogFacility = null, string grayLogSource = null, string grayLogVersion = "1.1", bool isCriticalException = false) { + if (!IsLoggingEnabled) + { + return; + } + + if (DisableConsole) + { + writeToConsole = false; + } + if (!HasBeenSetup) { Setup(); @@ -169,7 +190,7 @@ namespace EonaCat.Network Write(message, ELogType.WARNING, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings); } - private static void _logManager_OnException(object? sender, ErrorMessage e) + private static void LogManager_OnException(object? sender, ErrorMessage e) { Console.WriteLine(e.Message); if (e.Exception != null) @@ -177,11 +198,12 @@ namespace EonaCat.Network Console.WriteLine(e.Exception); } } + private static void Write(string message, ELogType logType, bool? writeToConsole = null, bool? sendToSysLogServers = null, bool? sendToSplunkServers = null, string? customSplunkSourceType = null, bool? sendToGrayLogServers = null, GrayLogSettings grayLogSettings = null) { - if (!HasBeenSetup) + if (!IsLoggingEnabled) { - Setup(); + return; } if (DisableConsole) @@ -189,6 +211,11 @@ namespace EonaCat.Network writeToConsole = false; } + if (!HasBeenSetup) + { + Setup(); + } + if (grayLogSettings != null) { _logManager.Write(message, logType, writeToConsole, sendToSysLogServers, sendToSplunkServers, customSplunkSourceType, sendToGrayLogServers, grayLogSettings.Facility, grayLogSettings.Source, grayLogSettings.Version); diff --git a/EonaCat.Network/System/Sockets/Web/Core/SSLConfig/SSLConfigClient.cs b/EonaCat.Network/System/Sockets/Web/Core/SSLConfig/SSLConfigClient.cs index 240c5e6..f041a50 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/SSLConfig/SSLConfigClient.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/SSLConfig/SSLConfigClient.cs @@ -55,6 +55,7 @@ namespace EonaCat.Network } public bool CheckForCertificateRevocation { get; set; } + public LocalCertificateSelectionCallback ClientCertificateSelectionCallback { get diff --git a/EonaCat.Network/System/Sockets/Web/Core/SSLConfig/SSLConfigServer.cs b/EonaCat.Network/System/Sockets/Web/Core/SSLConfig/SSLConfigServer.cs index d4aa157..628bfa4 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/SSLConfig/SSLConfigServer.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/SSLConfig/SSLConfigServer.cs @@ -57,6 +57,7 @@ namespace EonaCat.Network public bool IsClientCertificateRequired { get; set; } public SslProtocols SslProtocols { get; set; } + private static bool ValidateClientCertificate( object sender, X509Certificate certificate, diff --git a/EonaCat.Network/System/Sockets/Web/Core/Stream/RequestStream.cs b/EonaCat.Network/System/Sockets/Web/Core/Stream/RequestStream.cs index 081176d..3fd614d 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Stream/RequestStream.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Stream/RequestStream.cs @@ -14,6 +14,7 @@ namespace EonaCat.Network private int _count; private bool _disposed; private int _offset; + internal RequestStream(Stream stream, byte[] buffer, int offset, int count) : this(stream, buffer, offset, count, -1) { diff --git a/EonaCat.Network/System/Sockets/Web/Core/Stream/ResponseStream.cs b/EonaCat.Network/System/Sockets/Web/Core/Stream/ResponseStream.cs index 83018e9..13ea0cc 100644 --- a/EonaCat.Network/System/Sockets/Web/Core/Stream/ResponseStream.cs +++ b/EonaCat.Network/System/Sockets/Web/Core/Stream/ResponseStream.cs @@ -18,6 +18,7 @@ namespace EonaCat.Network private bool _sendChunked; private Stream _stream; private Action _writeBody; + internal ResponseStream( Stream stream, HttpListenerResponse response, bool ignoreWriteExceptions) { @@ -251,6 +252,7 @@ namespace EonaCat.Network return true; } + private void writeChunked(byte[] buffer, int offset, int count) { var size = getChunkSizeBytes(count, false); diff --git a/EonaCat.Network/System/Sockets/Web/EventArgs/CloseEventArgs.cs b/EonaCat.Network/System/Sockets/Web/EventArgs/CloseEventArgs.cs index d18797b..98d6858 100644 --- a/EonaCat.Network/System/Sockets/Web/EventArgs/CloseEventArgs.cs +++ b/EonaCat.Network/System/Sockets/Web/EventArgs/CloseEventArgs.cs @@ -9,7 +9,7 @@ namespace EonaCat.Network { internal CloseEventArgs() { - PayloadData = PayloadData.Empty; + Payload = Payload.Empty; } internal CloseEventArgs(ushort code) @@ -22,14 +22,14 @@ namespace EonaCat.Network { } - internal CloseEventArgs(PayloadData payloadData) + internal CloseEventArgs(Payload payload) { - PayloadData = payloadData; + Payload = payload; } internal CloseEventArgs(ushort code, string reason) { - PayloadData = new PayloadData(code, reason); + Payload = new Payload(code, reason); } internal CloseEventArgs(CloseStatusCode code, string reason) @@ -37,9 +37,24 @@ namespace EonaCat.Network { } - public ushort Code => PayloadData.Code; - public string Reason => PayloadData.Reason ?? string.Empty; + /// + /// Code + /// + public ushort Code => Payload.Code; + + /// + /// Reason + /// + public string Reason => Payload.Reason ?? string.Empty; + + /// + /// Determnines if both the client and server requests where handled + /// public bool WasClean { get; internal set; } - internal PayloadData PayloadData { get; } + + /// + /// Payload + /// + internal Payload Payload { get; } } } \ No newline at end of file diff --git a/EonaCat.Network/System/Sockets/Web/EventArgs/MessageEventArgs.cs b/EonaCat.Network/System/Sockets/Web/EventArgs/MessageEventArgs.cs index 34114a8..2935f8f 100644 --- a/EonaCat.Network/System/Sockets/Web/EventArgs/MessageEventArgs.cs +++ b/EonaCat.Network/System/Sockets/Web/EventArgs/MessageEventArgs.cs @@ -10,15 +10,16 @@ namespace EonaCat.Network private readonly byte[] _rawData; private string _data; private bool _dataSet; + internal MessageEventArgs(WSFrame frame) { Opcode = frame.Opcode; - _rawData = frame.PayloadData.ApplicationData; + _rawData = frame.Payload.ApplicationData; } internal MessageEventArgs(OperationCode opcode, byte[] rawData) { - if ((ulong)rawData.LongLength > PayloadData.MaxLength) + if ((ulong)rawData.LongLength > Payload.MaxLength) { throw new WSException(CloseStatusCode.TooBig); } @@ -39,6 +40,7 @@ namespace EonaCat.Network public bool IsBinary => Opcode == OperationCode.Binary; public bool IsPing => Opcode == OperationCode.Ping; public bool IsText => Opcode == OperationCode.Text; + public byte[] RawData { get @@ -49,6 +51,7 @@ namespace EonaCat.Network } internal OperationCode Opcode { get; } + private void setData() { if (_dataSet) diff --git a/EonaCat.Network/System/Sockets/Web/Extensions.cs b/EonaCat.Network/System/Sockets/Web/Extensions.cs index 06faeab..d5248e1 100644 --- a/EonaCat.Network/System/Sockets/Web/Extensions.cs +++ b/EonaCat.Network/System/Sockets/Web/Extensions.cs @@ -17,6 +17,7 @@ namespace EonaCat.Network private const int BUFFER_SIZE = 1024; private static readonly byte[] _last = new byte[] { 0x00 }; private static readonly int _retry = 5; + public static bool Contains(this string value, params char[] chars) { return chars == null || chars.Length == 0 @@ -55,20 +56,14 @@ namespace EonaCat.Network public static void Emit(this EventHandler eventHandler, object sender, EventArgs e) { - if (eventHandler != null) - { - eventHandler(sender, e); - } + eventHandler?.Invoke(sender, e); } public static void Emit( this EventHandler eventHandler, object sender, TEventArgs e) where TEventArgs : EventArgs { - if (eventHandler != null) - { - eventHandler(sender, e); - } + eventHandler?.Invoke(sender, e); } public static CookieCollection GetCookies(this NameValueCollection headers, bool response) @@ -161,7 +156,7 @@ namespace EonaCat.Network /// /// An extension method to determine if an IP address is internal - /// Class A Private IP Range: 10.0.0.0 ? 10.255.255.255 + /// Class A Private IP Range: 10.0.0.0 ? 10.255.255.255 /// Class B Private IP Range: 172.16.0.0 ? 172.31.255.255 /// Class C Private IP Range: 192.168.0.0 ? 192.168.255.25 /// @@ -174,10 +169,13 @@ namespace EonaCat.Network { case 10: return true; + case 172: return bytes[1] < 32 && bytes[1] >= 16; + case 192: return bytes[1] == 168; + default: return false; } @@ -741,10 +739,7 @@ namespace EonaCat.Network var nread = source.EndRead(ar); if (nread <= 0) { - if (completed != null) - { - completed(); - } + completed?.Invoke(); return; } @@ -754,10 +749,7 @@ namespace EonaCat.Network } catch (Exception ex) { - if (error != null) - { - error(ex); - } + error?.Invoke(ex); } }; @@ -767,10 +759,7 @@ namespace EonaCat.Network } catch (Exception ex) { - if (error != null) - { - error(ex); - } + error?.Invoke(ex); } } @@ -839,7 +828,7 @@ namespace EonaCat.Network ? "A policy violation has occurred." : code == CloseStatusCode.TooBig ? "A too big message has been received." - : code == CloseStatusCode.MandatoryExtension + : code == CloseStatusCode.MissingExtension ? "WebSocket client didn't receive expected extension(s)." : code == CloseStatusCode.ServerError ? "WebSocket server got an internal error." @@ -1101,10 +1090,7 @@ namespace EonaCat.Network if (nread == length) { - if (completed != null) - { - completed(buff.SubArray(0, offset + nread)); - } + completed?.Invoke(buff.SubArray(0, offset + nread)); return; } @@ -1118,10 +1104,7 @@ namespace EonaCat.Network } catch (Exception ex) { - if (error != null) - { - error(ex); - } + error?.Invoke(ex); } }; @@ -1131,10 +1114,7 @@ namespace EonaCat.Network } catch (Exception ex) { - if (error != null) - { - error(ex); - } + error?.Invoke(ex); } } @@ -1199,10 +1179,7 @@ namespace EonaCat.Network catch (Exception ex) { dest.Dispose(); - if (error != null) - { - error(ex); - } + error?.Invoke(ex); } }, null @@ -1216,10 +1193,7 @@ namespace EonaCat.Network catch (Exception ex) { dest.Dispose(); - if (error != null) - { - error(ex); - } + error?.Invoke(ex); } } @@ -1558,20 +1532,14 @@ namespace EonaCat.Network bufferLength, () => { - if (completed != null) - { - completed(); - } + completed?.Invoke(); input.Dispose(); }, ex => { input.Dispose(); - if (error != null) - { - error(ex); - } + error?.Invoke(ex); }); } diff --git a/EonaCat.Network/System/Sockets/Web/PayloadData.cs b/EonaCat.Network/System/Sockets/Web/Payload.cs similarity index 89% rename from EonaCat.Network/System/Sockets/Web/PayloadData.cs rename to EonaCat.Network/System/Sockets/Web/Payload.cs index dc0386e..fc0937c 100644 --- a/EonaCat.Network/System/Sockets/Web/PayloadData.cs +++ b/EonaCat.Network/System/Sockets/Web/Payload.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; namespace EonaCat.Network { - internal class PayloadData : IEnumerable + internal class Payload : IEnumerable { private ushort _code; private bool _codeSet; @@ -16,17 +16,17 @@ namespace EonaCat.Network private string _reason; private bool _reasonSet; - public static readonly PayloadData Empty; + public static readonly Payload Empty; public static readonly ulong MaxLength; - static PayloadData() + static Payload() { - Empty = new PayloadData(); + Empty = new Payload(); MaxLength = long.MaxValue; } - internal PayloadData() + internal Payload() { _code = (ushort)CloseStatusCode.NoStatus; _reason = string.Empty; @@ -37,7 +37,7 @@ namespace EonaCat.Network _reasonSet = true; } - internal PayloadData(PayloadData original) + internal Payload(Payload original) { _code = original._code; _codeSet = original._codeSet; @@ -48,22 +48,20 @@ namespace EonaCat.Network _data = new byte[_length]; original._data.CopyTo(_data, 0); - - } - internal PayloadData(byte[] data) + internal Payload(byte[] data) : this(data, data.LongLength) { } - internal PayloadData(byte[] data, long length) + internal Payload(byte[] data, long length) { _data = data; _length = length; } - internal PayloadData(ushort code, string reason) + internal Payload(ushort code, string reason) { _code = code; _reason = reason ?? string.Empty; diff --git a/EonaCat.Network/System/Sockets/Web/Rsv.cs b/EonaCat.Network/System/Sockets/Web/ReservedBits.cs similarity index 86% rename from EonaCat.Network/System/Sockets/Web/Rsv.cs rename to EonaCat.Network/System/Sockets/Web/ReservedBits.cs index de067d4..d49e872 100644 --- a/EonaCat.Network/System/Sockets/Web/Rsv.cs +++ b/EonaCat.Network/System/Sockets/Web/ReservedBits.cs @@ -3,7 +3,7 @@ namespace EonaCat.Network { - internal enum Rsv : byte + internal enum ReservedBits : byte { Off = 0x0, diff --git a/EonaCat.Network/System/Sockets/Web/Server/HttpRequestEventArgs.cs b/EonaCat.Network/System/Sockets/Web/Server/HttpRequestEventArgs.cs index 8679885..98bd225 100644 --- a/EonaCat.Network/System/Sockets/Web/Server/HttpRequestEventArgs.cs +++ b/EonaCat.Network/System/Sockets/Web/Server/HttpRequestEventArgs.cs @@ -44,7 +44,7 @@ namespace EonaCat.Network throw new ArgumentException("It contains '..'.", nameof(path)); } - tryReadFile(createFilePath(path), out byte[] contents); + tryReadFile(CreateFilePath(path), out byte[] contents); return contents; } @@ -66,7 +66,7 @@ namespace EonaCat.Network throw new ArgumentException("It contains '..'.", nameof(path)); } - return tryReadFile(createFilePath(path), out contents); + return tryReadFile(CreateFilePath(path), out contents); } private static bool tryReadFile(string path, out byte[] contents) @@ -90,7 +90,7 @@ namespace EonaCat.Network return true; } - private string createFilePath(string childPath) + private string CreateFilePath(string childPath) { childPath = childPath.TrimStart('/', '\\'); return new StringBuilder(_docRootPath, 32) diff --git a/EonaCat.Network/System/Sockets/Web/Server/HttpServer.cs b/EonaCat.Network/System/Sockets/Web/Server/HttpServer.cs index 902b4a7..c4a140c 100644 --- a/EonaCat.Network/System/Sockets/Web/Server/HttpServer.cs +++ b/EonaCat.Network/System/Sockets/Web/Server/HttpServer.cs @@ -4,7 +4,6 @@ using System; using System.IO; using System.Security.Principal; -using System.Text; using System.Threading; namespace EonaCat.Network @@ -17,7 +16,8 @@ namespace EonaCat.Network private HttpListener _listener; private Thread _receiveThread; private volatile ServerState _state; - private object _sync; + private object _locker; + public HttpServer() { init("*", System.Net.IPAddress.Any, 80, false); @@ -158,7 +158,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!canSet(out message)) { @@ -234,7 +234,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!canSet(out message)) { @@ -256,15 +256,17 @@ namespace EonaCat.Network { get { - return WebSocketServices.AutoCleanSessions; + return WSEndpoints.AutoCleanSessions; } set { - WebSocketServices.AutoCleanSessions = value; + WSEndpoints.AutoCleanSessions = value; } } + public int Port { get; private set; } + public string Realm { get @@ -280,7 +282,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!canSet(out message)) { @@ -308,7 +310,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!canSet(out message)) { @@ -350,7 +352,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!canSet(out message)) { @@ -363,24 +365,25 @@ namespace EonaCat.Network } } - public TimeSpan WaitTime + public TimeSpan ResponseWaitingTime { get { - return WebSocketServices.WaitTime; + return WSEndpoints.ResponseWaitingTime; } set { - WebSocketServices.WaitTime = value; + WSEndpoints.ResponseWaitingTime = value; } } - public WSEndpointManager WebSocketServices { get; private set; } + public WSEndpointManager WSEndpoints { get; private set; } + public void AddWebSocketService(string path) where TEndpoint : WSEndpoint, new() { - WebSocketServices.AddService(path, null); + WSEndpoints.AddEndpoint(path, null); } public void AddWebSocketService( @@ -388,12 +391,12 @@ namespace EonaCat.Network ) where TEndpoint : WSEndpoint, new() { - WebSocketServices.AddService(path, initializer); + WSEndpoints.AddEndpoint(path, initializer); } public bool RemoveWebSocketService(string path) { - return WebSocketServices.RemoveService(path); + return WSEndpoints.RemoveEndpoint(path); } public void Start() @@ -422,9 +425,9 @@ namespace EonaCat.Network throw new ArgumentOutOfRangeException(nameof(code), message); } - if (code == (ushort)CloseStatusCode.MandatoryExtension) + if (code == (ushort)CloseStatusCode.MissingExtension) { - var message = $"{(ushort)CloseStatusCode.MandatoryExtension} cannot be used."; + var message = $"{(ushort)CloseStatusCode.MissingExtension} cannot be used."; throw new ArgumentException(message, nameof(code)); } @@ -454,7 +457,7 @@ namespace EonaCat.Network public void Stop(CloseStatusCode code, string reason) { - if (code == CloseStatusCode.MandatoryExtension) + if (code == CloseStatusCode.MissingExtension) { var message = "MandatoryExtension cannot be used."; throw new ArgumentException(message, nameof(code)); @@ -548,7 +551,7 @@ namespace EonaCat.Network private void abort() { - lock (_sync) + lock (_locker) { if (_state != ServerState.Start) { @@ -562,7 +565,7 @@ namespace EonaCat.Network { try { - WebSocketServices.Stop((ushort)CloseStatusCode.Abnormal, string.Empty); + WSEndpoints.Stop((ushort)CloseStatusCode.Abnormal, string.Empty); } finally { @@ -620,6 +623,7 @@ namespace EonaCat.Network return true; } + private void init( string hostname, System.Net.IPAddress address, int port, bool secure ) @@ -631,8 +635,8 @@ namespace EonaCat.Network _docRootPath = "./Public"; _listener = createListener(_hostname, Port, IsSecure); - WebSocketServices = new WSEndpointManager(); - _sync = new object(); + WSEndpoints = new WSEndpointManager(); + _locker = new object(); } private void processRequest(HttpListenerContext context) @@ -674,7 +678,7 @@ namespace EonaCat.Network { var path = context.RequestUri.AbsolutePath; - if (!WebSocketServices.InternalTryGetServiceHost(path, out WSEndpointHost host)) + if (!WSEndpoints.InternalTryGetEndpointHost(path, out WSEndpointHost host)) { context.Close(HttpStatusCode.NotImplemented); return; @@ -687,29 +691,29 @@ namespace EonaCat.Network { while (true) { - HttpListenerContext ctx = null; + HttpListenerContext context = null; try { - ctx = _listener.GetContext(); + context = _listener.GetContext(); ThreadPool.QueueUserWorkItem( state => { try { - if (ctx.Request.IsUpgradeTo("websocket")) + if (context.Request.IsUpgradeTo("websocket")) { - processRequest(ctx.AcceptWebSocket(null)); + processRequest(context.AcceptWebSocket(null)); return; } - processRequest(ctx); + processRequest(context); } catch (Exception ex) { Logger.Error(ex.Message); Logger.Debug(ex.ToString()); - ctx.Connection.Close(true); + context.Connection.Close(true); } } ); @@ -729,7 +733,7 @@ namespace EonaCat.Network Logger.Error(ex.Message); Logger.Debug(ex.ToString()); - ctx?.Connection.Close(true); + context?.Connection.Close(true); break; } @@ -755,7 +759,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (_state == ServerState.Start) { @@ -769,7 +773,7 @@ namespace EonaCat.Network return; } - WebSocketServices.Start(); + WSEndpoints.Start(); try { @@ -777,7 +781,7 @@ namespace EonaCat.Network } catch { - WebSocketServices.Stop((ushort)CloseStatusCode.ServerError, string.Empty); + WSEndpoints.Stop((ushort)CloseStatusCode.ServerError, string.Empty); throw; } @@ -822,7 +826,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (_state == ServerState.ShuttingDown) { @@ -844,7 +848,7 @@ namespace EonaCat.Network var threw = false; try { - WebSocketServices.Stop(code, reason); + WSEndpoints.Stop(code, reason); } catch { diff --git a/EonaCat.Network/System/Sockets/Web/Server/WSEndpoint.cs b/EonaCat.Network/System/Sockets/Web/Server/WSEndpoint.cs index 6f60b6e..cf0cdaa 100644 --- a/EonaCat.Network/System/Sockets/Web/Server/WSEndpoint.cs +++ b/EonaCat.Network/System/Sockets/Web/Server/WSEndpoint.cs @@ -19,6 +19,7 @@ namespace EonaCat.Network public WSContext Context { get; private set; } public Func CookiesValidator { get; set; } + public bool EmitOnPing { get @@ -41,6 +42,7 @@ namespace EonaCat.Network public string ID { get; private set; } public bool IgnoreExtensions { get; set; } public Func OriginValidator { get; set; } + public string Protocol { get @@ -67,6 +69,7 @@ namespace EonaCat.Network public DateTime StartTime { get; private set; } public WSState State => _websocket != null ? _websocket.ReadyState : WSState.Connecting; protected WSSessionManager Sessions { get; private set; } + internal void Start(WSContext context, WSSessionManager sessions) { if (_websocket != null) @@ -86,10 +89,10 @@ namespace EonaCat.Network _websocket.IgnoreExtensions = IgnoreExtensions; _websocket.Protocol = _protocol; - var waitTime = sessions.WaitTime; - if (waitTime != _websocket.WaitTime) + var responseWaitingTime = sessions.ResponseWaitingTime; + if (responseWaitingTime != _websocket.ResponseWaitingTime) { - _websocket.WaitTime = waitTime; + _websocket.ResponseWaitingTime = responseWaitingTime; } _websocket.OnConnect += onOpen; diff --git a/EonaCat.Network/System/Sockets/Web/Server/WSEndpointHost.cs b/EonaCat.Network/System/Sockets/Web/Server/WSEndpointHost.cs index d711343..e6e7011 100644 --- a/EonaCat.Network/System/Sockets/Web/Server/WSEndpointHost.cs +++ b/EonaCat.Network/System/Sockets/Web/Server/WSEndpointHost.cs @@ -14,7 +14,8 @@ namespace EonaCat.Network } public abstract Type EndpointType { get; } - public bool KeepClean + + public bool AutoCleanSessions { get { @@ -29,20 +30,22 @@ namespace EonaCat.Network public string Path { get; } public WSSessionManager Sessions { get; } - public TimeSpan WaitTime + + public TimeSpan ResponseWaitingTime { get { - return Sessions.WaitTime; + return Sessions.ResponseWaitingTime; } set { - Sessions.WaitTime = value; + Sessions.ResponseWaitingTime = value; } } internal ServerState State => Sessions.State; + internal void Start() { Sessions.Start(); diff --git a/EonaCat.Network/System/Sockets/Web/Server/WSEndpointManager.cs b/EonaCat.Network/System/Sockets/Web/Server/WSEndpointManager.cs index 663166e..d993dd5 100644 --- a/EonaCat.Network/System/Sockets/Web/Server/WSEndpointManager.cs +++ b/EonaCat.Network/System/Sockets/Web/Server/WSEndpointManager.cs @@ -5,25 +5,24 @@ using System; using System.Collections; using System.Collections.Generic; using System.IO; -using System.Threading; namespace EonaCat.Network { public class WSEndpointManager { private readonly Dictionary _hosts; - private readonly object _sync; + private readonly object _locker; private volatile bool _clean; private volatile ServerState _state; - private TimeSpan _waitTime; + private TimeSpan _responseWaitingTime; internal WSEndpointManager() { _clean = true; _hosts = new Dictionary(); _state = ServerState.Started; - _sync = ((ICollection)_hosts).SyncRoot; - _waitTime = TimeSpan.FromSeconds(1); + _locker = ((ICollection)_hosts).SyncRoot; + _responseWaitingTime = TimeSpan.FromSeconds(1); } public bool AutoCleanSessions @@ -41,7 +40,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!canSet(out message)) { @@ -51,7 +50,7 @@ namespace EonaCat.Network foreach (var host in _hosts.Values) { - host.KeepClean = value; + host.AutoCleanSessions = value; } _clean = value; @@ -63,7 +62,7 @@ namespace EonaCat.Network { get { - lock (_sync) + lock (_locker) { return _hosts.Count; } @@ -74,7 +73,7 @@ namespace EonaCat.Network { get { - lock (_sync) + lock (_locker) { return _hosts.Values.ToList(); } @@ -85,18 +84,18 @@ namespace EonaCat.Network { get { - lock (_sync) + lock (_locker) { return _hosts.Keys.ToList(); } } } - public TimeSpan WaitTime + public TimeSpan ResponseWaitingTime { get { - return _waitTime; + return _responseWaitingTime; } set @@ -112,7 +111,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!canSet(out message)) { @@ -122,10 +121,10 @@ namespace EonaCat.Network foreach (var host in _hosts.Values) { - host.WaitTime = value; + host.ResponseWaitingTime = value; } - _waitTime = value; + _responseWaitingTime = value; } } } @@ -155,12 +154,13 @@ namespace EonaCat.Network throw new ArgumentException(message, nameof(path)); } - InternalTryGetServiceHost(path, out WSEndpointHost host); + InternalTryGetEndpointHost(path, out WSEndpointHost host); return host; } } - public void AddService( + + public void AddEndpoint( string path, Action initializer ) where TEndpoint : WSEndpoint, new() @@ -188,7 +188,7 @@ namespace EonaCat.Network path = HttpUtility.UrlDecode(path).TrimSlashFromEnd(); - lock (_sync) + lock (_locker) { if (_hosts.TryGetValue(path, out WSEndpointHost host)) { @@ -201,12 +201,12 @@ namespace EonaCat.Network if (!_clean) { - host.KeepClean = false; + host.AutoCleanSessions = false; } - if (_waitTime != host.WaitTime) + if (_responseWaitingTime != host.ResponseWaitingTime) { - host.WaitTime = _waitTime; + host.ResponseWaitingTime = _responseWaitingTime; } if (_state == ServerState.Start) @@ -222,7 +222,7 @@ namespace EonaCat.Network { List hosts = null; - lock (_sync) + lock (_locker) { hosts = _hosts.Values.ToList(); _hosts.Clear(); @@ -237,7 +237,7 @@ namespace EonaCat.Network } } - public bool RemoveService(string path) + public bool RemoveEndpoint(string path) { if (path == null) { @@ -263,7 +263,7 @@ namespace EonaCat.Network path = HttpUtility.UrlDecode(path).TrimSlashFromEnd(); WSEndpointHost host; - lock (_sync) + lock (_locker) { if (!_hosts.TryGetValue(path, out host)) { @@ -281,7 +281,7 @@ namespace EonaCat.Network return true; } - public bool TryGetServiceHost(string path, out WSEndpointHost host) + public bool TryGetEndpointHost(string path, out WSEndpointHost host) { if (path == null) { @@ -304,7 +304,7 @@ namespace EonaCat.Network throw new ArgumentException(message, nameof(path)); } - return InternalTryGetServiceHost(path, out host); + return InternalTryGetEndpointHost(path, out host); } internal void Add(string path, Func creator) @@ -312,7 +312,7 @@ namespace EonaCat.Network { path = HttpUtility.UrlDecode(path).TrimSlashFromEnd(); - lock (_sync) + lock (_locker) { if (_hosts.TryGetValue(path, out WSEndpointHost host)) { @@ -325,12 +325,12 @@ namespace EonaCat.Network if (!_clean) { - host.KeepClean = false; + host.AutoCleanSessions = false; } - if (_waitTime != host.WaitTime) + if (_responseWaitingTime != host.ResponseWaitingTime) { - host.WaitTime = _waitTime; + host.ResponseWaitingTime = _responseWaitingTime; } if (_state == ServerState.Start) @@ -342,13 +342,13 @@ namespace EonaCat.Network } } - internal bool InternalTryGetServiceHost( + internal bool InternalTryGetEndpointHost( string path, out WSEndpointHost host ) { path = HttpUtility.UrlDecode(path).TrimSlashFromEnd(); - lock (_sync) + lock (_locker) { return _hosts.TryGetValue(path, out host); } @@ -356,7 +356,7 @@ namespace EonaCat.Network internal void Start() { - lock (_sync) + lock (_locker) { foreach (var host in _hosts.Values) { @@ -369,7 +369,7 @@ namespace EonaCat.Network internal void Stop(ushort code, string reason) { - lock (_sync) + lock (_locker) { _state = ServerState.ShuttingDown; @@ -399,10 +399,7 @@ namespace EonaCat.Network host.Sessions.Broadcast(opcode, data, cache); } - if (completed != null) - { - completed(); - } + completed?.Invoke(); } catch (Exception ex) { @@ -431,10 +428,7 @@ namespace EonaCat.Network host.Sessions.Broadcast(opcode, stream, cache); } - if (completed != null) - { - completed(); - } + completed?.Invoke(); } catch (Exception ex) { diff --git a/EonaCat.Network/System/Sockets/Web/Server/WSServer.cs b/EonaCat.Network/System/Sockets/Web/Server/WSServer.cs index ef74e8e..08a1d51 100644 --- a/EonaCat.Network/System/Sockets/Web/Server/WSServer.cs +++ b/EonaCat.Network/System/Sockets/Web/Server/WSServer.cs @@ -10,7 +10,7 @@ namespace EonaCat.Network { public class WSServer { - private static readonly string _defaultRealm; + private static readonly string _defaultRealm = "EonaCat Network - Area51"; private bool _allowForwardedRequest; private AuthenticationSchemes _authSchemes; private bool _dnsStyle; @@ -23,12 +23,8 @@ namespace EonaCat.Network private SSLConfigServer _sslConfig; private SSLConfigServer _sslConfigInUse; private volatile ServerState _state; - private object _sync; + private object _locker; private Func _userCredentialsFinder; - static WSServer() - { - _defaultRealm = "SECRET AREA"; - } public WSServer() { @@ -115,6 +111,7 @@ namespace EonaCat.Network } public System.Net.IPAddress Address { get; private set; } + public bool AllowForwardedRequest { get @@ -130,7 +127,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!CanSet(out message)) { @@ -158,7 +155,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!CanSet(out message)) { @@ -188,6 +185,7 @@ namespace EonaCat.Network } public WSEndpointManager Endpoints { get; private set; } + public Func FindCredentials { get @@ -203,7 +201,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!CanSet(out message)) { @@ -237,7 +235,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!CanSet(out message)) { @@ -265,7 +263,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!CanSet(out message)) { @@ -291,31 +289,33 @@ namespace EonaCat.Network return GetSSLConfig(); } } - public TimeSpan WaitTime + + public TimeSpan ResponseWaitingTime { get { - return Endpoints.WaitTime; + return Endpoints.ResponseWaitingTime; } set { - Endpoints.WaitTime = value; + Endpoints.ResponseWaitingTime = value; } } + public void AddEndpoint(string path) where TEndpoint : WSEndpoint, new() { - Endpoints.AddService(path, null); + Endpoints.AddEndpoint(path, null); } public void AddEndpoint(string path, Action initializer) where TEndpoint : WSEndpoint, new() { - Endpoints.AddService(path, initializer); + Endpoints.AddEndpoint(path, initializer); } public bool RemoveEndpoint(string path) { - return Endpoints.RemoveService(path); + return Endpoints.RemoveEndpoint(path); } public void Start() @@ -348,9 +348,9 @@ namespace EonaCat.Network throw new ArgumentOutOfRangeException(nameof(code), message); } - if (code == (ushort)CloseStatusCode.MandatoryExtension) + if (code == (ushort)CloseStatusCode.MissingExtension) { - var message = $"{(ushort)CloseStatusCode.MandatoryExtension} cannot be used."; + var message = $"{(ushort)CloseStatusCode.MissingExtension} cannot be used."; throw new ArgumentException(message, nameof(code)); } @@ -380,7 +380,7 @@ namespace EonaCat.Network public void Stop(CloseStatusCode code, string reason) { - if (code == CloseStatusCode.MandatoryExtension) + if (code == CloseStatusCode.MissingExtension) { var message = "MandatoryExtension cannot be used."; throw new ArgumentException(message, nameof(code)); @@ -446,7 +446,7 @@ namespace EonaCat.Network private void abort() { - lock (_sync) + lock (_locker) { if (_state != ServerState.Start) { @@ -499,6 +499,7 @@ namespace EonaCat.Network || Uri.CheckHostName(name) != UriHostNameType.Dns || name == _hostname; } + private string GetRealm() { var realm = _realm; @@ -525,7 +526,7 @@ namespace EonaCat.Network _dnsStyle = Uri.CheckHostName(hostname) == UriHostNameType.Dns; _listener = new TcpListener(address, port); Endpoints = new WSEndpointManager(); - _sync = new object(); + _locker = new object(); } private void processRequest(TcpListenerWSContext context) @@ -552,7 +553,7 @@ namespace EonaCat.Network } } - if (!Endpoints.InternalTryGetServiceHost(uri.AbsolutePath, out WSEndpointHost host)) + if (!Endpoints.InternalTryGetEndpointHost(uri.AbsolutePath, out WSEndpointHost host)) { context.Close(HttpStatusCode.NotImplemented); return; @@ -574,15 +575,15 @@ namespace EonaCat.Network { try { - var ctx = new TcpListenerWSContext( + var context = new TcpListenerWSContext( cl, null, IsSecure, _sslConfigInUse); - if (!ctx.Authenticate(_authSchemes, _realmInUse, _userCredentialsFinder)) + if (!context.Authenticate(_authSchemes, _realmInUse, _userCredentialsFinder)) { return; } - processRequest(ctx); + processRequest(context); } catch (Exception ex) { @@ -641,7 +642,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (_state == ServerState.Start) { @@ -717,7 +718,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (_state == ServerState.ShuttingDown) { diff --git a/EonaCat.Network/System/Sockets/Web/Server/WSSessionManager.cs b/EonaCat.Network/System/Sockets/Web/Server/WSSessionManager.cs index edb6a2b..77fd73c 100644 --- a/EonaCat.Network/System/Sockets/Web/Server/WSSessionManager.cs +++ b/EonaCat.Network/System/Sockets/Web/Server/WSSessionManager.cs @@ -12,25 +12,26 @@ namespace EonaCat.Network { public class WSSessionManager { - private readonly object _forSweep; + private const int _cleanupIntervalInMiliSeconds = 60000; + private readonly object _cleanLocker; private readonly Dictionary _sessions; - private readonly object _sync; + private readonly object _locker; private volatile bool _clean; private volatile ServerState _state; private volatile bool _sweeping; private System.Timers.Timer _sweepTimer; - private TimeSpan _waitTime; + private TimeSpan _responseWaitingTime; internal WSSessionManager() { _clean = true; - _forSweep = new object(); + _cleanLocker = new object(); _sessions = new Dictionary(); _state = ServerState.Started; - _sync = ((ICollection)_sessions).SyncRoot; - _waitTime = TimeSpan.FromSeconds(1); + _locker = ((ICollection)_sessions).SyncRoot; + _responseWaitingTime = TimeSpan.FromSeconds(1); - setSweepTimer(60000); + setCleanupTimer(_cleanupIntervalInMiliSeconds); } public IEnumerable ActiveIDs @@ -51,7 +52,7 @@ namespace EonaCat.Network { get { - lock (_sync) + lock (_locker) { return _sessions.Count; } @@ -67,7 +68,7 @@ namespace EonaCat.Network return Enumerable.Empty(); } - lock (_sync) + lock (_locker) { if (_state != ServerState.Start) { @@ -108,7 +109,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!canSet(out message)) { @@ -130,7 +131,7 @@ namespace EonaCat.Network return Enumerable.Empty(); } - lock (_sync) + lock (_locker) { if (_state != ServerState.Start) { @@ -142,11 +143,11 @@ namespace EonaCat.Network } } - public TimeSpan WaitTime + internal TimeSpan ResponseWaitingTime { get { - return _waitTime; + return _responseWaitingTime; } set @@ -162,7 +163,7 @@ namespace EonaCat.Network return; } - lock (_sync) + lock (_locker) { if (!canSet(out message)) { @@ -170,12 +171,13 @@ namespace EonaCat.Network return; } - _waitTime = value; + _responseWaitingTime = value; } } } internal ServerState State => _state; + public IWSSession this[string id] { get @@ -195,6 +197,7 @@ namespace EonaCat.Network return session; } } + public void Broadcast(byte[] data) { if (_state != ServerState.Start) @@ -538,7 +541,7 @@ namespace EonaCat.Network return; } - lock (_forSweep) + lock (_cleanLocker) { if (_sweeping) { @@ -556,7 +559,7 @@ namespace EonaCat.Network break; } - lock (_sync) + lock (_locker) { if (_state != ServerState.Start) { @@ -602,7 +605,7 @@ namespace EonaCat.Network internal string Add(IWSSession session) { - lock (_sync) + lock (_locker) { if (_state != ServerState.Start) { @@ -624,7 +627,7 @@ namespace EonaCat.Network { if (_state != ServerState.Start) { - Logger.Error("The service is shutting down."); + Logger.Error("The endpoint is shutting down."); break; } @@ -640,7 +643,7 @@ namespace EonaCat.Network { if (_state != ServerState.Start) { - Logger.Error("The service is shutting down."); + Logger.Error("The endpoint is shutting down."); break; } @@ -658,7 +661,7 @@ namespace EonaCat.Network { if (_state != ServerState.Start) { - Logger.Error("The service is shutting down."); + Logger.Error("The endpoint is shutting down."); break; } @@ -671,7 +674,7 @@ namespace EonaCat.Network internal bool Remove(string id) { - lock (_sync) + lock (_locker) { return _sessions.Remove(id); } @@ -679,7 +682,7 @@ namespace EonaCat.Network internal void Start() { - lock (_sync) + lock (_locker) { _sweepTimer.Enabled = _clean; _state = ServerState.Start; @@ -690,11 +693,11 @@ namespace EonaCat.Network { if (code == (ushort)CloseStatusCode.NoStatus) { // == no status - stop(PayloadData.Empty, true); + stop(Payload.Empty, true); return; } - stop(new PayloadData(code, reason), !code.IsReserved()); + stop(new Payload(code, reason), !code.IsReserved()); } private static string createID() @@ -712,17 +715,14 @@ namespace EonaCat.Network { if (_state != ServerState.Start) { - Logger.Error("The service is shutting down."); + Logger.Error("The endpoint is shutting down."); break; } session.Context.WebSocket.Send(opcode, data, cache); } - if (completed != null) - { - completed(); - } + completed?.Invoke(); } catch (Exception ex) { @@ -745,17 +745,14 @@ namespace EonaCat.Network { if (_state != ServerState.Start) { - Logger.Error("The service is shutting down."); + Logger.Error("The endpoint is shutting down."); break; } session.Context.WebSocket.Send(opcode, stream, cache); } - if (completed != null) - { - completed(); - } + completed?.Invoke(); } catch (Exception ex) { @@ -789,21 +786,21 @@ namespace EonaCat.Network private Dictionary broadping(byte[] frameAsBytes) { - var ret = new Dictionary(); + var result = new Dictionary(); foreach (var session in Sessions) { if (_state != ServerState.Start) { - Logger.Error("The service is shutting down."); + Logger.Error("The endpoint is shutting down."); break; } - var res = session.Context.WebSocket.Ping(frameAsBytes, _waitTime); - ret.Add(session.ID, res); + var pingResult = session.Context.WebSocket.Ping(frameAsBytes, _responseWaitingTime); + result.Add(session.ID, pingResult); } - return ret; + return result; } private bool canSet(out string message) @@ -812,38 +809,39 @@ namespace EonaCat.Network if (_state == ServerState.Start) { - message = "The service has already started."; + message = "The endpoint has already started."; return false; } if (_state == ServerState.ShuttingDown) { - message = "The service is shutting down."; + message = "The endpoint is shutting down."; return false; } return true; } - private void setSweepTimer(double interval) + + private void setCleanupTimer(double interval) { _sweepTimer = new System.Timers.Timer(interval); _sweepTimer.Elapsed += (sender, e) => Sweep(); } - private void stop(PayloadData payloadData, bool send) + private void stop(Payload payload, bool send) { var bytes = send - ? WSFrame.CreateCloseFrame(payloadData, false).ToArray() + ? WSFrame.CreateCloseFrame(payload, false).ToArray() : null; - lock (_sync) + lock (_locker) { _state = ServerState.ShuttingDown; _sweepTimer.Enabled = false; foreach (var session in _sessions.Values.ToList()) { - session.Context.WebSocket.Close(payloadData, bytes); + session.Context.WebSocket.Close(payload, bytes); } _state = ServerState.Stop; @@ -859,7 +857,7 @@ namespace EonaCat.Network return false; } - lock (_sync) + lock (_locker) { if (_state != ServerState.Start) { diff --git a/EonaCat.Network/System/Sockets/Web/WSClient.cs b/EonaCat.Network/System/Sockets/Web/WSClient.cs index eda7872..697feec 100644 --- a/EonaCat.Network/System/Sockets/Web/WSClient.cs +++ b/EonaCat.Network/System/Sockets/Web/WSClient.cs @@ -8,6 +8,7 @@ using System.IO; using System.Net.Security; using System.Net.Sockets; using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -18,9 +19,13 @@ namespace EonaCat.Network { internal static readonly byte[] EmptyBytes; internal static readonly RandomNumberGenerator RandomNumber; - private const string _version = "13"; + private const string _webSocketVersion = "13"; private const string _webSocketGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; private const int FRAGMENT_LENGTH = 1016; + private const int MAX_PING_SIZE = 125; + private const string NOT_CONNECTED_MESSAGE = "Connection state is not 'Open', please connect to the server first"; + private const string SERVER_CANNOT_USE_SET_MESSAGE = "The set operation cannot be used by servers."; + private const string CLOSING_MESSAGE = "The connection is closing."; private static readonly int _maxRetryCountForConnect; private readonly bool _client; private readonly Action _message; @@ -32,10 +37,10 @@ namespace EonaCat.Network private WSContext _context; private string _extensions; private bool _extensionsRequested; - private object _forMessageEventQueue; - private object _forPing; - private object _forSend; - private object _forState; + private object _messageEventQueueLocker; + private object _pingLocker; + private object _sendLocker; + private object _stateLocker; private MemoryStream _fragmentsBuffer; private bool _fragmentsCompressed; private OperationCode _fragmentsOpcode; @@ -58,7 +63,8 @@ namespace EonaCat.Network private Stream _stream; private TcpClient _tcpClient; private Uri _uri; - private TimeSpan _waitTime; + private TimeSpan _responseWaitingTime; + static WSClient() { _maxRetryCountForConnect = 10; @@ -67,7 +73,7 @@ namespace EonaCat.Network RandomNumber = new RNGCryptoServiceProvider(); } - public WSClient(string url, params string[] protocols) + public WSClient(string url, X509Certificate clientCertificate = null, params string[] protocols) { if (url == null) { @@ -93,8 +99,13 @@ namespace EonaCat.Network _base64Key = CreateBase64Key(); _client = true; _message = messagec; - IsSecure = _uri.Scheme == "wss"; - _waitTime = TimeSpan.FromSeconds(5); + IsSSL = _uri.Scheme == "wss"; + _responseWaitingTime = TimeSpan.FromSeconds(5); + + if (IsSSL && clientCertificate != null) + { + SSL.Certificates.Add(clientCertificate); + } Setup(); } @@ -106,9 +117,9 @@ namespace EonaCat.Network _closeContext = context.Close; _message = messages; - IsSecure = context.IsSecureConnection; + IsSSL = context.IsSecureConnection; _stream = context.Stream; - _waitTime = TimeSpan.FromSeconds(1); + _responseWaitingTime = TimeSpan.FromSeconds(1); Setup(); } @@ -120,9 +131,9 @@ namespace EonaCat.Network _closeContext = context.Close; _message = messages; - IsSecure = context.IsSecureConnection; + IsSSL = context.IsSecureConnection; _stream = context.Stream; - _waitTime = TimeSpan.FromSeconds(1); + _responseWaitingTime = TimeSpan.FromSeconds(1); Setup(); } @@ -139,7 +150,9 @@ namespace EonaCat.Network /// Fragment length /// public static int FragmentLength { get; set; } + public bool CallMessageOnPing { get; set; } + public CompressionMethod Compression { get @@ -149,21 +162,18 @@ namespace EonaCat.Network set { - string message = null; - if (!_client) { - message = "The set operation cannot be used by servers."; - throw new InvalidOperationException(message); + throw new InvalidOperationException(SERVER_CANNOT_USE_SET_MESSAGE); } - if (!canSet(out message)) + if (!canSet(out string message)) { Logger.Warning(message); return; } - lock (_forState) + lock (_stateLocker) { if (!canSet(out message)) { @@ -191,6 +201,7 @@ namespace EonaCat.Network } public NetworkCredential Credentials { get; private set; } + /// /// Gets or sets the custom headers /// @@ -198,6 +209,7 @@ namespace EonaCat.Network public string Extensions => _extensions ?? string.Empty; public bool IsAlive => ping(EmptyBytes); + public bool IsRedirectionEnabled { get @@ -207,21 +219,19 @@ namespace EonaCat.Network set { - string message = null; if (!_client) { - message = "The set operation cannot be used by servers."; - throw new InvalidOperationException(message); + throw new InvalidOperationException(SERVER_CANNOT_USE_SET_MESSAGE); } - if (!canSet(out message)) + if (!canSet(out string message)) { Logger.Warning(message); return; } - lock (_forState) + lock (_stateLocker) { if (!canSet(out message)) { @@ -234,7 +244,8 @@ namespace EonaCat.Network } } - public bool IsSecure { get; private set; } + public bool IsSSL { get; private set; } + public string Origin { get @@ -273,7 +284,7 @@ namespace EonaCat.Network return; } - lock (_forState) + lock (_stateLocker) { if (!canSet(out message)) { @@ -300,6 +311,7 @@ namespace EonaCat.Network } public WSState ReadyState => _readyState; + public SSLConfigClient SSL { get @@ -310,7 +322,7 @@ namespace EonaCat.Network throw new InvalidOperationException(message); } - if (!IsSecure) + if (!IsSSL) { var message = "This instance does not use a secure connection."; throw new InvalidOperationException(message); @@ -334,11 +346,12 @@ namespace EonaCat.Network } public Uri Url => _client ? _uri : _context.RequestUri; - public TimeSpan WaitTime + + internal TimeSpan ResponseWaitingTime { get { - return _waitTime; + return _responseWaitingTime; } set @@ -354,7 +367,7 @@ namespace EonaCat.Network return; } - lock (_forState) + lock (_stateLocker) { if (!canSet(out message)) { @@ -362,7 +375,7 @@ namespace EonaCat.Network return; } - _waitTime = value; + _responseWaitingTime = value; } } } @@ -374,7 +387,7 @@ namespace EonaCat.Network { get { - lock (_forMessageEventQueue) + lock (_messageEventQueueLocker) { return _messageEventQueue.Count > 0; } @@ -384,6 +397,7 @@ namespace EonaCat.Network internal bool IgnoreExtensions { get; set; } internal bool IsConnected => _readyState == WSState.Open || _readyState == WSState.Closing; + public void Accept() { if (!checkIfAvailable(false, true, true, false, false, false, out string message)) @@ -438,9 +452,9 @@ namespace EonaCat.Network throw new ArgumentException(message, nameof(code)); } - if (!_client && code == (ushort)CloseStatusCode.MandatoryExtension) + if (!_client && code == (ushort)CloseStatusCode.MissingExtension) { - var message = $"{(ushort)CloseStatusCode.MandatoryExtension} cannot be used."; + var message = $"{(ushort)CloseStatusCode.MissingExtension} cannot be used."; throw new ArgumentException(message, nameof(code)); } @@ -455,7 +469,7 @@ namespace EonaCat.Network throw new ArgumentException(message, nameof(code)); } - if (!_client && code == CloseStatusCode.MandatoryExtension) + if (!_client && code == CloseStatusCode.MissingExtension) { var message = "MandatoryExtension cannot be used."; throw new ArgumentException(message, nameof(code)); @@ -478,9 +492,9 @@ namespace EonaCat.Network throw new ArgumentException(message, nameof(code)); } - if (!_client && code == (ushort)CloseStatusCode.MandatoryExtension) + if (!_client && code == (ushort)CloseStatusCode.MissingExtension) { - var message = $"{(ushort)CloseStatusCode.MandatoryExtension} cannot be used."; + var message = $"{(ushort)CloseStatusCode.MissingExtension} cannot be used."; throw new ArgumentException(message, nameof(code)); } @@ -519,7 +533,7 @@ namespace EonaCat.Network throw new ArgumentException(message, nameof(code)); } - if (!_client && code == CloseStatusCode.MandatoryExtension) + if (!_client && code == CloseStatusCode.MissingExtension) { var message = "MandatoryExtension cannot be used."; throw new ArgumentException(message, nameof(code)); @@ -571,9 +585,9 @@ namespace EonaCat.Network throw new ArgumentException(message, nameof(code)); } - if (!_client && code == (ushort)CloseStatusCode.MandatoryExtension) + if (!_client && code == (ushort)CloseStatusCode.MissingExtension) { - var message = $"{(ushort)CloseStatusCode.MandatoryExtension} cannot be used."; + var message = $"{(ushort)CloseStatusCode.MissingExtension} cannot be used."; throw new ArgumentException(message, nameof(code)); } @@ -588,7 +602,7 @@ namespace EonaCat.Network throw new ArgumentException(message, nameof(code)); } - if (!_client && code == CloseStatusCode.MandatoryExtension) + if (!_client && code == CloseStatusCode.MissingExtension) { var message = "MandatoryExtension cannot be used."; throw new ArgumentException(message, nameof(code)); @@ -611,9 +625,9 @@ namespace EonaCat.Network throw new ArgumentException(message, nameof(code)); } - if (!_client && code == (ushort)CloseStatusCode.MandatoryExtension) + if (!_client && code == (ushort)CloseStatusCode.MissingExtension) { - var message = $"{(ushort)CloseStatusCode.MandatoryExtension} cannot be used."; + var message = $"{(ushort)CloseStatusCode.MissingExtension} cannot be used."; throw new ArgumentException(message, nameof(code)); } @@ -652,7 +666,7 @@ namespace EonaCat.Network throw new ArgumentException(message, nameof(code)); } - if (!_client && code == CloseStatusCode.MandatoryExtension) + if (!_client && code == CloseStatusCode.MissingExtension) { var message = "MandatoryExtension cannot be used."; throw new ArgumentException(message, nameof(code)); @@ -685,39 +699,45 @@ namespace EonaCat.Network closeAsync((ushort)code, reason); } + /// + /// Connect to the server + /// public void Connect() { - if (!checkIfAvailable(true, false, true, false, false, true, out string message)) + if (TryConnect(out string errorMessage)) { - Logger.Error(message); + Logger.Error(errorMessage); Error("An error has occurred in connecting.", null); - return; } - if (connect()) - { - open(); - } + open(); } - public void ConnectAsync() + /// + /// COnnect to the server + /// + /// + public async Task ConnectAsync() { - if (!checkIfAvailable(true, false, true, false, false, true, out string message)) + if (TryConnect(out string errorMessage)) { - Logger.Error(message); + Logger.Error(errorMessage); Error("An error has occurred in connecting.", null); return; } - Func connector = connect; - Task.Run(() => + await Task.Run(() => open()).ConfigureAwait(false); + } + + private bool TryConnect(out string errorMessage) + { + if (!checkIfAvailable(true, false, true, false, false, true, out errorMessage)) { - if (connector()) - { - open(); - } - }); + return true; + } + + return !connect(); } void IDisposable.Dispose() @@ -743,9 +763,9 @@ namespace EonaCat.Network throw new ArgumentException(pingMessage, nameof(message)); } - if (bytes.Length > 125) + if (bytes.Length > MAX_PING_SIZE) { - var pingMessage = "Its size is greater than 125 bytes."; + var pingMessage = $"Size is greater than {MAX_PING_SIZE} bytes."; throw new ArgumentOutOfRangeException(nameof(message), pingMessage); } @@ -768,8 +788,7 @@ namespace EonaCat.Network { if (_readyState != WSState.Open) { - var message = "The current state of the connection is not Open."; - throw new InvalidOperationException(message); + throw new InvalidOperationException(NOT_CONNECTED_MESSAGE); } if (data == null) @@ -784,8 +803,7 @@ namespace EonaCat.Network { if (_readyState != WSState.Open) { - var message = "The current state of the connection is not Open."; - throw new InvalidOperationException(message); + throw new InvalidOperationException(NOT_CONNECTED_MESSAGE); } if (fileInfo == null) @@ -812,8 +830,7 @@ namespace EonaCat.Network { if (_readyState != WSState.Open) { - var message = "The current state of the connection is not Open."; - throw new InvalidOperationException(message); + throw new InvalidOperationException(NOT_CONNECTED_MESSAGE); } if (data == null) @@ -834,8 +851,7 @@ namespace EonaCat.Network { if (_readyState != WSState.Open) { - var message = "The current state of the connection is not Open."; - throw new InvalidOperationException(message); + throw new InvalidOperationException(NOT_CONNECTED_MESSAGE); } if (stream == null) @@ -881,8 +897,7 @@ namespace EonaCat.Network { if (_readyState != WSState.Open) { - var message = "The current state of the connection is not Open."; - throw new InvalidOperationException(message); + throw new InvalidOperationException(NOT_CONNECTED_MESSAGE); } if (data == null) @@ -897,8 +912,7 @@ namespace EonaCat.Network { if (_readyState != WSState.Open) { - var message = "The current state of the connection is not Open."; - throw new InvalidOperationException(message); + throw new InvalidOperationException(NOT_CONNECTED_MESSAGE); } if (fileInfo == null) @@ -925,8 +939,7 @@ namespace EonaCat.Network { if (_readyState != WSState.Open) { - var message = "The current state of the connection is not Open."; - throw new InvalidOperationException(message); + throw new InvalidOperationException(NOT_CONNECTED_MESSAGE); } if (data == null) @@ -947,8 +960,7 @@ namespace EonaCat.Network { if (_readyState != WSState.Open) { - var message = "The current state of the connection is not Open."; - throw new InvalidOperationException(message); + throw new InvalidOperationException(NOT_CONNECTED_MESSAGE); } if (stream == null) @@ -1008,7 +1020,7 @@ namespace EonaCat.Network return; } - lock (_forState) + lock (_stateLocker) { if (!checkIfAvailable(true, false, false, true, out message)) { @@ -1043,7 +1055,7 @@ namespace EonaCat.Network return; } - lock (_forState) + lock (_stateLocker) { if (!checkIfAvailable(true, false, false, true, out message)) { @@ -1085,7 +1097,7 @@ namespace EonaCat.Network return; } - lock (_forState) + lock (_stateLocker) { if (!checkIfAvailable(true, false, false, true, out message)) { @@ -1154,9 +1166,9 @@ namespace EonaCat.Network Close(createHandshakeFailureResponse(code)); } - internal void Close(PayloadData payloadData, byte[] frameAsBytes) + internal void Close(Payload payload, byte[] frameAsBytes) { - lock (_forState) + lock (_stateLocker) { if (_readyState == WSState.Closing) { @@ -1176,16 +1188,11 @@ namespace EonaCat.Network Logger.Trace("Begin closing the connection."); var sent = frameAsBytes != null && sendBytes(frameAsBytes); - var received = sent && _receivingExited != null -&& _receivingExited.WaitOne(_waitTime); + var received = sent && _receivingExited != null && _receivingExited.WaitOne(_responseWaitingTime); - var res = sent && received; + var result = sent && received; - Logger.Debug( - string.Format( - "Was clean?: {0}\n sent: {1}\n received: {2}", res, sent, received - ) - ); + Logger.Debug($"Was clean?: {result}\n sent: {sent}\n received: {received}"); releaseServerResources(); releaseCommonResources(); @@ -1194,8 +1201,8 @@ namespace EonaCat.Network _readyState = WSState.Closed; - var e = new CloseEventArgs(payloadData); - e.WasClean = res; + var e = new CloseEventArgs(payload); + e.WasClean = result; try { @@ -1242,13 +1249,13 @@ namespace EonaCat.Network return false; } - lock (_forPing) + lock (_pingLocker) { try { pongReceived.Reset(); - lock (_forState) + lock (_stateLocker) { if (_readyState != WSState.Open) { @@ -1274,13 +1281,13 @@ namespace EonaCat.Network OperationCode opcode, byte[] data, Dictionary cache ) { - lock (_forSend) + lock (_sendLocker) { - lock (_forState) + lock (_stateLocker) { if (_readyState != WSState.Open) { - Logger.Error("The connection is closing."); + Logger.Error(CLOSING_MESSAGE); return; } @@ -1307,7 +1314,7 @@ namespace EonaCat.Network OperationCode opcode, Stream stream, Dictionary cache ) { - lock (_forSend) + lock (_sendLocker) { if (!cache.TryGetValue(_compression, out Stream found)) { @@ -1423,7 +1430,7 @@ namespace EonaCat.Network private bool accept() { - lock (_forState) + lock (_stateLocker) { if (!checkIfAvailable(true, false, false, false, out string message)) { @@ -1505,7 +1512,7 @@ namespace EonaCat.Network if (_readyState == WSState.Closing) { - message = "The connection is closing."; + message = CLOSING_MESSAGE; return false; } @@ -1667,6 +1674,7 @@ namespace EonaCat.Network return checkIfAvailable(connecting, open, closing, closed, out message); } + private bool checkReceivedFrame(WSFrame frame, out string message) { message = null; @@ -1702,13 +1710,13 @@ namespace EonaCat.Network return false; } - if (frame.Rsv2 == Rsv.On) + if (frame.Rsv2 == ReservedBits.On) { message = "The RSV2 of a frame is non-zero without any negotiation for it."; return false; } - if (frame.Rsv3 == Rsv.On) + if (frame.Rsv3 == ReservedBits.On) { message = "The RSV3 of a frame is non-zero without any negotiation for it."; return false; @@ -1733,19 +1741,17 @@ namespace EonaCat.Network if (code == (ushort)CloseStatusCode.NoStatus) { // == no status - close(PayloadData.Empty, true, true, false); + close(Payload.Empty, true, true, false); return; } var send = !code.IsReserved(); - close(new PayloadData(code, reason), send, send, false); + close(new Payload(code, reason), send, send, false); } - private void close( - PayloadData payloadData, bool send, bool receive, bool received - ) + private void close(Payload payload, bool send, bool receive, bool received) { - lock (_forState) + lock (_stateLocker) { if (_readyState == WSState.Closing) { @@ -1767,14 +1773,14 @@ namespace EonaCat.Network Logger.Trace("Begin closing the connection."); - var res = closeHandshake(payloadData, send, receive, received); + var res = closeHandshake(payload, send, receive, received); releaseResources(); Logger.Trace("End closing the connection."); _readyState = WSState.Closed; - var e = new CloseEventArgs(payloadData); + var e = new CloseEventArgs(payload); e.WasClean = res; try @@ -1804,27 +1810,27 @@ namespace EonaCat.Network if (code == (ushort)CloseStatusCode.NoStatus) { // == no status - closeAsync(PayloadData.Empty, true, true, false); + closeAsync(Payload.Empty, true, true, false); return; } var send = !code.IsReserved(); - closeAsync(new PayloadData(code, reason), send, send, false); + closeAsync(new Payload(code, reason), send, send, false); } - private async Task closeAsync(PayloadData payloadData, bool send, bool receive, bool received) + private async Task closeAsync(Payload payload, bool send, bool receive, bool received) { - await Task.Run(() => close(payloadData, send, receive, received)); + await Task.Run(() => close(payload, send, receive, received)); } private bool closeHandshake( - PayloadData payloadData, bool send, bool receive, bool received + Payload payload, bool send, bool receive, bool received ) { var sent = false; if (send) { - var frame = WSFrame.CreateCloseFrame(payloadData, _client); + var frame = WSFrame.CreateCloseFrame(payload, _client); sent = sendBytes(frame.ToArray()); if (_client) @@ -1836,7 +1842,7 @@ namespace EonaCat.Network var wait = !received && sent && receive && _receivingExited != null; if (wait) { - received = _receivingExited.WaitOne(_waitTime); + received = _receivingExited.WaitOne(_responseWaitingTime); } var ret = sent && received; @@ -1852,7 +1858,7 @@ namespace EonaCat.Network private bool connect() { - lock (_forState) + lock (_stateLocker) { if (!checkIfAvailable(true, false, false, true, out string message)) { @@ -1898,9 +1904,7 @@ namespace EonaCat.Network if (_compression != CompressionMethod.None) { - var str = _compression.ToExtensionString( - "server_no_context_takeover", "client_no_context_takeover"); - + var str = _compression.ToExtensionString("server_no_context_takeover", "client_no_context_takeover"); buff.AppendFormat("{0}, ", str); } @@ -1916,10 +1920,9 @@ namespace EonaCat.Network private WebResponse createHandshakeFailureResponse(HttpStatusCode code) { - var ret = WebResponse.CreateCloseResponse(code); - ret.Headers["Sec-WebSocket-Version"] = _version; - - return ret; + var result = WebResponse.CreateCloseResponse(code); + result.Headers["Sec-WebSocket-Version"] = _webSocketVersion; + return result; } private WebRequest createHandshakeRequest() @@ -1946,7 +1949,7 @@ namespace EonaCat.Network headers["Sec-WebSocket-Extensions"] = createExtensions(); } - headers["Sec-WebSocket-Version"] = _version; + headers["Sec-WebSocket-Version"] = _webSocketVersion; AuthenticationResponse authRes = null; if (_authChallenge != null && Credentials != null) @@ -2011,7 +2014,7 @@ namespace EonaCat.Network private void EnqueueToMessageEventQueue(MessageEventArgs e) { - lock (_forMessageEventQueue) + lock (_messageEventQueueLocker) { _messageEventQueue.Enqueue(e); } @@ -2040,7 +2043,7 @@ namespace EonaCat.Network private void fatal(string message, ushort code) { - var payload = new PayloadData(code, message); + var payload = new Payload(code, message); close(payload, !code.IsReserved(), false, false); } @@ -2071,10 +2074,11 @@ namespace EonaCat.Network processCookies(response.Cookies); } + private void message() { MessageEventArgs e = null; - lock (_forMessageEventQueue) + lock (_messageEventQueueLocker) { if (_inMessage || _messageEventQueue.Count == 0 || _readyState != WSState.Open) { @@ -2102,7 +2106,7 @@ namespace EonaCat.Network Error("An error has occurred during an OnMessage event.", ex); } - lock (_forMessageEventQueue) + lock (_messageEventQueueLocker) { if (_messageEventQueue.Count == 0 || _readyState != WSState.Open) { @@ -2128,7 +2132,7 @@ namespace EonaCat.Network Error("An error has occurred during an OnMessage event.", ex); } - lock (_forMessageEventQueue) + lock (_messageEventQueueLocker) { if (_messageEventQueue.Count == 0 || _readyState != WSState.Open) { @@ -2157,7 +2161,7 @@ namespace EonaCat.Network } MessageEventArgs e = null; - lock (_forMessageEventQueue) + lock (_messageEventQueueLocker) { if (_messageEventQueue.Count == 0 || _readyState != WSState.Open) { @@ -2184,7 +2188,7 @@ namespace EonaCat.Network return false; } - lock (_forPing) + lock (_pingLocker) { try { @@ -2194,7 +2198,7 @@ namespace EonaCat.Network return false; } - return pongReceived.WaitOne(_waitTime); + return pongReceived.WaitOne(_responseWaitingTime); } catch (ObjectDisposedException) { @@ -2207,8 +2211,7 @@ namespace EonaCat.Network { if (_readyState != WSState.Open) { - var msg = "The current state of the connection is not Open."; - throw new InvalidOperationException(msg); + throw new InvalidOperationException(NOT_CONNECTED_MESSAGE); } sendAsync(OperationCode.Ping, new MemoryStream(data), completed); @@ -2216,7 +2219,7 @@ namespace EonaCat.Network private bool processCloseFrame(WSFrame frame) { - var payload = frame.PayloadData; + var payload = frame.Payload; close(payload, !payload.HasReservedCode, false, true); return ping(EmptyBytes); @@ -2237,7 +2240,7 @@ namespace EonaCat.Network EnqueueToMessageEventQueue( frame.IsCompressed ? new MessageEventArgs( - frame.Opcode, frame.PayloadData.ApplicationData.Decompress(_compression)) + frame.Opcode, frame.Payload.ApplicationData.Decompress(_compression)) : new MessageEventArgs(frame)); return true; @@ -2259,7 +2262,7 @@ namespace EonaCat.Network _inContinuation = true; } - _fragmentsBuffer.WriteBytes(frame.PayloadData.ApplicationData, 1024); + _fragmentsBuffer.WriteBytes(frame.Payload.ApplicationData, 1024); if (frame.IsFinal) { using (_fragmentsBuffer) @@ -2282,13 +2285,13 @@ namespace EonaCat.Network { Logger.Trace("A ping was received."); - var pong = WSFrame.CreatePongFrame(frame.PayloadData, _client); + var pong = WSFrame.CreatePongFrame(frame.Payload, _client); - lock (_forState) + lock (_stateLocker) { if (_readyState != WSState.Open) { - Logger.Error("The connection is closing."); + Logger.Error(CLOSING_MESSAGE); return true; } @@ -2372,19 +2375,13 @@ namespace EonaCat.Network var buff = new StringBuilder(80); var comp = false; - foreach (var e in value.SplitHeaderValue(',')) + foreach (var extensions in value.SplitHeaderValue(',')) { - var ext = e.Trim(); - if (!comp && ext.IsCompressionExtension(CompressionMethod.Deflate)) + var extension = extensions.Trim(); + if (!comp && extension.IsCompressionExtension(CompressionMethod.Deflate)) { _compression = CompressionMethod.Deflate; - buff.AppendFormat( - "{0}, ", - _compression.ToExtensionString( - "client_no_context_takeover", "server_no_context_takeover" - ) - ); - + buff.AppendFormat($"{_compression.ToExtensionString("client_no_context_takeover", "server_no_context_takeover")}, "); comp = true; } } @@ -2422,7 +2419,6 @@ namespace EonaCat.Network { Logger.Error("An unsupported frame:" + frame.PrintToString(false)); fatal("There is no way to handle it.", CloseStatusCode.PolicyViolation); - return false; } @@ -2492,7 +2488,7 @@ namespace EonaCat.Network private bool send(OperationCode opcode, Stream stream) { - lock (_forSend) + lock (_sendLocker) { var src = stream; var compressed = false; @@ -2596,11 +2592,11 @@ namespace EonaCat.Network private bool send(FinalFrame fin, OperationCode opcode, byte[] data, bool compressed) { - lock (_forState) + lock (_stateLocker) { if (_readyState != WSState.Open) { - Logger.Error("The connection is closing."); + Logger.Error(CLOSING_MESSAGE); return false; } @@ -2647,28 +2643,28 @@ namespace EonaCat.Network private WebResponse sendHandshakeRequest() { var req = createHandshakeRequest(); - var res = sendHttpRequest(req, 90000); - if (res.IsUnauthorized) + var result = sendHttpRequest(req, 90000); + if (result.IsUnauthorized) { - var chal = res.Headers["WWW-Authenticate"]; - Logger.Warning(string.Format("Received an authentication requirement for '{0}'.", chal)); - if (chal.IsNullOrEmpty()) + var challenge = result.Headers["WWW-Authenticate"]; + Logger.Warning($"Received an authentication requirement for '{challenge}'."); + if (challenge.IsNullOrEmpty()) { Logger.Error("No authentication challenge is specified."); - return res; + return result; } - _authChallenge = AuthenticationChallenge.Parse(chal); + _authChallenge = AuthenticationChallenge.Parse(challenge); if (_authChallenge == null) { Logger.Error("An invalid authentication challenge is specified."); - return res; + return result; } if (Credentials != null && (!_preAuth || _authChallenge.Scheme == AuthenticationSchemes.Digest)) { - if (res.HasConnectionClose) + if (result.HasConnectionClose) { releaseClientResources(); SetClientStream(); @@ -2677,39 +2673,39 @@ namespace EonaCat.Network var authRes = new AuthenticationResponse(_authChallenge, Credentials, _nonceCount); _nonceCount = authRes.NonceCount; req.Headers["Authorization"] = authRes.ToString(); - res = sendHttpRequest(req, 15000); + result = sendHttpRequest(req, 15000); } } - if (res.IsRedirect) + if (result.IsRedirect) { - var url = res.Headers["Location"]; - Logger.Warning(string.Format("Received a redirection to '{0}'.", url)); + var url = result.Headers["Location"]; + Logger.Warning($"Received a redirection to '{url}'."); if (_isRedirectionEnabled) { if (url.IsNullOrEmpty()) { Logger.Error("No url to redirect is located."); - return res; + return result; } if (!url.TryCreateWebSocketUri(out Uri uri, out string message)) { Logger.Error("An invalid url to redirect is located: " + message); - return res; + return result; } releaseClientResources(); _uri = uri; - IsSecure = uri.Scheme == "wss"; + IsSSL = uri.Scheme == "wss"; SetClientStream(); return sendHandshakeRequest(); } } - return res; + return result; } private WebResponse sendHttpRequest(WebRequest request, int millisecondsTimeout) @@ -2730,48 +2726,41 @@ namespace EonaCat.Network private void sendProxyConnectRequest() { var req = WebRequest.CreateConnectRequest(_uri); - var res = sendHttpRequest(req, 90000); - if (res.IsProxyAuthenticationRequired) + var result = sendHttpRequest(req, 90000); + if (result.IsProxyAuthenticationRequired) { - var chal = res.Headers["Proxy-Authenticate"]; - Logger.Warning( - string.Format("Received a proxy authentication requirement for '{0}'.", chal)); + var challenge = result.Headers["Proxy-Authenticate"]; + Logger.Warning($"Received a proxy authentication requirement for '{challenge}'."); - if (chal.IsNullOrEmpty()) + if (challenge.IsNullOrEmpty()) { throw new WSException("No proxy authentication challenge is specified."); } - var authChal = AuthenticationChallenge.Parse(chal); - if (authChal == null) - { - throw new WSException("An invalid proxy authentication challenge is specified."); - } - + var authChallenge = AuthenticationChallenge.Parse(challenge) ?? throw new WSException("An invalid proxy authentication challenge is specified."); if (_proxyCredentials != null) { - if (res.HasConnectionClose) + if (result.HasConnectionClose) { releaseClientResources(); _tcpClient = new TcpClient(_proxyUri.DnsSafeHost, _proxyUri.Port); _stream = _tcpClient.GetStream(); } - var authRes = new AuthenticationResponse(authChal, _proxyCredentials, 0); + var authRes = new AuthenticationResponse(authChallenge, _proxyCredentials, 0); req.Headers["Proxy-Authorization"] = authRes.ToString(); - res = sendHttpRequest(req, 15000); + result = sendHttpRequest(req, 15000); } - if (res.IsProxyAuthenticationRequired) + if (result.IsProxyAuthenticationRequired) { throw new WSException("A proxy authentication is required."); } } - if (res.StatusCode[0] != '2') + if (result.StatusCode[0] != '2') { - throw new WSException( - "The proxy has failed a connection to the requested host and port."); + throw new WSException("The proxy has failed a connection to the requested host and port."); } } @@ -2789,7 +2778,7 @@ namespace EonaCat.Network _stream = _tcpClient.GetStream(); } - if (IsSecure) + if (IsSSL) { var conf = SSL; var host = conf.TargetHost; @@ -2807,8 +2796,8 @@ namespace EonaCat.Network conf.ServerCertificateValidationCallback, conf.ClientCertificateSelectionCallback); - sslStream.ReadTimeout = (int)WaitTime.TotalMilliseconds; - sslStream.WriteTimeout = (int)WaitTime.TotalMilliseconds; + sslStream.ReadTimeout = (int)ResponseWaitingTime.TotalMilliseconds; + sslStream.WriteTimeout = (int)ResponseWaitingTime.TotalMilliseconds; sslStream.AuthenticateAsClient( host, @@ -2829,13 +2818,14 @@ namespace EonaCat.Network { _compression = CompressionMethod.None; CookieCollection = new CookieCollection(); - _forPing = new object(); - _forSend = new object(); - _forState = new object(); + _pingLocker = new object(); + _sendLocker = new object(); + _stateLocker = new object(); _messageEventQueue = new Queue(); - _forMessageEventQueue = ((ICollection)_messageEventQueue).SyncRoot; + _messageEventQueueLocker = ((ICollection)_messageEventQueue).SyncRoot; _readyState = WSState.Connecting; } + private void startReceiving() { if (_messageEventQueue.Count > 0) @@ -2862,7 +2852,7 @@ namespace EonaCat.Network return; } - // Receive next asap because the Ping or Close needs a response to it. + // Receive next because the Ping or Close needs a response to it. receive(); if (_inMessage || !HasMessage || _readyState != WSState.Open) @@ -2910,31 +2900,31 @@ namespace EonaCat.Network } var comp = _compression != CompressionMethod.None; - foreach (var e in value.SplitHeaderValue(',')) + foreach (var currentExtension in value.SplitHeaderValue(',')) { - var ext = e.Trim(); - if (comp && ext.IsCompressionExtension(_compression)) + var extension = currentExtension.Trim(); + if (comp && extension.IsCompressionExtension(_compression)) { - if (!ext.Contains("server_no_context_takeover")) + if (!extension.Contains("server_no_context_takeover")) { Logger.Error("The server hasn't sent back 'server_no_context_takeover'."); return false; } - if (!ext.Contains("client_no_context_takeover")) + if (!extension.Contains("client_no_context_takeover")) { Logger.Warning("The server hasn't sent back 'client_no_context_takeover'."); } var method = _compression.ToExtensionString(); var invalid = - ext.SplitHeaderValue(';').Contains( - t => + extension.SplitHeaderValue(';').Contains( + x => { - t = t.Trim(); - return t != method - && t != "server_no_context_takeover" - && t != "client_no_context_takeover"; + x = x.Trim(); + return x != method + && x != "server_no_context_takeover" + && x != "client_no_context_takeover"; } ); @@ -2979,12 +2969,12 @@ namespace EonaCat.Network private bool validateSecWebSocketVersionClientHeader(string value) { - return value != null && value == _version; + return value != null && value == _webSocketVersion; } private bool validateSecWebSocketVersionServerHeader(string value) { - return value == null || value == _version; + return value == null || value == _webSocketVersion; } } } \ No newline at end of file diff --git a/EonaCat.Network/System/Sockets/Web/WSFrame.cs b/EonaCat.Network/System/Sockets/Web/WSFrame.cs index 7cb6250..8f3fa32 100644 --- a/EonaCat.Network/System/Sockets/Web/WSFrame.cs +++ b/EonaCat.Network/System/Sockets/Web/WSFrame.cs @@ -13,32 +13,33 @@ namespace EonaCat.Network { internal static readonly byte[] EmptyPingBytes; private const int BUFFER_SIZE = 1024; + static WSFrame() { EmptyPingBytes = CreatePingFrame(false).ToArray(); } - internal WSFrame(OperationCode opcode, PayloadData payloadData, bool mask) - : this(FinalFrame.Final, opcode, payloadData, false, mask) + internal WSFrame(OperationCode opcode, Payload payload, bool mask) + : this(FinalFrame.Final, opcode, payload, false, mask) { } internal WSFrame(FinalFrame finalFrame, OperationCode opcode, byte[] data, bool compressed, bool mask) - : this(finalFrame, opcode, new PayloadData(data), compressed, mask) + : this(finalFrame, opcode, new Payload(data), compressed, mask) { } internal WSFrame( - FinalFrame fin, OperationCode opcode, PayloadData payloadData, bool compressed, bool mask) + FinalFrame fin, OperationCode opcode, Payload payload, bool compressed, bool mask) { Fin = fin; - Rsv1 = opcode.IsData() && compressed ? Rsv.On : Rsv.Off; - Rsv2 = Rsv.Off; - Rsv3 = Rsv.Off; + Rsv1 = opcode.IsData() && compressed ? ReservedBits.On : ReservedBits.Off; + Rsv2 = ReservedBits.Off; + Rsv3 = ReservedBits.Off; Opcode = opcode; - PayloadData = new PayloadData(payloadData); + Payload = new Payload(payload); - var len = PayloadData.Length; + var len = Payload.Length; if (len < 126) { PayloadLength = (byte)len; @@ -58,8 +59,8 @@ namespace EonaCat.Network if (mask) { Mask = Mask.On; - MaskingKey = createMaskingKey(); - PayloadData.Mask(MaskingKey); + MaskingKey = CreateMaskingKey(); + Payload.Mask(MaskingKey); } else { @@ -71,11 +72,12 @@ namespace EonaCat.Network private WSFrame() { } + public byte[] ExtendedPayloadLength { get; private set; } public FinalFrame Fin { get; private set; } public bool IsBinary => Opcode == OperationCode.Binary; public bool IsClose => Opcode == OperationCode.Close; - public bool IsCompressed => Rsv1 == Rsv.On; + public bool IsCompressed => Rsv1 == ReservedBits.On; public bool IsContinuation => Opcode == OperationCode.Continue; public bool IsControl => Opcode >= OperationCode.Close; public bool IsData => Opcode == OperationCode.Text || Opcode == OperationCode.Binary; @@ -85,15 +87,15 @@ namespace EonaCat.Network public bool IsPing => Opcode == OperationCode.Ping; public bool IsPong => Opcode == OperationCode.Pong; public bool IsText => Opcode == OperationCode.Text; - public ulong Length => 2 + (ulong)(ExtendedPayloadLength.Length + MaskingKey.Length) + PayloadData.Length; + public ulong Length => 2 + (ulong)(ExtendedPayloadLength.Length + MaskingKey.Length) + Payload.Length; public Mask Mask { get; private set; } public byte[] MaskingKey { get; private set; } public OperationCode Opcode { get; private set; } - public PayloadData PayloadData { get; private set; } + public Payload Payload { get; private set; } public byte PayloadLength { get; private set; } - public Rsv Rsv1 { get; private set; } - public Rsv Rsv2 { get; private set; } - public Rsv Rsv3 { get; private set; } + public ReservedBits Rsv1 { get; private set; } + public ReservedBits Rsv2 { get; private set; } + public ReservedBits Rsv3 { get; private set; } internal int ExtendedPayloadLengthCount => PayloadLength < 126 ? 0 : (PayloadLength == 126 ? 2 : 8); internal ulong FullPayloadLength => PayloadLength < 126 @@ -101,6 +103,7 @@ namespace EonaCat.Network : PayloadLength == 126 ? ExtendedPayloadLength.ToUInt16(ByteOrder.Big) : ExtendedPayloadLength.ToUInt64(ByteOrder.Big); + public IEnumerator GetEnumerator() { foreach (var b in ToArray()) @@ -116,12 +119,12 @@ namespace EonaCat.Network public void Print(bool dumped) { - Console.WriteLine(dumped ? dump(this) : print(this)); + Console.WriteLine(dumped ? Dump(this) : Print(this)); } public string PrintToString(bool dumped) { - return dumped ? dump(this) : print(this); + return dumped ? Dump(this) : Print(this); } public byte[] ToArray() @@ -149,7 +152,7 @@ namespace EonaCat.Network if (PayloadLength > 0) { - var bytes = PayloadData.ToArray(); + var bytes = Payload.ToArray(); if (PayloadLength < 127) { buff.Write(bytes, 0, bytes.Length); @@ -171,34 +174,34 @@ namespace EonaCat.Network } internal static WSFrame CreateCloseFrame( - PayloadData payloadData, bool mask + Payload payload, bool mask ) { return new WSFrame( - FinalFrame.Final, OperationCode.Close, payloadData, false, mask + FinalFrame.Final, OperationCode.Close, payload, false, mask ); } internal static WSFrame CreatePingFrame(bool mask) { return new WSFrame( - FinalFrame.Final, OperationCode.Ping, PayloadData.Empty, false, mask + FinalFrame.Final, OperationCode.Ping, Payload.Empty, false, mask ); } internal static WSFrame CreatePingFrame(byte[] data, bool mask) { return new WSFrame( - FinalFrame.Final, OperationCode.Ping, new PayloadData(data), false, mask + FinalFrame.Final, OperationCode.Ping, new Payload(data), false, mask ); } internal static WSFrame CreatePongFrame( - PayloadData payloadData, bool mask + Payload payload, bool mask ) { return new WSFrame( - FinalFrame.Final, OperationCode.Pong, payloadData, false, mask + FinalFrame.Final, OperationCode.Pong, payload, false, mask ); } @@ -207,7 +210,7 @@ namespace EonaCat.Network var frame = readHeader(stream); readExtendedPayloadLength(stream, frame); readMaskingKey(stream, frame); - readPayloadData(stream, frame); + readPayload(stream, frame); if (unmask) { @@ -235,7 +238,7 @@ namespace EonaCat.Network stream, frame1, frame2 => - readPayloadDataAsync( + readPayloadAsync( stream, frame2, frame3 => @@ -265,11 +268,11 @@ namespace EonaCat.Network } Mask = Mask.Off; - PayloadData.Mask(MaskingKey); + Payload.Mask(MaskingKey); MaskingKey = WSClient.EmptyBytes; } - private static byte[] createMaskingKey() + private static byte[] CreateMaskingKey() { var key = new byte[4]; WSClient.RandomNumber.GetBytes(key); @@ -277,40 +280,40 @@ namespace EonaCat.Network return key; } - private static string dump(WSFrame frame) + private static string Dump(WSFrame frame) { var len = frame.Length; - var cnt = (long)(len / 4); - var rem = (int)(len % 4); + var amount = (long)(len / 4); + var remainder = (int)(len % 4); - int cntDigit; - string cntFmt; - if (cnt < 10000) + int digitAmount; + string frameCount; + if (amount < 10000) { - cntDigit = 4; - cntFmt = "{0,4}"; + digitAmount = 4; + frameCount = "{0,4}"; } - else if (cnt < 0x010000) + else if (amount < 0x010000) { - cntDigit = 4; - cntFmt = "{0,4:X}"; + digitAmount = 4; + frameCount = "{0,4:X}"; } - else if (cnt < 0x0100000000) + else if (amount < 0x0100000000) { - cntDigit = 8; - cntFmt = "{0,8:X}"; + digitAmount = 8; + frameCount = "{0,8:X}"; } else { - cntDigit = 16; - cntFmt = "{0,16:X}"; + digitAmount = 16; + frameCount = "{0,16:X}"; } - var spFmt = string.Format("{{0,{0}}}", cntDigit); - var headerFmt = string.Format(@" + var spFmt = string.Format("{{0,{0}}}", digitAmount); + var headerFormat = string.Format(@" {0} 01234567 89ABCDEF 01234567 89ABCDEF {0}+--------+--------+--------+--------+\n", spFmt); - var lineFmt = string.Format("{0}|{{1,8}} {{2,8}} {{3,8}} {{4,8}}|\n", cntFmt); + var lineFmt = string.Format("{0}|{{1,8}} {{2,8}} {{3,8}} {{4,8}}|\n", frameCount); var footerFmt = string.Format("{0}+--------+--------+--------+--------+", spFmt); var output = new StringBuilder(64); @@ -322,13 +325,13 @@ namespace EonaCat.Network }; var printLine = linePrinter(); - output.AppendFormat(headerFmt, string.Empty); + output.AppendFormat(headerFormat, string.Empty); var bytes = frame.ToArray(); - for (long i = 0; i <= cnt; i++) + for (long i = 0; i <= amount; i++) { var j = i * 4; - if (i < cnt) + if (i < amount) { printLine( Convert.ToString(bytes[j], 2).PadLeft(8, '0'), @@ -339,12 +342,12 @@ namespace EonaCat.Network continue; } - if (rem > 0) + if (remainder > 0) { printLine( Convert.ToString(bytes[j], 2).PadLeft(8, '0'), - rem >= 2 ? Convert.ToString(bytes[j + 1], 2).PadLeft(8, '0') : string.Empty, - rem == 3 ? Convert.ToString(bytes[j + 2], 2).PadLeft(8, '0') : string.Empty, + remainder >= 2 ? Convert.ToString(bytes[j + 1], 2).PadLeft(8, '0') : string.Empty, + remainder == 3 ? Convert.ToString(bytes[j + 2], 2).PadLeft(8, '0') : string.Empty, string.Empty); } } @@ -353,7 +356,7 @@ namespace EonaCat.Network return output.ToString(); } - private static string print(WSFrame frame) + private static string Print(WSFrame frame) { // Payload Length var payloadLen = frame.PayloadLength; @@ -370,10 +373,10 @@ namespace EonaCat.Network : payloadLen > 125 ? "---" : frame.IsText && !(frame.IsFragment || frame.IsMasked || frame.IsCompressed) - ? frame.PayloadData.ApplicationData.UTF8Decode() - : frame.PayloadData.ToString(); + ? frame.Payload.ApplicationData.UTF8Decode() + : frame.Payload.ToString(); - var fmt = @" + var format = @" FIN: {0} RSV1: {1} RSV2: {2} @@ -386,7 +389,7 @@ Extended Payload Length: {7} Payload Data: {9}"; return string.Format( - fmt, + format, frame.Fin, frame.Rsv1, frame.Rsv2, @@ -399,7 +402,7 @@ Extended Payload Length: {7} payload); } - private static WSFrame processHeader(byte[] header) + private static WSFrame ProcessHeader(byte[] header) { if (header.Length != 2) { @@ -410,13 +413,13 @@ Extended Payload Length: {7} var fin = (header[0] & 0x80) == 0x80 ? FinalFrame.Final : FinalFrame.More; // RSV1 - var rsv1 = (header[0] & 0x40) == 0x40 ? Rsv.On : Rsv.Off; + var rsv1 = (header[0] & 0x40) == 0x40 ? ReservedBits.On : ReservedBits.Off; // RSV2 - var rsv2 = (header[0] & 0x20) == 0x20 ? Rsv.On : Rsv.Off; + var rsv2 = (header[0] & 0x20) == 0x20 ? ReservedBits.On : ReservedBits.Off; // RSV3 - var rsv3 = (header[0] & 0x10) == 0x10 ? Rsv.On : Rsv.Off; + var rsv3 = (header[0] & 0x10) == 0x10 ? ReservedBits.On : ReservedBits.Off; // Opcode var opcode = (byte)(header[0] & 0x0f); @@ -429,7 +432,7 @@ Extended Payload Length: {7} var err = !opcode.IsSupported() ? "An unsupported opcode." - : !opcode.IsData() && rsv1 == Rsv.On + : !opcode.IsData() && rsv1 == ReservedBits.On ? "A non data frame is compressed." : opcode.IsControl() && fin == FinalFrame.More ? "A control frame is fragmented." @@ -507,13 +510,13 @@ Extended Payload Length: {7} private static WSFrame readHeader(Stream stream) { - return processHeader(stream.ReadBytes(2)); + return ProcessHeader(stream.ReadBytes(2)); } private static void readHeaderAsync( Stream stream, Action completed, Action error) { - stream.ReadBytesAsync(2, bytes => completed(processHeader(bytes)), error); + stream.ReadBytesAsync(2, bytes => completed(ProcessHeader(bytes)), error); } private static WSFrame readMaskingKey(Stream stream, WSFrame frame) @@ -566,16 +569,16 @@ Extended Payload Length: {7} error); } - private static WSFrame readPayloadData(Stream stream, WSFrame frame) + private static WSFrame readPayload(Stream stream, WSFrame frame) { var len = frame.FullPayloadLength; if (len == 0) { - frame.PayloadData = PayloadData.Empty; + frame.Payload = Payload.Empty; return frame; } - if (len > PayloadData.MaxLength) + if (len > Payload.MaxLength) { throw new WSException(CloseStatusCode.TooBig, "A frame has a long payload length."); } @@ -591,11 +594,11 @@ Extended Payload Length: {7} "The payload data of a frame cannot be read from the stream."); } - frame.PayloadData = new PayloadData(bytes, llen); + frame.Payload = new Payload(bytes, llen); return frame; } - private static void readPayloadDataAsync( + private static void readPayloadAsync( Stream stream, WSFrame frame, Action completed, @@ -604,13 +607,13 @@ Extended Payload Length: {7} var len = frame.FullPayloadLength; if (len == 0) { - frame.PayloadData = PayloadData.Empty; + frame.Payload = Payload.Empty; completed(frame); return; } - if (len > PayloadData.MaxLength) + if (len > Payload.MaxLength) { throw new WSException(CloseStatusCode.TooBig, "A frame has a long payload length."); } @@ -624,7 +627,7 @@ Extended Payload Length: {7} "The payload data of a frame cannot be read from the stream."); } - frame.PayloadData = new PayloadData(bytes, llen); + frame.Payload = new Payload(bytes, llen); completed(frame); }; diff --git a/EonaCat.Network/System/Sockets/Web/WebBase.cs b/EonaCat.Network/System/Sockets/Web/WebBase.cs index 8f372e3..9018a40 100644 --- a/EonaCat.Network/System/Sockets/Web/WebBase.cs +++ b/EonaCat.Network/System/Sockets/Web/WebBase.cs @@ -15,6 +15,7 @@ namespace EonaCat.Network internal byte[] EntityBodyData; protected const string CrLf = "\r\n"; private const int _headersMaxLength = 8192; + protected WebBase(Version version, NameValueCollection headers) { ProtocolVersion = version; diff --git a/EonaCat.Network/System/Sockets/Web/WebRequest.cs b/EonaCat.Network/System/Sockets/Web/WebRequest.cs index 2b14982..d7e9e59 100644 --- a/EonaCat.Network/System/Sockets/Web/WebRequest.cs +++ b/EonaCat.Network/System/Sockets/Web/WebRequest.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Specialized; using System.IO; -using System.Reflection; using System.Text; namespace EonaCat.Network @@ -26,6 +25,7 @@ namespace EonaCat.Network HttpMethod = method; RequestUri = uri; } + public AuthenticationResponse AuthenticationResponse { get diff --git a/EonaCat.Network/System/Sockets/Web/WebResponse.cs b/EonaCat.Network/System/Sockets/Web/WebResponse.cs index e5b0e1a..303c3e2 100644 --- a/EonaCat.Network/System/Sockets/Web/WebResponse.cs +++ b/EonaCat.Network/System/Sockets/Web/WebResponse.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Specialized; using System.IO; -using System.Reflection; using System.Text; namespace EonaCat.Network @@ -28,6 +27,7 @@ namespace EonaCat.Network StatusCode = code; Reason = reason; } + public CookieCollection Cookies => Headers.GetCookies(true); public bool HasConnectionClose => Headers.Contains("Connection", "close"); diff --git a/EonaCat.Network/System/Tools/Helpers.cs b/EonaCat.Network/System/Tools/Helpers.cs index e56bb02..145087c 100644 --- a/EonaCat.Network/System/Tools/Helpers.cs +++ b/EonaCat.Network/System/Tools/Helpers.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; -using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Threading; diff --git a/EonaCat.Network/System/Web/ContentRouteProcessor.cs b/EonaCat.Network/System/Web/ContentRouteProcessor.cs index ad66504..80deb6c 100644 --- a/EonaCat.Network/System/Web/ContentRouteProcessor.cs +++ b/EonaCat.Network/System/Web/ContentRouteProcessor.cs @@ -40,32 +40,32 @@ namespace EonaCat.Network _Routes = routes; } - internal async Task Process(HttpContext ctx, CancellationToken token) + internal async Task Process(HttpContext context, CancellationToken token) { - if (ctx == null) + if (context == null) { - throw new ArgumentNullException(nameof(ctx)); + throw new ArgumentNullException(nameof(context)); } - if (ctx.Request == null) + if (context.Request == null) { - throw new ArgumentNullException(nameof(ctx.Request)); + throw new ArgumentNullException(nameof(context.Request)); } - if (ctx.Response == null) + if (context.Response == null) { - throw new ArgumentNullException(nameof(ctx.Response)); + throw new ArgumentNullException(nameof(context.Response)); } - if (ctx.Request.Method != HttpMethod.GET - && ctx.Request.Method != HttpMethod.HEAD) + if (context.Request.Method != HttpMethod.GET + && context.Request.Method != HttpMethod.HEAD) { - Set500Response(ctx); - await ctx.Response.Send(token).ConfigureAwait(false); + Set500Response(context); + await context.Response.Send(token).ConfigureAwait(false); return; } - string filePath = ctx.Request.Url.RawWithoutQuery; + string filePath = context.Request.Url.RawWithoutQuery; if (!string.IsNullOrEmpty(filePath)) { while (filePath.StartsWith("/")) @@ -88,35 +88,35 @@ namespace EonaCat.Network if (!File.Exists(filePath)) { - Set404Response(ctx); - await ctx.Response.Send(token).ConfigureAwait(false); + Set404Response(context); + await context.Response.Send(token).ConfigureAwait(false); return; } FileInfo fi = new FileInfo(filePath); long contentLength = fi.Length; - if (ctx.Request.Method == HttpMethod.GET) + if (context.Request.Method == HttpMethod.GET) { FileStream fs = new FileStream(filePath, ContentFileMode, ContentFileAccess, ContentFileShare); - ctx.Response.StatusCode = 200; - ctx.Response.ContentLength = contentLength; - ctx.Response.ContentType = GetContentType(filePath); - await ctx.Response.Send(contentLength, fs, token).ConfigureAwait(false); + context.Response.StatusCode = 200; + context.Response.ContentLength = contentLength; + context.Response.ContentType = GetContentType(filePath); + await context.Response.Send(contentLength, fs, token).ConfigureAwait(false); return; } - else if (ctx.Request.Method == HttpMethod.HEAD) + else if (context.Request.Method == HttpMethod.HEAD) { - ctx.Response.StatusCode = 200; - ctx.Response.ContentLength = contentLength; - ctx.Response.ContentType = GetContentType(filePath); - await ctx.Response.Send(contentLength, token).ConfigureAwait(false); + context.Response.StatusCode = 200; + context.Response.ContentLength = contentLength; + context.Response.ContentType = GetContentType(filePath); + await context.Response.Send(contentLength, token).ConfigureAwait(false); return; } else { - Set500Response(ctx); - await ctx.Response.Send(token).ConfigureAwait(false); + Set500Response(context); + await context.Response.Send(token).ConfigureAwait(false); return; } } @@ -137,16 +137,16 @@ namespace EonaCat.Network return "application/octet-stream"; } - private void Set404Response(HttpContext ctx) + private void Set404Response(HttpContext context) { - ctx.Response.StatusCode = 404; - ctx.Response.ContentLength = 0; + context.Response.StatusCode = 404; + context.Response.ContentLength = 0; } - private void Set500Response(HttpContext ctx) + private void Set500Response(HttpContext context) { - ctx.Response.StatusCode = 500; - ctx.Response.ContentLength = 0; + context.Response.StatusCode = 500; + context.Response.ContentLength = 0; } } } \ No newline at end of file diff --git a/EonaCat.Network/System/Web/DynamicRouteManager.cs b/EonaCat.Network/System/Web/DynamicRouteManager.cs index e78c2da..e338fef 100644 --- a/EonaCat.Network/System/Web/DynamicRouteManager.cs +++ b/EonaCat.Network/System/Web/DynamicRouteManager.cs @@ -129,7 +129,6 @@ namespace EonaCat.Network throw new ArgumentNullException(nameof(rawUrl)); } - if (Matcher.Match( BuildConsolidatedRegex(method, rawUrl), out object val)) diff --git a/EonaCat.Network/System/Web/EonaCatWebserver.cs b/EonaCat.Network/System/Web/EonaCatWebserver.cs index 53b1cae..523e5a6 100644 --- a/EonaCat.Network/System/Web/EonaCatWebserver.cs +++ b/EonaCat.Network/System/Web/EonaCatWebserver.cs @@ -374,9 +374,9 @@ namespace EonaCat.Network continue; } - System.Net.HttpListenerContext listenerCtx = await _HttpListener.GetContextAsync().ConfigureAwait(false); + System.Net.HttpListenerContext listenercontext = await _HttpListener.GetContextAsync().ConfigureAwait(false); Interlocked.Increment(ref _RequestCount); - HttpContext ctx = null; + HttpContext context = null; Task unawaited = Task.Run(async () => { @@ -385,49 +385,49 @@ namespace EonaCat.Network try { Events.HandleConnectionReceived(this, new ConnectionEventArgs( - listenerCtx.Request.RemoteEndPoint.Address.ToString(), - listenerCtx.Request.RemoteEndPoint.Port)); + listenercontext.Request.RemoteEndPoint.Address.ToString(), + listenercontext.Request.RemoteEndPoint.Port)); - ctx = new HttpContext(listenerCtx, _Settings, Events); + context = new HttpContext(listenercontext, _Settings, Events); - Events.HandleRequestReceived(this, new RequestEventArgs(ctx)); + Events.HandleRequestReceived(this, new RequestEventArgs(context)); if (_Settings.Debug.Requests) { Events.Logger?.Invoke( - _Header + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + " " + - ctx.Request.Method.ToString() + " " + ctx.Request.Url.RawWithoutQuery); + _Header + context.Request.Source.IpAddress + ":" + context.Request.Source.Port + " " + + context.Request.Method.ToString() + " " + context.Request.Url.RawWithoutQuery); } - Statistics.IncrementRequestCounter(ctx.Request.Method); - Statistics.IncrementReceivedPayloadBytes(ctx.Request.ContentLength); + Statistics.IncrementRequestCounter(context.Request.Method); + Statistics.IncrementReceivedPayloadBytes(context.Request.ContentLength); - if (!_Settings.AccessControl.Permit(ctx.Request.Source.IpAddress)) + if (!_Settings.AccessControl.Permit(context.Request.Source.IpAddress)) { - Events.HandleRequestDenied(this, new RequestEventArgs(ctx)); + Events.HandleRequestDenied(this, new RequestEventArgs(context)); if (_Settings.Debug.AccessControl) { - Events.Logger?.Invoke(_Header + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + " denied due to access control"); + Events.Logger?.Invoke(_Header + context.Request.Source.IpAddress + ":" + context.Request.Source.Port + " denied due to access control"); } - listenerCtx.Response.StatusCode = 403; - listenerCtx.Response.Close(); + listenercontext.Response.StatusCode = 403; + listenercontext.Response.Close(); return; } - if (ctx.Request.Method == HttpMethod.OPTIONS) + if (context.Request.Method == HttpMethod.OPTIONS) { if (_Routes.Preflight != null) { if (_Settings.Debug.Routing) { Events.Logger?.Invoke( - _Header + "preflight route for " + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + " " + - ctx.Request.Method.ToString() + " " + ctx.Request.Url.RawWithoutQuery); + _Header + "preflight route for " + context.Request.Source.IpAddress + ":" + context.Request.Source.Port + " " + + context.Request.Method.ToString() + " " + context.Request.Url.RawWithoutQuery); } - await _Routes.Preflight(ctx).ConfigureAwait(false); + await _Routes.Preflight(context).ConfigureAwait(false); return; } } @@ -435,85 +435,85 @@ namespace EonaCat.Network bool terminate = false; if (_Routes.PreRouting != null) { - terminate = await _Routes.PreRouting(ctx).ConfigureAwait(false); + terminate = await _Routes.PreRouting(context).ConfigureAwait(false); if (terminate) { if (_Settings.Debug.Routing) { Events.Logger?.Invoke( - _Header + "prerouting terminated connection for " + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + " " + - ctx.Request.Method.ToString() + " " + ctx.Request.Url.RawWithoutQuery); + _Header + "prerouting terminated connection for " + context.Request.Source.IpAddress + ":" + context.Request.Source.Port + " " + + context.Request.Method.ToString() + " " + context.Request.Url.RawWithoutQuery); } return; } } - if (ctx.Request.Method == HttpMethod.GET || ctx.Request.Method == HttpMethod.HEAD) + if (context.Request.Method == HttpMethod.GET || context.Request.Method == HttpMethod.HEAD) { - if (_Routes.Content.Match(ctx.Request.Url.RawWithoutQuery, out ContentRoute cr)) + if (_Routes.Content.Match(context.Request.Url.RawWithoutQuery, out ContentRoute cr)) { if (_Settings.Debug.Routing) { Events.Logger?.Invoke( - _Header + "content route for " + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + " " + - ctx.Request.Method.ToString() + " " + ctx.Request.Url.RawWithoutQuery); + _Header + "content route for " + context.Request.Source.IpAddress + ":" + context.Request.Source.Port + " " + + context.Request.Method.ToString() + " " + context.Request.Url.RawWithoutQuery); } - ctx.RouteType = RouteTypeEnum.Content; - ctx.Route = cr; - await _Routes.ContentHandler.Process(ctx, token).ConfigureAwait(false); + context.RouteType = RouteTypeEnum.Content; + context.Route = cr; + await _Routes.ContentHandler.Process(context, token).ConfigureAwait(false); return; } } - Func handler = _Routes.Static.Match(ctx.Request.Method, ctx.Request.Url.RawWithoutQuery, out StaticRoute sr); + Func handler = _Routes.Static.Match(context.Request.Method, context.Request.Url.RawWithoutQuery, out StaticRoute sr); if (handler != null) { if (_Settings.Debug.Routing) { Events.Logger?.Invoke( - _Header + "static route for " + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + " " + - ctx.Request.Method.ToString() + " " + ctx.Request.Url.RawWithoutQuery); + _Header + "static route for " + context.Request.Source.IpAddress + ":" + context.Request.Source.Port + " " + + context.Request.Method.ToString() + " " + context.Request.Url.RawWithoutQuery); } - ctx.RouteType = RouteTypeEnum.Static; - ctx.Route = sr; - await handler(ctx).ConfigureAwait(false); + context.RouteType = RouteTypeEnum.Static; + context.Route = sr; + await handler(context).ConfigureAwait(false); return; } - handler = _Routes.Parameter.Match(ctx.Request.Method, ctx.Request.Url.RawWithoutQuery, out Dictionary parameters, out ParameterRoute pr); + handler = _Routes.Parameter.Match(context.Request.Method, context.Request.Url.RawWithoutQuery, out Dictionary parameters, out ParameterRoute pr); if (handler != null) { - ctx.Request.Url.Parameters = new Dictionary(parameters); + context.Request.Url.Parameters = new Dictionary(parameters); if (_Settings.Debug.Routing) { Events.Logger?.Invoke( - _Header + "parameter route for " + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + " " + - ctx.Request.Method.ToString() + " " + ctx.Request.Url.RawWithoutQuery); + _Header + "parameter route for " + context.Request.Source.IpAddress + ":" + context.Request.Source.Port + " " + + context.Request.Method.ToString() + " " + context.Request.Url.RawWithoutQuery); } - ctx.RouteType = RouteTypeEnum.Parameter; - ctx.Route = pr; - await handler(ctx).ConfigureAwait(false); + context.RouteType = RouteTypeEnum.Parameter; + context.Route = pr; + await handler(context).ConfigureAwait(false); return; } - handler = _Routes.Dynamic.Match(ctx.Request.Method, ctx.Request.Url.RawWithoutQuery, out DynamicRoute dr); + handler = _Routes.Dynamic.Match(context.Request.Method, context.Request.Url.RawWithoutQuery, out DynamicRoute dr); if (handler != null) { if (_Settings.Debug.Routing) { Events.Logger?.Invoke( - _Header + "dynamic route for " + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + " " + - ctx.Request.Method.ToString() + " " + ctx.Request.Url.RawWithoutQuery); + _Header + "dynamic route for " + context.Request.Source.IpAddress + ":" + context.Request.Source.Port + " " + + context.Request.Method.ToString() + " " + context.Request.Url.RawWithoutQuery); } - ctx.RouteType = RouteTypeEnum.Dynamic; - ctx.Route = dr; - await handler(ctx).ConfigureAwait(false); + context.RouteType = RouteTypeEnum.Dynamic; + context.Route = dr; + await handler(context).ConfigureAwait(false); return; } @@ -522,12 +522,12 @@ namespace EonaCat.Network if (_Settings.Debug.Routing) { Events.Logger?.Invoke( - _Header + "default route for " + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + " " + - ctx.Request.Method.ToString() + " " + ctx.Request.Url.RawWithoutQuery); + _Header + "default route for " + context.Request.Source.IpAddress + ":" + context.Request.Source.Port + " " + + context.Request.Method.ToString() + " " + context.Request.Url.RawWithoutQuery); } - ctx.RouteType = RouteTypeEnum.Default; - await _Routes.Default(ctx).ConfigureAwait(false); + context.RouteType = RouteTypeEnum.Default; + await _Routes.Default(context).ConfigureAwait(false); return; } else @@ -535,31 +535,31 @@ namespace EonaCat.Network if (_Settings.Debug.Routing) { Events.Logger?.Invoke( - _Header + "default route not found for " + ctx.Request.Source.IpAddress + ":" + ctx.Request.Source.Port + " " + - ctx.Request.Method.ToString() + " " + ctx.Request.Url.RawWithoutQuery); + _Header + "default route not found for " + context.Request.Source.IpAddress + ":" + context.Request.Source.Port + " " + + context.Request.Method.ToString() + " " + context.Request.Url.RawWithoutQuery); } - ctx.Response.StatusCode = 404; - ctx.Response.ContentType = Pages.Default404Page.ContentType; - await ctx.Response.Send(Pages.Default404Page.Content).ConfigureAwait(false); + context.Response.StatusCode = 404; + context.Response.ContentType = Pages.Default404Page.ContentType; + await context.Response.Send(Pages.Default404Page.Content).ConfigureAwait(false); return; } } catch (Exception eInner) { - ctx.Response.StatusCode = 500; - ctx.Response.ContentType = Pages.Default500Page.ContentType; - await ctx.Response.Send(Pages.Default500Page.Content).ConfigureAwait(false); - Events.HandleExceptionEncountered(this, new ExceptionEventArgs(ctx, eInner)); + context.Response.StatusCode = 500; + context.Response.ContentType = Pages.Default500Page.ContentType; + await context.Response.Send(Pages.Default500Page.Content).ConfigureAwait(false); + Events.HandleExceptionEncountered(this, new ExceptionEventArgs(context, eInner)); } finally { Interlocked.Decrement(ref _RequestCount); - if (ctx != null && ctx.Response != null && ctx.Response.ResponseSent) + if (context != null && context.Response != null && context.Response.ResponseSent) { - Events.HandleResponseSent(this, new ResponseEventArgs(ctx, TotalMsFrom(startTime))); - Statistics.IncrementSentPayloadBytes(ctx.Response.ContentLength); + Events.HandleResponseSent(this, new ResponseEventArgs(context, TotalMsFrom(startTime))); + Statistics.IncrementSentPayloadBytes(context.Response.ContentLength); } } }, token); diff --git a/EonaCat.Network/System/Web/EonaCatWebserverRoutes.cs b/EonaCat.Network/System/Web/EonaCatWebserverRoutes.cs index 0ed7af9..358fc4f 100644 --- a/EonaCat.Network/System/Web/EonaCatWebserverRoutes.cs +++ b/EonaCat.Network/System/Web/EonaCatWebserverRoutes.cs @@ -184,14 +184,14 @@ namespace EonaCat.Network _ContentHandler = new ContentRouteHandler(_Content); } - private async Task PreflightInternal(HttpContext ctx) + private async Task PreflightInternal(HttpContext context) { - ctx.Response.StatusCode = 200; + context.Response.StatusCode = 200; string[] requestedHeaders = null; - if (ctx.Request.Headers != null) + if (context.Request.Headers != null) { - foreach (KeyValuePair curr in ctx.Request.Headers) + foreach (KeyValuePair curr in context.Request.Headers) { if (string.IsNullOrEmpty(curr.Key)) { @@ -235,11 +235,11 @@ namespace EonaCat.Network foreach (KeyValuePair header in _Settings.Headers) { - ctx.Response.Headers.Add(header.Key, header.Value); + context.Response.Headers.Add(header.Key, header.Value); } - ctx.Response.ContentLength = 0; - await ctx.Response.Send().ConfigureAwait(false); + context.Response.ContentLength = 0; + await context.Response.Send().ConfigureAwait(false); } } } \ No newline at end of file diff --git a/EonaCat.Network/System/Web/EventArgs/ExceptionEventArgs.cs b/EonaCat.Network/System/Web/EventArgs/ExceptionEventArgs.cs index a88e051..2b84989 100644 --- a/EonaCat.Network/System/Web/EventArgs/ExceptionEventArgs.cs +++ b/EonaCat.Network/System/Web/EventArgs/ExceptionEventArgs.cs @@ -82,19 +82,19 @@ namespace EonaCat.Network } } - internal ExceptionEventArgs(HttpContext ctx, Exception e) + internal ExceptionEventArgs(HttpContext context, Exception e) { - if (ctx != null) + if (context != null) { - Ip = ctx.Request.Source.IpAddress; - Port = ctx.Request.Source.Port; - Method = ctx.Request.Method; - Url = ctx.Request.Url.Full; - Query = ctx.Request.Query.Elements; - RequestHeaders = ctx.Request.Headers; - RequestContentLength = ctx.Request.ContentLength; - StatusCode = ctx.Response.StatusCode; - ResponseContentLength = ctx.Response.ContentLength; + Ip = context.Request.Source.IpAddress; + Port = context.Request.Source.Port; + Method = context.Request.Method; + Url = context.Request.Url.Full; + Query = context.Request.Query.Elements; + RequestHeaders = context.Request.Headers; + RequestContentLength = context.Request.ContentLength; + StatusCode = context.Response.StatusCode; + ResponseContentLength = context.Response.ContentLength; } Exception = e; diff --git a/EonaCat.Network/System/Web/EventArgs/RequestEventArgs.cs b/EonaCat.Network/System/Web/EventArgs/RequestEventArgs.cs index bf6543f..95fafcf 100644 --- a/EonaCat.Network/System/Web/EventArgs/RequestEventArgs.cs +++ b/EonaCat.Network/System/Web/EventArgs/RequestEventArgs.cs @@ -46,15 +46,15 @@ namespace EonaCat.Network /// public long ContentLength { get; private set; } = 0; - internal RequestEventArgs(HttpContext ctx) + internal RequestEventArgs(HttpContext context) { - Ip = ctx.Request.Source.IpAddress; - Port = ctx.Request.Source.Port; - Method = ctx.Request.Method; - Url = ctx.Request.Url.Full; - Query = ctx.Request.Query.Elements; - Headers = ctx.Request.Headers; - ContentLength = ctx.Request.ContentLength; + Ip = context.Request.Source.IpAddress; + Port = context.Request.Source.Port; + Method = context.Request.Method; + Url = context.Request.Url.Full; + Query = context.Request.Query.Elements; + Headers = context.Request.Headers; + ContentLength = context.Request.ContentLength; } } } \ No newline at end of file diff --git a/EonaCat.Network/System/Web/EventArgs/ResponseEventArgs.cs b/EonaCat.Network/System/Web/EventArgs/ResponseEventArgs.cs index 0366bfc..87e93de 100644 --- a/EonaCat.Network/System/Web/EventArgs/ResponseEventArgs.cs +++ b/EonaCat.Network/System/Web/EventArgs/ResponseEventArgs.cs @@ -66,17 +66,17 @@ namespace EonaCat.Network /// public double TotalMs { get; private set; } = 0; - internal ResponseEventArgs(HttpContext ctx, double totalMs) + internal ResponseEventArgs(HttpContext context, double totalMs) { - Ip = ctx.Request.Source.IpAddress; - Port = ctx.Request.Source.Port; - Method = ctx.Request.Method; - Url = ctx.Request.Url.Full; - Query = ctx.Request.Query.Elements; - RequestHeaders = ctx.Request.Headers; - RequestContentLength = ctx.Request.ContentLength; - StatusCode = ctx.Response.StatusCode; - ResponseContentLength = ctx.Response.ContentLength; + Ip = context.Request.Source.IpAddress; + Port = context.Request.Source.Port; + Method = context.Request.Method; + Url = context.Request.Url.Full; + Query = context.Request.Query.Elements; + RequestHeaders = context.Request.Headers; + RequestContentLength = context.Request.ContentLength; + StatusCode = context.Response.StatusCode; + ResponseContentLength = context.Response.ContentLength; TotalMs = totalMs; } } diff --git a/EonaCat.Network/System/Web/HttpContext.cs b/EonaCat.Network/System/Web/HttpContext.cs index 0f35a50..012d8d8 100644 --- a/EonaCat.Network/System/Web/HttpContext.cs +++ b/EonaCat.Network/System/Web/HttpContext.cs @@ -50,11 +50,11 @@ namespace EonaCat.Network { } - internal HttpContext(System.Net.HttpListenerContext ctx, EonaCatWebserverSettings settings, EonaCatWebserverEvents events) + internal HttpContext(System.Net.HttpListenerContext context, EonaCatWebserverSettings settings, EonaCatWebserverEvents events) { - if (ctx == null) + if (context == null) { - throw new ArgumentNullException(nameof(ctx)); + throw new ArgumentNullException(nameof(context)); } if (events == null) @@ -62,9 +62,9 @@ namespace EonaCat.Network throw new ArgumentNullException(nameof(events)); } - _Context = ctx; - Request = new HttpRequest(ctx); - Response = new HttpResponse(Request, ctx, settings, events); + _Context = context; + Request = new HttpRequest(context); + Response = new HttpResponse(Request, context, settings, events); } } } \ No newline at end of file diff --git a/EonaCat.Network/System/Web/HttpRequest.cs b/EonaCat.Network/System/Web/HttpRequest.cs index d5badd4..03048b9 100644 --- a/EonaCat.Network/System/Web/HttpRequest.cs +++ b/EonaCat.Network/System/Web/HttpRequest.cs @@ -182,41 +182,41 @@ namespace EonaCat.Network /// HTTP request. /// Instantiate the object using an HttpListenerContext. /// - /// HttpListenerContext. - public HttpRequest(System.Net.HttpListenerContext ctx) + /// HttpListenerContext. + public HttpRequest(System.Net.HttpListenerContext context) { - if (ctx == null) + if (context == null) { - throw new ArgumentNullException(nameof(ctx)); + throw new ArgumentNullException(nameof(context)); } - if (ctx.Request == null) + if (context.Request == null) { - throw new ArgumentNullException(nameof(ctx.Request)); + throw new ArgumentNullException(nameof(context.Request)); } - ListenerContext = ctx; - Keepalive = ctx.Request.KeepAlive; - ContentLength = ctx.Request.ContentLength64; - Useragent = ctx.Request.UserAgent; - ContentType = ctx.Request.ContentType; + ListenerContext = context; + Keepalive = context.Request.KeepAlive; + ContentLength = context.Request.ContentLength64; + Useragent = context.Request.UserAgent; + ContentType = context.Request.ContentType; - _Uri = new Uri(ctx.Request.Url.ToString().Trim()); + _Uri = new Uri(context.Request.Url.ToString().Trim()); ThreadId = Thread.CurrentThread.ManagedThreadId; TimestampUtc = DateTime.Now.ToUniversalTime(); - ProtocolVersion = "HTTP/" + ctx.Request.ProtocolVersion.ToString(); - Source = new SourceDetails(ctx.Request.RemoteEndPoint.Address.ToString(), ctx.Request.RemoteEndPoint.Port); - Destination = new DestinationDetails(ctx.Request.LocalEndPoint.Address.ToString(), ctx.Request.LocalEndPoint.Port, _Uri.Host); - Method = (HttpMethod)Enum.Parse(typeof(HttpMethod), ctx.Request.HttpMethod, true); - Url = new UrlDetails(ctx.Request.Url.ToString().Trim(), ctx.Request.RawUrl.ToString().Trim()); + ProtocolVersion = "HTTP/" + context.Request.ProtocolVersion.ToString(); + Source = new SourceDetails(context.Request.RemoteEndPoint.Address.ToString(), context.Request.RemoteEndPoint.Port); + Destination = new DestinationDetails(context.Request.LocalEndPoint.Address.ToString(), context.Request.LocalEndPoint.Port, _Uri.Host); + Method = (HttpMethod)Enum.Parse(typeof(HttpMethod), context.Request.HttpMethod, true); + Url = new UrlDetails(context.Request.Url.ToString().Trim(), context.Request.RawUrl.ToString().Trim()); Query = new QueryDetails(Url.Full); Headers = new Dictionary(); - for (int i = 0; i < ctx.Request.Headers.Count; i++) + for (int i = 0; i < context.Request.Headers.Count; i++) { - string key = ctx.Request.Headers.GetKey(i); - string val = ctx.Request.Headers.Get(i); + string key = context.Request.Headers.GetKey(i); + string val = context.Request.Headers.Get(i); Headers = AddToDict(key, val, Headers); } @@ -258,7 +258,7 @@ namespace EonaCat.Network } } - Data = ctx.Request.InputStream; + Data = context.Request.InputStream; } /// diff --git a/EonaCat.Network/System/Web/HttpResponse.cs b/EonaCat.Network/System/Web/HttpResponse.cs index 743e20e..e88faa8 100644 --- a/EonaCat.Network/System/Web/HttpResponse.cs +++ b/EonaCat.Network/System/Web/HttpResponse.cs @@ -140,16 +140,16 @@ namespace EonaCat.Network { } - internal HttpResponse(HttpRequest req, System.Net.HttpListenerContext ctx, EonaCatWebserverSettings settings, EonaCatWebserverEvents events) + internal HttpResponse(HttpRequest httpRequest, System.Net.HttpListenerContext context, EonaCatWebserverSettings settings, EonaCatWebserverEvents events) { - if (req == null) + if (httpRequest == null) { - throw new ArgumentNullException(nameof(req)); + throw new ArgumentNullException(nameof(httpRequest)); } - if (ctx == null) + if (context == null) { - throw new ArgumentNullException(nameof(ctx)); + throw new ArgumentNullException(nameof(context)); } if (settings == null) @@ -162,8 +162,8 @@ namespace EonaCat.Network throw new ArgumentNullException(nameof(events)); } - _Request = req; - _Context = ctx; + _Request = httpRequest; + _Context = context; _Response = _Context.Response; _Settings = settings; _Events = events;