From 50ae0dcc536bed82c826accb12a5124cd5608dd6 Mon Sep 17 00:00:00 2001 From: Seabiscuit Date: Tue, 14 Aug 2018 03:11:36 +0800 Subject: [PATCH] ThrowHelper & LoggingExtensions --- DotNetty.sln | 72 +- .../AbstractUnpooledSlicedByteBuffer.cs | 30 +- src/DotNetty.Buffers/ByteBufferUtil.cs | 138 +- src/DotNetty.Buffers/CompositeByteBuffer.cs | 4 +- src/DotNetty.Buffers/EmptyByteBuffer.cs | 10 +- .../Internal/LoggingExtensions.cs | 19 + .../Internal/ThrowHelper.Extensions.cs | 52 + src/DotNetty.Buffers/PoolArena.cs | 4 +- src/DotNetty.Buffers/PoolThreadCache.cs | 2 +- .../UnpooledDuplicatedByteBuffer.cs | 30 +- .../CombinedHttpHeaders.cs | 6 +- .../Cookies/ClientCookieDecoder.cs | 4 +- .../Cookies/CookieDecoder.cs | 12 +- .../Cookies/CookieEncoder.cs | 6 +- .../Cookies/CookieUtil.cs | 2 +- .../Cookies/DefaultCookie.cs | 12 +- .../Cookies/ServerCookieDecoder.cs | 6 +- src/DotNetty.Codecs.Http/Cors/CorsConfig.cs | 2 +- src/DotNetty.Codecs.Http/Cors/CorsHandler.cs | 10 +- .../DefaultFullHttpRequest.cs | 10 +- .../DefaultFullHttpResponse.cs | 10 +- .../DefaultHttpHeaders.cs | 16 +- .../DefaultHttpMessage.cs | 10 +- src/DotNetty.Codecs.Http/DefaultHttpObject.cs | 6 +- .../DefaultHttpRequest.cs | 10 +- .../DotNetty.Codecs.Http.csproj | 15 + .../HttpClientUpgradeHandler.cs | 11 +- .../HttpContentCompressor.cs | 4 +- .../HttpContentDecoder.cs | 39 +- .../HttpContentEncoder.cs | 53 +- src/DotNetty.Codecs.Http/HttpMethod.cs | 10 +- .../HttpObjectAggregator.cs | 23 +- src/DotNetty.Codecs.Http/HttpObjectDecoder.cs | 2 +- src/DotNetty.Codecs.Http/HttpObjectEncoder.cs | 183 +-- .../HttpResponseStatus.cs | 16 +- src/DotNetty.Codecs.Http/HttpScheme.cs | 6 +- src/DotNetty.Codecs.Http/HttpStatusClass.cs | 2 +- src/DotNetty.Codecs.Http/HttpUtil.cs | 40 +- src/DotNetty.Codecs.Http/HttpVersion.cs | 34 +- .../Internal/LoggingExtensions.cs | 139 ++ src/DotNetty.Codecs.Http/Internal/SR.cs | 53 + .../Internal/Strings.Designer.cs | 63 + .../Internal/Strings.resx | 120 ++ .../Internal/ThrowHelper.Extensions.cs | 1162 +++++++++++++++++ .../Internal/ThrowHelper.cs | 222 ++++ .../Multipart/AbstractDiskHttpData.cs | 20 +- .../Multipart/AbstractHttpData.cs | 6 +- .../Multipart/AbstractMemoryHttpData.cs | 12 +- .../Multipart/DefaultHttpDataFactory.cs | 2 +- .../Multipart/DiskAttribute.cs | 10 +- .../Multipart/DiskFileUpload.cs | 8 +- .../Multipart/FileUploadUtil.cs | 2 +- .../Multipart/HttpPostBodyUtil.cs | 2 +- .../HttpPostMultipartRequestDecoder.cs | 146 +-- .../Multipart/HttpPostRequestDecoder.cs | 2 +- .../Multipart/HttpPostRequestEncoder.cs | 84 +- .../HttpPostStandardRequestDecoder.cs | 22 +- .../Multipart/InternalAttribute.cs | 6 +- .../Multipart/MemoryAttribute.cs | 8 +- .../Multipart/MemoryFileUpload.cs | 8 +- .../Multipart/MixedAttribute.cs | 4 +- .../Multipart/MixedFileUpload.cs | 4 +- .../QueryStringDecoder.cs | 2 +- src/DotNetty.Codecs.Http/ThrowHelper.cs | 2 +- .../WebSockets/ContinuationWebSocketFrame.cs | 2 +- .../Extensions/Compression/DeflateDecoder.cs | 49 +- .../Extensions/Compression/DeflateEncoder.cs | 36 +- .../DeflateFrameClientExtensionHandshaker.cs | 43 +- .../DeflateFrameServerExtensionHandshaker.cs | 47 +- .../Compression/PerFrameDeflateDecoder.cs | 19 +- .../Compression/PerFrameDeflateEncoder.cs | 21 +- ...MessageDeflateClientExtensionHandshaker.cs | 17 +- .../Compression/PerMessageDeflateDecoder.cs | 32 +- .../Compression/PerMessageDeflateEncoder.cs | 49 +- ...MessageDeflateServerExtensionHandshaker.cs | 31 +- .../WebSocketClientExtensionHandler.cs | 2 +- .../Extensions/WebSocketExtensionData.cs | 2 +- .../Extensions/WebSocketExtensionUtil.cs | 4 +- .../WebSockets/TextWebSocketFrame.cs | 2 +- .../WebSockets/WebSocket00FrameDecoder.cs | 10 +- .../WebSockets/WebSocket00FrameEncoder.cs | 101 +- .../WebSockets/WebSocket08FrameDecoder.cs | 6 +- .../WebSockets/WebSocket08FrameEncoder.cs | 50 +- .../WebSockets/WebSocketClientHandshaker.cs | 22 +- .../WebSockets/WebSocketClientHandshaker00.cs | 8 +- .../WebSockets/WebSocketClientHandshaker07.cs | 11 +- .../WebSockets/WebSocketClientHandshaker08.cs | 11 +- .../WebSockets/WebSocketClientHandshaker13.cs | 11 +- .../WebSocketClientHandshakerFactory.cs | 2 +- ...WebSocketClientProtocolHandshakeHandler.cs | 6 +- .../WebSockets/WebSocketFrameAggregator.cs | 30 +- .../WebSockets/WebSocketProtocolHandler.cs | 25 +- .../WebSockets/WebSocketServerHandshaker.cs | 16 +- .../WebSockets/WebSocketServerHandshaker00.cs | 4 +- .../WebSockets/WebSocketServerHandshaker07.cs | 6 +- .../WebSockets/WebSocketServerHandshaker08.cs | 6 +- .../WebSockets/WebSocketServerHandshaker13.cs | 6 +- ...WebSocketServerProtocolHandshakeHandler.cs | 4 +- .../WebSockets/WebSocketVersion.cs | 2 +- src/DotNetty.Codecs.Redis/RedisDecoder.cs | 2 +- src/DotNetty.Codecs/Base64/Base64.cs | 18 +- src/DotNetty.Codecs/DateFormatter.cs | 4 +- src/DotNetty.Codecs/DefaultHeaders.cs | 36 +- .../DelimiterBasedFrameDecoder.cs | 16 +- .../Internal/ThrowHelper.Extensions.cs | 189 ++- src/DotNetty.Codecs/MessageAggregator.cs | 14 +- src/DotNetty.Codecs/MessageToByteEncoder.cs | 2 +- .../MessageToMessageEncoder.cs | 2 +- src/DotNetty.Codecs/Strings/StringDecoder.cs | 2 +- src/DotNetty.Codecs/Strings/StringEncoder.cs | 2 +- .../Concurrency/AbstractEventExecutor.cs | 2 +- .../Concurrency/SingleThreadEventExecutor.cs | 12 +- .../Internal/AppendableCharSequence.cs | 2 +- .../Internal/Logging/GenericLogger.cs | 90 +- .../Internal/Logging/MessageFormatter.cs | 86 +- .../Internal/LoggingExtensions.cs | 106 ++ .../Internal/MacAddressUtil.cs | 2 +- .../Internal/ThrowHelper.Extensions.cs | 259 +++- src/DotNetty.Common/PreciseTimeSpan.cs | 4 +- src/DotNetty.Common/ResourceLeakDetector.cs | 2 +- src/DotNetty.Common/ThreadDeathWatcher.cs | 6 +- src/DotNetty.Common/ThreadLocalPool.cs | 2 +- .../Utilities/AbstractConstant.cs | 2 +- src/DotNetty.Common/Utilities/AsciiString.cs | 111 +- .../Utilities/CharSequenceEnumerator.cs | 8 +- .../Utilities/CharUtil.Extensions.cs | 21 + src/DotNetty.Common/Utilities/CharUtil.cs | 56 +- .../Utilities/HashedWheelTimer.cs | 33 +- .../Utilities/ReferenceCountUtil.cs | 16 +- src/DotNetty.Common/Utilities/Signal.cs | 8 +- .../Utilities/StringUtil.Extensions.cs | 13 + src/DotNetty.Common/Utilities/StringUtil.cs | 16 +- .../Flow/FlowControlHandler.cs | 2 +- .../Internal/LoggingExtensions.cs | 46 + .../Logging/LoggingHandler.cs | 19 +- .../Streams/ChunkedWriteHandler.cs | 8 +- src/DotNetty.Handlers/Tls/SniHandler.cs | 6 +- .../DispatcherEventLoop.cs | 2 +- .../EventLoopGroup.cs | 6 +- .../Internal/LoggingExtensions.cs | 218 ++++ .../Internal/ThrowHelper.Extensions.cs | 71 +- src/DotNetty.Transport.Libuv/LoopExecutor.cs | 24 +- src/DotNetty.Transport.Libuv/Native/Async.cs | 2 +- .../Native/Loop.Extensions.cs | 22 + src/DotNetty.Transport.Libuv/Native/Loop.cs | 26 +- .../Native/NativeHandle.Extensions.cs | 24 + .../Native/NativeHandle.cs | 6 +- .../Native/NativeMethods.cs | 4 +- .../Native/NativeRequest.cs | 2 +- src/DotNetty.Transport.Libuv/Native/Pipe.cs | 2 +- .../Native/PipeListener.cs | 4 +- src/DotNetty.Transport.Libuv/Native/Tcp.cs | 2 +- src/DotNetty.Transport.Libuv/Native/Timer.cs | 2 +- src/DotNetty.Transport.Libuv/NativeChannel.cs | 14 +- .../TcpServerChannel.cs | 11 +- .../WorkerEventLoop.cs | 10 +- .../WorkerEventLoopGroup.cs | 2 +- .../Bootstrapping/AbstractBootstrap.cs | 28 +- .../Bootstrapping/Bootstrap.cs | 6 +- .../Bootstrapping/ServerBootstrap.cs | 8 +- .../Channels/AbstractChannel.cs | 30 +- .../Channels/AbstractChannelHandlerContext.cs | 23 +- .../Channels/ChannelHandlerAdapter.cs | 2 +- .../Channels/ChannelInitializer.cs | 2 +- .../Channels/ChannelOutboundBuffer.cs | 2 +- .../Channels/CombinedChannelDuplexHandler.cs | 20 +- .../Channels/DefaultChannelPipeline.cs | 24 +- .../Channels/DefaultFileRegion.cs | 2 +- .../Channels/Embedded/EmbeddedChannel.cs | 6 +- .../Channels/Embedded/EmbeddedEventLoop.cs | 6 +- .../Channels/Groups/CombinedEnumerator.cs | 2 +- .../Channels/Local/LocalAddress.cs | 2 +- .../Channels/Local/LocalChannel.cs | 14 +- .../Channels/Local/LocalChannelRegistry.cs | 12 +- .../Channels/Local/LocalServerChannel.cs | 2 +- .../Channels/Pool/FixedChannelPool.cs | 26 +- .../Channels/Pool/SimpleChannelPool.cs | 6 +- .../Sockets/AbstractSocketByteChannel.cs | 5 +- .../Channels/Sockets/AbstractSocketChannel.cs | 12 +- .../DefaultSocketChannelConfiguration.cs | 48 +- .../Sockets/SocketChannelAsyncOperation.cs | 2 +- .../Sockets/TcpServerSocketChannel.cs | 9 +- .../Channels/Sockets/TcpSocketChannel.cs | 10 +- src/DotNetty.Transport/Channels/Util.cs | 6 +- .../Internal/LoggingExtensions.cs | 185 +++ .../Internal/ThrowHelper.Extensions.cs | 500 +++++++ src/version.props | 2 +- 187 files changed, 5027 insertions(+), 1377 deletions(-) create mode 100644 src/DotNetty.Buffers/Internal/LoggingExtensions.cs create mode 100644 src/DotNetty.Codecs.Http/Internal/LoggingExtensions.cs create mode 100644 src/DotNetty.Codecs.Http/Internal/SR.cs create mode 100644 src/DotNetty.Codecs.Http/Internal/Strings.Designer.cs create mode 100644 src/DotNetty.Codecs.Http/Internal/Strings.resx create mode 100644 src/DotNetty.Codecs.Http/Internal/ThrowHelper.Extensions.cs create mode 100644 src/DotNetty.Codecs.Http/Internal/ThrowHelper.cs create mode 100644 src/DotNetty.Common/Internal/LoggingExtensions.cs create mode 100644 src/DotNetty.Common/Utilities/CharUtil.Extensions.cs create mode 100644 src/DotNetty.Common/Utilities/StringUtil.Extensions.cs create mode 100644 src/DotNetty.Handlers/Internal/LoggingExtensions.cs create mode 100644 src/DotNetty.Transport.Libuv/Internal/LoggingExtensions.cs create mode 100644 src/DotNetty.Transport.Libuv/Native/Loop.Extensions.cs create mode 100644 src/DotNetty.Transport.Libuv/Native/NativeHandle.Extensions.cs create mode 100644 src/DotNetty.Transport/Internal/LoggingExtensions.cs diff --git a/DotNetty.sln b/DotNetty.sln index 1394d9499..07e4a4d99 100644 --- a/DotNetty.sln +++ b/DotNetty.sln @@ -98,9 +98,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HttpServer", "examples\Http EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetty.Transport.Libuv.Tests", "test\DotNetty.Transport.Libuv.Tests\DotNetty.Transport.Libuv.Tests.csproj", "{5938CE7C-61CD-4C70-82B8-B236AC881A14}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSockets.Client", "examples\WebSockets.Client\WebSockets.Client.csproj", "{91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSockets.Server", "examples\WebSockets.Server\WebSockets.Server.csproj", "{F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSockets.Server", "examples\WebSockets.Server\WebSockets.Server.csproj", "{AA8F9D2A-1055-4018-84A3-D623172787CD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebSockets.Client", "examples\WebSockets.Client\WebSockets.Client.csproj", "{DA148037-5219-49C2-B76F-9B0F2BFC5FA9}" EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution @@ -710,38 +710,38 @@ Global {5938CE7C-61CD-4C70-82B8-B236AC881A14}.Release|x64.Build.0 = Release|Any CPU {5938CE7C-61CD-4C70-82B8-B236AC881A14}.Release|x86.ActiveCfg = Release|Any CPU {5938CE7C-61CD-4C70-82B8-B236AC881A14}.Release|x86.Build.0 = Release|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Debug|Any CPU.Build.0 = Debug|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Debug|ARM.ActiveCfg = Debug|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Debug|ARM.Build.0 = Debug|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Debug|x64.ActiveCfg = Debug|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Debug|x64.Build.0 = Debug|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Debug|x86.ActiveCfg = Debug|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Debug|x86.Build.0 = Debug|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Release|Any CPU.ActiveCfg = Release|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Release|Any CPU.Build.0 = Release|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Release|ARM.ActiveCfg = Release|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Release|ARM.Build.0 = Release|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Release|x64.ActiveCfg = Release|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Release|x64.Build.0 = Release|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Release|x86.ActiveCfg = Release|Any CPU - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649}.Release|x86.Build.0 = Release|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Debug|ARM.ActiveCfg = Debug|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Debug|ARM.Build.0 = Debug|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Debug|x64.ActiveCfg = Debug|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Debug|x64.Build.0 = Debug|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Debug|x86.ActiveCfg = Debug|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Debug|x86.Build.0 = Debug|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Release|Any CPU.Build.0 = Release|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Release|ARM.ActiveCfg = Release|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Release|ARM.Build.0 = Release|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Release|x64.ActiveCfg = Release|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Release|x64.Build.0 = Release|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Release|x86.ActiveCfg = Release|Any CPU - {AA8F9D2A-1055-4018-84A3-D623172787CD}.Release|x86.Build.0 = Release|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Debug|ARM.ActiveCfg = Debug|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Debug|ARM.Build.0 = Debug|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Debug|x64.ActiveCfg = Debug|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Debug|x64.Build.0 = Debug|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Debug|x86.ActiveCfg = Debug|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Debug|x86.Build.0 = Debug|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Release|Any CPU.Build.0 = Release|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Release|ARM.ActiveCfg = Release|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Release|ARM.Build.0 = Release|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Release|x64.ActiveCfg = Release|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Release|x64.Build.0 = Release|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Release|x86.ActiveCfg = Release|Any CPU + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385}.Release|x86.Build.0 = Release|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Debug|ARM.ActiveCfg = Debug|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Debug|ARM.Build.0 = Debug|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Debug|x64.ActiveCfg = Debug|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Debug|x64.Build.0 = Debug|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Debug|x86.ActiveCfg = Debug|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Debug|x86.Build.0 = Debug|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Release|Any CPU.Build.0 = Release|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Release|ARM.ActiveCfg = Release|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Release|ARM.Build.0 = Release|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Release|x64.ActiveCfg = Release|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Release|x64.Build.0 = Release|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Release|x86.ActiveCfg = Release|Any CPU + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -786,8 +786,8 @@ Global {26A8779A-44B1-46D4-A43E-FA2616EBFD02} = {01F3CC7E-F996-411E-AFD6-72673A826549} {BDDF75B4-4BAB-49DE-97A3-CA191C523636} = {3511E2D1-F581-420E-8DC4-8F0386947621} {5938CE7C-61CD-4C70-82B8-B236AC881A14} = {01F3CC7E-F996-411E-AFD6-72673A826549} - {91F3EB7C-FB5C-4ADB-A3F2-D95A3165E649} = {3511E2D1-F581-420E-8DC4-8F0386947621} - {AA8F9D2A-1055-4018-84A3-D623172787CD} = {3511E2D1-F581-420E-8DC4-8F0386947621} + {F3AA2B9E-0AA7-4F13-B5F5-5BFF34FF8385} = {3511E2D1-F581-420E-8DC4-8F0386947621} + {DA148037-5219-49C2-B76F-9B0F2BFC5FA9} = {3511E2D1-F581-420E-8DC4-8F0386947621} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A659CEFB-DDB3-49BE-AEDD-FF2F1B3297DB} diff --git a/src/DotNetty.Buffers/AbstractUnpooledSlicedByteBuffer.cs b/src/DotNetty.Buffers/AbstractUnpooledSlicedByteBuffer.cs index aa245c500..0260fbd68 100644 --- a/src/DotNetty.Buffers/AbstractUnpooledSlicedByteBuffer.cs +++ b/src/DotNetty.Buffers/AbstractUnpooledSlicedByteBuffer.cs @@ -21,20 +21,22 @@ protected AbstractUnpooledSlicedByteBuffer(IByteBuffer buffer, int index, int le { CheckSliceOutOfBounds(index, length, buffer); - if (buffer is AbstractUnpooledSlicedByteBuffer byteBuffer) + switch (buffer) { - this.buffer = byteBuffer.buffer; - this.adjustment = byteBuffer.adjustment + index; - } - else if (buffer is UnpooledDuplicatedByteBuffer) - { - this.buffer = buffer.Unwrap(); - this.adjustment = index; - } - else - { - this.buffer = buffer; - this.adjustment = index; + case AbstractUnpooledSlicedByteBuffer byteBuffer: + this.buffer = byteBuffer.buffer; + this.adjustment = byteBuffer.adjustment + index; + break; + + case UnpooledDuplicatedByteBuffer _: + this.buffer = buffer.Unwrap(); + this.adjustment = index; + break; + + default: + this.buffer = buffer; + this.adjustment = index; + break; } this.SetWriterIndex0(length); @@ -329,7 +331,7 @@ internal static void CheckSliceOutOfBounds(int index, int length, IByteBuffer bu { if (MathUtil.IsOutOfBounds(index, length, buffer.Capacity)) { - throw new IndexOutOfRangeException($"{buffer}.Slice({index}, {length})"); + ThrowHelper.ThrowIndexOutOfRangeException_CheckSliceOutOfBounds(index, length, buffer); } } } diff --git a/src/DotNetty.Buffers/ByteBufferUtil.cs b/src/DotNetty.Buffers/ByteBufferUtil.cs index 310b45200..71d20b66b 100644 --- a/src/DotNetty.Buffers/ByteBufferUtil.cs +++ b/src/DotNetty.Buffers/ByteBufferUtil.cs @@ -317,25 +317,25 @@ public static IByteBuffer WriteUtf8(IByteBufferAllocator alloc, ICharSequence se public static int ReserveAndWriteUtf8(IByteBuffer buf, ICharSequence seq, int reserveBytes) { - for (;;) + while(true) { - if (buf is AbstractByteBuffer byteBuf) + switch (buf) { - byteBuf.EnsureWritable0(reserveBytes); - int written = WriteUtf8(byteBuf, byteBuf.WriterIndex, seq, seq.Count); - byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); - return written; - } - else if (buf is WrappedByteBuffer) - { - // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. - buf = buf.Unwrap(); - } - else - { - byte[] bytes = Encoding.UTF8.GetBytes(seq.ToString()); - buf.WriteBytes(bytes); - return bytes.Length; + case AbstractByteBuffer byteBuf: + byteBuf.EnsureWritable0(reserveBytes); + int written = WriteUtf8(byteBuf, byteBuf.WriterIndex, seq, seq.Count); + byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); + return written; + + case WrappedByteBuffer _: + // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. + buf = buf.Unwrap(); + break; + + default: + byte[] bytes = Encoding.UTF8.GetBytes(seq.ToString()); + buf.WriteBytes(bytes); + return bytes.Length; } } } @@ -422,25 +422,25 @@ public static IByteBuffer WriteUtf8(IByteBufferAllocator alloc, string value) /// This method returns the actual number of bytes written. public static int ReserveAndWriteUtf8(IByteBuffer buf, string value, int reserveBytes) { - for (;;) + while(true) { - if (buf is AbstractByteBuffer byteBuf) + switch (buf) { - byteBuf.EnsureWritable0(reserveBytes); - int written = WriteUtf8(byteBuf, byteBuf.WriterIndex, value, value.Length); - byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); - return written; - } - else if (buf is WrappedByteBuffer) - { - // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. - buf = buf.Unwrap(); - } - else - { - byte[] bytes = Encoding.UTF8.GetBytes(value); - buf.WriteBytes(bytes); - return bytes.Length; + case AbstractByteBuffer byteBuf: + byteBuf.EnsureWritable0(reserveBytes); + int written = WriteUtf8(byteBuf, byteBuf.WriterIndex, value, value.Length); + byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); + return written; + + case WrappedByteBuffer _: + // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. + buf = buf.Unwrap(); + break; + + default: + byte[] bytes = Encoding.UTF8.GetBytes(value); + buf.WriteBytes(bytes); + return bytes.Length; } } } @@ -595,25 +595,25 @@ public static int WriteAscii(IByteBuffer buf, ICharSequence seq) } else { - for (;;) + while(true) { - if (buf is AbstractByteBuffer byteBuf) + switch (buf) { - byteBuf.EnsureWritable0(len); - int written = WriteAscii(byteBuf, byteBuf.WriterIndex, seq, len); - byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); - return written; - } - else if (buf is WrappedByteBuffer) - { - // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. - buf = buf.Unwrap(); - } - else - { - byte[] bytes = Encoding.ASCII.GetBytes(seq.ToString()); - buf.WriteBytes(bytes); - return bytes.Length; + case AbstractByteBuffer byteBuf: + byteBuf.EnsureWritable0(len); + int written = WriteAscii(byteBuf, byteBuf.WriterIndex, seq, len); + byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); + return written; + + case WrappedByteBuffer _: + // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. + buf = buf.Unwrap(); + break; + + default: + byte[] bytes = Encoding.ASCII.GetBytes(seq.ToString()); + buf.WriteBytes(bytes); + return bytes.Length; } } } @@ -644,25 +644,25 @@ public static int WriteAscii(IByteBuffer buf, string value) { // ASCII uses 1 byte per char int len = value.Length; - for (;;) + while(true) { - if (buf is AbstractByteBuffer byteBuf) - { - byteBuf.EnsureWritable0(len); - int written = WriteAscii(byteBuf, byteBuf.WriterIndex, value, len); - byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); - return written; - } - else if (buf is WrappedByteBuffer) + switch (buf) { - // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. - buf = buf.Unwrap(); - } - else - { - byte[] bytes = Encoding.ASCII.GetBytes(value); - buf.WriteBytes(bytes); - return bytes.Length; + case AbstractByteBuffer byteBuf: + byteBuf.EnsureWritable0(len); + int written = WriteAscii(byteBuf, byteBuf.WriterIndex, value, len); + byteBuf.SetWriterIndex(byteBuf.WriterIndex + written); + return written; + + case WrappedByteBuffer _: + // Unwrap as the wrapped buffer may be an AbstractByteBuf and so we can use fast-path. + buf = buf.Unwrap(); + break; + + default: + byte[] bytes = Encoding.ASCII.GetBytes(value); + buf.WriteBytes(bytes); + return bytes.Length; } } } @@ -1037,7 +1037,7 @@ public static bool IsText(IByteBuffer buf, int index, int length, Encoding encod int maxIndex = buf.ReaderIndex + buf.ReadableBytes; if (index < 0 || length < 0 || index > maxIndex - length) { - throw new IndexOutOfRangeException($"index: {index}length: {length}"); + ThrowHelper.ThrowIndexOutOfRangeException_IsText(index, length); } if (ReferenceEquals(Encoding.UTF8, encoding)) { diff --git a/src/DotNetty.Buffers/CompositeByteBuffer.cs b/src/DotNetty.Buffers/CompositeByteBuffer.cs index 2fd4de090..b2b3abe53 100644 --- a/src/DotNetty.Buffers/CompositeByteBuffer.cs +++ b/src/DotNetty.Buffers/CompositeByteBuffer.cs @@ -804,7 +804,7 @@ public virtual int ToComponentIndex(int offset) } } - throw new Exception("should not reach here"); + return ThrowHelper.ThrowGetException_ShouldNotReachHere(); } public virtual int ToByteIndex(int cIndex) @@ -1304,7 +1304,7 @@ ComponentEntry FindComponent(int offset) } } - throw new Exception("should not reach here"); + return ThrowHelper.ThrowGetException_ShouldNotReachHere(); } /// diff --git a/src/DotNetty.Buffers/EmptyByteBuffer.cs b/src/DotNetty.Buffers/EmptyByteBuffer.cs index 6553901b3..0564be96c 100644 --- a/src/DotNetty.Buffers/EmptyByteBuffer.cs +++ b/src/DotNetty.Buffers/EmptyByteBuffer.cs @@ -506,7 +506,7 @@ IByteBuffer CheckIndex(int index) { if (index != 0) { - throw new IndexOutOfRangeException(); + ThrowHelper.ThrowIndexOutOfRangeException(); } return this; } @@ -515,11 +515,11 @@ IByteBuffer CheckIndex(int index, int length) { if (length < 0) { - throw new ArgumentException("length: " + length); + ThrowHelper.ThrowArgumentException_CheckIndex(length); } if (index != 0 || length != 0) { - throw new IndexOutOfRangeException(); + ThrowHelper.ThrowIndexOutOfRangeException(); } return this; @@ -530,11 +530,11 @@ IByteBuffer CheckLength(int length) { if (length < 0) { - throw new ArgumentException("length: " + length + " (expected: >= 0)"); + ThrowHelper.ThrowArgumentException_CheckLength(length); } if (length != 0) { - throw new IndexOutOfRangeException(); + ThrowHelper.ThrowIndexOutOfRangeException(); } return this; } diff --git a/src/DotNetty.Buffers/Internal/LoggingExtensions.cs b/src/DotNetty.Buffers/Internal/LoggingExtensions.cs new file mode 100644 index 000000000..e29147217 --- /dev/null +++ b/src/DotNetty.Buffers/Internal/LoggingExtensions.cs @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Runtime.CompilerServices; +using DotNetty.Common.Concurrency; +using DotNetty.Common.Internal.Logging; + +namespace DotNetty.Buffers +{ + internal static class BuffersLoggingExtensions + { + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FreedThreadLocalBufferFromThread(this IInternalLogger logger, int numFreed, XThread deathWatchThread) + { + logger.Debug("Freed {} thread-local buffer(s) from thread: {}", numFreed, deathWatchThread.Name); + } + } +} diff --git a/src/DotNetty.Buffers/Internal/ThrowHelper.Extensions.cs b/src/DotNetty.Buffers/Internal/ThrowHelper.Extensions.cs index 7daf7ab41..86805b12e 100644 --- a/src/DotNetty.Buffers/Internal/ThrowHelper.Extensions.cs +++ b/src/DotNetty.Buffers/Internal/ThrowHelper.Extensions.cs @@ -85,6 +85,36 @@ internal enum ExceptionResource partial class ThrowHelper { + [MethodImpl(MethodImplOptions.NoInlining)] + internal static T ThrowGetException_ShouldNotReachHere() + { + throw GetException(); + Exception GetException() + { + return new Exception("should not reach here"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_CheckIndex(int length) + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException("length: " + length); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_CheckLength(int length) + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException("length: " + length + " (expected: >= 0)"); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowArgumentException_LenIsTooBig() { @@ -155,6 +185,28 @@ ArgumentException GetArgumentException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowIndexOutOfRangeException_IsText(int index, int length) + { + throw GetIndexOutOfRangeException(); + + IndexOutOfRangeException GetIndexOutOfRangeException() + { + return new IndexOutOfRangeException($"index: {index}length: {length}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowIndexOutOfRangeException_CheckSliceOutOfBounds(int index, int length, IByteBuffer buffer) + { + throw GetIndexOutOfRangeException(); + + IndexOutOfRangeException GetIndexOutOfRangeException() + { + return new IndexOutOfRangeException($"{buffer}.Slice({index}, {length})"); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowIndexOutOfRangeException_Expected(int offset, int length, int capacity) { diff --git a/src/DotNetty.Buffers/PoolArena.cs b/src/DotNetty.Buffers/PoolArena.cs index 0e1a13b7a..46d31e0dc 100644 --- a/src/DotNetty.Buffers/PoolArena.cs +++ b/src/DotNetty.Buffers/PoolArena.cs @@ -491,7 +491,7 @@ static List SubPageMetricList(PoolSubpage[] pages) continue; } PoolSubpage s = head.Next; - for (; ; ) + while (true) { metrics.Add(s); s = s.Next; @@ -661,7 +661,7 @@ static void AppendPoolSubPages(StringBuilder buf, PoolSubpage[] subpages) .Append(i) .Append(": "); PoolSubpage s = head.Next; - for (; ; ) + while (true) { buf.Append(s); s = s.Next; diff --git a/src/DotNetty.Buffers/PoolThreadCache.cs b/src/DotNetty.Buffers/PoolThreadCache.cs index d8d0d66d2..2947f7367 100644 --- a/src/DotNetty.Buffers/PoolThreadCache.cs +++ b/src/DotNetty.Buffers/PoolThreadCache.cs @@ -263,7 +263,7 @@ void Free0() if (numFreed > 0 && Logger.DebugEnabled) { - Logger.Debug("Freed {} thread-local buffer(s) from thread: {}", numFreed, this.deathWatchThread.Name); + Logger.FreedThreadLocalBufferFromThread(numFreed, this.deathWatchThread); } this.DirectArena?.DecrementNumThreadCaches(); diff --git a/src/DotNetty.Buffers/UnpooledDuplicatedByteBuffer.cs b/src/DotNetty.Buffers/UnpooledDuplicatedByteBuffer.cs index 20e7811ae..960817f00 100644 --- a/src/DotNetty.Buffers/UnpooledDuplicatedByteBuffer.cs +++ b/src/DotNetty.Buffers/UnpooledDuplicatedByteBuffer.cs @@ -21,21 +21,23 @@ public UnpooledDuplicatedByteBuffer(AbstractByteBuffer buffer) internal UnpooledDuplicatedByteBuffer(AbstractByteBuffer buffer, int readerIndex, int writerIndex) : base(buffer.MaxCapacity) { - if (buffer is UnpooledDuplicatedByteBuffer duplicated) + switch (buffer) { - this.buffer = duplicated.buffer; - } - else if (buffer is AbstractPooledDerivedByteBuffer) - { - this.buffer = (AbstractByteBuffer)buffer.Unwrap(); - } - else if (buffer is AbstractBufferManagerDerivedByteBuffer) - { - this.buffer = (AbstractByteBuffer)buffer.Unwrap(); - } - else - { - this.buffer = buffer; + case UnpooledDuplicatedByteBuffer duplicated: + this.buffer = duplicated.buffer; + break; + + case AbstractPooledDerivedByteBuffer _: + this.buffer = (AbstractByteBuffer)buffer.Unwrap(); + break; + + case AbstractBufferManagerDerivedByteBuffer _: + this.buffer = (AbstractByteBuffer)buffer.Unwrap(); + break; + + default: + this.buffer = buffer; + break; } this.SetIndex0(readerIndex, writerIndex); diff --git a/src/DotNetty.Codecs.Http/CombinedHttpHeaders.cs b/src/DotNetty.Codecs.Http/CombinedHttpHeaders.cs index af460a001..45d46b6e9 100644 --- a/src/DotNetty.Codecs.Http/CombinedHttpHeaders.cs +++ b/src/DotNetty.Codecs.Http/CombinedHttpHeaders.cs @@ -39,7 +39,7 @@ public override IEnumerable ValueIterator(AsciiString name) { if (value != null) { - throw new InvalidOperationException($"{nameof(CombinedHttpHeaders)} should only have one value"); + ThrowHelper.ThrowInvalidOperationException_OnlyHaveOneValue(); } value = v; } @@ -55,7 +55,7 @@ public override IList GetAll(AsciiString name) } if (values.Count != 1) { - throw new InvalidOperationException($"{nameof(CombinedHttpHeaders)} should only have one value"); + ThrowHelper.ThrowInvalidOperationException_OnlyHaveOneValue(); } return UnescapeCsvFields(values[0]); @@ -66,7 +66,7 @@ public override IHeaders Add(IHeaders= 0) { - throw new ArgumentException($"Cookie name contains an invalid char: {name[pos]}"); + ThrowHelper.ThrowArgumentException_CookieName(name, pos); } var sequnce = new StringCharSequence(value); ICharSequence unwrappedValue = UnwrapValue(sequnce); if (unwrappedValue == null) { - throw new ArgumentException($"Cookie value wrapping quotes are not balanced: {value}"); + ThrowHelper.ThrowArgumentException_CookieValue(value); } if ((pos = FirstInvalidCookieValueOctet(unwrappedValue)) >= 0) { - throw new ArgumentException($"Cookie value contains an invalid char: {value[pos]}"); + ThrowHelper.ThrowArgumentException_CookieValue(value, pos); } } } diff --git a/src/DotNetty.Codecs.Http/Cookies/CookieUtil.cs b/src/DotNetty.Codecs.Http/Cookies/CookieUtil.cs index c09888990..c5bf4212f 100644 --- a/src/DotNetty.Codecs.Http/Cookies/CookieUtil.cs +++ b/src/DotNetty.Codecs.Http/Cookies/CookieUtil.cs @@ -194,7 +194,7 @@ internal static string ValidateAttributeValue(string name, string value) int i = FirstInvalidOctet(value, ValidCookieAttributeOctets); if (i != -1) { - throw new ArgumentException($"{name} contains the prohibited characters: ${value[i]}"); + ThrowHelper.ThrowArgumentException_ValidateAttrValue(name, value, i); } return value; diff --git a/src/DotNetty.Codecs.Http/Cookies/DefaultCookie.cs b/src/DotNetty.Codecs.Http/Cookies/DefaultCookie.cs index 53a6899e0..467a66d13 100644 --- a/src/DotNetty.Codecs.Http/Cookies/DefaultCookie.cs +++ b/src/DotNetty.Codecs.Http/Cookies/DefaultCookie.cs @@ -97,7 +97,7 @@ public bool Equals(ICookie other) return true; } - if (!this.name.Equals(other.Name)) + if (!string.Equals(this.name, other.Name, StringComparison.Ordinal)) { return false; } @@ -113,7 +113,7 @@ public bool Equals(ICookie other) { return false; } - else if (!this.path.Equals(other.Path)) + else if (!string.Equals(this.path, other.Path, StringComparison.Ordinal)) { return false; } @@ -127,7 +127,7 @@ public bool Equals(ICookie other) } else { - return this.domain.Equals(other.Domain, StringComparison.OrdinalIgnoreCase); + return string.Equals(this.domain, other.Domain, StringComparison.OrdinalIgnoreCase); } return true; @@ -188,12 +188,12 @@ public int CompareTo(object obj) return 1; } - if (!(obj is ICookie cookie)) + if (obj is ICookie cookie) { - throw new ArgumentException($"{nameof(obj)} must be of {nameof(ICookie)} type"); + return this.CompareTo(cookie); } - return this.CompareTo(cookie); + return ThrowHelper.ThrowArgumentException_CompareToCookie(); } public override string ToString() diff --git a/src/DotNetty.Codecs.Http/Cookies/ServerCookieDecoder.cs b/src/DotNetty.Codecs.Http/Cookies/ServerCookieDecoder.cs index 59266d0fd..23f19e463 100644 --- a/src/DotNetty.Codecs.Http/Cookies/ServerCookieDecoder.cs +++ b/src/DotNetty.Codecs.Http/Cookies/ServerCookieDecoder.cs @@ -58,10 +58,10 @@ public ISet Decode(string header) } // loop - for (;;) + while(true) { // Skip spaces and separators. - for (;;) + while(true) { if (i == headerLen) { @@ -82,7 +82,7 @@ public ISet Decode(string header) int valueBegin; int valueEnd; - for (;;) + while(true) { char curChar = header[i]; if (curChar == ';') diff --git a/src/DotNetty.Codecs.Http/Cors/CorsConfig.cs b/src/DotNetty.Codecs.Http/Cors/CorsConfig.cs index a0b1677ee..87e68c045 100644 --- a/src/DotNetty.Codecs.Http/Cors/CorsConfig.cs +++ b/src/DotNetty.Codecs.Http/Cors/CorsConfig.cs @@ -95,7 +95,7 @@ static object GetValue(ICallable callable) } catch (Exception exception) { - throw new InvalidOperationException($"Could not generate value for callable [{callable}]", exception); + return ThrowHelper.ThrowInvalidOperationException_Cqrs(callable, exception); } } diff --git a/src/DotNetty.Codecs.Http/Cors/CorsHandler.cs b/src/DotNetty.Codecs.Http/Cors/CorsHandler.cs index c6e38d2e0..fb8affcce 100644 --- a/src/DotNetty.Codecs.Http/Cors/CorsHandler.cs +++ b/src/DotNetty.Codecs.Http/Cors/CorsHandler.cs @@ -100,7 +100,7 @@ bool SetOrigin(IHttpResponse response) SetVaryHeader(response); return true; } - Logger.Debug("Request origin [{}]] was not among the configured origins [{}]", origin, this.config.Origins); + if (Logger.DebugEnabled) Logger.RequestOriginWasNotAmongTheConfiguredOrigins(origin, this.config); return false; } @@ -137,7 +137,7 @@ bool ValidateOrigin() void SetAllowCredentials(IHttpResponse response) { - if (this.config.IsCredentialsAllowed + if (this.config.IsCredentialsAllowed && !AsciiString.ContentEquals(response.Headers.Get(HttpHeaderNames.AccessControlAllowOrigin, null), AnyOrigin)) { response.Headers.Set(HttpHeaderNames.AccessControlAllowCredentials, new AsciiString("true")); @@ -147,8 +147,8 @@ void SetAllowCredentials(IHttpResponse response) static bool IsPreflightRequest(IHttpRequest request) { HttpHeaders headers = request.Headers; - return request.Method.Equals(HttpMethod.Options) - && headers.Contains(HttpHeaderNames.Origin) + return request.Method.Equals(HttpMethod.Options) + && headers.Contains(HttpHeaderNames.Origin) && headers.Contains(HttpHeaderNames.AccessControlRequestMethod); } @@ -197,7 +197,7 @@ static void Respond(IChannelHandlerContext ctx, IHttpRequest request, IHttpRespo Task task = ctx.WriteAndFlushAsync(response); if (!keepAlive) { - task.ContinueWith(CloseOnComplete, ctx, + task.ContinueWith(CloseOnComplete, ctx, TaskContinuationOptions.ExecuteSynchronously); } } diff --git a/src/DotNetty.Codecs.Http/DefaultFullHttpRequest.cs b/src/DotNetty.Codecs.Http/DefaultFullHttpRequest.cs index 4472d2185..a302d4bc0 100644 --- a/src/DotNetty.Codecs.Http/DefaultFullHttpRequest.cs +++ b/src/DotNetty.Codecs.Http/DefaultFullHttpRequest.cs @@ -130,13 +130,13 @@ public override int GetHashCode() public override bool Equals(object obj) { - if (!(obj is DefaultFullHttpRequest other)) + if (obj is DefaultFullHttpRequest other) { - return false; + return base.Equals(other) + && this.content.Equals(other.content) + && this.trailingHeader.Equals(other.trailingHeader); } - return base.Equals(other) - && this.content.Equals(other.content) - && this.trailingHeader.Equals(other.trailingHeader); + return false; } public override string ToString() => StringBuilderManager.ReturnAndFree(HttpMessageUtil.AppendFullRequest(StringBuilderManager.Allocate(256), this)); diff --git a/src/DotNetty.Codecs.Http/DefaultFullHttpResponse.cs b/src/DotNetty.Codecs.Http/DefaultFullHttpResponse.cs index f14474016..ab736577a 100644 --- a/src/DotNetty.Codecs.Http/DefaultFullHttpResponse.cs +++ b/src/DotNetty.Codecs.Http/DefaultFullHttpResponse.cs @@ -143,13 +143,13 @@ public override int GetHashCode() public override bool Equals(object obj) { - if (!(obj is DefaultFullHttpResponse other)) + if (obj is DefaultFullHttpResponse other) { - return false; + return base.Equals(other) + && this.content.Equals(other.content) + && this.trailingHeaders.Equals(other.trailingHeaders); } - return base.Equals(other) - && this.content.Equals(other.content) - && this.trailingHeaders.Equals(other.trailingHeaders); + return false; } public override string ToString() => StringBuilderManager.ReturnAndFree(HttpMessageUtil.AppendFullResponse(StringBuilderManager.Allocate(256), this)); diff --git a/src/DotNetty.Codecs.Http/DefaultHttpHeaders.cs b/src/DotNetty.Codecs.Http/DefaultHttpHeaders.cs index 45aad90b9..0717ccbbf 100644 --- a/src/DotNetty.Codecs.Http/DefaultHttpHeaders.cs +++ b/src/DotNetty.Codecs.Http/DefaultHttpHeaders.cs @@ -271,15 +271,17 @@ class HeaderValueConverter : CharSequenceValueConverter { public override ICharSequence ConvertObject(object value) { - if (value is ICharSequence seq) + switch (value) { - return seq; - } - if (value is DateTime time) - { - return new StringCharSequence(DateFormatter.Format(time)); + case ICharSequence seq: + return seq; + + case DateTime time: + return new StringCharSequence(DateFormatter.Format(time)); + + default: + return new StringCharSequence(value.ToString()); } - return new StringCharSequence(value.ToString()); } } diff --git a/src/DotNetty.Codecs.Http/DefaultHttpMessage.cs b/src/DotNetty.Codecs.Http/DefaultHttpMessage.cs index 4ba8e30bf..6c6dee979 100644 --- a/src/DotNetty.Codecs.Http/DefaultHttpMessage.cs +++ b/src/DotNetty.Codecs.Http/DefaultHttpMessage.cs @@ -53,14 +53,14 @@ public override int GetHashCode() public override bool Equals(object obj) { - if (!(obj is DefaultHttpMessage other)) + if (obj is DefaultHttpMessage other) { - return false; + return this.headers.Equals(other.headers) + && this.version.Equals(other.version) + && base.Equals(obj); } - return this.headers.Equals(other.headers) - && this.version.Equals(other.version) - && base.Equals(obj); + return false; } public IHttpMessage SetProtocolVersion(HttpVersion value) diff --git a/src/DotNetty.Codecs.Http/DefaultHttpObject.cs b/src/DotNetty.Codecs.Http/DefaultHttpObject.cs index 0cd7d71c4..18d08f05b 100644 --- a/src/DotNetty.Codecs.Http/DefaultHttpObject.cs +++ b/src/DotNetty.Codecs.Http/DefaultHttpObject.cs @@ -34,11 +34,11 @@ public override int GetHashCode() public override bool Equals(object obj) { - if (!(obj is DefaultHttpObject other)) + if (obj is DefaultHttpObject other) { - return false; + return this.decoderResult.Equals(other.decoderResult); } - return this.decoderResult.Equals(other.decoderResult); + return false; } } } diff --git a/src/DotNetty.Codecs.Http/DefaultHttpRequest.cs b/src/DotNetty.Codecs.Http/DefaultHttpRequest.cs index c92e5ce2c..5d5be16d9 100644 --- a/src/DotNetty.Codecs.Http/DefaultHttpRequest.cs +++ b/src/DotNetty.Codecs.Http/DefaultHttpRequest.cs @@ -73,14 +73,14 @@ public override int GetHashCode() public override bool Equals(object obj) { - if (!(obj is DefaultHttpRequest other)) + if (obj is DefaultHttpRequest other) { - return false; + return this.method.Equals(other.method) + && string.Equals(this.uri, other.uri, StringComparison.OrdinalIgnoreCase) + && base.Equals(obj); } - return this.method.Equals(other.method) - && this.uri.Equals(other.uri, StringComparison.OrdinalIgnoreCase) - && base.Equals(obj); + return false; } public override string ToString() => StringBuilderManager.ReturnAndFree(HttpMessageUtil.AppendRequest(StringBuilderManager.Allocate(256), this)); diff --git a/src/DotNetty.Codecs.Http/DotNetty.Codecs.Http.csproj b/src/DotNetty.Codecs.Http/DotNetty.Codecs.Http.csproj index 86357ec5d..42adccacd 100644 --- a/src/DotNetty.Codecs.Http/DotNetty.Codecs.Http.csproj +++ b/src/DotNetty.Codecs.Http/DotNetty.Codecs.Http.csproj @@ -19,4 +19,19 @@ + + + + True + True + Strings.resx + + + + + + ResXFileCodeGenerator + Strings.Designer.cs + + diff --git a/src/DotNetty.Codecs.Http/HttpClientUpgradeHandler.cs b/src/DotNetty.Codecs.Http/HttpClientUpgradeHandler.cs index 98f8af188..7bdec2402 100644 --- a/src/DotNetty.Codecs.Http/HttpClientUpgradeHandler.cs +++ b/src/DotNetty.Codecs.Http/HttpClientUpgradeHandler.cs @@ -74,18 +74,19 @@ public HttpClientUpgradeHandler(ISourceCodec sourceCodec, IUpgradeCodec upgradeC public override Task WriteAsync(IChannelHandlerContext context, object message) { - if (!(message is IHttpRequest)) + var request = message as IHttpRequest; + if (null == request) { return context.WriteAsync(message); } if (this.upgradeRequested) { - return TaskUtil.FromException(new InvalidOperationException("Attempting to write HTTP request with upgrade in progress")); + return ThrowHelper.ThrowInvalidOperationException_Attempting(); } this.upgradeRequested = true; - this.SetUpgradeRequestHeaders(context, (IHttpRequest)message); + this.SetUpgradeRequestHeaders(context, request); // Continue writing the request. Task task = context.WriteAsync(message); @@ -103,7 +104,7 @@ protected override void Decode(IChannelHandlerContext context, IHttpObject messa { if (!this.upgradeRequested) { - throw new InvalidOperationException("Read HTTP response without requesting protocol switch"); + ThrowHelper.ThrowInvalidOperationException_ReadHttpResponse(); } if (message is IHttpResponse rep) @@ -144,7 +145,7 @@ protected override void Decode(IChannelHandlerContext context, IHttpObject messa if (response.Headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgradeHeader) && !AsciiString.ContentEqualsIgnoreCase(this.upgradeCodec.Protocol, upgradeHeader)) { - throw new InvalidOperationException($"Switching Protocols response with unexpected UPGRADE protocol: {upgradeHeader}"); + ThrowHelper.ThrowInvalidOperationException_UnexpectedUpgradeProtocol(upgradeHeader); } // Upgrade to the new protocol. diff --git a/src/DotNetty.Codecs.Http/HttpContentCompressor.cs b/src/DotNetty.Codecs.Http/HttpContentCompressor.cs index fae24a4de..585ddabcc 100644 --- a/src/DotNetty.Codecs.Http/HttpContentCompressor.cs +++ b/src/DotNetty.Codecs.Http/HttpContentCompressor.cs @@ -57,7 +57,7 @@ protected override Result BeginEncode(IHttpResponse headers, ICharSequence accep return null; } - ICharSequence targetContentEncoding; + ICharSequence targetContentEncoding = null; switch (wrapper.Value) { case ZlibWrapper.Gzip: @@ -67,7 +67,7 @@ protected override Result BeginEncode(IHttpResponse headers, ICharSequence accep targetContentEncoding = DeflateString; break; default: - throw new CodecException($"{wrapper.Value} not supported, only Gzip and Zlib are allowed."); + ThrowHelper.ThrowCodecException_InvalidCompression(wrapper.Value); break; } return new Result(targetContentEncoding, diff --git a/src/DotNetty.Codecs.Http/HttpContentDecoder.cs b/src/DotNetty.Codecs.Http/HttpContentDecoder.cs index 8932289ac..21305d91d 100644 --- a/src/DotNetty.Codecs.Http/HttpContentDecoder.cs +++ b/src/DotNetty.Codecs.Http/HttpContentDecoder.cs @@ -42,6 +42,7 @@ protected override void Decode(IChannelHandlerContext context, IHttpObject messa return; } + var httpContent = message as IHttpContent; if (message is IHttpMessage httpMessage) { this.Cleanup(); @@ -60,7 +61,7 @@ protected override void Decode(IChannelHandlerContext context, IHttpObject messa if (this.decoder == null) { - if (httpMessage is IHttpContent httpContent) + if (httpContent != null) { httpContent.Retain(); } @@ -93,26 +94,26 @@ protected override void Decode(IChannelHandlerContext context, IHttpObject messa headers.Set(HttpHeaderNames.ContentEncoding, targetContentEncoding); } - if (httpMessage is IHttpContent) + if (httpContent != null) { // If message is a full request or response object (headers + data), don't copy data part into out. // Output headers only; data part will be decoded below. // Note: "copy" object must not be an instance of LastHttpContent class, // as this would (erroneously) indicate the end of the HttpMessage to other handlers. - IHttpMessage copy; - if (httpMessage is IHttpRequest req) + IHttpMessage copy = null; + switch (httpMessage) { - // HttpRequest or FullHttpRequest - copy = new DefaultHttpRequest(req.ProtocolVersion, req.Method, req.Uri); - } - else if (httpMessage is IHttpResponse res) - { - // HttpResponse or FullHttpResponse - copy = new DefaultHttpResponse(res.ProtocolVersion, res.Status); - } - else - { - throw new CodecException($"Object of class {StringUtil.SimpleClassName(httpMessage.GetType())} is not a HttpRequest or HttpResponse"); + case IHttpRequest req: + // HttpRequest or FullHttpRequest + copy = new DefaultHttpRequest(req.ProtocolVersion, req.Method, req.Uri); + break; + case IHttpResponse res: + // HttpResponse or FullHttpResponse + copy = new DefaultHttpResponse(res.ProtocolVersion, res.Status); + break; + default: + ThrowHelper.ThrowCodecException_InvalidHttpMsg(httpMessage); + break; } copy.Headers.Set(httpMessage.Headers); copy.Result = httpMessage.Result; @@ -124,15 +125,15 @@ protected override void Decode(IChannelHandlerContext context, IHttpObject messa } } - if (message is IHttpContent c) + if (httpContent != null) { if (this.decoder == null) { - output.Add(c.Retain()); + output.Add(httpContent.Retain()); } else { - this.DecodeContent(c, output); + this.DecodeContent(httpContent, output); } } } @@ -224,7 +225,7 @@ void FinishDecode(ICollection output) void FetchDecoderOutput(ICollection output) { - for (;;) + while(true) { var buf = this.decoder.ReadInbound(); if (buf == null) diff --git a/src/DotNetty.Codecs.Http/HttpContentEncoder.cs b/src/DotNetty.Codecs.Http/HttpContentEncoder.cs index eb7454e5f..c93d244fa 100644 --- a/src/DotNetty.Codecs.Http/HttpContentEncoder.cs +++ b/src/DotNetty.Codecs.Http/HttpContentEncoder.cs @@ -7,6 +7,7 @@ namespace DotNetty.Codecs.Http using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Contracts; + using System.Runtime.CompilerServices; using DotNetty.Buffers; using DotNetty.Common.Utilities; using DotNetty.Transport.Channels; @@ -29,7 +30,18 @@ enum State EmbeddedChannel encoder; State state = State.AwaitHeaders; - public override bool AcceptOutboundMessage(object msg) => msg is IHttpContent || msg is IHttpResponse; + public override bool AcceptOutboundMessage(object msg) + { + switch (msg) + { + case IHttpContent _: + case IHttpResponse _: + return true; + + default: + return false; + } + } protected override void Decode(IChannelHandlerContext ctx, IHttpRequest msg, List output) { @@ -51,7 +63,9 @@ protected override void Decode(IChannelHandlerContext ctx, IHttpRequest msg, Lis protected override void Encode(IChannelHandlerContext ctx, IHttpObject msg, List output) { - bool isFull = msg is IHttpResponse && msg is ILastHttpContent; + var res = msg as IHttpResponse; + var lastContent = msg as ILastHttpContent; + bool isFull = res != null && lastContent != null; switch (this.state) { case State.AwaitHeaders: @@ -59,7 +73,6 @@ protected override void Encode(IChannelHandlerContext ctx, IHttpObject msg, List EnsureHeaders(msg); Debug.Assert(this.encoder == null); - var res = (IHttpResponse)msg; int code = res.Status.Code; ICharSequence acceptEncoding; if (code == ContinueCode) @@ -74,7 +87,7 @@ protected override void Encode(IChannelHandlerContext ctx, IHttpObject msg, List acceptEncoding = this.acceptEncodingQueue.Count > 0 ? this.acceptEncodingQueue.Dequeue() : null; if (acceptEncoding == null) { - throw new InvalidOperationException("cannot send more responses than requests"); + ThrowHelper.ThrowInvalidOperationException_CannotSendMore(); } } @@ -186,7 +199,7 @@ protected override void Encode(IChannelHandlerContext ctx, IHttpObject msg, List EnsureContent(msg); output.Add(ReferenceCountUtil.Retain(msg)); // Passed through all following contents of the current response. - if (msg is ILastHttpContent) + if (lastContent != null) { this.state = State.AwaitHeaders; } @@ -219,24 +232,40 @@ void EncodeFullResponse(IHttpResponse newRes, IHttpContent content, IList - code < 200 || code == 204 || code == 304 - || (ReferenceEquals(httpMethod, ZeroLengthHead) || ReferenceEquals(httpMethod, ZeroLengthConnect) && code == 200) - || ReferenceEquals(version, HttpVersion.Http10); + static bool IsPassthru(HttpVersion version, int code, ICharSequence httpMethod) + { + switch (code) + { + case 204: + case 304: + return true; + case 200 when ReferenceEquals(httpMethod, ZeroLengthConnect): + return true; + default: + if (code < 200) { return true; } + break; + } + return ReferenceEquals(httpMethod, ZeroLengthHead) || ReferenceEquals(version, HttpVersion.Http10); + //return code < 200 || code == 204 || code == 304 + // || (ReferenceEquals(httpMethod, ZeroLengthHead) || ReferenceEquals(httpMethod, ZeroLengthConnect) && code == 200) + // || ReferenceEquals(version, HttpVersion.Http10); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] static void EnsureHeaders(IHttpObject msg) { if (!(msg is IHttpResponse)) { - throw new CodecException($"unexpected message type: {msg.GetType().Name} (expected: {StringUtil.SimpleClassName()})"); + ThrowHelper.ThrowCodecException_EnsureHeaders(msg); } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] static void EnsureContent(IHttpObject msg) { if (!(msg is IHttpContent)) { - throw new CodecException($"unexpected message type: {msg.GetType().Name} (expected: {StringUtil.SimpleClassName()})"); + ThrowHelper.ThrowCodecException_EnsureContent(msg); } } @@ -322,7 +351,7 @@ void FinishEncode(IList output) void FetchEncoderOutput(ICollection output) { - for (;;) + while(true) { var buf = this.encoder.ReadOutbound(); if (buf == null) diff --git a/src/DotNetty.Codecs.Http/HttpMethod.cs b/src/DotNetty.Codecs.Http/HttpMethod.cs index edef2dcec..8a9693e9f 100644 --- a/src/DotNetty.Codecs.Http/HttpMethod.cs +++ b/src/DotNetty.Codecs.Http/HttpMethod.cs @@ -194,7 +194,7 @@ public HttpMethod(string name) name = name.Trim(); if (string.IsNullOrEmpty(name)) { - throw new ArgumentException(nameof(name)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); } for (int i=0; i this.name.ToString(); diff --git a/src/DotNetty.Codecs.Http/HttpObjectAggregator.cs b/src/DotNetty.Codecs.Http/HttpObjectAggregator.cs index fbbfc41ee..c6e08c9b4 100644 --- a/src/DotNetty.Codecs.Http/HttpObjectAggregator.cs +++ b/src/DotNetty.Codecs.Http/HttpObjectAggregator.cs @@ -111,16 +111,15 @@ protected override IFullHttpMessage BeginAggregation(IHttpMessage start, IByteBu HttpUtil.SetTransferEncodingChunked(start, false); - if (start is IHttpRequest request) + switch (start) { - return new AggregatedFullHttpRequest(request, content, null); + case IHttpRequest request: + return new AggregatedFullHttpRequest(request, content, null); + case IHttpResponse response: + return new AggregatedFullHttpResponse(response, content, null); + default: + return ThrowHelper.ThrowCodecException_InvalidType(start); } - else if (start is IHttpResponse response) - { - return new AggregatedFullHttpResponse(response, content, null); - } - - throw new CodecException($"Invalid type {StringUtil.SimpleClassName(start)} expecting {nameof(IHttpRequest)} or {nameof(IHttpResponse)}"); } protected override void Aggregate(IFullHttpMessage aggregated, IHttpContent content) @@ -163,7 +162,7 @@ protected override void HandleOversizedMessage(IChannelHandlerContext ctx, IHttp { if (t.IsFaulted) { - Logger.Debug("Failed to send a 413 Request Entity Too Large.", t.Exception); + if (Logger.DebugEnabled) Logger.FailedToSendA413RequestEntityTooLarge(t); } ((IChannelHandlerContext)s).CloseAsync(); }, @@ -176,7 +175,7 @@ protected override void HandleOversizedMessage(IChannelHandlerContext ctx, IHttp { if (t.IsFaulted) { - Logger.Debug("Failed to send a 413 Request Entity Too Large.", t.Exception); + if (Logger.DebugEnabled) Logger.FailedToSendA413RequestEntityTooLarge(t); ((IChannelHandlerContext)s).CloseAsync(); } }, @@ -191,11 +190,11 @@ protected override void HandleOversizedMessage(IChannelHandlerContext ctx, IHttp else if (oversized is IHttpResponse) { ctx.CloseAsync(); - throw new TooLongFrameException($"Response entity too large: {oversized}"); + ThrowHelper.ThrowTooLongFrameException_ResponseTooLarge(oversized); } else { - throw new InvalidOperationException($"Invalid type {StringUtil.SimpleClassName(oversized)}, expecting {nameof(IHttpRequest)} or {nameof(IHttpResponse)}"); + ThrowHelper.ThrowInvalidOperationException_InvalidType(oversized); } } diff --git a/src/DotNetty.Codecs.Http/HttpObjectDecoder.cs b/src/DotNetty.Codecs.Http/HttpObjectDecoder.cs index 2521b426b..62fff47a2 100644 --- a/src/DotNetty.Codecs.Http/HttpObjectDecoder.cs +++ b/src/DotNetty.Codecs.Http/HttpObjectDecoder.cs @@ -152,7 +152,7 @@ protected override void Decode(IChannelHandlerContext context, IByteBuffer buffe { if (!this.chunkedSupported) { - throw new ArgumentException("Chunked messages not supported"); + ThrowHelper.ThrowArgumentException_ChunkedMsgNotSupported(); } // Chunked encoding - generate HttpMessage first. HttpChunks will follow. output.Add(this.message); diff --git a/src/DotNetty.Codecs.Http/HttpObjectEncoder.cs b/src/DotNetty.Codecs.Http/HttpObjectEncoder.cs index 1dfd0b00c..f07403ad7 100644 --- a/src/DotNetty.Codecs.Http/HttpObjectEncoder.cs +++ b/src/DotNetty.Codecs.Http/HttpObjectEncoder.cs @@ -39,7 +39,7 @@ protected override void Encode(IChannelHandlerContext context, object message, L { if (this.state != StInit) { - throw new InvalidOperationException($"unexpected message type: {StringUtil.SimpleClassName(message)}"); + ThrowHelper.ThrowInvalidOperationException_UnexpectedMsg(message); } var m = (T)message; @@ -73,80 +73,84 @@ protected override void Encode(IChannelHandlerContext context, object message, L } } - if (message is IHttpContent || message is IByteBuffer || message is IFileRegion) + switch (message) { - switch (this.state) - { - case StInit: - throw new InvalidOperationException($"unexpected message type: {StringUtil.SimpleClassName(message)}"); - case StContentNonChunk: - long contentLength = ContentLength(message); - if (contentLength > 0) - { - if (buf != null && buf.WritableBytes >= contentLength && message is IHttpContent) + case IHttpContent _: + case IByteBuffer _: + case IFileRegion _: + switch (this.state) + { + case StInit: + ThrowHelper.ThrowInvalidOperationException_UnexpectedMsg(message); break; + case StContentNonChunk: + long contentLength = ContentLength(message); + if (contentLength > 0) { - // merge into other buffer for performance reasons - buf.WriteBytes(((IHttpContent)message).Content); + if (buf != null && buf.WritableBytes >= contentLength && message is IHttpContent) + { + // merge into other buffer for performance reasons + buf.WriteBytes(((IHttpContent)message).Content); + output.Add(buf); + } + else + { + if (buf != null) + { + output.Add(buf); + } + output.Add(EncodeAndRetain(message)); + } + + if (message is ILastHttpContent) + { + this.state = StInit; + } + break; + } + + goto case StContentAlwaysEmpty; // fall-through! + case StContentAlwaysEmpty: + // ReSharper disable once ConvertIfStatementToNullCoalescingExpression + if (buf != null) + { + // We allocated a buffer so add it now. output.Add(buf); } else { - if (buf != null) - { - output.Add(buf); - } - output.Add(EncodeAndRetain(message)); + // Need to produce some output otherwise an + // IllegalStateException will be thrown as we did not write anything + // Its ok to just write an EMPTY_BUFFER as if there are reference count issues these will be + // propagated as the caller of the encode(...) method will release the original + // buffer. + // Writing an empty buffer will not actually write anything on the wire, so if there is a user + // error with msg it will not be visible externally + output.Add(Unpooled.Empty); } - if (message is ILastHttpContent) + break; + case StContentChunk: + if (buf != null) { - this.state = StInit; + // We allocated a buffer so add it now. + output.Add(buf); } + this.EncodeChunkedContent(context, message, ContentLength(message), output); + break; - } - - goto case StContentAlwaysEmpty; // fall-through! - case StContentAlwaysEmpty: - // ReSharper disable once ConvertIfStatementToNullCoalescingExpression - if (buf != null) - { - // We allocated a buffer so add it now. - output.Add(buf); - } - else - { - // Need to produce some output otherwise an - // IllegalStateException will be thrown as we did not write anything - // Its ok to just write an EMPTY_BUFFER as if there are reference count issues these will be - // propagated as the caller of the encode(...) method will release the original - // buffer. - // Writing an empty buffer will not actually write anything on the wire, so if there is a user - // error with msg it will not be visible externally - output.Add(Unpooled.Empty); - } - - break; - case StContentChunk: - if (buf != null) - { - // We allocated a buffer so add it now. - output.Add(buf); - } - this.EncodeChunkedContent(context, message, ContentLength(message), output); - - break; - default: - throw new EncoderException($"unexpected state {this.state}: {StringUtil.SimpleClassName(message)}"); - } + default: + ThrowHelper.ThrowEncoderException_UnexpectedState(this.state, message); break; + } - if (message is ILastHttpContent) - { - this.state = StInit; - } - } - else if (buf != null) - { - output.Add(buf); + if (message is ILastHttpContent) + { + this.state = StInit; + } + break; + + default: + output.Add(buf); + break; } } @@ -205,40 +209,47 @@ protected virtual void SanitizeHeadersBeforeEncode(T msg, bool isAlwaysEmpty) protected virtual bool IsContentAlwaysEmpty(T msg) => false; - public override bool AcceptOutboundMessage(object msg) => msg is IHttpObject || msg is IByteBuffer || msg is IFileRegion; - - static object EncodeAndRetain(object message) + public override bool AcceptOutboundMessage(object msg) { - if (message is IByteBuffer buffer) + switch (msg) { - return buffer.Retain(); + case IHttpObject _: + case IByteBuffer _: + case IFileRegion _: + return true; + default: + return false; } - if (message is IHttpContent content) - { - return content.Content.Retain(); - } - if (message is IFileRegion region) + } + + static object EncodeAndRetain(object message) + { + switch (message) { - return region.Retain(); + case IByteBuffer buffer: + return buffer.Retain(); + case IHttpContent content: + return content.Content.Retain(); + case IFileRegion region: + return region.Retain(); + default: + ThrowHelper.ThrowInvalidOperationException_UnexpectedMsg(message); return null; } - throw new InvalidOperationException($"unexpected message type: {StringUtil.SimpleClassName(message)}"); } static long ContentLength(object message) { - if (message is IHttpContent content) - { - return content.Content.ReadableBytes; - } - if (message is IByteBuffer buffer) - { - return buffer.ReadableBytes; - } - if (message is IFileRegion region) + switch (message) { - return region.Count; + case IHttpContent content: + return content.Content.ReadableBytes; + case IByteBuffer buffer: + return buffer.ReadableBytes; + case IFileRegion region: + return region.Count; + default: + ThrowHelper.ThrowInvalidOperationException_UnexpectedMsg(message); return default; } - throw new InvalidOperationException($"unexpected message type: {StringUtil.SimpleClassName(message)}"); } // Add some additional overhead to the buffer. The rational is that it is better to slightly over allocate and waste diff --git a/src/DotNetty.Codecs.Http/HttpResponseStatus.cs b/src/DotNetty.Codecs.Http/HttpResponseStatus.cs index e8c24f760..94290afd0 100644 --- a/src/DotNetty.Codecs.Http/HttpResponseStatus.cs +++ b/src/DotNetty.Codecs.Http/HttpResponseStatus.cs @@ -448,7 +448,7 @@ public static HttpResponseStatus ParseLine(string line) } catch (Exception e) { - throw new ArgumentException($"malformed status line: {line}", e); + return ThrowHelper.ThrowArgumentException_ParseLine(line, e); } } @@ -463,7 +463,7 @@ public static HttpResponseStatus ParseLine(AsciiString line) } catch (Exception e) { - throw new ArgumentException($"malformed status line: {line}", e); + return ThrowHelper.ThrowArgumentException_ParseLine(line, e); } } @@ -489,11 +489,11 @@ public HttpResponseStatus(int code, AsciiString reasonPhrase, bool bytes) { if (code < 0) { - throw new ArgumentException($"code: {code} (expected: 0+)"); + ThrowHelper.ThrowArgumentException_InvalidResponseCode(code); } if (reasonPhrase == null) { - throw new ArgumentException(nameof(reasonPhrase)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.reasonPhrase); } // ReSharper disable once ForCanBeConvertedToForeach @@ -505,7 +505,7 @@ public HttpResponseStatus(int code, AsciiString reasonPhrase, bool bytes) { case '\n': case '\r': - throw new ArgumentException($"reasonPhrase contains one of the following prohibited characters: \\r\\n: {reasonPhrase}"); + ThrowHelper.ThrowArgumentException_ReasonPhrase(reasonPhrase); break; } } @@ -528,11 +528,11 @@ public HttpResponseStatus(int code, AsciiString reasonPhrase, bool bytes) public override bool Equals(object obj) { - if (!(obj is HttpResponseStatus other)) + if (obj is HttpResponseStatus other) { - return false; + return this.code == other.code; } - return this.code == other.code; + return false; } public int CompareTo(HttpResponseStatus other) => this.code - other.code; diff --git a/src/DotNetty.Codecs.Http/HttpScheme.cs b/src/DotNetty.Codecs.Http/HttpScheme.cs index 9bba09bf1..d31aff24d 100644 --- a/src/DotNetty.Codecs.Http/HttpScheme.cs +++ b/src/DotNetty.Codecs.Http/HttpScheme.cs @@ -30,12 +30,12 @@ public sealed class HttpScheme public override bool Equals(object obj) { - if (!(obj is HttpScheme other)) + if (obj is HttpScheme other) { - return false; + return other.port == this.port && other.name.Equals(this.name); } - return other.port == this.port && other.name.Equals(this.name); + return false; } public override int GetHashCode() => this.port * 31 + this.name.GetHashCode(); diff --git a/src/DotNetty.Codecs.Http/HttpStatusClass.cs b/src/DotNetty.Codecs.Http/HttpStatusClass.cs index 73f5dd026..83d2d10af 100644 --- a/src/DotNetty.Codecs.Http/HttpStatusClass.cs +++ b/src/DotNetty.Codecs.Http/HttpStatusClass.cs @@ -90,7 +90,7 @@ public static bool Contains(HttpStatusClass httpStatusClass, int code) public bool Equals(HttpStatusClass other) => this.min == other.min && this.max == other.max; - public override bool Equals(object obj) => obj is HttpStatusClass && this.Equals((HttpStatusClass)obj); + public override bool Equals(object obj) => obj is HttpStatusClass httpStatusClass && this.Equals(httpStatusClass); public override int GetHashCode() => this.min.GetHashCode() ^ this.max.GetHashCode(); diff --git a/src/DotNetty.Codecs.Http/HttpUtil.cs b/src/DotNetty.Codecs.Http/HttpUtil.cs index 54bc86a8b..ab8a96446 100644 --- a/src/DotNetty.Codecs.Http/HttpUtil.cs +++ b/src/DotNetty.Codecs.Http/HttpUtil.cs @@ -75,7 +75,7 @@ public static long GetContentLength(IHttpMessage message) } // Otherwise we don't. - throw new FormatException($"header not found: {HttpHeaderNames.ContentLength}"); + return ThrowHelper.ThrowFormatException_HeaderNotFound(); } public static long GetContentLength(IHttpMessage message, long defaultValue) @@ -104,23 +104,25 @@ static int GetWebSocketContentLength(IHttpMessage message) { // WebSocket messages have constant content-lengths. HttpHeaders h = message.Headers; - if (message is IHttpRequest req) + switch (message) { - if (HttpMethod.Get.Equals(req.Method) - && h.Contains(HttpHeaderNames.SecWebsocketKey1) - && h.Contains(HttpHeaderNames.SecWebsocketKey2)) - { - return 8; - } - } - else if (message is IHttpResponse res) - { - if (res.Status.Code == 101 - && h.Contains(HttpHeaderNames.SecWebsocketOrigin) - && h.Contains(HttpHeaderNames.SecWebsocketLocation)) - { - return 16; - } + case IHttpRequest req: + if (HttpMethod.Get.Equals(req.Method) + && h.Contains(HttpHeaderNames.SecWebsocketKey1) + && h.Contains(HttpHeaderNames.SecWebsocketKey2)) + { + return 8; + } + break; + + case IHttpResponse res: + if (res.Status.Code == 101 + && h.Contains(HttpHeaderNames.SecWebsocketOrigin) + && h.Contains(HttpHeaderNames.SecWebsocketLocation)) + { + return 16; + } + break; } // Not a web socket message @@ -252,7 +254,7 @@ public static ICharSequence GetCharsetAsSequence(ICharSequence contentTypeValue) { if (contentTypeValue == null) { - throw new ArgumentException(nameof(contentTypeValue)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.contentTypeValue); } int indexOfCharset = AsciiString.IndexOfIgnoreCaseAscii(contentTypeValue, CharsetEquals, 0); if (indexOfCharset != AsciiString.IndexNotFound) @@ -273,7 +275,7 @@ public static ICharSequence GetMimeType(ICharSequence contentTypeValue) { if (contentTypeValue == null) { - throw new ArgumentException(nameof(contentTypeValue)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.contentTypeValue); } int indexOfSemicolon = AsciiString.IndexOfIgnoreCaseAscii(contentTypeValue, Semicolon, 0); if (indexOfSemicolon != AsciiString.IndexNotFound) diff --git a/src/DotNetty.Codecs.Http/HttpVersion.cs b/src/DotNetty.Codecs.Http/HttpVersion.cs index e128fb34c..99cd540b2 100644 --- a/src/DotNetty.Codecs.Http/HttpVersion.cs +++ b/src/DotNetty.Codecs.Http/HttpVersion.cs @@ -105,16 +105,16 @@ public HttpVersion(string text, bool keepAliveDefault) { Contract.Requires(text != null); - text = text.Trim().ToUpper(); + text = text.Trim().ToUpperInvariant(); if (string.IsNullOrEmpty(text)) { - throw new ArgumentException("empty text"); + ThrowHelper.ThrowArgumentException_Empty(ExceptionArgument.text); } Match match = VersionPattern.Match(text); if (!match.Success) { - throw new ArgumentException($"invalid version format: {text}"); + ThrowHelper.ThrowArgumentException_InvalidVersion(text); } this.protocolName = match.Groups[1].Value; @@ -129,13 +129,13 @@ public HttpVersion(string text, bool keepAliveDefault) { if (protocolName == null) { - throw new ArgumentException(nameof(protocolName)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.protocolName); } - protocolName = protocolName.Trim().ToUpper(); + protocolName = protocolName.Trim().ToUpperInvariant(); if (string.IsNullOrEmpty(protocolName)) { - throw new ArgumentException("empty protocolName"); + ThrowHelper.ThrowArgumentException_Empty(ExceptionArgument.protocolName); } // ReSharper disable once ForCanBeConvertedToForeach @@ -144,17 +144,17 @@ public HttpVersion(string text, bool keepAliveDefault) char c = protocolName[i]; if (CharUtil.IsISOControl(c) || char.IsWhiteSpace(c)) { - throw new ArgumentException($"invalid character {c} in protocolName"); + ThrowHelper.ThrowArgumentException_InvalidProtocolName(c); } } if (majorVersion < 0) { - throw new ArgumentException("negative majorVersion"); + ThrowHelper.ThrowArgumentException_NegativeVersion(ExceptionArgument.majorVersion); } if (minorVersion < 0) { - throw new ArgumentException("negative minorVersion"); + ThrowHelper.ThrowArgumentException_NegativeVersion(ExceptionArgument.minorVersion); } this.protocolName = protocolName; @@ -182,14 +182,14 @@ public HttpVersion(string text, bool keepAliveDefault) public override bool Equals(object obj) { - if (!(obj is HttpVersion that)) + if (obj is HttpVersion that) { - return false; + return this.minorVersion == that.minorVersion + && this.majorVersion == that.majorVersion + && string.Equals(this.protocolName, that.protocolName, StringComparison.Ordinal); } - return this.minorVersion == that.minorVersion - && this.majorVersion == that.majorVersion - && this.protocolName.Equals(that.protocolName); + return false; } public int CompareTo(HttpVersion other) @@ -216,12 +216,12 @@ public int CompareTo(object obj) return 0; } - if (!(obj is HttpVersion)) + if (obj is HttpVersion httpVersion) { - throw new ArgumentException($"{nameof(obj)} must be of {nameof(HttpVersion)} type"); + return this.CompareTo(httpVersion); } - return this.CompareTo((HttpVersion)obj); + return ThrowHelper.ThrowArgumentException_CompareToHttpVersion(); } internal void Encode(IByteBuffer buf) diff --git a/src/DotNetty.Codecs.Http/Internal/LoggingExtensions.cs b/src/DotNetty.Codecs.Http/Internal/LoggingExtensions.cs new file mode 100644 index 000000000..649ad27d1 --- /dev/null +++ b/src/DotNetty.Codecs.Http/Internal/LoggingExtensions.cs @@ -0,0 +1,139 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.IO; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using DotNetty.Common.Concurrency; +using DotNetty.Common.Internal.Logging; +using DotNetty.Common.Utilities; +using DotNetty.Codecs.Http.Cors; +using DotNetty.Codecs.Http.WebSockets; +using DotNetty.Transport.Channels; + +namespace DotNetty.Codecs.Http +{ + internal static class HttpLoggingExtensions + { + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SkippingCookieWithNullName(this IInternalLogger logger) + { + logger.Debug("Skipping cookie with null name"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SkippingCookieWithNullValue(this IInternalLogger logger) + { + logger.Debug("Skipping cookie with null value"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SkippingCookieBecauseStartingQuotesAreNotProperlyBalancedIn(this IInternalLogger logger, StringCharSequence sequence) + { + logger.Debug("Skipping cookie because starting quotes are not properly balanced in '{}'", sequence); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SkippingCookieBecauseNameContainsInvalidChar(this IInternalLogger logger, string name, int index) + { + logger.Debug("Skipping cookie because name '{}' contains invalid char '{}'", name, name[index]); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void SkippingCookieBecauseValueContainsInvalidChar(this IInternalLogger logger, ICharSequence value, int index) + { + logger.Debug("Skipping cookie because value '{}' contains invalid char '{}'", value, value[index]); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void RequestOriginWasNotAmongTheConfiguredOrigins(this IInternalLogger logger, ICharSequence origin, CorsConfig config) + { + logger.Debug("Request origin [{}]] was not among the configured origins [{}]", origin, config.Origins); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void DecodingWebSocketFrameOpCode(this IInternalLogger logger, int frameOpcode) + { + logger.Debug("Decoding WebSocket Frame opCode={}", frameOpcode); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void DecodingWebSocketFrameLength(this IInternalLogger logger, long framePayloadLength) + { + logger.Debug("Decoding WebSocket Frame length={}", framePayloadLength); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void EncodingWebSocketFrameOpCode(this IInternalLogger logger, byte opcode, int length) + { + logger.Debug($"Encoding WebSocket Frame opCode={opcode} length={length}"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void WebSocketVersion07ClientHandshakeKey(this IInternalLogger logger, string key, AsciiString expectedChallengeResponseString) + { + logger.Debug("WebSocket version 07 client handshake key: {}, expected response: {}", key, expectedChallengeResponseString); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void WebSocketVersion08ClientHandshakeKey(this IInternalLogger logger, string key, AsciiString expectedChallengeResponseString) + { + logger.Debug("WebSocket version 08 client handshake key: {}, expected response: {}", key, expectedChallengeResponseString); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void WebSocketVersion13ClientHandshakeKey(this IInternalLogger logger, string key, AsciiString expectedChallengeResponseString) + { + logger.Debug("WebSocket version 13 client handshake key: {}, expected response: {}", key, expectedChallengeResponseString); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void WebSocketVersionServerHandshake(this IInternalLogger logger, IChannel channel, WebSocketVersion version) + { + logger.Debug("{} WebSocket version {} server handshake", channel, version); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void RequestedSubprotocolNotSupported(this IInternalLogger logger, ICharSequence subprotocols) + { + logger.Debug("Requested subprotocol(s) not supported: {}", subprotocols); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void WebSocketVersion07ServerHandshakeKey(this IInternalLogger logger, ICharSequence key, string accept) + { + logger.Debug("WebSocket version 07 server handshake key: {}, response: {}.", key, accept); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void WebSocketVersion08ServerHandshakeKey(this IInternalLogger logger, ICharSequence key, string accept) + { + logger.Debug("WebSocket version 08 server handshake key: {}, response: {}.", key, accept); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void WebSocketVersion13ServerHandshakeKey(this IInternalLogger logger, ICharSequence key, string accept) + { + logger.Debug("WebSocket version 13 server handshake key: {}, response: {}.", key, accept); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToSendA413RequestEntityTooLarge(this IInternalLogger logger, Task t) + { + logger.Debug("Failed to send a 413 Request Entity Too Large.", t.Exception); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToDelete(this IInternalLogger logger, FileStream fileStream, Exception error) + { + logger.Warn("Failed to delete: {} {}", fileStream, error); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToDeleteFile(this IInternalLogger logger, Exception error) + { + logger.Warn("Failed to delete file.", error); + } + } +} diff --git a/src/DotNetty.Codecs.Http/Internal/SR.cs b/src/DotNetty.Codecs.Http/Internal/SR.cs new file mode 100644 index 000000000..95b3526f1 --- /dev/null +++ b/src/DotNetty.Codecs.Http/Internal/SR.cs @@ -0,0 +1,53 @@ +using System; +using System.Resources; + +namespace DotNetty.Codecs.Http.Internal +{ + internal sealed partial class SR : Strings + { + // Needed for debugger integration + internal static string GetResourceString(string resourceKey) + { + return GetResourceString(resourceKey, String.Empty); + } + + internal static string GetResourceString(string resourceKey, string defaultString) + { + string resourceString = null; + try { resourceString = ResourceManager.GetString(resourceKey, null); } + catch (MissingManifestResourceException) { } + + if (defaultString != null && resourceKey.Equals(resourceString, StringComparison.Ordinal)) + { + return defaultString; + } + + return resourceString; + } + + internal static string Format(string resourceFormat, params object[] args) + { + if (args != null) + { + return String.Format(resourceFormat, args); + } + + return resourceFormat; + } + + internal static string Format(string resourceFormat, object p1) + { + return String.Format(resourceFormat, p1); + } + + internal static string Format(string resourceFormat, object p1, object p2) + { + return String.Format(resourceFormat, p1, p2); + } + + internal static string Format(string resourceFormat, object p1, object p2, object p3) + { + return String.Format(resourceFormat, p1, p2, p3); + } + } +} diff --git a/src/DotNetty.Codecs.Http/Internal/Strings.Designer.cs b/src/DotNetty.Codecs.Http/Internal/Strings.Designer.cs new file mode 100644 index 000000000..6c25a424f --- /dev/null +++ b/src/DotNetty.Codecs.Http/Internal/Strings.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// 此代码由工具生成。 +// 运行时版本:4.0.30319.42000 +// +// 对此文件的更改可能会导致不正确的行为,并且如果 +// 重新生成代码,这些更改将会丢失。 +// +//------------------------------------------------------------------------------ + +namespace DotNetty.Codecs.Http.Internal { + using System; + + + /// + /// 一个强类型的资源类,用于查找本地化的字符串等。 + /// + // 此类是由 StronglyTypedResourceBuilder + // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 + // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen + // (以 /str 作为命令选项),或重新生成 VS 项目。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Strings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Strings() { + } + + /// + /// 返回此类使用的缓存的 ResourceManager 实例。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetty.Codecs.Http.Internal.Strings", typeof(Strings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 使用此强类型资源类,为所有资源查找 + /// 重写当前线程的 CurrentUICulture 属性。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/src/DotNetty.Codecs.Http/Internal/Strings.resx b/src/DotNetty.Codecs.Http/Internal/Strings.resx new file mode 100644 index 000000000..1af7de150 --- /dev/null +++ b/src/DotNetty.Codecs.Http/Internal/Strings.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/DotNetty.Codecs.Http/Internal/ThrowHelper.Extensions.cs b/src/DotNetty.Codecs.Http/Internal/ThrowHelper.Extensions.cs new file mode 100644 index 000000000..c0bff0039 --- /dev/null +++ b/src/DotNetty.Codecs.Http/Internal/ThrowHelper.Extensions.cs @@ -0,0 +1,1162 @@ +using System; +using System.IO; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using DotNetty.Codecs; +using DotNetty.Codecs.Compression; +using DotNetty.Codecs.Http.Cookies; +using DotNetty.Codecs.Http.Multipart; +using DotNetty.Codecs.Http.WebSockets; +using DotNetty.Common.Utilities; +using DotNetty.Transport.Channels; + +namespace DotNetty.Codecs.Http +{ + #region -- ExceptionArgument -- + + /// The convention for this enum is using the argument name as the enum name + internal enum ExceptionArgument + { + array, + assembly, + buffer, + destination, + key, + obj, + s, + str, + source, + type, + types, + value, + values, + valueFactory, + name, + item, + options, + list, + ts, + other, + pool, + inner, + policy, + offset, + count, + path, + typeInfo, + method, + qualifiedTypeName, + fullName, + feature, + manager, + directories, + dirEnumArgs, + asm, + includedAssemblies, + func, + defaultFn, + returnType, + propertyInfo, + parameterTypes, + fieldInfo, + memberInfo, + attributeType, + pi, + fi, + invoker, + instanceType, + target, + member, + typeName, + predicate, + assemblyPredicate, + collection, + capacity, + match, + index, + length, + startIndex, + newSize, + expression, + contentTypeValue, + text, + protocolName, + preferredClientWindowSize, + requestedServerWindowSize, + reasonPhrase, + majorVersion, + minorVersion, + HttpPostMultipartRequestDecoder, + HttpPostStandardRequestDecoder, + ReadDelimiter, + ReadDelimiterStandard, + } + + #endregion + + #region -- ExceptionResource -- + + /// The convention for this enum is using the resource name as the enum name + internal enum ExceptionResource + { + } + + #endregion + + partial class ThrowHelper + { + #region -- Exception -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowException_FrameDecoder() + { + throw GetException(); + Exception GetException() + { + return new Exception("Shouldn't reach here."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static WebSocketFrame ThrowException_UnkonwFrameType() + { + throw GetException(); + Exception GetException() + { + return new Exception("Unkonw WebSocketFrame type, must be either TextWebSocketFrame or BinaryWebSocketFrame"); + } + } + + #endregion + + #region -- ArgumentException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_Empty(ExceptionArgument argument) + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException("empty " + GetArgumentName(argument)); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_NegativeVersion(ExceptionArgument argument) + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException("negative " + GetArgumentName(argument)); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_DiffArrayLen() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("Different array length"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_BufferNoBacking() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("buffer hasn't backing byte array"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_FileTooBig() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("File too big to be loaded in memory"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_CookieName(string name, int pos) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"Cookie name contains an invalid char: {name[pos]}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_CookieValue(string value) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"Cookie value wrapping quotes are not balanced: {value}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_CookieValue(string value, int pos) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"Cookie value contains an invalid char: {value[pos]}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_ValidateAttrValue(string name, string value, int index) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"{name} contains the prohibited characters: ${value[index]}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowArgumentException_CompareToCookie() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"obj must be of {nameof(ICookie)} type"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowArgumentException_CompareToHttpVersion() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"obj must be of {nameof(HttpVersion)} type"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowArgumentException_CompareToHttpData(HttpDataType x, HttpDataType y) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"Cannot compare {x} with {y}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_Stream_NotReadable() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"inputStream is not readable"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_Stream_NotWritable() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"destination is not writable"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_AttrBigger() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("Attribute bigger than maxSize allowed"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_TextFrame() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("a text frame should not contain 0xFF."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_HeadCantAddSelf() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("can't add to itself."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_ChunkedMsgNotSupported() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("Chunked messages not supported"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_InvalidMethodName(char c, string name) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"Invalid character '{c}' in {name}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_CompressionLevel(int compressionLevel) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"compressionLevel: {compressionLevel} (expected: 0-9)"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_WindowSize(ExceptionArgument argument, int windowSize) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"{GetArgumentName(argument)}: {windowSize} (expected: 8-15)"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_InvalidResponseCode(int code) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"code: {code} (expected: 0+)"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static HttpResponseStatus ThrowArgumentException_ParseLine(T line, Exception e) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"malformed status line: {line}", e); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_ReasonPhrase(AsciiString reasonPhrase) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"reasonPhrase contains one of the following prohibited characters: \\r\\n: {reasonPhrase}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_InvalidVersion(string text) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"invalid version format: {text}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_InvalidProtocolName(char c) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"invalid character {c} in protocolName"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_UnterminatedEscapeSeq(int index, string s) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"unterminated escape sequence at index {index} of: {s}"); + } + } + + #endregion + + #region -- IOException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowIOException_CheckSize() + { + throw GetException(); + IOException GetException() + { + return new IOException("Size exceed allowed maximum capacity"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowIOException_CheckSize(HttpDataType dataType) + { + throw GetException(); + IOException GetException() + { + return new IOException($"{dataType} Size exceed allowed maximum capacity"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowIOException_CheckSize(long maxSize) + { + throw GetException(); + IOException GetException() + { + return new IOException($"Size exceed allowed maximum capacity of {maxSize}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowIOException_OutOfSize(long size, long definedSize) + { + throw GetException(); + IOException GetException() + { + return new IOException($"Out of size: {size} > {definedSize}"); + } + } + + #endregion + + #region -- InvalidOperationException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_HttpRequestEncoder() + { + throw GetInvalidOperationException(); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static Task ThrowInvalidOperationException_HttpResponseDecoder() + { + return TaskUtil.FromException(GetInvalidOperationException()); + } + + internal static InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException($"ChannelPipeline does not contain a {typeof(T).Name} or HttpClientCodec"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static Task ThrowInvalidOperationException_NoHttpDecoderAndServerCodec() + { + return TaskUtil.FromException(GetInvalidOperationException_NoHttpDecoderAndServerCodec()); + } + + internal static InvalidOperationException GetInvalidOperationException_NoHttpDecoderAndServerCodec() + { + return new InvalidOperationException("No HttpDecoder and no HttpServerCodec in the pipeline"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static Task ThrowInvalidOperationException_Attempting() + { + return TaskUtil.FromException(GetException()); + InvalidOperationException GetException() + { + return new InvalidOperationException("Attempting to write HTTP request with upgrade in progress"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static object ThrowInvalidOperationException_Cqrs(object callable, Exception exception) + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException($"Could not generate value for callable [{callable}]", exception); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_NoMoreElement() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("No more element to iterate"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_WebSocketClientHandshaker() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("WebSocketClientHandshaker should have been finished yet"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_UnknownWebSocketVersion() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("Unknown web socket version"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_OnlyHaveOneValue() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException($"{nameof(CombinedHttpHeaders)} should only have one value"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_NoFileDefined() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("No file defined so cannot be renamed"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_CannotSendMore() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("cannot send more responses than requests"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_ReadHttpResponse() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("Read HTTP response without requesting protocol switch"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_CheckDestroyed() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException($"{StringUtil.SimpleClassName()} was destroyed already"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_UnexpectedMsg(object message) + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException($"unexpected message type: {StringUtil.SimpleClassName(message)}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_InvalidType(IHttpMessage oversized) + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException($"Invalid type {StringUtil.SimpleClassName(oversized)}, expecting {nameof(IHttpRequest)} or {nameof(IHttpResponse)}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_UnexpectedUpgradeProtocol(ICharSequence upgradeHeader) + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException($"Switching Protocols response with unexpected UPGRADE protocol: {upgradeHeader}"); + } + } + + #endregion + + #region -- ChannelException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowChannelException_IO(IOException e) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException(e); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static T ThrowChannelException_IO(IOException e) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException(e); + } + } + + #endregion + + #region -- EncoderException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowEncoderException_UnexpectedState(int state, object message) + { + throw GetException(); + EncoderException GetException() + { + return new EncoderException($"unexpected state {state}: {StringUtil.SimpleClassName(message)}"); + } + } + + #endregion + + #region -- FormatException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static long ThrowFormatException_HeaderNotFound() + { + throw GetException(); + FormatException GetException() + { + return new FormatException($"header not found: {HttpHeaderNames.ContentLength}"); + } + } + + #endregion + + #region -- TooLongFrameException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowTooLongFrameException_WebSocket00FrameDecoder() + { + throw GetException(); + TooLongFrameException GetException() + { + return new TooLongFrameException(nameof(WebSocket00FrameDecoder)); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowTooLongFrameException_ResponseTooLarge(IHttpMessage oversized) + { + throw GetException(); + TooLongFrameException GetException() + { + return new TooLongFrameException($"Response entity too large: {oversized}"); + } + } + + #endregion + + #region -- NotEnoughDataDecoderException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowNotEnoughDataDecoderException(ExceptionArgument argument) + { + throw GetException(); + NotEnoughDataDecoderException GetException() + { + return new NotEnoughDataDecoderException(GetArgumentName(argument)); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowNotEnoughDataDecoderException(Exception e) + { + throw GetException(); + NotEnoughDataDecoderException GetException() + { + return new NotEnoughDataDecoderException(e); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowNotEnoughDataDecoderException_AccessOutOfBounds() + { + throw GetException(); + NotEnoughDataDecoderException GetException() + { + return new NotEnoughDataDecoderException("Access out of bounds"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static StringCharSequence ThrowNotEnoughDataDecoderException_ReadLineStandard() + { + throw GetException(); + NotEnoughDataDecoderException GetException() + { + return new NotEnoughDataDecoderException("ReadLineStandard"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static StringCharSequence ThrowNotEnoughDataDecoderException_ReadLine() + { + throw GetException(); + NotEnoughDataDecoderException GetException() + { + return new NotEnoughDataDecoderException("ReadLine"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static StringBuilderCharSequence ThrowNotEnoughDataDecoderException_ReadDelimiterStandard() + { + throw GetException(); + NotEnoughDataDecoderException GetException() + { + return new NotEnoughDataDecoderException("ReadDelimiterStandard"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static StringBuilderCharSequence ThrowNotEnoughDataDecoderException_ReadDelimiter() + { + throw GetException(); + NotEnoughDataDecoderException GetException() + { + return new NotEnoughDataDecoderException("ReadDelimiter"); + } + } + + #endregion + + #region -- ErrorDataDecoderException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException(Exception e) + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException(e); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_GetStatus() + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException("Should not be called with the current getStatus"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_Attr() + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException($"{HttpHeaderValues.Name} attribute cannot be null."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_NameAttr() + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException($"{HttpHeaderValues.Name} attribute cannot be null for file upload"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_FileNameAttr() + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException($"{HttpHeaderValues.FileName} attribute cannot be null for file upload"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_ReachHere() + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException("Shouldn't reach here."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_NoMultipartDelimiterFound() + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException("No Multipart delimiter found"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_MixedMultipartFound() + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException("Mixed Multipart found in a previous Mixed Multipart"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_UnknownParams(StringCharSequence newline) + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException($"Unknown Params: {newline}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_FileName() + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException("Filename not found"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_NeedBoundaryValue() + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException("Needs a boundary value"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_BadEndOfLine() + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException("Bad end of line"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static string ThrowErrorDataDecoderException_BadString(string s, Exception e) + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException($"Bad string: '{s}'", e); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataDecoderException_TransferEncoding(string code) + { + throw GetErrorDataDecoderException(); + ErrorDataDecoderException GetErrorDataDecoderException() + { + return new ErrorDataDecoderException("TransferEncoding Unknown: " + code); + } + } + + #endregion + + #region -- ErrorDataEncoderException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataEncoderException(Exception e) + { + throw GetErrorDataEncoderException(); + ErrorDataEncoderException GetErrorDataEncoderException() + { + return new ErrorDataEncoderException(e); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataEncoderException_HeaderAlreadyEncoded() + { + throw GetErrorDataEncoderException(); + ErrorDataEncoderException GetErrorDataEncoderException() + { + return new ErrorDataEncoderException("Header already encoded"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataEncoderException_CannotAddValue() + { + throw GetErrorDataEncoderException(); + ErrorDataEncoderException GetErrorDataEncoderException() + { + return new ErrorDataEncoderException("Cannot add value once finalized"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowErrorDataEncoderException_CannotCreate() + { + throw GetErrorDataEncoderException(); + ErrorDataEncoderException GetErrorDataEncoderException() + { + return new ErrorDataEncoderException("Cannot create a Encoder if request is a TRACE"); + } + } + + #endregion + + #region -- CodecException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static IFullHttpMessage ThrowCodecException_InvalidType(IHttpMessage start) + { + throw GetException(); + CodecException GetException() + { + return new CodecException($"Invalid type {StringUtil.SimpleClassName(start)} expecting {nameof(IHttpRequest)} or {nameof(IHttpResponse)}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowCodecException_EnsureContent(IHttpObject msg) + { + throw GetException(); + CodecException GetException() + { + return new CodecException($"unexpected message type: {msg.GetType().Name} (expected: {StringUtil.SimpleClassName()})"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowCodecException_EnsureHeaders(IHttpObject msg) + { + throw GetException(); + CodecException GetException() + { + return new CodecException($"unexpected message type: {msg.GetType().Name} (expected: {StringUtil.SimpleClassName()})"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowCodecException_InvalidHttpMsg(IHttpMessage httpMessage) + { + throw GetException(); + CodecException GetException() + { + return new CodecException($"Object of class {StringUtil.SimpleClassName(httpMessage.GetType())} is not a HttpRequest or HttpResponse"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowCodecException_InvalidCompression(ZlibWrapper mode) + { + throw GetException(); + CodecException GetException() + { + return new CodecException($"{mode} not supported, only Gzip and Zlib are allowed."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowCodecException_InvalidWSExHandshake(string extensionsHeader) + { + throw GetException(); + CodecException GetException() + { + return new CodecException($"invalid WebSocket Extension handshake for \"{extensionsHeader}\""); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowCodecException_UnexpectedFrameType(WebSocketFrame msg) + { + throw GetException(); + CodecException GetException() + { + return new CodecException($"unexpected frame type: {msg.GetType().Name}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowCodecException_CannotReadCompressedBuf() + { + throw GetException(); + CodecException GetException() + { + return new CodecException("cannot read compressed buffer"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowCodecException_CannotReadUncompressedBuf() + { + throw GetException(); + CodecException GetException() + { + return new CodecException("cannot read uncompressed buffer"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowCodecException_UnexpectedInitialFrameType(WebSocketFrame msg) + { + throw GetException(); + CodecException GetException() + { + return new CodecException($"unexpected initial frame type: {msg.GetType().Name}"); + } + } + + #endregion + + #region -- WebSocketHandshakeException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static WebSocketClientHandshaker ThrowWebSocketHandshakeException_InvalidVersion(WebSocketVersion version) + { + throw GetException(); + WebSocketHandshakeException GetException() + { + return new WebSocketHandshakeException($"Protocol version {version}not supported."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowWebSocketHandshakeException_InvalidSubprotocol(string receivedProtocol, string expectedSubprotocol) + { + throw GetException(); + WebSocketHandshakeException GetException() + { + return new WebSocketHandshakeException($"Invalid subprotocol. Actual: {receivedProtocol}. Expected one of: {expectedSubprotocol}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowWebSocketHandshakeException_InvalidHandshakeResponseGS(IFullHttpResponse response) + { + throw GetException(); + WebSocketHandshakeException GetException() + { + return new WebSocketHandshakeException($"Invalid handshake response getStatus: {response.Status}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowWebSocketHandshakeException_InvalidHandshakeResponseU(ICharSequence upgrade) + { + throw GetException(); + WebSocketHandshakeException GetException() + { + return new WebSocketHandshakeException($"Invalid handshake response upgrade: {upgrade}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowWebSocketHandshakeException_InvalidHandshakeResponseConn(ICharSequence upgrade) + { + throw GetException(); + WebSocketHandshakeException GetException() + { + return new WebSocketHandshakeException($"Invalid handshake response connection: {upgrade}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowWebSocketHandshakeException_InvalidChallenge() + { + throw GetException(); + WebSocketHandshakeException GetException() + { + return new WebSocketHandshakeException("Invalid challenge"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowWebSocketHandshakeException_InvalidChallenge(ICharSequence accept, AsciiString expectedChallengeResponseString) + { + throw GetException(); + WebSocketHandshakeException GetException() + { + return new WebSocketHandshakeException($"Invalid challenge. Actual: {accept}. Expected: {expectedChallengeResponseString}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowWebSocketHandshakeException_MissingUpgrade() + { + throw GetException(); + WebSocketHandshakeException GetException() + { + return new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowWebSocketHandshakeException_MissingKey() + { + throw GetException(); + WebSocketHandshakeException GetException() + { + return new WebSocketHandshakeException("not a WebSocket request: missing key"); + } + } + + #endregion + + #region -- EndOfDataDecoderException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowEndOfDataDecoderException_HttpPostStandardRequestDecoder() + { + throw GetException(); + EndOfDataDecoderException GetException() + { + return new EndOfDataDecoderException(nameof(HttpPostStandardRequestDecoder)); + } + } + + #endregion + } +} diff --git a/src/DotNetty.Codecs.Http/Internal/ThrowHelper.cs b/src/DotNetty.Codecs.Http/Internal/ThrowHelper.cs new file mode 100644 index 000000000..484eecf0e --- /dev/null +++ b/src/DotNetty.Codecs.Http/Internal/ThrowHelper.cs @@ -0,0 +1,222 @@ +using System; +using System.Runtime.CompilerServices; +using System.Diagnostics; +using DotNetty.Codecs.Http.Internal; + +namespace DotNetty.Codecs.Http +{ + internal static partial class ThrowHelper + { + #region -- Throw ArgumentException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException() + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException(); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException(ExceptionResource resource) + { + throw GetArgumentException(resource); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException(ExceptionResource resource, ExceptionArgument argument) + { + throw GetArgumentException(resource, argument); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException(string message, ExceptionArgument argument) + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException(message, GetArgumentName(argument)); + + } + } + + #endregion + + #region -- Get ArgumentException -- + + internal static ArgumentException GetArgumentException(ExceptionResource resource) + { + return new ArgumentException(GetResourceString(resource)); + } + + internal static ArgumentException GetArgumentException(ExceptionResource resource, ExceptionArgument argument) + { + return new ArgumentException(GetResourceString(resource), GetArgumentName(argument)); + } + + #endregion + + + #region -- Throw ArgumentOutOfRangeException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentOutOfRangeException() + { + throw GetArgumentOutOfRangeException(); + ArgumentOutOfRangeException GetArgumentOutOfRangeException() + { + return new ArgumentOutOfRangeException(); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument) + { + throw GetArgumentOutOfRangeException(argument); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) + { + throw GetArgumentOutOfRangeException(argument, resource); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, int paramNumber, ExceptionResource resource) + { + throw GetArgumentOutOfRangeException(argument, paramNumber, resource); + } + + #endregion + + #region -- Get ArgumentOutOfRangeException -- + + internal static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument) + { + return new ArgumentOutOfRangeException(GetArgumentName(argument)); + } + + internal static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) + { + return new ArgumentOutOfRangeException(GetArgumentName(argument), GetResourceString(resource)); + } + + internal static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument, int paramNumber, ExceptionResource resource) + { + return new ArgumentOutOfRangeException(GetArgumentName(argument) + "[" + paramNumber.ToString() + "]", GetResourceString(resource)); + } + + #endregion + + + #region -- Throw ArgumentNullException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentNullException(ExceptionArgument argument) + { + throw GetArgumentNullException(argument); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentNullException(ExceptionResource resource) + { + throw GetArgumentNullException(resource); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentNullException(ExceptionArgument argument, ExceptionResource resource) + { + throw GetArgumentNullException(argument, resource); + } + + #endregion + + #region -- Get ArgumentNullException -- + + internal static ArgumentNullException GetArgumentNullException(ExceptionArgument argument) + { + return new ArgumentNullException(GetArgumentName(argument)); + } + + internal static ArgumentNullException GetArgumentNullException(ExceptionResource resource) + { + return new ArgumentNullException(GetResourceString(resource), innerException: null); + } + + internal static ArgumentNullException GetArgumentNullException(ExceptionArgument argument, ExceptionResource resource) + { + return new ArgumentNullException(GetArgumentName(argument), GetResourceString(resource)); + } + + #endregion + + + #region -- IndexOutOfRangeException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowIndexOutOfRangeException() + { + throw GetIndexOutOfRangeException(); + IndexOutOfRangeException GetIndexOutOfRangeException() + { + return new IndexOutOfRangeException(); + } + } + + #endregion + + #region -- Throw InvalidOperationException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException(ExceptionResource resource) + { + throw GetInvalidOperationException(resource); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException(ExceptionResource resource, Exception e) + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException(GetResourceString(resource), e); + } + } + + internal static InvalidOperationException GetInvalidOperationException(ExceptionResource resource) + { + return new InvalidOperationException(GetResourceString(resource)); + } + + #endregion + + #region ** GetArgumentName ** + + [MethodImpl(MethodImplOptions.NoInlining)] + private static string GetArgumentName(ExceptionArgument argument) + { + Debug.Assert(Enum.IsDefined(typeof(ExceptionArgument), argument), + "The enum value is not defined, please check the ExceptionArgument Enum."); + + return argument.ToString(); + } + + #endregion + + #region ** GetResourceString ** + + // This function will convert an ExceptionResource enum value to the resource string. + [MethodImpl(MethodImplOptions.NoInlining)] + private static string GetResourceString(ExceptionResource resource) + { + Debug.Assert(Enum.IsDefined(typeof(ExceptionResource), resource), + "The enum value is not defined, please check the ExceptionResource Enum."); + + return SR.GetResourceString(resource.ToString()); + } + + #endregion + } +} diff --git a/src/DotNetty.Codecs.Http/Multipart/AbstractDiskHttpData.cs b/src/DotNetty.Codecs.Http/Multipart/AbstractDiskHttpData.cs index f8130a5a5..63763a5c4 100644 --- a/src/DotNetty.Codecs.Http/Multipart/AbstractDiskHttpData.cs +++ b/src/DotNetty.Codecs.Http/Multipart/AbstractDiskHttpData.cs @@ -63,7 +63,7 @@ public override void SetContent(IByteBuffer buffer) this.CheckSize(this.Size); if (this.DefinedSize > 0 && this.DefinedSize < this.Size) { - throw new IOException($"Out of size: {this.Size} > {this.DefinedSize}"); + ThrowHelper.ThrowIOException_OutOfSize(this.Size, this.DefinedSize); } if (this.fileStream == null) { @@ -98,7 +98,7 @@ public override void AddContent(IByteBuffer buffer, bool last) this.CheckSize(this.Size + localsize); if (this.DefinedSize > 0 && this.DefinedSize < this.Size + localsize) { - throw new IOException($"Out of size: {this.Size} > {this.DefinedSize}"); + ThrowHelper.ThrowIOException_OutOfSize(this.Size, this.DefinedSize); } if (this.fileStream == null) { @@ -129,7 +129,7 @@ public override void AddContent(IByteBuffer buffer, bool last) { if (buffer == null) { - throw new ArgumentNullException(nameof(buffer)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.buffer); } } } @@ -171,10 +171,10 @@ public override void SetContent(Stream source) } catch (Exception error) { - Logger.Warn("Failed to delete: {} {}", this.fileStream, error); + if (Logger.WarnEnabled) Logger.FailedToDelete(this.fileStream, error); } this.fileStream = null; - throw new IOException($"Out of size: {this.Size} > {this.DefinedSize}"); + ThrowHelper.ThrowIOException_OutOfSize(this.Size, this.DefinedSize); } //isRenamed = true; this.SetCompleted(); @@ -190,7 +190,7 @@ public override void Delete() } catch (IOException error) { - Logger.Warn("Failed to delete file.", error); + if (Logger.WarnEnabled) Logger.FailedToDeleteFile(error); } this.fileStream = null; @@ -263,7 +263,7 @@ public override bool RenameTo(FileStream destination) Contract.Requires(destination != null); if (this.fileStream == null) { - throw new InvalidOperationException("No file defined so cannot be renamed"); + ThrowHelper.ThrowInvalidOperationException_NoFileDefined(); } // must copy @@ -295,7 +295,7 @@ public override bool RenameTo(FileStream destination) } catch (IOException exception) { - Logger.Warn("Failed to delete file.", exception); + if (Logger.WarnEnabled) Logger.FailedToDeleteFile(exception); } this.fileStream = destination; return true; @@ -308,7 +308,7 @@ public override bool RenameTo(FileStream destination) } catch (IOException exception) { - Logger.Warn("Failed to delete file.", exception); + if (Logger.WarnEnabled) Logger.FailedToDeleteFile(exception); } return false; } @@ -326,7 +326,7 @@ static byte[] ReadFrom(Stream fileStream) long srcsize = fileStream.Length; if (srcsize > int.MaxValue) { - throw new ArgumentException("File too big to be loaded in memory"); + ThrowHelper.ThrowArgumentException_FileTooBig(); } var array = new byte[(int)srcsize]; diff --git a/src/DotNetty.Codecs.Http/Multipart/AbstractHttpData.cs b/src/DotNetty.Codecs.Http/Multipart/AbstractHttpData.cs index 75f2f0a78..97e1a7492 100644 --- a/src/DotNetty.Codecs.Http/Multipart/AbstractHttpData.cs +++ b/src/DotNetty.Codecs.Http/Multipart/AbstractHttpData.cs @@ -35,7 +35,7 @@ protected AbstractHttpData(string name, Encoding charset, long size) name = ReplacePattern.Replace(name, ""); if (string.IsNullOrEmpty(name)) { - throw new ArgumentException("empty name"); + ThrowHelper.ThrowArgumentException_Empty(ExceptionArgument.name); } this.name = name; @@ -57,7 +57,7 @@ public void CheckSize(long newSize) { if (this.MaxSize >= 0 && newSize > this.MaxSize) { - throw new IOException("Size exceed allowed maximum capacity"); + ThrowHelper.ThrowIOException_CheckSize(); } } @@ -91,7 +91,7 @@ public IByteBuffer Content } catch (IOException e) { - throw new ChannelException(e); + return ThrowHelper.ThrowChannelException_IO(e); } } } diff --git a/src/DotNetty.Codecs.Http/Multipart/AbstractMemoryHttpData.cs b/src/DotNetty.Codecs.Http/Multipart/AbstractMemoryHttpData.cs index eb97433e3..7a2462160 100644 --- a/src/DotNetty.Codecs.Http/Multipart/AbstractMemoryHttpData.cs +++ b/src/DotNetty.Codecs.Http/Multipart/AbstractMemoryHttpData.cs @@ -28,7 +28,7 @@ public override void SetContent(IByteBuffer buffer) this.CheckSize(localsize); if (this.DefinedSize > 0 && this.DefinedSize < localsize) { - throw new IOException($"Out of size: {localsize} > {this.DefinedSize}"); + ThrowHelper.ThrowIOException_OutOfSize(localsize, this.DefinedSize); } this.byteBuf?.Release(); @@ -43,7 +43,7 @@ public override void SetContent(Stream inputStream) if (!inputStream.CanRead) { - throw new ArgumentException($"{nameof(inputStream)} is not readable"); + ThrowHelper.ThrowArgumentException_Stream_NotReadable(); } IByteBuffer buffer = Unpooled.Buffer(); @@ -64,7 +64,7 @@ public override void SetContent(Stream inputStream) this.Size = written; if (this.DefinedSize > 0 && this.DefinedSize < this.Size) { - throw new IOException($"Out of size: {this.Size} > {this.DefinedSize}"); + ThrowHelper.ThrowIOException_OutOfSize(this.Size, this.DefinedSize); } this.byteBuf?.Release(); @@ -80,7 +80,7 @@ public override void AddContent(IByteBuffer buffer, bool last) this.CheckSize(this.Size + localsize); if (this.DefinedSize > 0 && this.DefinedSize < this.Size + localsize) { - throw new IOException($"Out of size: {(this.Size + localsize)} > {this.DefinedSize}"); + ThrowHelper.ThrowIOException_OutOfSize(this.Size + localsize, this.DefinedSize); } this.Size += localsize; @@ -109,7 +109,7 @@ public override void AddContent(IByteBuffer buffer, bool last) { if (buffer == null) { - throw new ArgumentNullException(nameof(buffer)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.buffer); } } } @@ -184,7 +184,7 @@ public override bool RenameTo(FileStream destination) if (!destination.CanWrite) { - throw new ArgumentException($"{nameof(destination)} is not writable"); + ThrowHelper.ThrowArgumentException_Stream_NotWritable(); } if (this.byteBuf == null) { diff --git a/src/DotNetty.Codecs.Http/Multipart/DefaultHttpDataFactory.cs b/src/DotNetty.Codecs.Http/Multipart/DefaultHttpDataFactory.cs index 20daafb4f..e4ff8b64c 100644 --- a/src/DotNetty.Codecs.Http/Multipart/DefaultHttpDataFactory.cs +++ b/src/DotNetty.Codecs.Http/Multipart/DefaultHttpDataFactory.cs @@ -128,7 +128,7 @@ static void CheckHttpDataSize(IHttpData data) } catch (IOException) { - throw new ArgumentException("Attribute bigger than maxSize allowed"); + ThrowHelper.ThrowArgumentException_AttrBigger(); } } diff --git a/src/DotNetty.Codecs.Http/Multipart/DiskAttribute.cs b/src/DotNetty.Codecs.Http/Multipart/DiskAttribute.cs index 52d5dd44a..cf8eb5edb 100644 --- a/src/DotNetty.Codecs.Http/Multipart/DiskAttribute.cs +++ b/src/DotNetty.Codecs.Http/Multipart/DiskAttribute.cs @@ -89,19 +89,19 @@ public override bool Equals(object obj) { if (obj is IAttribute attribute) { - return this.Name.Equals(attribute.Name, StringComparison.OrdinalIgnoreCase); + return string.Equals(this.Name, attribute.Name, StringComparison.OrdinalIgnoreCase); } return false; } public override int CompareTo(IInterfaceHttpData other) { - if (!(other is IAttribute)) + if (other is IAttribute attr) { - throw new ArgumentException($"Cannot compare {this.DataType} with {other.DataType}"); + return this.CompareTo(attr); } - return this.CompareTo((IAttribute)other); + return ThrowHelper.ThrowArgumentException_CompareToHttpData(this.DataType, other.DataType); } public int CompareTo(IAttribute attribute) => string.Compare(this.Name, attribute.Name, StringComparison.OrdinalIgnoreCase); @@ -171,7 +171,7 @@ public override IByteBufferHolder Replace(IByteBuffer content) } catch (IOException e) { - throw new ChannelException(e); + ThrowHelper.ThrowChannelException_IO(e); } } return attr; diff --git a/src/DotNetty.Codecs.Http/Multipart/DiskFileUpload.cs b/src/DotNetty.Codecs.Http/Multipart/DiskFileUpload.cs index cc7da953a..83bef86a4 100644 --- a/src/DotNetty.Codecs.Http/Multipart/DiskFileUpload.cs +++ b/src/DotNetty.Codecs.Http/Multipart/DiskFileUpload.cs @@ -52,12 +52,12 @@ public string FileName public override int CompareTo(IInterfaceHttpData other) { - if (!(other is IFileUpload)) + if (other is IFileUpload fu) { - throw new ArgumentException($"Cannot compare {this.DataType} with {other.DataType}"); + return this.CompareTo(fu); } - return this.CompareTo((IFileUpload)other); + return ThrowHelper.ThrowArgumentException_CompareToHttpData(this.DataType, other.DataType); } public int CompareTo(IFileUpload other) => FileUploadUtil.CompareTo(this, other); @@ -155,7 +155,7 @@ public override IByteBufferHolder Replace(IByteBuffer content) } catch (IOException e) { - throw new ChannelException(e); + ThrowHelper.ThrowChannelException_IO(e); } } diff --git a/src/DotNetty.Codecs.Http/Multipart/FileUploadUtil.cs b/src/DotNetty.Codecs.Http/Multipart/FileUploadUtil.cs index 0832ff6b0..c587e3a0b 100644 --- a/src/DotNetty.Codecs.Http/Multipart/FileUploadUtil.cs +++ b/src/DotNetty.Codecs.Http/Multipart/FileUploadUtil.cs @@ -10,7 +10,7 @@ static class FileUploadUtil public static int HashCode(IFileUpload upload) => upload.Name.GetHashCode(); public static bool Equals(IFileUpload upload1, IFileUpload upload2) => - upload1.Name.Equals(upload2.Name, StringComparison.OrdinalIgnoreCase); + string.Equals(upload1.Name, upload2.Name, StringComparison.OrdinalIgnoreCase); public static int CompareTo(IFileUpload upload1, IFileUpload upload2) => string.Compare(upload1.Name, upload2.Name, StringComparison.OrdinalIgnoreCase); diff --git a/src/DotNetty.Codecs.Http/Multipart/HttpPostBodyUtil.cs b/src/DotNetty.Codecs.Http/Multipart/HttpPostBodyUtil.cs index d666a6579..68e68d29a 100644 --- a/src/DotNetty.Codecs.Http/Multipart/HttpPostBodyUtil.cs +++ b/src/DotNetty.Codecs.Http/Multipart/HttpPostBodyUtil.cs @@ -52,7 +52,7 @@ internal SeekAheadOptimize(IByteBuffer buffer) { if (!buffer.HasArray) { - throw new ArgumentException("buffer hasn't backing byte array"); + ThrowHelper.ThrowArgumentException_BufferNoBacking(); } this.Buffer = buffer; this.Bytes = buffer.Array; diff --git a/src/DotNetty.Codecs.Http/Multipart/HttpPostMultipartRequestDecoder.cs b/src/DotNetty.Codecs.Http/Multipart/HttpPostMultipartRequestDecoder.cs index 046a63591..22ab952bf 100644 --- a/src/DotNetty.Codecs.Http/Multipart/HttpPostMultipartRequestDecoder.cs +++ b/src/DotNetty.Codecs.Http/Multipart/HttpPostMultipartRequestDecoder.cs @@ -118,7 +118,7 @@ void CheckDestroyed() { if (this.destroyed) { - throw new InvalidOperationException($"{StringUtil.SimpleClassName()} was destroyed already"); + ThrowHelper.ThrowInvalidOperationException_CheckDestroyed(); } } @@ -147,7 +147,7 @@ public List GetBodyHttpDatas() if (!this.isLastChunk) { - throw new NotEnoughDataDecoderException(nameof(HttpPostMultipartRequestDecoder)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.HttpPostMultipartRequestDecoder); } return this.bodyListHttpData; } @@ -158,7 +158,7 @@ public List GetBodyHttpDatas(AsciiString name) if (!this.isLastChunk) { - throw new NotEnoughDataDecoderException(nameof(HttpPostMultipartRequestDecoder)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.HttpPostMultipartRequestDecoder); } return this.bodyMapHttpData[name]; } @@ -169,7 +169,7 @@ public IInterfaceHttpData GetBodyHttpData(AsciiString name) if (!this.isLastChunk) { - throw new NotEnoughDataDecoderException(nameof(HttpPostMultipartRequestDecoder)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.HttpPostMultipartRequestDecoder); } if (this.bodyMapHttpData.TryGetValue(name, out List list)) { @@ -218,7 +218,7 @@ public bool HasNext // OK except if end of list if (this.bodyListHttpDataRank >= this.bodyListHttpData.Count) { - throw new NotEnoughDataDecoderException(nameof(HttpPostMultipartRequestDecoder)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.HttpPostMultipartRequestDecoder); } } return this.bodyListHttpData.Count > 0 && this.bodyListHttpDataRank < this.bodyListHttpData.Count; @@ -308,10 +308,10 @@ IInterfaceHttpData DecodeMultipart(MultiPartStatus state) switch (state) { case MultiPartStatus.Notstarted: - throw new ErrorDataDecoderException("Should not be called with the current getStatus"); + ThrowHelper.ThrowErrorDataDecoderException_GetStatus(); return null; case MultiPartStatus.Preamble: // Content-type: multipart/form-data, boundary=AaB03x - throw new ErrorDataDecoderException("Should not be called with the current getStatus"); + ThrowHelper.ThrowErrorDataDecoderException_GetStatus(); return null; case MultiPartStatus.HeaderDelimiter: { // --AaB03x or --AaB03x-- @@ -343,11 +343,11 @@ IInterfaceHttpData DecodeMultipart(MultiPartStatus state) } catch (IOException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (ArgumentException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } } this.currentFieldAttributes.TryGetValue(HttpHeaderValues.Name, out IAttribute nameAttribute); @@ -361,17 +361,17 @@ IInterfaceHttpData DecodeMultipart(MultiPartStatus state) } catch (IOException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); size = 0L; } catch (FormatException) { - size = 0; + size = 0L; } try { if (nameAttribute == null) { - throw new ErrorDataDecoderException($"{HttpHeaderValues.Name} attribute cannot be null."); + ThrowHelper.ThrowErrorDataDecoderException_Attr(); } if (size > 0) { @@ -386,11 +386,11 @@ IInterfaceHttpData DecodeMultipart(MultiPartStatus state) } catch (ArgumentException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (IOException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } if (localCharset != null) { @@ -435,7 +435,7 @@ IInterfaceHttpData DecodeMultipart(MultiPartStatus state) case MultiPartStatus.Epilogue: return null; default: - throw new ErrorDataDecoderException("Shouldn't reach here."); + ThrowHelper.ThrowErrorDataDecoderException_ReachHere(); return null; } } @@ -449,7 +449,7 @@ static void SkipControlCharacters(IByteBuffer undecodedChunk) } catch (IndexOutOfRangeException e) { - throw new NotEnoughDataDecoderException(e); + ThrowHelper.ThrowNotEnoughDataDecoderException(e); } return; } @@ -463,7 +463,7 @@ static void SkipControlCharacters(IByteBuffer undecodedChunk) return; } } - throw new NotEnoughDataDecoderException("Access out of bounds"); + ThrowHelper.ThrowNotEnoughDataDecoderException_AccessOutOfBounds(); } static void SkipControlCharactersStandard(IByteBuffer undecodedChunk) @@ -523,7 +523,7 @@ IInterfaceHttpData FindMultipartDelimiter(ICharSequence delimiter, MultiPartStat return null; } this.undecodedChunk.SetReaderIndex(readerIndex); - throw new ErrorDataDecoderException("No Multipart delimiter found"); + ThrowHelper.ThrowErrorDataDecoderException_NoMultipartDelimiterFound(); return null; } IInterfaceHttpData FindMultipartDisposition() @@ -566,18 +566,18 @@ IInterfaceHttpData FindMultipartDisposition() for (int i = 2; i < contents.Length; i++) { ICharSequence[] values = CharUtil.Split(contents[i], '='); - IAttribute attribute; + IAttribute attribute = null; try { attribute = this.GetContentDispositionAttribute(values); } catch (ArgumentNullException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (ArgumentException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } this.currentFieldAttributes.Add(new AsciiString(attribute.Name), attribute); } @@ -585,7 +585,7 @@ IInterfaceHttpData FindMultipartDisposition() } else if (HttpHeaderNames.ContentTransferEncoding.ContentEqualsIgnoreCase(contents[0])) { - IAttribute attribute; + IAttribute attribute = null; try { attribute = this.factory.CreateAttribute(this.request, HttpHeaderNames.ContentTransferEncoding.ToString(), @@ -593,18 +593,18 @@ IInterfaceHttpData FindMultipartDisposition() } catch (ArgumentNullException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (ArgumentException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } this.currentFieldAttributes.Add(HttpHeaderNames.ContentTransferEncoding, attribute); } else if (HttpHeaderNames.ContentLength.ContentEqualsIgnoreCase(contents[0])) { - IAttribute attribute; + IAttribute attribute = null; try { attribute = this.factory.CreateAttribute(this.request, HttpHeaderNames.ContentLength.ToString(), @@ -612,11 +612,11 @@ IInterfaceHttpData FindMultipartDisposition() } catch (ArgumentNullException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (ArgumentException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } this.currentFieldAttributes.Add(HttpHeaderNames.ContentLength, attribute); @@ -635,7 +635,7 @@ IInterfaceHttpData FindMultipartDisposition() } else { - throw new ErrorDataDecoderException("Mixed Multipart found in a previous Mixed Multipart"); + ThrowHelper.ThrowErrorDataDecoderException_MixedMultipartFound(); } } else @@ -646,25 +646,25 @@ IInterfaceHttpData FindMultipartDisposition() if (contents[i].RegionMatchesIgnoreCase(0, charsetHeader, 0, charsetHeader.Count)) { ICharSequence values = contents[i].SubstringAfter('='); - IAttribute attribute; + IAttribute attribute = null; try { attribute = this.factory.CreateAttribute(this.request, charsetHeader.ToString(), CleanString(values).ToString()); } catch (ArgumentNullException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (ArgumentException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } this.currentFieldAttributes.Add(HttpHeaderValues.Charset, attribute); } else { - IAttribute attribute; - ICharSequence name; + IAttribute attribute = null; + ICharSequence name = null; try { name = CleanString(contents[0]); @@ -673,11 +673,11 @@ IInterfaceHttpData FindMultipartDisposition() } catch (ArgumentNullException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (ArgumentException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } this.currentFieldAttributes.Add(new AsciiString(name), attribute); } @@ -686,7 +686,7 @@ IInterfaceHttpData FindMultipartDisposition() } else { - throw new ErrorDataDecoderException($"Unknown Params: {newline}"); + ThrowHelper.ThrowErrorDataDecoderException_UnknownParams(newline); } } // Is it a FileUpload @@ -720,7 +720,7 @@ IInterfaceHttpData FindMultipartDisposition() else { // Field is not supported in MIXED mode - throw new ErrorDataDecoderException("Filename not found"); + ThrowHelper.ThrowErrorDataDecoderException_FileName(); return null; } } } @@ -755,11 +755,11 @@ IAttribute GetContentDispositionAttribute(params ICharSequence[] values) } catch (IndexOutOfRangeException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (ArgumentException e) // Invalid encoding { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } } else @@ -780,32 +780,32 @@ protected IInterfaceHttpData GetFileUpload(ICharSequence delimiter) HttpPostBodyUtil.TransferEncodingMechanism mechanism = HttpPostBodyUtil.TransferEncodingMechanism.Bit7; if (encodingAttribute != null) { - string code; + string code = null; try { - code = encodingAttribute.Value.ToLower(); + code = encodingAttribute.Value.ToLowerInvariant(); } catch (IOException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } - if (code.Equals(HttpPostBodyUtil.TransferEncodingMechanism.Bit7.Value)) + if (string.Equals(code, HttpPostBodyUtil.TransferEncodingMechanism.Bit7.Value, StringComparison.Ordinal)) { localCharset = Encoding.ASCII; } - else if (code.Equals(HttpPostBodyUtil.TransferEncodingMechanism.Bit8.Value)) + else if (string.Equals(code, HttpPostBodyUtil.TransferEncodingMechanism.Bit8.Value, StringComparison.Ordinal)) { localCharset = Encoding.UTF8; mechanism = HttpPostBodyUtil.TransferEncodingMechanism.Bit8; } - else if (code.Equals(HttpPostBodyUtil.TransferEncodingMechanism.Binary.Value)) + else if (string.Equals(code, HttpPostBodyUtil.TransferEncodingMechanism.Binary.Value, StringComparison.Ordinal)) { // no real charset, so let the default mechanism = HttpPostBodyUtil.TransferEncodingMechanism.Binary; } else { - throw new ErrorDataDecoderException("TransferEncoding Unknown: " + code); + ThrowHelper.ThrowErrorDataDecoderException_TransferEncoding(code); } } if (this.currentFieldAttributes.TryGetValue(HttpHeaderValues.Charset, out IAttribute charsetAttribute)) @@ -816,11 +816,11 @@ protected IInterfaceHttpData GetFileUpload(ICharSequence delimiter) } catch (IOException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (ArgumentException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } } if (this.currentFileUpload == null) @@ -836,11 +836,11 @@ protected IInterfaceHttpData GetFileUpload(ICharSequence delimiter) } catch (IOException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); size = 0L; } catch (FormatException) { - size = 0; + size = 0L; } try { @@ -855,11 +855,11 @@ protected IInterfaceHttpData GetFileUpload(ICharSequence delimiter) } if (nameAttribute == null) { - throw new ErrorDataDecoderException($"{HttpHeaderValues.Name} attribute cannot be null for file upload"); + ThrowHelper.ThrowErrorDataDecoderException_NameAttr(); } if (filenameAttribute == null) { - throw new ErrorDataDecoderException($"{HttpHeaderValues.FileName} attribute cannot be null for file upload"); + ThrowHelper.ThrowErrorDataDecoderException_FileNameAttr(); } this.currentFileUpload = this.factory.CreateFileUpload(this.request, CleanString(nameAttribute.Value).ToString(), CleanString(filenameAttribute.Value).ToString(), @@ -868,15 +868,15 @@ protected IInterfaceHttpData GetFileUpload(ICharSequence delimiter) } catch (ArgumentNullException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (ArgumentException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (IOException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } } // load data as much as possible @@ -992,10 +992,10 @@ static StringCharSequence ReadLineStandard(IByteBuffer undecodedChunk, Encoding catch (IndexOutOfRangeException e) { undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(e); + ThrowHelper.ThrowNotEnoughDataDecoderException(e); } undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiterStandard)); + return ThrowHelper.ThrowNotEnoughDataDecoderException_ReadLineStandard(); } static StringCharSequence ReadLine(IByteBuffer undecodedChunk, Encoding charset) @@ -1049,10 +1049,10 @@ static StringCharSequence ReadLine(IByteBuffer undecodedChunk, Encoding charset) catch (IndexOutOfRangeException e) { undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(e); + ThrowHelper.ThrowNotEnoughDataDecoderException(e); } undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadLine)); + return ThrowHelper.ThrowNotEnoughDataDecoderException_ReadLine(); } static StringBuilderCharSequence ReadDelimiterStandard(IByteBuffer undecodedChunk, ICharSequence delimiter) @@ -1075,7 +1075,7 @@ static StringBuilderCharSequence ReadDelimiterStandard(IByteBuffer undecodedChun { // delimiter not found so break here ! undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiterStandard)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.ReadDelimiterStandard); } } // Now check if either opening delimiter or closing delimiter @@ -1095,7 +1095,7 @@ static StringBuilderCharSequence ReadDelimiterStandard(IByteBuffer undecodedChun // error since CR must be followed by LF // delimiter not found so break here ! undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiterStandard)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.ReadDelimiterStandard); } } else if (nextByte == HttpConstants.LineFeed) @@ -1126,7 +1126,7 @@ static StringBuilderCharSequence ReadDelimiterStandard(IByteBuffer undecodedChun // error CR without LF // delimiter not found so break here ! undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiterStandard)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.ReadDelimiterStandard); } } else if (nextByte == HttpConstants.LineFeed) @@ -1156,10 +1156,10 @@ static StringBuilderCharSequence ReadDelimiterStandard(IByteBuffer undecodedChun catch (IndexOutOfRangeException e) { undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(e); + ThrowHelper.ThrowNotEnoughDataDecoderException(e); } undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiterStandard)); + return ThrowHelper.ThrowNotEnoughDataDecoderException_ReadDelimiterStandard(); } static StringBuilderCharSequence ReadDelimiter(IByteBuffer undecodedChunk, ICharSequence delimiter) @@ -1188,7 +1188,7 @@ static StringBuilderCharSequence ReadDelimiter(IByteBuffer undecodedChunk, IChar { // delimiter not found so break here ! undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiter)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.ReadDelimiter); } } // Now check if either opening delimiter or closing delimiter @@ -1211,7 +1211,7 @@ static StringBuilderCharSequence ReadDelimiter(IByteBuffer undecodedChunk, IChar // error CR without LF // delimiter not found so break here ! undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiter)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.ReadDelimiter); } } else @@ -1219,7 +1219,7 @@ static StringBuilderCharSequence ReadDelimiter(IByteBuffer undecodedChunk, IChar // error since CR must be followed by LF // delimiter not found so break here ! undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiter)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.ReadDelimiter); } } else if (nextByte == HttpConstants.LineFeed) @@ -1258,7 +1258,7 @@ static StringBuilderCharSequence ReadDelimiter(IByteBuffer undecodedChunk, IChar // error CR without LF // delimiter not found so break here ! undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiter)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.ReadDelimiter); } } else @@ -1266,7 +1266,7 @@ static StringBuilderCharSequence ReadDelimiter(IByteBuffer undecodedChunk, IChar // error CR without LF // delimiter not found so break here ! undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiter)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.ReadDelimiter); } } else if (nextByte == HttpConstants.LineFeed) @@ -1301,10 +1301,10 @@ static StringBuilderCharSequence ReadDelimiter(IByteBuffer undecodedChunk, IChar catch (IndexOutOfRangeException e) { undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(e); + ThrowHelper.ThrowNotEnoughDataDecoderException(e); } undecodedChunk.SetReaderIndex(readerIndex); - throw new NotEnoughDataDecoderException(nameof(ReadDelimiter)); + return ThrowHelper.ThrowNotEnoughDataDecoderException_ReadDelimiter(); } static bool LoadDataMultipartStandard(IByteBuffer undecodedChunk, ICharSequence delimiter, IHttpData httpData) @@ -1348,7 +1348,7 @@ static bool LoadDataMultipartStandard(IByteBuffer undecodedChunk, ICharSequence } catch (IOException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } undecodedChunk.SetReaderIndex(lastPosition); return delimiterFound; @@ -1401,7 +1401,7 @@ static bool LoadDataMultipart(IByteBuffer undecodedChunk, ICharSequence delimite } catch (IOException e) { - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } undecodedChunk.SetReaderIndex(lastPosition); return delimiterFound; diff --git a/src/DotNetty.Codecs.Http/Multipart/HttpPostRequestDecoder.cs b/src/DotNetty.Codecs.Http/Multipart/HttpPostRequestDecoder.cs index e7005c3e4..20a5b7f71 100644 --- a/src/DotNetty.Codecs.Http/Multipart/HttpPostRequestDecoder.cs +++ b/src/DotNetty.Codecs.Http/Multipart/HttpPostRequestDecoder.cs @@ -85,7 +85,7 @@ protected internal static ICharSequence[] GetMultipartDataBoundary(ICharSequence ICharSequence boundary = headerContentType[mrank].SubstringAfter('='); if (boundary == null) { - throw new ErrorDataDecoderException("Needs a boundary value"); + ThrowHelper.ThrowErrorDataDecoderException_NeedBoundaryValue(); } if (boundary[0] == '"') { diff --git a/src/DotNetty.Codecs.Http/Multipart/HttpPostRequestEncoder.cs b/src/DotNetty.Codecs.Http/Multipart/HttpPostRequestEncoder.cs index 097eb9ac5..1006b19d3 100644 --- a/src/DotNetty.Codecs.Http/Multipart/HttpPostRequestEncoder.cs +++ b/src/DotNetty.Codecs.Http/Multipart/HttpPostRequestEncoder.cs @@ -108,7 +108,7 @@ public HttpPostRequestEncoder( HttpMethod method = request.Method; if (method.Equals(HttpMethod.Trace)) { - throw new ErrorDataEncoderException("Cannot create a Encoder if request is a TRACE"); + ThrowHelper.ThrowErrorDataEncoderException_CannotCreate(); } // Fill default values this.bodyListDatas = new List(); @@ -151,7 +151,7 @@ public HttpPostRequestEncoder( void InitMixedMultipart() => this.MultipartMixedBoundary = GetNewMultipartDelimiter(); // construct a generated delimiter - static string GetNewMultipartDelimiter() => Convert.ToString(PlatformDependent.GetThreadLocalRandom().NextLong(), 16).ToLower(); + static string GetNewMultipartDelimiter() => Convert.ToString(PlatformDependent.GetThreadLocalRandom().NextLong(), 16).ToLowerInvariant(); public List GetBodyListAttributes() => this.bodyListDatas; @@ -213,7 +213,7 @@ public void AddBodyFileUpload(string name, string fileName, FileStream fileStrea } catch (IOException e) { - throw new ErrorDataEncoderException(e); + ThrowHelper.ThrowErrorDataEncoderException(e); } this.AddBodyHttpData(fileUpload); @@ -223,7 +223,7 @@ public void AddBodyFileUploads(string name, FileStream[] file, string[] contentT { if (file.Length != contentType.Length && file.Length != isText.Length) { - throw new ArgumentException("Different array length"); + ThrowHelper.ThrowArgumentException_DiffArrayLen(); } for (int i = 0; i < file.Length; i++) { @@ -236,36 +236,38 @@ public void AddBodyHttpData(IInterfaceHttpData data) Contract.Requires(data != null); if (this.headerFinalized) { - throw new ErrorDataEncoderException("Cannot add value once finalized"); + ThrowHelper.ThrowErrorDataEncoderException_CannotAddValue(); } this.bodyListDatas.Add(data); if (!this.isMultipart) { - if (data is IAttribute dataAttribute) + switch (data) { - try - { - // name=value& with encoded name and attribute - string key = this.EncodeAttribute(dataAttribute.Name, this.charset); - string value = this.EncodeAttribute(dataAttribute.Value, this.charset); - IAttribute newattribute = this.factory.CreateAttribute(this.request, key, value); - this.MultipartHttpDatas.Add(newattribute); - this.globalBodySize += newattribute.Name.Length + 1 + newattribute.Length + 1; - } - catch (IOException e) - { - throw new ErrorDataEncoderException(e); - } - } - else if (data is IFileUpload fileUpload) - { - // since not Multipart, only name=filename => Attribute - // name=filename& with encoded name and filename - string key = this.EncodeAttribute(fileUpload.Name, this.charset); - string value = this.EncodeAttribute(fileUpload.FileName, this.charset); - IAttribute newattribute = this.factory.CreateAttribute(this.request, key, value); - this.MultipartHttpDatas.Add(newattribute); - this.globalBodySize += newattribute.Name.Length + 1 + newattribute.Length + 1; + case IAttribute dataAttribute: + try + { + // name=value& with encoded name and attribute + string key = this.EncodeAttribute(dataAttribute.Name, this.charset); + string value = this.EncodeAttribute(dataAttribute.Value, this.charset); + IAttribute newattribute = this.factory.CreateAttribute(this.request, key, value); + this.MultipartHttpDatas.Add(newattribute); + this.globalBodySize += newattribute.Name.Length + 1 + newattribute.Length + 1; + } + catch (IOException e) + { + ThrowHelper.ThrowErrorDataEncoderException(e); + } + break; + + case IFileUpload fileUpload: + // since not Multipart, only name=filename => Attribute + // name=filename& with encoded name and filename + string key0 = this.EncodeAttribute(fileUpload.Name, this.charset); + string value0 = this.EncodeAttribute(fileUpload.FileName, this.charset); + IAttribute newattribute0 = this.factory.CreateAttribute(this.request, key0, value0); + this.MultipartHttpDatas.Add(newattribute0); + this.globalBodySize += newattribute0.Name.Length + 1 + newattribute0.Length + 1; + break; } return; } @@ -346,7 +348,7 @@ public void AddBodyHttpData(IInterfaceHttpData data) bool localMixed; if (this.duringMixedMode) { - if (this.currentFileUpload != null && this.currentFileUpload.Name.Equals(fileUpload.Name)) + if (this.currentFileUpload != null && string.Equals(this.currentFileUpload.Name, fileUpload.Name, StringComparison.Ordinal)) { // continue a mixed mode @@ -375,7 +377,7 @@ public void AddBodyHttpData(IInterfaceHttpData data) else { if (this.encoderMode != EncoderMode.HTML5 && this.currentFileUpload != null - && this.currentFileUpload.Name.Equals(fileUpload.Name)) + && string.Equals(this.currentFileUpload.Name, fileUpload.Name, StringComparison.Ordinal)) { // create a new mixed mode (from previous file) @@ -511,7 +513,7 @@ public void AddBodyHttpData(IInterfaceHttpData data) internalAttribute.AddValue($"{HttpHeaderNames.ContentType}: {fileUpload.ContentType}"); string contentTransferEncoding = fileUpload.ContentTransferEncoding; if (contentTransferEncoding != null - && contentTransferEncoding.Equals(HttpPostBodyUtil.TransferEncodingMechanism.Binary.Value)) + && string.Equals(contentTransferEncoding, HttpPostBodyUtil.TransferEncodingMechanism.Binary.Value, StringComparison.Ordinal)) { internalAttribute.AddValue($"\r\n{HttpHeaderNames.ContentTransferEncoding}: {HttpPostBodyUtil.TransferEncodingMechanism.Binary.Value}\r\n\r\n"); } @@ -555,7 +557,7 @@ public IHttpRequest FinalizeRequest() } else { - throw new ErrorDataEncoderException("Header already encoded"); + ThrowHelper.ThrowErrorDataEncoderException_HeaderAlreadyEncoded(); } HttpHeaders headers = this.request.Headers; @@ -567,9 +569,9 @@ public IHttpRequest FinalizeRequest() foreach (ICharSequence contentType in contentTypes) { // "multipart/form-data; boundary=--89421926422648" - string lowercased = contentType.ToString().ToLower(); - if (lowercased.StartsWith(HttpHeaderValues.MultipartFormData.ToString()) - || lowercased.StartsWith(HttpHeaderValues.ApplicationXWwwFormUrlencoded.ToString())) + string lowercased = contentType.ToString().ToLowerInvariant(); + if (lowercased.StartsWith(HttpHeaderValues.MultipartFormData.ToString(), StringComparison.Ordinal) + || lowercased.StartsWith(HttpHeaderValues.ApplicationXWwwFormUrlencoded.ToString(), StringComparison.Ordinal)) { // ignore } @@ -701,7 +703,7 @@ IHttpContent EncodeNextChunkMultipart(int sizeleft) { return null; } - IByteBuffer buffer; + IByteBuffer buffer = null; if (this.currentData is InternalAttribute internalAttribute) { buffer = internalAttribute.ToByteBuffer(); @@ -715,7 +717,7 @@ IHttpContent EncodeNextChunkMultipart(int sizeleft) } catch (IOException e) { - throw new ErrorDataEncoderException(e); + ThrowHelper.ThrowErrorDataEncoderException(e); } if (buffer.Capacity == 0) { @@ -747,7 +749,7 @@ IHttpContent EncodeNextChunkUrlEncoded(int sizeleft) return null; } int size = sizeleft; - IByteBuffer buffer; + IByteBuffer buffer = null; // Set name= if (this.isKey) @@ -783,7 +785,7 @@ IHttpContent EncodeNextChunkUrlEncoded(int sizeleft) } catch (IOException e) { - throw new ErrorDataEncoderException(e); + ThrowHelper.ThrowErrorDataEncoderException(e); } // Figure out delimiter @@ -1085,7 +1087,7 @@ public IInterfaceHttpData Next() { if (!this.HasNext()) { - throw new InvalidOperationException("No more element to iterate"); + ThrowHelper.ThrowInvalidOperationException_NoMoreElement(); } IInterfaceHttpData data = this.list[this.index++]; diff --git a/src/DotNetty.Codecs.Http/Multipart/HttpPostStandardRequestDecoder.cs b/src/DotNetty.Codecs.Http/Multipart/HttpPostStandardRequestDecoder.cs index 3711c9709..a2f4bc5b3 100644 --- a/src/DotNetty.Codecs.Http/Multipart/HttpPostStandardRequestDecoder.cs +++ b/src/DotNetty.Codecs.Http/Multipart/HttpPostStandardRequestDecoder.cs @@ -84,7 +84,7 @@ void CheckDestroyed() { if (this.destroyed) { - throw new InvalidOperationException($"{StringUtil.SimpleClassName()} was destroyed already"); + ThrowHelper.ThrowInvalidOperationException_CheckDestroyed(); } } @@ -113,7 +113,7 @@ public List GetBodyHttpDatas() if (!this.isLastChunk) { - throw new NotEnoughDataDecoderException(nameof(HttpPostStandardRequestDecoder)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.HttpPostStandardRequestDecoder); } return this.bodyListHttpData; } @@ -124,7 +124,7 @@ public List GetBodyHttpDatas(AsciiString name) if (!this.isLastChunk) { - throw new NotEnoughDataDecoderException(nameof(HttpPostStandardRequestDecoder)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.HttpPostStandardRequestDecoder); } return this.bodyMapHttpData[name]; } @@ -135,7 +135,7 @@ public IInterfaceHttpData GetBodyHttpData(AsciiString name) if (!this.isLastChunk) { - throw new NotEnoughDataDecoderException(nameof(HttpPostStandardRequestDecoder)); + ThrowHelper.ThrowNotEnoughDataDecoderException(ExceptionArgument.HttpPostStandardRequestDecoder); } if (this.bodyMapHttpData.TryGetValue(name, out List list)) @@ -186,7 +186,7 @@ public bool HasNext // OK except if end of list if (this.bodyListHttpDataRank >= this.bodyListHttpData.Count) { - throw new EndOfDataDecoderException(nameof(HttpPostStandardRequestDecoder)); + ThrowHelper.ThrowEndOfDataDecoderException_HttpPostStandardRequestDecoder(); } } @@ -303,7 +303,7 @@ void ParseBodyAttributesStandard() else { // Error - throw new ErrorDataDecoderException("Bad end of line"); + ThrowHelper.ThrowErrorDataDecoderException_BadEndOfLine(); } } else @@ -370,7 +370,7 @@ void ParseBodyAttributesStandard() { // error while decoding this.undecodedChunk.SetReaderIndex(firstpos); - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } } @@ -452,7 +452,7 @@ void ParseBodyAttributes() { // Error sao.SetReadPosition(0); - throw new ErrorDataDecoderException("Bad end of line"); + ThrowHelper.ThrowErrorDataDecoderException_BadEndOfLine(); } } else @@ -526,13 +526,13 @@ void ParseBodyAttributes() { // error while decoding this.undecodedChunk.SetReaderIndex(firstpos); - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } catch (ArgumentException e) { // error while decoding this.undecodedChunk.SetReaderIndex(firstpos); - throw new ErrorDataDecoderException(e); + ThrowHelper.ThrowErrorDataDecoderException(e); } } @@ -553,7 +553,7 @@ static string DecodeAttribute(string s, Encoding charset) } catch (ArgumentException e) { - throw new ErrorDataDecoderException($"Bad string: '{s}'", e); + return ThrowHelper.ThrowErrorDataDecoderException_BadString(s, e); } } diff --git a/src/DotNetty.Codecs.Http/Multipart/InternalAttribute.cs b/src/DotNetty.Codecs.Http/Multipart/InternalAttribute.cs index 2efdf5f0d..65104f009 100644 --- a/src/DotNetty.Codecs.Http/Multipart/InternalAttribute.cs +++ b/src/DotNetty.Codecs.Http/Multipart/InternalAttribute.cs @@ -73,12 +73,12 @@ public override bool Equals(object obj) public int CompareTo(IInterfaceHttpData other) { - if (!(other is InternalAttribute)) + if (other is InternalAttribute attr) { - throw new ArgumentException($"Cannot compare {this.DataType} with {other.DataType}"); + return this.CompareTo(attr); } - return this.CompareTo((InternalAttribute)other); + return ThrowHelper.ThrowArgumentException_CompareToHttpData(this.DataType, other.DataType); } public int CompareTo(InternalAttribute other) => string.Compare(this.Name, other.Name, StringComparison.OrdinalIgnoreCase); diff --git a/src/DotNetty.Codecs.Http/Multipart/MemoryAttribute.cs b/src/DotNetty.Codecs.Http/Multipart/MemoryAttribute.cs index a4ed93b07..ad5210154 100644 --- a/src/DotNetty.Codecs.Http/Multipart/MemoryAttribute.cs +++ b/src/DotNetty.Codecs.Http/Multipart/MemoryAttribute.cs @@ -88,12 +88,12 @@ public override bool Equals(object obj) public override int CompareTo(IInterfaceHttpData other) { - if (!(other is IAttribute)) + if (other is IAttribute attr) { - throw new ArgumentException($"Cannot compare {this.DataType} with {other.DataType}"); + return this.CompareTo(attr); } - return this.CompareTo((IAttribute)other); + return ThrowHelper.ThrowArgumentException_CompareToHttpData(this.DataType, other.DataType); } public int CompareTo(IAttribute attribute) => string.Compare(this.Name, attribute.Name, StringComparison.OrdinalIgnoreCase); @@ -151,7 +151,7 @@ public override IByteBufferHolder Replace(IByteBuffer content) } catch (IOException e) { - throw new ChannelException(e); + ThrowHelper.ThrowChannelException_IO(e); } } return attr; diff --git a/src/DotNetty.Codecs.Http/Multipart/MemoryFileUpload.cs b/src/DotNetty.Codecs.Http/Multipart/MemoryFileUpload.cs index 12bff90ef..f329b791a 100644 --- a/src/DotNetty.Codecs.Http/Multipart/MemoryFileUpload.cs +++ b/src/DotNetty.Codecs.Http/Multipart/MemoryFileUpload.cs @@ -55,12 +55,12 @@ public override bool Equals(object obj) public override int CompareTo(IInterfaceHttpData other) { - if (!(other is IFileUpload)) + if (other is IFileUpload fu) { - throw new ArgumentException($"Cannot compare {this.DataType} with {other.DataType}"); + return this.CompareTo(fu); } - return this.CompareTo((IFileUpload)other); + return ThrowHelper.ThrowArgumentException_CompareToHttpData(this.DataType, other.DataType); } public int CompareTo(IFileUpload other) => FileUploadUtil.CompareTo(this, other); @@ -137,7 +137,7 @@ public override IByteBufferHolder Replace(IByteBuffer content) } catch (IOException e) { - throw new ChannelException(e); + ThrowHelper.ThrowChannelException_IO(e); } } return upload; diff --git a/src/DotNetty.Codecs.Http/Multipart/MixedAttribute.cs b/src/DotNetty.Codecs.Http/Multipart/MixedAttribute.cs index ed91a7469..a82038f25 100644 --- a/src/DotNetty.Codecs.Http/Multipart/MixedAttribute.cs +++ b/src/DotNetty.Codecs.Http/Multipart/MixedAttribute.cs @@ -5,6 +5,7 @@ namespace DotNetty.Codecs.Http.Multipart { using System; using System.IO; + using System.Runtime.CompilerServices; using System.Text; using DotNetty.Buffers; using DotNetty.Common; @@ -89,11 +90,12 @@ public long MaxSize } } + [MethodImpl(InlineMethod.Value)] public void CheckSize(long newSize) { if (this.maxSize >= 0 && newSize > this.maxSize) { - throw new IOException($"Size exceed allowed maximum capacity of {this.maxSize}"); + ThrowHelper.ThrowIOException_CheckSize(this.maxSize); } } diff --git a/src/DotNetty.Codecs.Http/Multipart/MixedFileUpload.cs b/src/DotNetty.Codecs.Http/Multipart/MixedFileUpload.cs index 104d10f0e..d9a3421f1 100644 --- a/src/DotNetty.Codecs.Http/Multipart/MixedFileUpload.cs +++ b/src/DotNetty.Codecs.Http/Multipart/MixedFileUpload.cs @@ -4,6 +4,7 @@ namespace DotNetty.Codecs.Http.Multipart { using System.IO; + using System.Runtime.CompilerServices; using System.Text; using DotNetty.Buffers; using DotNetty.Common; @@ -46,11 +47,12 @@ public long MaxSize } } + [MethodImpl(InlineMethod.Value)] public void CheckSize(long newSize) { if (this.maxSize >= 0 && newSize > this.maxSize) { - throw new IOException($"{this.DataType} Size exceed allowed maximum capacity"); + ThrowHelper.ThrowIOException_CheckSize(this.DataType); } } diff --git a/src/DotNetty.Codecs.Http/QueryStringDecoder.cs b/src/DotNetty.Codecs.Http/QueryStringDecoder.cs index f9d5f1bd4..c3f5a5100 100644 --- a/src/DotNetty.Codecs.Http/QueryStringDecoder.cs +++ b/src/DotNetty.Codecs.Http/QueryStringDecoder.cs @@ -222,7 +222,7 @@ static string DecodeComponent(string s, int from, int toExcluded, Encoding chars { if (i + 3 > toExcluded) { - throw new ArgumentException($"unterminated escape sequence at index {i} of: {s}"); + ThrowHelper.ThrowArgumentException_UnterminatedEscapeSeq(i, s); } byteBuf[idx++] = StringUtil.DecodeHexByte(s, i + 1); i += 3; diff --git a/src/DotNetty.Codecs.Http/ThrowHelper.cs b/src/DotNetty.Codecs.Http/ThrowHelper.cs index 55d2ff7b8..5556245ab 100644 --- a/src/DotNetty.Codecs.Http/ThrowHelper.cs +++ b/src/DotNetty.Codecs.Http/ThrowHelper.cs @@ -8,7 +8,7 @@ namespace DotNetty.Codecs.Http using System.Runtime.CompilerServices; using DotNetty.Common.Utilities; - static class ThrowHelper + static partial class ThrowHelper { [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowArgumentException_NullText() diff --git a/src/DotNetty.Codecs.Http/WebSockets/ContinuationWebSocketFrame.cs b/src/DotNetty.Codecs.Http/WebSockets/ContinuationWebSocketFrame.cs index 6854fe2b2..0b523d363 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/ContinuationWebSocketFrame.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/ContinuationWebSocketFrame.cs @@ -30,7 +30,7 @@ public ContinuationWebSocketFrame(bool finalFragment, int rsv, string text) public string Text() => this.Content.ToString(Encoding.UTF8); - static IByteBuffer FromText(string text) => string.IsNullOrEmpty(text) + static IByteBuffer FromText(string text) => string.IsNullOrEmpty(text) ? Unpooled.Empty : Unpooled.CopiedBuffer(text, Encoding.UTF8); public override IByteBufferHolder Replace(IByteBuffer content) => new ContinuationWebSocketFrame(this.IsFinalFragment, this.Rsv, content); diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateDecoder.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateDecoder.cs index b119e2f25..e434b98db 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateDecoder.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateDecoder.cs @@ -30,9 +30,18 @@ protected override void Decode(IChannelHandlerContext ctx, WebSocketFrame msg, L { if (this.decoder == null) { - if (!(msg is TextWebSocketFrame) && !(msg is BinaryWebSocketFrame)) + //if (!(msg is TextWebSocketFrame) && !(msg is BinaryWebSocketFrame)) + //{ + // ThrowHelper.ThrowCodecException_UnexpectedInitialFrameType(msg); + //} + switch (msg) { - throw new CodecException($"unexpected initial frame type: {msg.GetType().Name}"); + case TextWebSocketFrame _: + case BinaryWebSocketFrame _: + break; + default: + ThrowHelper.ThrowCodecException_UnexpectedInitialFrameType(msg); + break; } this.decoder = new EmbeddedChannel(ZlibCodecFactory.NewZlibDecoder(ZlibWrapper.None)); @@ -46,7 +55,7 @@ protected override void Decode(IChannelHandlerContext ctx, WebSocketFrame msg, L } CompositeByteBuffer compositeUncompressedContent = ctx.Allocator.CompositeDirectBuffer(); - for (;;) + while(true) { var partUncompressedContent = this.decoder.ReadInbound(); if (partUncompressedContent == null) @@ -68,7 +77,7 @@ protected override void Decode(IChannelHandlerContext ctx, WebSocketFrame msg, L if (readable && compositeUncompressedContent.NumComponents <= 0) { compositeUncompressedContent.Release(); - throw new CodecException("cannot read uncompressed buffer"); + ThrowHelper.ThrowCodecException_CannotReadUncompressedBuf(); } if (msg.IsFinalFragment && this.noContext) @@ -76,24 +85,22 @@ protected override void Decode(IChannelHandlerContext ctx, WebSocketFrame msg, L this.Cleanup(); } - WebSocketFrame outMsg; - if (msg is TextWebSocketFrame) + WebSocketFrame outMsg = null; + switch (msg) { - outMsg = new TextWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent); - } - else if (msg is BinaryWebSocketFrame) - { - outMsg = new BinaryWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent); - } - else if (msg is ContinuationWebSocketFrame) - { - outMsg = new ContinuationWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent); - } - else - { - throw new CodecException($"unexpected frame type: {msg.GetType().Name}"); + case TextWebSocketFrame _: + outMsg = new TextWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent); + break; + case BinaryWebSocketFrame _: + outMsg = new BinaryWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent); + break; + case ContinuationWebSocketFrame _: + outMsg = new ContinuationWebSocketFrame(msg.IsFinalFragment, this.NewRsv(msg), compositeUncompressedContent); + break; + default: + ThrowHelper.ThrowCodecException_UnexpectedFrameType(msg); + break; } - output.Add(outMsg); } @@ -116,7 +123,7 @@ void Cleanup() // Clean-up the previous encoder if not cleaned up correctly. if (this.decoder.Finish()) { - for (;;) + while(true) { var buf = this.decoder.ReadOutbound(); if (buf == null) diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateEncoder.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateEncoder.cs index abcf36ac7..1e7770d48 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateEncoder.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateEncoder.cs @@ -45,7 +45,7 @@ protected override void Encode(IChannelHandlerContext ctx, WebSocketFrame msg, L this.encoder.WriteOutbound(msg.Content.Retain()); CompositeByteBuffer fullCompressedContent = ctx.Allocator.CompositeBuffer(); - for (;;) + while(true) { var partCompressedContent = this.encoder.ReadOutbound(); if (partCompressedContent == null) @@ -65,7 +65,7 @@ protected override void Encode(IChannelHandlerContext ctx, WebSocketFrame msg, L if (fullCompressedContent.NumComponents <= 0) { fullCompressedContent.Release(); - throw new CodecException("cannot read compressed buffer"); + ThrowHelper.ThrowCodecException_CannotReadCompressedBuf(); } if (msg.IsFinalFragment && this.noContext) @@ -84,24 +84,22 @@ protected override void Encode(IChannelHandlerContext ctx, WebSocketFrame msg, L compressedContent = fullCompressedContent; } - WebSocketFrame outMsg; - if (msg is TextWebSocketFrame) + WebSocketFrame outMsg = null; + switch (msg) { - outMsg = new TextWebSocketFrame(msg.IsFinalFragment, this.Rsv(msg), compressedContent); - } - else if (msg is BinaryWebSocketFrame) - { - outMsg = new BinaryWebSocketFrame(msg.IsFinalFragment, this.Rsv(msg), compressedContent); - } - else if (msg is ContinuationWebSocketFrame) - { - outMsg = new ContinuationWebSocketFrame(msg.IsFinalFragment, this.Rsv(msg), compressedContent); - } - else - { - throw new CodecException($"unexpected frame type: {msg.GetType().Name}"); + case TextWebSocketFrame _: + outMsg = new TextWebSocketFrame(msg.IsFinalFragment, this.Rsv(msg), compressedContent); + break; + case BinaryWebSocketFrame _: + outMsg = new BinaryWebSocketFrame(msg.IsFinalFragment, this.Rsv(msg), compressedContent); + break; + case ContinuationWebSocketFrame _: + outMsg = new ContinuationWebSocketFrame(msg.IsFinalFragment, this.Rsv(msg), compressedContent); + break; + default: + ThrowHelper.ThrowCodecException_UnexpectedFrameType(msg); + break; } - output.Add(outMsg); } @@ -118,7 +116,7 @@ void Cleanup() // Clean-up the previous encoder if not cleaned up correctly. if (this.encoder.Finish()) { - for (;;) + while(true) { var buf = this.encoder.ReadOutbound(); if (buf == null) diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateFrameClientExtensionHandshaker.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateFrameClientExtensionHandshaker.cs index c5600dae7..cebd1e193 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateFrameClientExtensionHandshaker.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateFrameClientExtensionHandshaker.cs @@ -22,7 +22,7 @@ public DeflateFrameClientExtensionHandshaker(int compressionLevel, bool useWebki { if (compressionLevel < 0 || compressionLevel > 9) { - throw new ArgumentException($"compressionLevel: {compressionLevel} (expected: 0-9)"); + ThrowHelper.ThrowArgumentException_CompressionLevel(compressionLevel); } this.compressionLevel = compressionLevel; this.useWebkitExtensionName = useWebkitExtensionName; @@ -30,23 +30,40 @@ public DeflateFrameClientExtensionHandshaker(int compressionLevel, bool useWebki public WebSocketExtensionData NewRequestData() => new WebSocketExtensionData( this.useWebkitExtensionName ? XWebkitDeflateFrameExtension : DeflateFrameExtension, - new Dictionary()); + new Dictionary(StringComparer.Ordinal)); public IWebSocketClientExtension HandshakeExtension(WebSocketExtensionData extensionData) { - if (!XWebkitDeflateFrameExtension.Equals(extensionData.Name) && - !DeflateFrameExtension.Equals(extensionData.Name)) - { - return null; - } + //if (!string.Equals(XWebkitDeflateFrameExtension, extensionData.Name, StringComparison.Ordinal) && + // !string.Equals(DeflateFrameExtension, extensionData.Name, StringComparison.Ordinal)) + //{ + // return null; + //} - if (extensionData.Parameters.Count == 0) + //if (extensionData.Parameters.Count == 0) + //{ + // return new DeflateFrameClientExtension(this.compressionLevel); + //} + //else + //{ + // return null; + //} + var extensionDataName = extensionData.Name; + switch (extensionDataName) { - return new DeflateFrameClientExtension(this.compressionLevel); - } - else - { - return null; + case XWebkitDeflateFrameExtension: + case DeflateFrameExtension: + if (extensionData.Parameters.Count == 0) + { + return new DeflateFrameClientExtension(this.compressionLevel); + } + else + { + return null; + } + + default: + return null; } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateFrameServerExtensionHandshaker.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateFrameServerExtensionHandshaker.cs index 9d6c24a38..2919bc31f 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateFrameServerExtensionHandshaker.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/DeflateFrameServerExtensionHandshaker.cs @@ -8,8 +8,8 @@ namespace DotNetty.Codecs.Http.WebSockets.Extensions.Compression public sealed class DeflateFrameServerExtensionHandshaker : IWebSocketServerExtensionHandshaker { - internal static readonly string XWebkitDeflateFrameExtension = "x-webkit-deflate-frame"; - internal static readonly string DeflateFrameExtension = "deflate-frame"; + internal const string XWebkitDeflateFrameExtension = "x-webkit-deflate-frame"; + internal const string DeflateFrameExtension = "deflate-frame"; readonly int compressionLevel; @@ -22,26 +22,43 @@ public DeflateFrameServerExtensionHandshaker(int compressionLevel) { if (compressionLevel < 0 || compressionLevel > 9) { - throw new ArgumentException($"compressionLevel: {compressionLevel} (expected: 0-9)"); + ThrowHelper.ThrowArgumentException_CompressionLevel(compressionLevel); } this.compressionLevel = compressionLevel; } public IWebSocketServerExtension HandshakeExtension(WebSocketExtensionData extensionData) { - if (!XWebkitDeflateFrameExtension.Equals(extensionData.Name) - && !DeflateFrameExtension.Equals(extensionData.Name)) - { - return null; - } + //if (!string.Equals(XWebkitDeflateFrameExtension, extensionData.Name, StringComparison.Ordinal) + // && !string.Equals(DeflateFrameExtension, extensionData.Name, StringComparison.Ordinal)) + //{ + // return null; + //} - if (extensionData.Parameters.Count == 0) + //if (extensionData.Parameters.Count == 0) + //{ + // return new DeflateFrameServerExtension(this.compressionLevel, extensionData.Name); + //} + //else + //{ + // return null; + //} + var extensionDataName = extensionData.Name; + switch (extensionDataName) { - return new DeflateFrameServerExtension(this.compressionLevel, extensionData.Name); - } - else - { - return null; + case XWebkitDeflateFrameExtension: + case DeflateFrameExtension: + if (extensionData.Parameters.Count == 0) + { + return new DeflateFrameServerExtension(this.compressionLevel, extensionData.Name); + } + else + { + return null; + } + + default: + return null; } } @@ -62,7 +79,7 @@ public DeflateFrameServerExtension(int compressionLevel, string extensionName) public WebSocketExtensionDecoder NewExtensionDecoder() => new PerFrameDeflateDecoder(false); - public WebSocketExtensionData NewReponseData() => new WebSocketExtensionData(this.extensionName, new Dictionary()); + public WebSocketExtensionData NewReponseData() => new WebSocketExtensionData(this.extensionName, new Dictionary(StringComparer.Ordinal)); } } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerFrameDeflateDecoder.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerFrameDeflateDecoder.cs index 00e595d71..07078944c 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerFrameDeflateDecoder.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerFrameDeflateDecoder.cs @@ -10,9 +10,22 @@ public PerFrameDeflateDecoder(bool noContext) { } - public override bool AcceptInboundMessage(object msg) => - (msg is TextWebSocketFrame || msg is BinaryWebSocketFrame || msg is ContinuationWebSocketFrame) - && (((WebSocketFrame) msg).Rsv & WebSocketRsv.Rsv1) > 0; + public override bool AcceptInboundMessage(object msg) + { + switch (msg) + { + case TextWebSocketFrame textFrame when (textFrame.Rsv & WebSocketRsv.Rsv1) > 0: + return true; + case BinaryWebSocketFrame binFrame when (binFrame.Rsv & WebSocketRsv.Rsv1) > 0: + return true; + case ContinuationWebSocketFrame conFrame when (conFrame.Rsv & WebSocketRsv.Rsv1) > 0: + return true; + default: + return false; + } + //return (msg is TextWebSocketFrame || msg is BinaryWebSocketFrame || msg is ContinuationWebSocketFrame) + //&& (((WebSocketFrame)msg).Rsv & WebSocketRsv.Rsv1) > 0; + } protected override int NewRsv(WebSocketFrame msg) => msg.Rsv ^ WebSocketRsv.Rsv1; diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerFrameDeflateEncoder.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerFrameDeflateEncoder.cs index 4b5937d80..f6ba24d52 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerFrameDeflateEncoder.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerFrameDeflateEncoder.cs @@ -10,10 +10,23 @@ public PerFrameDeflateEncoder(int compressionLevel, int windowSize, bool noConte { } - public override bool AcceptOutboundMessage(object msg) => - (msg is TextWebSocketFrame || msg is BinaryWebSocketFrame || msg is ContinuationWebSocketFrame) - && ((WebSocketFrame)msg).Content.ReadableBytes > 0 - && (((WebSocketFrame)msg).Rsv & WebSocketRsv.Rsv1) == 0; + public override bool AcceptOutboundMessage(object msg) + { + switch (msg) + { + case TextWebSocketFrame textFrame when textFrame.Content.ReadableBytes > 0 && (textFrame.Rsv & WebSocketRsv.Rsv1) == 0: + return true; + case BinaryWebSocketFrame binFrame when binFrame.Content.ReadableBytes > 0 && (binFrame.Rsv & WebSocketRsv.Rsv1) == 0: + return true; + case ContinuationWebSocketFrame conFrame when conFrame.Content.ReadableBytes > 0 && (conFrame.Rsv & WebSocketRsv.Rsv1) == 0: + return true; + default: + return false; + } + //return (msg is TextWebSocketFrame || msg is BinaryWebSocketFrame || msg is ContinuationWebSocketFrame) + //&& ((WebSocketFrame)msg).Content.ReadableBytes > 0 + //&& (((WebSocketFrame)msg).Rsv & WebSocketRsv.Rsv1) == 0; + } protected override int Rsv(WebSocketFrame msg) => msg.Rsv | WebSocketRsv.Rsv1; diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateClientExtensionHandshaker.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateClientExtensionHandshaker.cs index 45599f331..4d90349f6 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateClientExtensionHandshaker.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateClientExtensionHandshaker.cs @@ -28,11 +28,11 @@ public PerMessageDeflateClientExtensionHandshaker(int compressionLevel, { if (requestedServerWindowSize > MaxWindowSize || requestedServerWindowSize < MinWindowSize) { - throw new ArgumentException($"requestedServerWindowSize: {requestedServerWindowSize} (expected: 8-15)"); + ThrowHelper.ThrowArgumentException_WindowSize(ExceptionArgument.requestedServerWindowSize, requestedServerWindowSize); } if (compressionLevel < 0 || compressionLevel > 9) { - throw new ArgumentException($"compressionLevel: {compressionLevel} (expected: 0-9)"); + ThrowHelper.ThrowArgumentException_CompressionLevel(compressionLevel); } this.compressionLevel = compressionLevel; this.allowClientWindowSize = allowClientWindowSize; @@ -43,7 +43,7 @@ public PerMessageDeflateClientExtensionHandshaker(int compressionLevel, public WebSocketExtensionData NewRequestData() { - var parameters = new Dictionary(4); + var parameters = new Dictionary(4, StringComparer.Ordinal); if (this.requestedServerWindowSize != MaxWindowSize) { parameters.Add(ServerNoContext, null); @@ -65,7 +65,7 @@ public WebSocketExtensionData NewRequestData() public IWebSocketClientExtension HandshakeExtension(WebSocketExtensionData extensionData) { - if (!PerMessageDeflateExtension.Equals(extensionData.Name)) + if (!string.Equals(PerMessageDeflateExtension, extensionData.Name, StringComparison.Ordinal)) { return null; } @@ -78,7 +78,8 @@ public IWebSocketClientExtension HandshakeExtension(WebSocketExtensionData exten foreach (KeyValuePair parameter in extensionData.Parameters) { - if (ClientMaxWindow.Equals(parameter.Key, StringComparison.OrdinalIgnoreCase)) + var parameterKey = parameter.Key; + if (string.Equals(ClientMaxWindow, parameterKey, StringComparison.OrdinalIgnoreCase)) { // allowed client_window_size_bits if (this.allowClientWindowSize) @@ -90,7 +91,7 @@ public IWebSocketClientExtension HandshakeExtension(WebSocketExtensionData exten succeed = false; } } - else if (ServerMaxWindow.Equals(parameter.Key, StringComparison.OrdinalIgnoreCase)) + else if (string.Equals(ServerMaxWindow, parameterKey, StringComparison.OrdinalIgnoreCase)) { // acknowledged server_window_size_bits serverWindowSize = int.Parse(parameter.Value); @@ -99,7 +100,7 @@ public IWebSocketClientExtension HandshakeExtension(WebSocketExtensionData exten succeed = false; } } - else if (ClientNoContext.Equals(parameter.Key, StringComparison.OrdinalIgnoreCase)) + else if (string.Equals(ClientNoContext, parameterKey, StringComparison.OrdinalIgnoreCase)) { // allowed client_no_context_takeover if (this.allowClientNoContext) @@ -111,7 +112,7 @@ public IWebSocketClientExtension HandshakeExtension(WebSocketExtensionData exten succeed = false; } } - else if (ServerNoContext.Equals(parameter.Key, StringComparison.OrdinalIgnoreCase)) + else if (string.Equals(ServerNoContext, parameterKey, StringComparison.OrdinalIgnoreCase)) { // acknowledged server_no_context_takeover if (this.requestedServerNoContext) diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateDecoder.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateDecoder.cs index 516f10ce4..148ec0da6 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateDecoder.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateDecoder.cs @@ -15,12 +15,24 @@ public PerMessageDeflateDecoder(bool noContext) { } - public override bool AcceptInboundMessage(object msg) => - ((msg is TextWebSocketFrame || msg is BinaryWebSocketFrame) - && (((WebSocketFrame)msg).Rsv & WebSocketRsv.Rsv1) > 0) - || (msg is ContinuationWebSocketFrame && this.compressing); + public override bool AcceptInboundMessage(object msg) + { + switch (msg) + { + case TextWebSocketFrame textFrame when (textFrame.Rsv & WebSocketRsv.Rsv1) > 0: + return true; + case BinaryWebSocketFrame binFrame when (binFrame.Rsv & WebSocketRsv.Rsv1) > 0: + return true; + case ContinuationWebSocketFrame conFrame when this.compressing: + return true; + default: + return false; + } + //return ((msg is TextWebSocketFrame || msg is BinaryWebSocketFrame) && (((WebSocketFrame)msg).Rsv & WebSocketRsv.Rsv1) > 0) + // || (msg is ContinuationWebSocketFrame && this.compressing); + } - protected override int NewRsv(WebSocketFrame msg) => + protected override int NewRsv(WebSocketFrame msg) => (msg.Rsv & WebSocketRsv.Rsv1) > 0 ? msg.Rsv ^ WebSocketRsv.Rsv1 : msg.Rsv; protected override bool AppendFrameTail(WebSocketFrame msg) => msg.IsFinalFragment; @@ -33,9 +45,15 @@ protected override void Decode(IChannelHandlerContext ctx, WebSocketFrame msg, L { this.compressing = false; } - else if (msg is TextWebSocketFrame || msg is BinaryWebSocketFrame) + else //if (msg is TextWebSocketFrame || msg is BinaryWebSocketFrame) { - this.compressing = true; + switch (msg) + { + case TextWebSocketFrame _: + case BinaryWebSocketFrame _: + this.compressing = true; + break; + } } } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateEncoder.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateEncoder.cs index 9bd2a91fa..2d544072b 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateEncoder.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateEncoder.cs @@ -15,15 +15,38 @@ public PerMessageDeflateEncoder(int compressionLevel, int windowSize, bool noCon { } - public override bool AcceptOutboundMessage(object msg) => - ((msg is TextWebSocketFrame || msg is BinaryWebSocketFrame) - && (((WebSocketFrame) msg).Rsv & WebSocketRsv.Rsv1) == 0) - || (msg is ContinuationWebSocketFrame && this.compressing); + public override bool AcceptOutboundMessage(object msg) + { + switch (msg) + { + case TextWebSocketFrame textFrame when (textFrame.Rsv & WebSocketRsv.Rsv1) == 0: + return true; + case BinaryWebSocketFrame binFrame when (binFrame.Rsv & WebSocketRsv.Rsv1) == 0: + return true; + case ContinuationWebSocketFrame conFrame when this.compressing: + return true; + default: + return false; + } + //return ((msg is TextWebSocketFrame || msg is BinaryWebSocketFrame) + // && (((WebSocketFrame)msg).Rsv & WebSocketRsv.Rsv1) == 0) + //|| (msg is ContinuationWebSocketFrame && this.compressing); + } - protected override int Rsv(WebSocketFrame msg) => - msg is TextWebSocketFrame || msg is BinaryWebSocketFrame - ? msg.Rsv | WebSocketRsv.Rsv1 - : msg.Rsv; + protected override int Rsv(WebSocketFrame msg) + { + switch (msg) + { + case TextWebSocketFrame _: + case BinaryWebSocketFrame _: + return msg.Rsv | WebSocketRsv.Rsv1; + default: + return msg.Rsv; + } + //return msg is TextWebSocketFrame || msg is BinaryWebSocketFrame + // ? msg.Rsv | WebSocketRsv.Rsv1 + // : msg.Rsv; + } protected override bool RemoveFrameTail(WebSocketFrame msg) => msg.IsFinalFragment; @@ -35,9 +58,15 @@ protected override void Encode(IChannelHandlerContext ctx, WebSocketFrame msg, L { this.compressing = false; } - else if (msg is TextWebSocketFrame || msg is BinaryWebSocketFrame) + else //if (msg is TextWebSocketFrame || msg is BinaryWebSocketFrame) { - this.compressing = true; + switch (msg) + { + case TextWebSocketFrame _: + case BinaryWebSocketFrame _: + this.compressing = true; + break; + } } } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateServerExtensionHandshaker.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateServerExtensionHandshaker.cs index 6275ac929..21615d376 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateServerExtensionHandshaker.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/Compression/PerMessageDeflateServerExtensionHandshaker.cs @@ -9,14 +9,14 @@ namespace DotNetty.Codecs.Http.WebSockets.Extensions.Compression public sealed class PerMessageDeflateServerExtensionHandshaker : IWebSocketServerExtensionHandshaker { - public static readonly int MinWindowSize = 8; - public static readonly int MaxWindowSize = 15; + public const int MinWindowSize = 8; + public const int MaxWindowSize = 15; - internal static readonly string PerMessageDeflateExtension = "permessage-deflate"; - internal static readonly string ClientMaxWindow = "client_max_window_bits"; - internal static readonly string ServerMaxWindow = "server_max_window_bits"; - internal static readonly string ClientNoContext = "client_no_context_takeover"; - internal static readonly string ServerNoContext = "server_no_context_takeover"; + internal const string PerMessageDeflateExtension = "permessage-deflate"; + internal const string ClientMaxWindow = "client_max_window_bits"; + internal const string ServerMaxWindow = "server_max_window_bits"; + internal const string ClientNoContext = "client_no_context_takeover"; + internal const string ServerNoContext = "server_no_context_takeover"; readonly int compressionLevel; readonly bool allowServerWindowSize; @@ -35,11 +35,11 @@ public PerMessageDeflateServerExtensionHandshaker(int compressionLevel, { if (preferredClientWindowSize > MaxWindowSize || preferredClientWindowSize < MinWindowSize) { - throw new ArgumentException($"preferredServerWindowSize: {preferredClientWindowSize} (expected: 8-15)"); + ThrowHelper.ThrowArgumentException_WindowSize(ExceptionArgument.preferredClientWindowSize, preferredClientWindowSize); } if (compressionLevel < 0 || compressionLevel > 9) { - throw new ArgumentException($"compressionLevel: {compressionLevel} (expected: 0-9)"); + ThrowHelper.ThrowArgumentException_CompressionLevel(compressionLevel); } this.compressionLevel = compressionLevel; this.allowServerWindowSize = allowServerWindowSize; @@ -50,7 +50,7 @@ public PerMessageDeflateServerExtensionHandshaker(int compressionLevel, public IWebSocketServerExtension HandshakeExtension(WebSocketExtensionData extensionData) { - if (!PerMessageDeflateExtension.Equals(extensionData.Name)) + if (!string.Equals(PerMessageDeflateExtension, extensionData.Name, StringComparison.Ordinal)) { return null; } @@ -63,12 +63,13 @@ public IWebSocketServerExtension HandshakeExtension(WebSocketExtensionData exten foreach (KeyValuePair parameter in extensionData.Parameters) { - if (ClientMaxWindow.Equals(parameter.Key, StringComparison.OrdinalIgnoreCase)) + var parameterKey = parameter.Key; + if (string.Equals(ClientMaxWindow, parameterKey, StringComparison.OrdinalIgnoreCase)) { // use preferred clientWindowSize because client is compatible with customization clientWindowSize = this.preferredClientWindowSize; } - else if (ServerMaxWindow.Equals(parameter.Key, StringComparison.OrdinalIgnoreCase)) + else if (string.Equals(ServerMaxWindow, parameterKey, StringComparison.OrdinalIgnoreCase)) { // use provided windowSize if it is allowed if (this.allowServerWindowSize) @@ -84,12 +85,12 @@ public IWebSocketServerExtension HandshakeExtension(WebSocketExtensionData exten deflateEnabled = false; } } - else if (ClientNoContext.Equals(parameter.Key, StringComparison.OrdinalIgnoreCase)) + else if (string.Equals(ClientNoContext, parameterKey, StringComparison.OrdinalIgnoreCase)) { // use preferred clientNoContext because client is compatible with customization clientNoContext = this.preferredClientNoContext; } - else if (ServerNoContext.Equals(parameter.Key, StringComparison.OrdinalIgnoreCase)) + else if (string.Equals(ServerNoContext, parameterKey, StringComparison.OrdinalIgnoreCase)) { // use server no context if allowed if (this.allowServerNoContext) @@ -150,7 +151,7 @@ public WebSocketExtensionEncoder NewExtensionEncoder() => public WebSocketExtensionData NewReponseData() { - var parameters = new Dictionary(4); + var parameters = new Dictionary(4, StringComparer.Ordinal); if (this.serverNoContext) { parameters.Add(ServerNoContext, null); diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketClientExtensionHandler.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketClientExtensionHandler.cs index 5a72c6d1c..3d3e23da3 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketClientExtensionHandler.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketClientExtensionHandler.cs @@ -79,7 +79,7 @@ public override void ChannelRead(IChannelHandlerContext ctx, object msg) } else { - throw new CodecException($"invalid WebSocket Extension handshake for \"{extensionsHeader}\""); + ThrowHelper.ThrowCodecException_InvalidWSExHandshake(extensionsHeader); } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketExtensionData.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketExtensionData.cs index 9196c5963..46455fa0f 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketExtensionData.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketExtensionData.cs @@ -18,7 +18,7 @@ public WebSocketExtensionData(string name, IDictionary parameter Contract.Requires(parameters != null); this.name = name; - this.parameters = new Dictionary(parameters); + this.parameters = new Dictionary(parameters, System.StringComparer.Ordinal); } public string Name => this.name; diff --git a/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketExtensionUtil.cs b/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketExtensionUtil.cs index 169fb1064..ec9b5271d 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketExtensionUtil.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/Extensions/WebSocketExtensionUtil.cs @@ -32,7 +32,7 @@ public static List ExtractExtensions(string extensionHea Dictionary parameters; if (extensionParameters.Length > 1) { - parameters = new Dictionary(extensionParameters.Length - 1); + parameters = new Dictionary(extensionParameters.Length - 1, System.StringComparer.Ordinal); for (int i = 1; i < extensionParameters.Length; i++) { string parameter = extensionParameters[i].Trim(); @@ -46,7 +46,7 @@ public static List ExtractExtensions(string extensionHea } else { - parameters = new Dictionary(); + parameters = new Dictionary(System.StringComparer.Ordinal); } extensions.Add(new WebSocketExtensionData(name, parameters)); } diff --git a/src/DotNetty.Codecs.Http/WebSockets/TextWebSocketFrame.cs b/src/DotNetty.Codecs.Http/WebSockets/TextWebSocketFrame.cs index 399267956..8c393b6d0 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/TextWebSocketFrame.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/TextWebSocketFrame.cs @@ -28,7 +28,7 @@ public TextWebSocketFrame(bool finalFragment, int rsv, string text) { } - static IByteBuffer FromText(string text) => string.IsNullOrEmpty(text) + static IByteBuffer FromText(string text) => string.IsNullOrEmpty(text) ? Unpooled.Empty : Unpooled.CopiedBuffer(text, Encoding.UTF8); public TextWebSocketFrame(bool finalFragment, int rsv, IByteBuffer binaryData) diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocket00FrameDecoder.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocket00FrameDecoder.cs index e349f6602..bdc36fa46 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocket00FrameDecoder.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocket00FrameDecoder.cs @@ -72,13 +72,13 @@ WebSocketFrame DecodeBinaryFrame(IChannelHandlerContext ctx, byte type, IByteBuf frameSize |= (uint)(b & 0x7f); if (frameSize > this.maxFrameSize) { - throw new TooLongFrameException(nameof(WebSocket00FrameDecoder)); + ThrowHelper.ThrowTooLongFrameException_WebSocket00FrameDecoder(); } lengthFieldSize++; if (lengthFieldSize > 8) { // Perhaps a malicious peer? - throw new TooLongFrameException(nameof(WebSocket00FrameDecoder)); + ThrowHelper.ThrowTooLongFrameException_WebSocket00FrameDecoder(); } } while ((b & 0x80) == 0x80); @@ -102,7 +102,7 @@ WebSocketFrame DecodeTextFrame(IChannelHandlerContext ctx, IByteBuffer buffer) if (rbytes > this.maxFrameSize) { // Frame length exceeded the maximum - throw new TooLongFrameException(nameof(WebSocket00FrameDecoder)); + ThrowHelper.ThrowTooLongFrameException_WebSocket00FrameDecoder(); } else { @@ -114,7 +114,7 @@ WebSocketFrame DecodeTextFrame(IChannelHandlerContext ctx, IByteBuffer buffer) int frameSize = delimPos - ridx; if (frameSize > this.maxFrameSize) { - throw new TooLongFrameException(nameof(WebSocket00FrameDecoder)); + ThrowHelper.ThrowTooLongFrameException_WebSocket00FrameDecoder(); } IByteBuffer binaryData = ReadBytes(ctx.Allocator, buffer, frameSize); @@ -124,7 +124,7 @@ WebSocketFrame DecodeTextFrame(IChannelHandlerContext ctx, IByteBuffer buffer) if (ffDelimPos >= 0) { binaryData.Release(); - throw new ArgumentException("a text frame should not contain 0xFF."); + ThrowHelper.ThrowArgumentException_TextFrame(); } return new TextWebSocketFrame(binaryData); diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocket00FrameEncoder.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocket00FrameEncoder.cs index c90543f87..265b0e24e 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocket00FrameEncoder.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocket00FrameEncoder.cs @@ -24,80 +24,77 @@ public class WebSocket00FrameEncoder : MessageToMessageEncoder, protected override void Encode(IChannelHandlerContext context, WebSocketFrame message, List output) { - if (message is TextWebSocketFrame) + switch (message) { - // Text frame - IByteBuffer data = message.Content; + case TextWebSocketFrame _: + // Text frame + IByteBuffer data0 = message.Content; - output.Add(_0X00.Duplicate()); - output.Add(data.Retain()); - output.Add(_0XFF.Duplicate()); - } - else if (message is CloseWebSocketFrame) - { - // Close frame, needs to call duplicate to allow multiple writes. - // See https://github.com/netty/netty/issues/2768 - output.Add(_0XFF_0X00.Duplicate()); - } - else - { - // Binary frame - IByteBuffer data = message.Content; - int dataLen = data.ReadableBytes; - - IByteBuffer buf = context.Allocator.Buffer(5); - bool release = true; - try - { - // Encode type. - buf.WriteByte(0x80); + output.Add(_0X00.Duplicate()); + output.Add(data0.Retain()); + output.Add(_0XFF.Duplicate()); + break; + case CloseWebSocketFrame _: + // Close frame, needs to call duplicate to allow multiple writes. + // See https://github.com/netty/netty/issues/2768 + output.Add(_0XFF_0X00.Duplicate()); + break; + default: + // Binary frame + IByteBuffer data = message.Content; + int dataLen = data.ReadableBytes; - // Encode length. - int b1 = dataLen.RightUShift(28) & 0x7F; - int b2 = dataLen.RightUShift(14) & 0x7F; - int b3 = dataLen.RightUShift(7) & 0x7F; - int b4 = dataLen & 0x7F; - if (b1 == 0) + IByteBuffer buf = context.Allocator.Buffer(5); + bool release = true; + try { - if (b2 == 0) + // Encode type. + buf.WriteByte(0x80); + + // Encode length. + int b1 = dataLen.RightUShift(28) & 0x7F; + int b2 = dataLen.RightUShift(14) & 0x7F; + int b3 = dataLen.RightUShift(7) & 0x7F; + int b4 = dataLen & 0x7F; + if (b1 == 0) { - if (b3 == 0) + if (b2 == 0) { - buf.WriteByte(b4); + if (b3 == 0) + { + buf.WriteByte(b4); + } + else + { + buf.WriteByte(b3 | 0x80); + buf.WriteByte(b4); + } } else { + buf.WriteByte(b2 | 0x80); buf.WriteByte(b3 | 0x80); buf.WriteByte(b4); } } else { + buf.WriteByte(b1 | 0x80); buf.WriteByte(b2 | 0x80); buf.WriteByte(b3 | 0x80); buf.WriteByte(b4); } - } - else - { - buf.WriteByte(b1 | 0x80); - buf.WriteByte(b2 | 0x80); - buf.WriteByte(b3 | 0x80); - buf.WriteByte(b4); - } - // Encode binary data. - output.Add(buf); - output.Add(data.Retain()); - release = false; - } - finally - { - if (release) + // Encode binary data. + output.Add(buf); + output.Add(data.Retain()); + release = false; + } + finally { - buf.Release(); + if (release) { buf.Release(); } } - } + break; } } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocket08FrameDecoder.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocket08FrameDecoder.cs index 418b8d252..6f55d233c 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocket08FrameDecoder.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocket08FrameDecoder.cs @@ -91,7 +91,7 @@ protected override void Decode(IChannelHandlerContext context, IByteBuffer input if (Logger.DebugEnabled) { - Logger.Debug("Decoding WebSocket Frame opCode={}", this.frameOpcode); + Logger.DecodingWebSocketFrameOpCode(this.frameOpcode); } this.state = State.ReadingSecond; @@ -225,7 +225,7 @@ protected override void Decode(IChannelHandlerContext context, IByteBuffer input if (Logger.DebugEnabled) { - Logger.Debug("Decoding WebSocket Frame length={}", this.framePayloadLength); + Logger.DecodingWebSocketFrameLength(this.framePayloadLength); } this.state = State.MaskingKey; @@ -344,7 +344,7 @@ protected override void Decode(IChannelHandlerContext context, IByteBuffer input } return; default: - throw new Exception("Shouldn't reach here."); + ThrowHelper.ThrowException_FrameDecoder(); break; } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocket08FrameEncoder.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocket08FrameEncoder.cs index 46769f166..fbc604a98 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocket08FrameEncoder.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocket08FrameEncoder.cs @@ -45,40 +45,36 @@ protected override unsafe void Encode(IChannelHandlerContext ctx, WebSocketFrame var mask = stackalloc byte[4]; byte opcode = 0; - if (msg is TextWebSocketFrame) + switch (msg) { - opcode = OpcodeText; - } - else if (msg is PingWebSocketFrame) - { - opcode = OpcodePing; - } - else if (msg is PongWebSocketFrame) - { - opcode = OpcodePong; - } - else if (msg is CloseWebSocketFrame) - { - opcode = OpcodeClose; - } - else if (msg is BinaryWebSocketFrame) - { - opcode = OpcodeBinary; - } - else if (msg is ContinuationWebSocketFrame) - { - opcode = OpcodeCont; - } - else - { - ThrowNotSupportedException(msg); + case TextWebSocketFrame _: + opcode = OpcodeText; + break; + case PingWebSocketFrame _: + opcode = OpcodePing; + break; + case PongWebSocketFrame _: + opcode = OpcodePong; + break; + case CloseWebSocketFrame _: + opcode = OpcodeClose; + break; + case BinaryWebSocketFrame _: + opcode = OpcodeBinary; + break; + case ContinuationWebSocketFrame _: + opcode = OpcodeCont; + break; + default: + ThrowNotSupportedException(msg); + break; } int length = data.ReadableBytes; if (Logger.DebugEnabled) { - Logger.Debug($"Encoding WebSocket Frame opCode={opcode} length={length}"); + Logger.EncodingWebSocketFrameOpCode(opcode, length); } int b0 = 0; diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker.cs index 40794cc6d..9a3ac39dc 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker.cs @@ -71,7 +71,7 @@ public Task HandshakeAsync(IChannel channel) var codec = channel.Pipeline.Get(); if (codec == null) { - return TaskUtil.FromException(new InvalidOperationException("ChannelPipeline does not contain a HttpResponseDecoder or HttpClientCodec")); + return ThrowHelper.ThrowInvalidOperationException_HttpResponseDecoder(); } } @@ -86,7 +86,7 @@ public Task HandshakeAsync(IChannel channel) IChannelHandlerContext ctx = p.Context() ?? p.Context(); if (ctx == null) { - tcs.TrySetException(new InvalidOperationException("ChannelPipeline does not contain a HttpRequestEncoder or HttpClientCodec")); + tcs.TrySetException(ThrowHelper.GetInvalidOperationException()); return; } @@ -100,7 +100,7 @@ public Task HandshakeAsync(IChannel channel) tcs.TryUnwrap(t.Exception); break; default: - throw new ArgumentOutOfRangeException(); + ThrowHelper.ThrowArgumentOutOfRangeException(); break; } }, completion, @@ -137,7 +137,7 @@ public void FinishHandshake(IChannel channel, IFullHttpResponse response) // We require a subprotocol and received one -> verify it foreach (string protocol in expectedProtocol.Split(',')) { - if (protocol.Trim().Equals(receivedProtocol)) + if (string.Equals(protocol.Trim(), receivedProtocol, StringComparison.Ordinal)) { protocolValid = true; this.ActualSubprotocol = receivedProtocol; @@ -148,7 +148,7 @@ public void FinishHandshake(IChannel channel, IFullHttpResponse response) if (!protocolValid) { - throw new WebSocketHandshakeException($"Invalid subprotocol. Actual: {receivedProtocol}. Expected one of: {this.expectedSubprotocol}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidSubprotocol(receivedProtocol, this.expectedSubprotocol); } this.SetHandshakeComplete(); @@ -174,7 +174,7 @@ public void FinishHandshake(IChannel channel, IFullHttpResponse response) ctx = p.Context(); if (ctx == null) { - throw new InvalidOperationException("ChannelPipeline does not contain a HttpRequestEncoder or HttpClientCodec"); + ThrowHelper.ThrowInvalidOperationException_HttpRequestEncoder(); } var codec = (HttpClientCodec)ctx.Handler; @@ -230,7 +230,7 @@ public Task ProcessHandshakeAsync(IChannel channel, IHttpResponse response) ctx = p.Context(); if (ctx == null) { - completionSource.TrySetException(new InvalidOperationException("ChannelPipeline does not contain a HttpResponseDecoder or HttpClientCodec")); + completionSource.TrySetException(ThrowHelper.GetInvalidOperationException()); } } else @@ -342,8 +342,8 @@ internal static string WebsocketHostValue(Uri wsUrl) } if (port == HttpScheme.Https.Port) { - return HttpScheme.Https.Name.ToString().Equals(scheme) - || WebSocketScheme.WSS.Name.ToString().Equals(scheme) + return string.Equals(HttpScheme.Https.Name.ToString(), scheme, StringComparison.Ordinal) + || string.Equals(WebSocketScheme.WSS.Name.ToString(), scheme, StringComparison.Ordinal) ? host : NetUtil.ToSocketAddressString(host, port); } @@ -386,7 +386,7 @@ internal static string WebsocketOriginValue(Uri wsUrl) } // Convert uri-host to lower case (by RFC 6454, chapter 4 "Origin of a URI") - string host = uri.Host.ToLower(); + string host = uri.Host.ToLowerInvariant(); if (port != defaultPort && port != -1) { @@ -405,7 +405,7 @@ static Uri AbsoluteUri(Uri uri) } string relativeUri = uri.OriginalString; - return new Uri(relativeUri.StartsWith("//") + return new Uri(relativeUri.StartsWith("//", StringComparison.Ordinal) ? HttpScheme.Http + ":" + relativeUri : HttpSchemePrefix + relativeUri); } diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker00.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker00.cs index 85e59f40b..fc966f357 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker00.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker00.cs @@ -92,7 +92,7 @@ protected override void Verify(IFullHttpResponse response) { if (!response.Status.Equals(HttpResponseStatus.SwitchingProtocols)) { - throw new WebSocketHandshakeException($"Invalid handshake response getStatus: {response.Status}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseGS(response); } HttpHeaders headers = response.Headers; @@ -100,19 +100,19 @@ protected override void Verify(IFullHttpResponse response) if (!headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgrade) ||!Websocket.ContentEqualsIgnoreCase(upgrade)) { - throw new WebSocketHandshakeException($"Invalid handshake response upgrade: {upgrade}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseU(upgrade); } if (!headers.ContainsValue(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade, true)) { headers.TryGet(HttpHeaderNames.Connection, out upgrade); - throw new WebSocketHandshakeException($"Invalid handshake response connection: {upgrade}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseConn(upgrade); } IByteBuffer challenge = response.Content; if (!challenge.Equals(this.expectedChallengeResponseBytes)) { - throw new WebSocketHandshakeException("Invalid challenge"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidChallenge(); } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker07.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker07.cs index 218fd4b2e..e77fa0b17 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker07.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker07.cs @@ -51,8 +51,7 @@ protected internal override IFullHttpRequest NewHandshakeRequest() if (Logger.DebugEnabled) { - Logger.Debug("WebSocket version 07 client handshake key: {}, expected response: {}", - key, this.expectedChallengeResponseString); + Logger.WebSocketVersion07ClientHandshakeKey(key, this.expectedChallengeResponseString); } // Format request @@ -87,25 +86,25 @@ protected override void Verify(IFullHttpResponse response) if (!response.Status.Equals(status)) { - throw new WebSocketHandshakeException($"Invalid handshake response getStatus: {response.Status}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseGS(response); } if (headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgrade) || !HttpHeaderValues.Websocket.ContentEqualsIgnoreCase(upgrade)) { - throw new WebSocketHandshakeException($"Invalid handshake response upgrade: {upgrade}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseU(upgrade); } if (!headers.ContainsValue(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade, true)) { headers.TryGet(HttpHeaderNames.Connection, out upgrade); - throw new WebSocketHandshakeException($"Invalid handshake response connection: {upgrade}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseConn(upgrade); } if (headers.TryGet(HttpHeaderNames.SecWebsocketAccept, out ICharSequence accept) || !accept.Equals(this.expectedChallengeResponseString)) { - throw new WebSocketHandshakeException($"Invalid challenge. Actual: {accept}. Expected: {this.expectedChallengeResponseString}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidChallenge(accept, this.expectedChallengeResponseString); } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker08.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker08.cs index 8a05fb014..b66c6e606 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker08.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker08.cs @@ -52,8 +52,7 @@ protected internal override IFullHttpRequest NewHandshakeRequest() if (Logger.DebugEnabled) { - Logger.Debug("WebSocket version 08 client handshake key: {}, expected response: {}", - key, this.expectedChallengeResponseString); + Logger.WebSocketVersion08ClientHandshakeKey(key, this.expectedChallengeResponseString); } // Format request @@ -88,25 +87,25 @@ protected override void Verify(IFullHttpResponse response) if (!response.Status.Equals(status)) { - throw new WebSocketHandshakeException($"Invalid handshake response getStatus: {response.Status}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseGS(response); } if (!headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgrade) || !HttpHeaderValues.Websocket.ContentEqualsIgnoreCase(upgrade)) { - throw new WebSocketHandshakeException($"Invalid handshake response upgrade: {upgrade}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseU(upgrade); } if (!headers.ContainsValue(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade, true)) { headers.TryGet(HttpHeaderNames.Connection, out upgrade); - throw new WebSocketHandshakeException($"Invalid handshake response connection: {upgrade}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseConn(upgrade); } if (!headers.TryGet(HttpHeaderNames.SecWebsocketAccept, out ICharSequence accept) || !accept.Equals(this.expectedChallengeResponseString)) { - throw new WebSocketHandshakeException($"Invalid challenge. Actual: {accept}. Expected: {this.expectedChallengeResponseString}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidChallenge(accept, this.expectedChallengeResponseString); } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker13.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker13.cs index bce560e8e..65084013e 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker13.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshaker13.cs @@ -53,8 +53,7 @@ protected internal override IFullHttpRequest NewHandshakeRequest() if (Logger.DebugEnabled) { - Logger.Debug("WebSocket version 13 client handshake key: {}, expected response: {}", - key, this.expectedChallengeResponseString); + Logger.WebSocketVersion13ClientHandshakeKey(key, this.expectedChallengeResponseString); } // Format request @@ -89,25 +88,25 @@ protected override void Verify(IFullHttpResponse response) if (!response.Status.Equals(status)) { - throw new WebSocketHandshakeException($"Invalid handshake response getStatus: {response.Status}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseGS(response); } if (!headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgrade) || !HttpHeaderValues.Websocket.ContentEqualsIgnoreCase(upgrade)) { - throw new WebSocketHandshakeException($"Invalid handshake response upgrade: {upgrade}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseU(upgrade); } if (!headers.ContainsValue(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade, true)) { headers.TryGet(HttpHeaderNames.Connection, out upgrade); - throw new WebSocketHandshakeException($"Invalid handshake response connection: {upgrade}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseConn(upgrade); } if (!headers.TryGet(HttpHeaderNames.SecWebsocketAccept, out ICharSequence accept) || !accept.Equals(this.expectedChallengeResponseString)) { - throw new WebSocketHandshakeException($"Invalid challenge. Actual: {accept}. Expected: {this.expectedChallengeResponseString}"); + ThrowHelper.ThrowWebSocketHandshakeException_InvalidChallenge(accept, this.expectedChallengeResponseString); } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshakerFactory.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshakerFactory.cs index 7aca65aa9..eed105799 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshakerFactory.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientHandshakerFactory.cs @@ -44,7 +44,7 @@ public static WebSocketClientHandshaker NewHandshaker( webSocketUrl, V00, subprotocol, customHeaders, maxFramePayloadLength); } - throw new WebSocketHandshakeException($"Protocol version {version}not supported."); + return ThrowHelper.ThrowWebSocketHandshakeException_InvalidVersion(version); } } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientProtocolHandshakeHandler.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientProtocolHandshakeHandler.cs index 977863c0d..28d759c7a 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientProtocolHandshakeHandler.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketClientProtocolHandshakeHandler.cs @@ -38,13 +38,13 @@ public override void ChannelActive(IChannelHandlerContext context) public override void ChannelRead(IChannelHandlerContext ctx, object msg) { - if (!(msg is IFullHttpResponse)) + var response = msg as IFullHttpResponse; + if (null == response) { ctx.FireChannelRead(msg); return; } - var response = (IFullHttpResponse)msg; try { if (!this.handshaker.IsHandshakeComplete) @@ -55,7 +55,7 @@ public override void ChannelRead(IChannelHandlerContext ctx, object msg) return; } - throw new InvalidOperationException("WebSocketClientHandshaker should have been finished yet"); + ThrowHelper.ThrowInvalidOperationException_WebSocketClientHandshaker(); } finally { diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketFrameAggregator.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketFrameAggregator.cs index 8f95ebe6a..a15debaa2 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketFrameAggregator.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketFrameAggregator.cs @@ -15,7 +15,17 @@ public WebSocketFrameAggregator(int maxContentLength) { } - protected override bool IsStartMessage(WebSocketFrame msg) => msg is TextWebSocketFrame || msg is BinaryWebSocketFrame; + protected override bool IsStartMessage(WebSocketFrame msg) + { + switch (msg) + { + case TextWebSocketFrame _: + case BinaryWebSocketFrame _: + return true; + default: + return false; + } + } protected override bool IsContentMessage(WebSocketFrame msg) => msg is ContinuationWebSocketFrame; @@ -41,18 +51,16 @@ protected override bool IsAggregated(WebSocketFrame msg) protected override WebSocketFrame BeginAggregation(WebSocketFrame start, IByteBuffer content) { - if (start is TextWebSocketFrame) + switch (start) { - return new TextWebSocketFrame(true, start.Rsv, content); + case TextWebSocketFrame _: + return new TextWebSocketFrame(true, start.Rsv, content); + case BinaryWebSocketFrame _: + return new BinaryWebSocketFrame(true, start.Rsv, content); + default: + // Should not reach here. + return ThrowHelper.ThrowException_UnkonwFrameType(); } - - if (start is BinaryWebSocketFrame) - { - return new BinaryWebSocketFrame(true, start.Rsv, content); - } - - // Should not reach here. - throw new Exception("Unkonw WebSocketFrame type, must be either TextWebSocketFrame or BinaryWebSocketFrame"); } } } diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketProtocolHandler.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketProtocolHandler.cs index 36ec0fe61..cc51418a9 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketProtocolHandler.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketProtocolHandler.cs @@ -22,20 +22,21 @@ internal WebSocketProtocolHandler(bool dropPongFrames) protected override void Decode(IChannelHandlerContext ctx, WebSocketFrame frame, List output) { - if (frame is PingWebSocketFrame) + switch (frame) { - frame.Content.Retain(); - ctx.Channel.WriteAndFlushAsync(new PongWebSocketFrame(frame.Content)); - return; + case PingWebSocketFrame _: + frame.Content.Retain(); + ctx.Channel.WriteAndFlushAsync(new PongWebSocketFrame(frame.Content)); + return; + + case PongWebSocketFrame _ when this.dropPongFrames: + // Pong frames need to get ignored + return; + + default: + output.Add(frame.Retain()); + break; } - - if (frame is PongWebSocketFrame && this.dropPongFrames) - { - // Pong frames need to get ignored - return; - } - - output.Add(frame.Retain()); } public override void ExceptionCaught(IChannelHandlerContext ctx, Exception cause) diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker.cs index d238ad650..1808a5fde 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker.cs @@ -32,7 +32,7 @@ public abstract class WebSocketServerHandshaker string selectedSubprotocol; // Use this as wildcard to support all requested sub-protocols - public static readonly string SubProtocolWildcard = "*"; + public const string SubProtocolWildcard = "*"; protected WebSocketServerHandshaker(WebSocketVersion version, string uri, string subprotocols, int maxFramePayloadLength) { @@ -58,7 +58,7 @@ protected WebSocketServerHandshaker(WebSocketVersion version, string uri, string public ISet Subprotocols() { - var ret = new HashSet(this.subprotocols); + var ret = new HashSet(this.subprotocols, StringComparer.Ordinal); return ret; } @@ -79,7 +79,7 @@ public void Handshake(IChannel channel, IFullHttpRequest req, HttpHeaders respon { if (Logger.DebugEnabled) { - Logger.Debug("{} WebSocket version {} server handshake", channel, this.version); + Logger.WebSocketVersionServerHandshake(channel, this.version); } IFullHttpResponse response = this.NewHandshakeResponse(req, responseHeaders); @@ -102,7 +102,7 @@ public void Handshake(IChannel channel, IFullHttpRequest req, HttpHeaders respon ctx = p.Context(); if (ctx == null) { - completion.TrySetException(new InvalidOperationException("No HttpDecoder and no HttpServerCodec in the pipeline")); + completion.TrySetException(ThrowHelper.GetInvalidOperationException_NoHttpDecoderAndServerCodec()); return; } @@ -140,7 +140,7 @@ public Task HandshakeAsync(IChannel channel, IHttpRequest req, HttpHeaders respo } if (Logger.DebugEnabled) { - Logger.Debug("{} WebSocket version {} server handshake", channel, this.version); + Logger.WebSocketVersionServerHandshake(channel, this.version); } IChannelPipeline p = channel.Pipeline; IChannelHandlerContext ctx = p.Context(); @@ -150,7 +150,7 @@ public Task HandshakeAsync(IChannel channel, IHttpRequest req, HttpHeaders respo ctx = p.Context(); if (ctx == null) { - return TaskUtil.FromException(new InvalidOperationException("No HttpDecoder and no HttpServerCodec in the pipeline")); + return ThrowHelper.ThrowInvalidOperationException_NoHttpDecoderAndServerCodec(); } } @@ -235,8 +235,8 @@ protected string SelectSubprotocol(string requestedSubprotocols) foreach (string supportedSubprotocol in this.subprotocols) { - if (SubProtocolWildcard.Equals(supportedSubprotocol) - || requestedSubprotocol.Equals(supportedSubprotocol)) + if (string.Equals(SubProtocolWildcard, supportedSubprotocol, StringComparison.Ordinal) + || string.Equals(requestedSubprotocol, supportedSubprotocol, StringComparison.Ordinal)) { this.selectedSubprotocol = requestedSubprotocol; return requestedSubprotocol; diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker00.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker00.cs index b2fe99bbd..9f7754206 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker00.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker00.cs @@ -27,7 +27,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, || !req.Headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence value) || !HttpHeaderValues.Websocket.ContentEqualsIgnoreCase(value)) { - throw new WebSocketHandshakeException("not a WebSocket handshake request: missing upgrade"); + ThrowHelper.ThrowWebSocketHandshakeException_MissingUpgrade(); } // Hixie 75 does not contain these headers while Hixie 76 does @@ -61,7 +61,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, { if (Logger.DebugEnabled) { - Logger.Debug("Requested subprotocol(s) not supported: {}", subprotocols); + Logger.RequestedSubprotocolNotSupported(subprotocols); } } else diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker07.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker07.cs index 86f7a782e..7050bb8ed 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker07.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker07.cs @@ -38,7 +38,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, if (!req.Headers.TryGet(HttpHeaderNames.SecWebsocketKey, out ICharSequence key) || key == null) { - throw new WebSocketHandshakeException("not a WebSocket request: missing key"); + ThrowHelper.ThrowWebSocketHandshakeException_MissingKey(); } string acceptSeed = key + Websocket07AcceptGuid; byte[] sha1 = WebSocketUtil.Sha1(Encoding.ASCII.GetBytes(acceptSeed)); @@ -46,7 +46,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, if (Logger.DebugEnabled) { - Logger.Debug("WebSocket version 07 server handshake key: {}, response: {}.", key, accept); + Logger.WebSocketVersion07ServerHandshakeKey(key, accept); } res.Headers.Add(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket); @@ -62,7 +62,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, { if (Logger.DebugEnabled) { - Logger.Debug("Requested subprotocol(s) not supported: {}", subprotocols); + Logger.RequestedSubprotocolNotSupported(subprotocols); } } else diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker08.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker08.cs index 7dd3731cf..c7872aa18 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker08.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker08.cs @@ -38,7 +38,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, if (!req.Headers.TryGet(HttpHeaderNames.SecWebsocketKey, out ICharSequence key) || key == null) { - throw new WebSocketHandshakeException("not a WebSocket request: missing key"); + ThrowHelper.ThrowWebSocketHandshakeException_MissingKey(); } string acceptSeed = key + Websocket08AcceptGuid; byte[] sha1 = WebSocketUtil.Sha1(Encoding.ASCII.GetBytes(acceptSeed)); @@ -46,7 +46,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, if (Logger.DebugEnabled) { - Logger.Debug("WebSocket version 08 server handshake key: {}, response: {}", key, accept); + Logger.WebSocketVersion08ServerHandshakeKey(key, accept); } res.Headers.Add(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket); @@ -61,7 +61,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, { if (Logger.DebugEnabled) { - Logger.Debug("Requested subprotocol(s) not supported: {}", subprotocols); + Logger.RequestedSubprotocolNotSupported(subprotocols); } } else diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker13.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker13.cs index 888de19da..eec0735a9 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker13.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerHandshaker13.cs @@ -37,7 +37,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, if (!req.Headers.TryGet(HttpHeaderNames.SecWebsocketKey, out ICharSequence key) || key == null) { - throw new WebSocketHandshakeException("not a WebSocket request: missing key"); + ThrowHelper.ThrowWebSocketHandshakeException_MissingKey(); } string acceptSeed = key.ToString() + Websocket13AcceptGuid; byte[] sha1 = WebSocketUtil.Sha1(Encoding.ASCII.GetBytes(acceptSeed)); @@ -45,7 +45,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, if (Logger.DebugEnabled) { - Logger.Debug("WebSocket version 13 server handshake key: {}, response: {}", key, accept); + Logger.WebSocketVersion13ServerHandshakeKey(key, accept); } res.Headers.Add(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket); @@ -60,7 +60,7 @@ protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, { if (Logger.DebugEnabled) { - Logger.Debug("Requested subprotocol(s) not supported: {}", subprotocols); + Logger.RequestedSubprotocolNotSupported(subprotocols); } } else diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerProtocolHandshakeHandler.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerProtocolHandshakeHandler.cs index abd3ad136..a2180522a 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerProtocolHandshakeHandler.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketServerProtocolHandshakeHandler.cs @@ -93,8 +93,8 @@ public override void ChannelRead(IChannelHandlerContext ctx, object msg) } bool IsNotWebSocketPath(IFullHttpRequest req) => this.checkStartsWith - ? !req.Uri.StartsWith(this.websocketPath) - : !req.Uri.Equals(this.websocketPath); + ? !req.Uri.StartsWith(this.websocketPath, System.StringComparison.Ordinal) + : !string.Equals(req.Uri, this.websocketPath, System.StringComparison.Ordinal); static void SendHttpResponse(IChannelHandlerContext ctx, IHttpRequest req, IHttpResponse res) { diff --git a/src/DotNetty.Codecs.Http/WebSockets/WebSocketVersion.cs b/src/DotNetty.Codecs.Http/WebSockets/WebSocketVersion.cs index 0af355e62..dce22110e 100644 --- a/src/DotNetty.Codecs.Http/WebSockets/WebSocketVersion.cs +++ b/src/DotNetty.Codecs.Http/WebSockets/WebSocketVersion.cs @@ -40,7 +40,7 @@ public sealed class WebSocketVersion public AsciiString ToHttpHeaderValue() { - ThrowIfUnknown(this); + if (this == Unknown) ThrowHelper.ThrowInvalidOperationException_UnknownWebSocketVersion(); return this.value; } diff --git a/src/DotNetty.Codecs.Redis/RedisDecoder.cs b/src/DotNetty.Codecs.Redis/RedisDecoder.cs index b66009d42..79282411a 100644 --- a/src/DotNetty.Codecs.Redis/RedisDecoder.cs +++ b/src/DotNetty.Codecs.Redis/RedisDecoder.cs @@ -59,7 +59,7 @@ protected override void Decode(IChannelHandlerContext context, IByteBuffer input { try { - for (;;) + while(true) { switch (this.state) { diff --git a/src/DotNetty.Codecs/Base64/Base64.cs b/src/DotNetty.Codecs/Base64/Base64.cs index fba361e26..17206c261 100644 --- a/src/DotNetty.Codecs/Base64/Base64.cs +++ b/src/DotNetty.Codecs/Base64/Base64.cs @@ -148,16 +148,16 @@ public static unsafe IByteBuffer Encode(IByteBuffer src, int offset, int length, { if (src == null) { - throw new ArgumentNullException(nameof(src)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.src); } if (dialect.alphabet == null) { - throw new ArgumentNullException(nameof(dialect.alphabet)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dialect_alphabet); } Contract.Assert(dialect.alphabet.Length == 64, "alphabet.Length must be 64!"); if ((offset < src.ReaderIndex) || (offset + length > src.ReaderIndex + src.ReadableBytes)) { - throw new ArgumentOutOfRangeException(nameof(offset)); + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.offset); } if (length <= 0) { @@ -206,8 +206,7 @@ static unsafe int DecodeUsingPointer(IByteBuffer src, IByteBuffer dest, sbyte* d sbyte value = (sbyte)(srcArray[i] & 0x7F); if (decodabet[value] < WHITE_SPACE_ENC) { - throw new ArgumentException(string.Format("bad Base64 input character at {0}:{1}", - i, value)); + ThrowHelper.ThrowArgumentException_BadBase64InputChar(i, value); } if (decodabet[value] >= EQUALS_SIGN_ENC) { @@ -264,8 +263,7 @@ static unsafe int DecodeUsingGetSet(IByteBuffer src, IByteBuffer dest, sbyte* de sbyte value = (sbyte)(src.GetByte(i) & 0x7F); if (decodabet[value] < WHITE_SPACE_ENC) { - throw new ArgumentException(string.Format("bad Base64 input character at {0}:{1}", - i, value)); + ThrowHelper.ThrowArgumentException_BadBase64InputChar(i, value); } if (decodabet[value] >= EQUALS_SIGN_ENC) { @@ -312,15 +310,15 @@ public static unsafe IByteBuffer Decode(IByteBuffer src, int offset, int length, { if (src == null) { - throw new ArgumentNullException(nameof(src)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.src); } if (dialect.decodabet == null) { - throw new ArgumentNullException(nameof(dialect.decodabet)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dialect_decodabet); } if ((offset < src.ReaderIndex) || (offset + length > src.ReaderIndex + src.ReadableBytes)) { - throw new ArgumentOutOfRangeException(nameof(offset)); + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.offset); } Contract.Assert(dialect.decodabet.Length == 127, "decodabet.Length must be 127!"); if (length <= 0) diff --git a/src/DotNetty.Codecs/DateFormatter.cs b/src/DotNetty.Codecs/DateFormatter.cs index 0890a3435..411f698b9 100644 --- a/src/DotNetty.Codecs/DateFormatter.cs +++ b/src/DotNetty.Codecs/DateFormatter.cs @@ -67,11 +67,11 @@ static BitArray GetDelimiters() } else if (length < 0) { - throw new ArgumentException("Can't have end < start"); + ThrowHelper.ThrowArgumentException_CannotHaveEndStart(); } else if (length > 64) { - throw new ArgumentException("Can't parse more than 64 chars, looks like a user error or a malformed header"); + ThrowHelper.ThrowArgumentException_CannotParseMoreThan64Chars(); } return Formatter().Parse0(txt, start, end); diff --git a/src/DotNetty.Codecs/DefaultHeaders.cs b/src/DotNetty.Codecs/DefaultHeaders.cs index 2935f1f14..2a0023b7c 100644 --- a/src/DotNetty.Codecs/DefaultHeaders.cs +++ b/src/DotNetty.Codecs/DefaultHeaders.cs @@ -54,9 +54,9 @@ public DefaultHeaders(IHashingStrategy nameHashingStrategy, IValueConverte public DefaultHeaders(IHashingStrategy nameHashingStrategy, IValueConverter valueConverter, INameValidator nameValidator, int arraySizeHint) { - if (ReferenceEquals(nameHashingStrategy, null)) ThrowArgumentNullException(nameof(nameHashingStrategy)); - if (ReferenceEquals(valueConverter, null)) ThrowArgumentNullException(nameof(valueConverter)); - if (ReferenceEquals(nameValidator, null)) ThrowArgumentNullException(nameof(nameValidator)); + if (ReferenceEquals(nameHashingStrategy, null)) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.nameHashingStrategy); + if (ReferenceEquals(valueConverter, null)) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.valueConverter); + if (ReferenceEquals(nameValidator, null)) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.nameValidator); this.hashingStrategy = nameHashingStrategy; this.ValueConverter = valueConverter; @@ -71,7 +71,7 @@ public DefaultHeaders(IHashingStrategy nameHashingStrategy, public bool TryGet(TKey name, out TValue value) { - if (name == null) ThrowArgumentNullException(nameof(name)); + if (name == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); bool found = false; int h = this.hashingStrategy.HashCode(name); @@ -96,7 +96,7 @@ public bool TryGet(TKey name, out TValue value) public bool TryGetAndRemove(TKey name, out TValue value) { - if (name == null) ThrowArgumentNullException(nameof(name)); + if (name == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); int h = this.hashingStrategy.HashCode(name); return this.TryRemove0(h, this.Index(h), name, out value); @@ -106,7 +106,7 @@ public bool TryGetAndRemove(TKey name, out TValue value) public virtual IList GetAll(TKey name) { - if (name == null) ThrowArgumentNullException(nameof(name)); + if (name == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); var values = new List(); int h = this.hashingStrategy.HashCode(name); @@ -137,7 +137,7 @@ public IList GetAllAndRemove(TKey name) public bool ContainsObject(TKey name, object value) { - if (value == null) ThrowArgumentNullException(nameof(value)); + if (value == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); return this.Contains(name, this.ValueConverter.ConvertObject(value)); } @@ -164,7 +164,7 @@ public bool ContainsObject(TKey name, object value) public bool Contains(TKey name, TValue value, IHashingStrategy valueHashingStrategy) { - if (name == null) ThrowArgumentNullException(nameof(name)); + if (name == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); int h = this.hashingStrategy.HashCode(name); int i = this.Index(h); @@ -204,7 +204,7 @@ public ISet Names() public virtual IHeaders Add(TKey name, TValue value) { - if (ReferenceEquals(value, null)) ThrowArgumentNullException(nameof(value)); + if (ReferenceEquals(value, null)) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); this.nameValidator.ValidateName(name); int h = this.hashingStrategy.HashCode(name); @@ -227,7 +227,7 @@ public virtual IHeaders Add(TKey name, IEnumerable values) public virtual IHeaders AddObject(TKey name, object value) { - if (value == null) ThrowArgumentNullException(nameof(value)); + if (value == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); return this.Add(name, this.ValueConverter.ConvertObject(value)); } @@ -275,7 +275,7 @@ public virtual IHeaders Add(IHeaders headers) { if (ReferenceEquals(headers, this)) { - ThrowArgumentException("can't add to itself."); + ThrowHelper.ThrowArgumentException_CannotAddToItSelf(); } this.AddImpl(headers); return this; @@ -319,7 +319,7 @@ protected void AddImpl(IHeaders headers) public IHeaders Set(TKey name, TValue value) { - if (ReferenceEquals(value, null)) ThrowArgumentNullException(nameof(value)); + if (ReferenceEquals(value, null)) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); this.nameValidator.ValidateName(name); int h = this.hashingStrategy.HashCode(name); @@ -331,7 +331,7 @@ public IHeaders Set(TKey name, TValue value) public virtual IHeaders Set(TKey name, IEnumerable values) { - if (ReferenceEquals(values, null)) ThrowArgumentNullException(nameof(values)); + if (ReferenceEquals(values, null)) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); this.nameValidator.ValidateName(name); int h = this.hashingStrategy.HashCode(name); @@ -353,7 +353,7 @@ public virtual IHeaders Set(TKey name, IEnumerable values) public virtual IHeaders SetObject(TKey name, object value) { - if (value == null) ThrowArgumentNullException(nameof(value)); + if (value == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value); TValue convertedValue = this.ValueConverter.ConvertObject(value); return this.Set(name, convertedValue); @@ -361,7 +361,7 @@ public virtual IHeaders SetObject(TKey name, object value) public virtual IHeaders SetObject(TKey name, IEnumerable values) { - if (ReferenceEquals(values, null)) ThrowArgumentNullException(nameof(values)); + if (ReferenceEquals(values, null)) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.values); this.nameValidator.ValidateName(name); int h = this.hashingStrategy.HashCode(name); @@ -945,7 +945,7 @@ struct ValueEnumerator : IEnumerator, IEnumerable public ValueEnumerator(DefaultHeaders headers, TKey name) { - if (name == null) ThrowArgumentNullException(nameof(name)); + if (name == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); this.hashingStrategy = headers.hashingStrategy; this.hash = this.hashingStrategy.HashCode(name); @@ -1028,7 +1028,7 @@ object IEnumerator.Current { if (this.index == 0 || this.index == this.size + 1) { - ThrowInvalidOperationException("Enumerator not initialized or completed."); + ThrowHelper.ThrowInvalidOperationException_EnumeratorNotInitOrCompleted(); } return this.node; } @@ -1120,7 +1120,7 @@ internal void Remove() public TValue SetValue(TValue newValue) { - if (ReferenceEquals(newValue, null)) ThrowArgumentNullException(nameof(newValue)); + if (ReferenceEquals(newValue, null)) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.newValue); TValue oldValue = this.value; this.value = newValue; diff --git a/src/DotNetty.Codecs/DelimiterBasedFrameDecoder.cs b/src/DotNetty.Codecs/DelimiterBasedFrameDecoder.cs index 2dd450957..c6fb8766e 100644 --- a/src/DotNetty.Codecs/DelimiterBasedFrameDecoder.cs +++ b/src/DotNetty.Codecs/DelimiterBasedFrameDecoder.cs @@ -5,6 +5,7 @@ namespace DotNetty.Codecs { using System; using System.Collections.Generic; + using System.Runtime.CompilerServices; using DotNetty.Buffers; using DotNetty.Transport.Channels; @@ -61,10 +62,10 @@ public DelimiterBasedFrameDecoder(int maxFrameLength, bool stripDelimiter, bool { ValidateMaxFrameLength(maxFrameLength); if (delimiters == null) - throw new NullReferenceException("delimiters"); + ThrowHelper.ThrowNullReferenceException(ExceptionArgument.delimiters); if (delimiters.Length == 0) - throw new ArgumentException("empty delimiters"); + ThrowHelper.ThrowArgumentException_EmptyDelimiters(); if (IsLineBased(delimiters) && !this.IsSubclass()) { @@ -237,12 +238,13 @@ protected virtual object Decode(IChannelHandlerContext ctx, IByteBuffer buffer) } } + [MethodImpl(InlineMethod.Value)] void Fail(long frameLength) { if (frameLength > 0) - throw new TooLongFrameException("frame length exceeds " + this.maxFrameLength + ": " + frameLength + " - discarded"); + ThrowHelper.ThrowTooLongFrameException(this.maxFrameLength, frameLength); else - throw new TooLongFrameException("frame length exceeds " + this.maxFrameLength + " - discarding"); + ThrowHelper.ThrowTooLongFrameException(this.maxFrameLength); } /** @@ -285,16 +287,16 @@ static int IndexOf(IByteBuffer haystack, IByteBuffer needle) static void ValidateDelimiter(IByteBuffer delimiter) { if (delimiter == null) - throw new NullReferenceException("delimiter"); + ThrowHelper.ThrowNullReferenceException(ExceptionArgument.delimiter); if (!delimiter.IsReadable()) - throw new ArgumentException("empty delimiter"); + ThrowHelper.ThrowArgumentException_EmptyDelimiter(); } static void ValidateMaxFrameLength(int maxFrameLength) { if (maxFrameLength <= 0) - throw new ArgumentException("maxFrameLength must be a positive integer: " + maxFrameLength); + ThrowHelper.ThrowArgumentException_MaxFrameLengthMustBe(maxFrameLength); } } } \ No newline at end of file diff --git a/src/DotNetty.Codecs/Internal/ThrowHelper.Extensions.cs b/src/DotNetty.Codecs/Internal/ThrowHelper.Extensions.cs index 6c58f3640..2a2ddc66a 100644 --- a/src/DotNetty.Codecs/Internal/ThrowHelper.Extensions.cs +++ b/src/DotNetty.Codecs/Internal/ThrowHelper.Extensions.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.CompilerServices; +using System.Threading.Tasks; using DotNetty.Common.Utilities; namespace DotNetty.Codecs @@ -71,6 +72,15 @@ internal enum ExceptionArgument newSize, expression, encoding, + src, + dialect_alphabet, + dialect_decodabet, + nameHashingStrategy, + valueConverter, + nameValidator, + newValue, + delimiters, + delimiter, } #endregion @@ -86,14 +96,13 @@ internal enum ExceptionResource partial class ThrowHelper { - [MethodImpl(MethodImplOptions.NoInlining)] - internal static void ThrowNullReferenceException() + internal static void ThrowNullReferenceException(ExceptionArgument argument) { throw GetNullReferenceException(); NullReferenceException GetNullReferenceException() { - return new NullReferenceException("encoding"); + return new NullReferenceException(GetArgumentName(argument)); } } @@ -107,6 +116,96 @@ Exception GetException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_EmptyDelimiter() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("empty delimiter"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_EmptyDelimiters() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("empty delimiters"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_CannotAddToItSelf() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("can't add to itself."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_CannotHaveEndStart() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("Can't have end < start"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_CannotParseMoreThan64Chars() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("Can't parse more than 64 chars, looks like a user error or a malformed header"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_MaxFrameLengthMustBe(int maxFrameLength) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException("maxFrameLength must be a positive integer: " + maxFrameLength); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_MaxCumulationBufferComponents(int value) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"maxCumulationBufferComponents: {value} (expected: >= 2)"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_MaxContentLength(int maxContentLength) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"maxContentLength: {maxContentLength}(expected: >= 0)", nameof(maxContentLength)); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_BadBase64InputChar(int index, sbyte value) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException(string.Format("bad Base64 input character at {0}:{1}", index, value)); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowArgumentException_LessThanZero(int length) { @@ -147,6 +246,56 @@ ArgumentException GetException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowMessageAggregationException_UnknownAggregationState() + { + throw GetException(); + MessageAggregationException GetException() + { + return new MessageAggregationException("Unknown aggregation state."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowMessageAggregationException_StartMessage() + { + throw GetException(); + MessageAggregationException GetException() + { + return new MessageAggregationException("Start message should not have any current content."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_EnumeratorNotInitOrCompleted() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("Enumerator not initialized or completed."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_NotAddedToAPipelineYet() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("not added to a pipeline yet"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_DecoderProperties() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("decoder properties cannot be changed once the decoder is added to a pipeline."); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowInvalidOperationException_ByteToMessageDecoder() { @@ -207,6 +356,16 @@ DecoderException GetException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static Task ThrowEncoderException(Exception ex) + { + return TaskUtil.FromException(GetException()); + EncoderException GetException() + { + return new EncoderException(ex); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowEncoderException(Type type) { @@ -258,5 +417,29 @@ CorruptedFrameException GetException() "than initialBytesToStrip: " + initialBytesToStrip); } } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowTooLongFrameException(int maxFrameLength, long frameLength) + { + throw GetException(); + TooLongFrameException GetException() + { + return new TooLongFrameException("frame length exceeds " + maxFrameLength + ": " + frameLength + " - discarded"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowTooLongFrameException(int maxFrameLength) + { + throw GetException(); + TooLongFrameException GetException() + { + return new TooLongFrameException("frame length exceeds " + maxFrameLength + " - discarding"); + } + } + internal static TooLongFrameException GetTooLongFrameException(int maxContentLength) + { + return new TooLongFrameException($"content length exceeded {maxContentLength} bytes."); + } } } diff --git a/src/DotNetty.Codecs/MessageAggregator.cs b/src/DotNetty.Codecs/MessageAggregator.cs index d88668466..eaf0844c1 100644 --- a/src/DotNetty.Codecs/MessageAggregator.cs +++ b/src/DotNetty.Codecs/MessageAggregator.cs @@ -50,7 +50,7 @@ static void ValidateMaxContentLength(int maxContentLength) { if (maxContentLength < 0) { - throw new ArgumentException($"maxContentLength: {maxContentLength}(expected: >= 0)", nameof(maxContentLength)); + ThrowHelper.ThrowArgumentException_MaxContentLength(maxContentLength); } } @@ -84,11 +84,11 @@ public int MaxCumulationBufferComponents { if (value < 2) { - throw new ArgumentException($"maxCumulationBufferComponents: {value} (expected: >= 2)"); + ThrowHelper.ThrowArgumentException_MaxCumulationBufferComponents(value); } if (this.handlerContext != null) { - throw new InvalidOperationException("decoder properties cannot be changed once the decoder is added to a pipeline."); + ThrowHelper.ThrowInvalidOperationException_DecoderProperties(); } this.maxCumulationBufferComponents = value; @@ -99,7 +99,7 @@ protected IChannelHandlerContext HandlerContext() { if (this.handlerContext == null) { - throw new InvalidOperationException("not added to a pipeline yet"); + ThrowHelper.ThrowInvalidOperationException_NotAddedToAPipelineYet(); } return this.handlerContext; @@ -115,7 +115,7 @@ protected internal override void Decode(IChannelHandlerContext context, TMessage this.currentMessage.Release(); this.currentMessage = default(TOutput); - throw new MessageAggregationException("Start message should not have any current content."); + ThrowHelper.ThrowMessageAggregationException_StartMessage(); } var m = As(message); @@ -250,7 +250,7 @@ protected internal override void Decode(IChannelHandlerContext context, TMessage } else { - throw new MessageAggregationException("Unknown aggregation state."); + ThrowHelper.ThrowMessageAggregationException_UnknownAggregationState(); } } @@ -316,7 +316,7 @@ void InvokeHandleOversizedMessage(IChannelHandlerContext ctx, TStart oversized) } protected virtual void HandleOversizedMessage(IChannelHandlerContext ctx, TStart oversized) => - ctx.FireExceptionCaught(new TooLongFrameException($"content length exceeded {this.MaxContentLength} bytes.")); + ctx.FireExceptionCaught(ThrowHelper.GetTooLongFrameException(this.MaxContentLength)); public override void ChannelReadComplete(IChannelHandlerContext context) { diff --git a/src/DotNetty.Codecs/MessageToByteEncoder.cs b/src/DotNetty.Codecs/MessageToByteEncoder.cs index d25387895..a7433398d 100644 --- a/src/DotNetty.Codecs/MessageToByteEncoder.cs +++ b/src/DotNetty.Codecs/MessageToByteEncoder.cs @@ -58,7 +58,7 @@ public override Task WriteAsync(IChannelHandlerContext context, object message) } catch (Exception ex) { - return TaskUtil.FromException(new EncoderException(ex)); + return ThrowHelper.ThrowEncoderException(ex); } finally { diff --git a/src/DotNetty.Codecs/MessageToMessageEncoder.cs b/src/DotNetty.Codecs/MessageToMessageEncoder.cs index 9172e71cb..d36cd314b 100644 --- a/src/DotNetty.Codecs/MessageToMessageEncoder.cs +++ b/src/DotNetty.Codecs/MessageToMessageEncoder.cs @@ -56,7 +56,7 @@ public override Task WriteAsync(IChannelHandlerContext ctx, object msg) } catch (Exception ex) { - return TaskUtil.FromException(new EncoderException(ex)); // todo: we don't have a stack on EncoderException but it's present on inner exception. + return ThrowHelper.ThrowEncoderException(ex); // todo: we don't have a stack on EncoderException but it's present on inner exception. } finally { diff --git a/src/DotNetty.Codecs/Strings/StringDecoder.cs b/src/DotNetty.Codecs/Strings/StringDecoder.cs index dd638a811..146bed325 100644 --- a/src/DotNetty.Codecs/Strings/StringDecoder.cs +++ b/src/DotNetty.Codecs/Strings/StringDecoder.cs @@ -56,7 +56,7 @@ public StringDecoder(Encoding encoding) { if (encoding == null) { - ThrowHelper.ThrowNullReferenceException(); + ThrowHelper.ThrowNullReferenceException(ExceptionArgument.encoding); } this.encoding = encoding; diff --git a/src/DotNetty.Codecs/Strings/StringEncoder.cs b/src/DotNetty.Codecs/Strings/StringEncoder.cs index 281afffc5..9ed628179 100644 --- a/src/DotNetty.Codecs/Strings/StringEncoder.cs +++ b/src/DotNetty.Codecs/Strings/StringEncoder.cs @@ -53,7 +53,7 @@ public StringEncoder(Encoding encoding) { if (encoding == null) { - ThrowHelper.ThrowNullReferenceException(); + ThrowHelper.ThrowNullReferenceException(ExceptionArgument.encoding); } this.encoding = encoding; diff --git a/src/DotNetty.Common/Concurrency/AbstractEventExecutor.cs b/src/DotNetty.Common/Concurrency/AbstractEventExecutor.cs index d542fbc4e..0bb295895 100644 --- a/src/DotNetty.Common/Concurrency/AbstractEventExecutor.cs +++ b/src/DotNetty.Common/Concurrency/AbstractEventExecutor.cs @@ -165,7 +165,7 @@ protected static void SafeExecute(IRunnable task) } catch (Exception ex) { - Logger.Warn("A task raised an exception. Task: {}", task, ex); + Logger.ATaskRaisedAnException(task, ex); } } diff --git a/src/DotNetty.Common/Concurrency/SingleThreadEventExecutor.cs b/src/DotNetty.Common/Concurrency/SingleThreadEventExecutor.cs index d67c2ab00..8eed0665a 100644 --- a/src/DotNetty.Common/Concurrency/SingleThreadEventExecutor.cs +++ b/src/DotNetty.Common/Concurrency/SingleThreadEventExecutor.cs @@ -104,7 +104,7 @@ void Loop() } catch (Exception ex) { - Logger.Error("{}: execution loop failed", this.thread.Name, ex); + Logger.ExecutionLoopFailed(this.thread, ex); this.executionState = ST_TERMINATED; this.terminationCompletionSource.TrySetException(ex); } @@ -199,7 +199,7 @@ bool RunShutdownHooks() } catch (Exception ex) { - Logger.Warn("Shutdown hook raised an exception.", ex); + Logger.ShutdownHookRaisedAnException(ex); } finally { @@ -346,9 +346,9 @@ protected void CleanupAndTerminate(bool success) // Check if confirmShutdown() was called at the end of the loop. if (success && (this.gracefulShutdownStartTime == PreciseTimeSpan.Zero)) { - Logger.Error( - $"Buggy {typeof(IEventExecutor).Name} implementation; {typeof(SingleThreadEventExecutor).Name}.ConfirmShutdown() must be called " - + "before run() implementation terminates."); + Logger.BuggyImplementation(); + //$"Buggy {typeof(IEventExecutor).Name} implementation; {typeof(SingleThreadEventExecutor).Name}.ConfirmShutdown() must be called " + //+ "before run() implementation terminates."); } try @@ -373,7 +373,7 @@ protected void CleanupAndTerminate(bool success) Interlocked.Exchange(ref this.executionState, ST_TERMINATED); if (!this.taskQueue.IsEmpty) { - Logger.Warn($"An event executor terminated with non-empty task queue ({this.taskQueue.Count})"); + Logger.AnEventExecutorTerminatedWithNonEmptyTaskQueue(this.taskQueue.Count); } //firstRun = true; diff --git a/src/DotNetty.Common/Internal/AppendableCharSequence.cs b/src/DotNetty.Common/Internal/AppendableCharSequence.cs index e67d6b8dd..8940eae24 100644 --- a/src/DotNetty.Common/Internal/AppendableCharSequence.cs +++ b/src/DotNetty.Common/Internal/AppendableCharSequence.cs @@ -218,7 +218,7 @@ static byte[] Expand(byte[] array, int neededSpace, int size) if (newCapacity < 0) { - throw new InvalidOperationException($"New capacity {newCapacity} must be positive"); + ThrowHelper.ThrowInvalidOperationException_CapacityMustBePositive(newCapacity); } } while (neededSpace > newCapacity); diff --git a/src/DotNetty.Common/Internal/Logging/GenericLogger.cs b/src/DotNetty.Common/Internal/Logging/GenericLogger.cs index 85c8b36a1..595badadf 100644 --- a/src/DotNetty.Common/Internal/Logging/GenericLogger.cs +++ b/src/DotNetty.Common/Internal/Logging/GenericLogger.cs @@ -23,29 +23,29 @@ public GenericLogger(string name, ILogger logger) public override void Trace(string format, object arg) { - if (this.TraceEnabled) - { + //if (this.TraceEnabled) + //{ FormattingTuple ft = MessageFormatter.Format(format, arg); this.logger.Log(LogLevel.Trace, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Trace(string format, object argA, object argB) { - if (this.TraceEnabled) - { + //if (this.TraceEnabled) + //{ FormattingTuple ft = MessageFormatter.Format(format, argA, argB); this.logger.Log(LogLevel.Trace, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Trace(string format, params object[] arguments) { - if (this.TraceEnabled) - { + //if (this.TraceEnabled) + //{ FormattingTuple ft = MessageFormatter.ArrayFormat(format, arguments); this.logger.Log(LogLevel.Trace, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Trace(string msg, Exception t) => this.logger.Log(LogLevel.Trace, 0, msg, t, MessageFormatterFunc); @@ -56,29 +56,29 @@ public override void Trace(string format, params object[] arguments) public override void Debug(string format, object arg) { - if (this.DebugEnabled) - { + //if (this.DebugEnabled) + //{ FormattingTuple ft = MessageFormatter.Format(format, arg); this.logger.Log(LogLevel.Debug, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Debug(string format, object argA, object argB) { - if (this.DebugEnabled) - { + //if (this.DebugEnabled) + //{ FormattingTuple ft = MessageFormatter.Format(format, argA, argB); this.logger.Log(LogLevel.Debug, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Debug(string format, params object[] arguments) { - if (this.DebugEnabled) - { + //if (this.DebugEnabled) + //{ FormattingTuple ft = MessageFormatter.ArrayFormat(format, arguments); this.logger.Log(LogLevel.Debug, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Debug(string msg, Exception t) => this.logger.Log(LogLevel.Debug, 0, msg, t, MessageFormatterFunc); @@ -89,29 +89,29 @@ public override void Debug(string format, params object[] arguments) public override void Info(string format, object arg) { - if (this.InfoEnabled) - { + //if (this.InfoEnabled) + //{ FormattingTuple ft = MessageFormatter.Format(format, arg); this.logger.Log(LogLevel.Information, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Info(string format, object argA, object argB) { - if (this.InfoEnabled) - { + //if (this.InfoEnabled) + //{ FormattingTuple ft = MessageFormatter.Format(format, argA, argB); this.logger.Log(LogLevel.Information, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Info(string format, params object[] arguments) { - if (this.InfoEnabled) - { + //if (this.InfoEnabled) + //{ FormattingTuple ft = MessageFormatter.ArrayFormat(format, arguments); this.logger.Log(LogLevel.Information, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Info(string msg, Exception t) => this.logger.Log(LogLevel.Information, 0, msg, t, MessageFormatterFunc); @@ -122,29 +122,29 @@ public override void Info(string format, params object[] arguments) public override void Warn(string format, object arg) { - if (this.WarnEnabled) - { + //if (this.WarnEnabled) + //{ FormattingTuple ft = MessageFormatter.Format(format, arg); this.logger.Log(LogLevel.Warning, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Warn(string format, object argA, object argB) { - if (this.WarnEnabled) - { + //if (this.WarnEnabled) + //{ FormattingTuple ft = MessageFormatter.Format(format, argA, argB); this.logger.Log(LogLevel.Warning, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Warn(string format, params object[] arguments) { - if (this.WarnEnabled) - { + //if (this.WarnEnabled) + //{ FormattingTuple ft = MessageFormatter.ArrayFormat(format, arguments); this.logger.Log(LogLevel.Warning, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Warn(string msg, Exception t) => this.logger.Log(LogLevel.Warning, 0, msg, t, MessageFormatterFunc); @@ -155,29 +155,29 @@ public override void Warn(string format, params object[] arguments) public override void Error(string format, object arg) { - if (this.ErrorEnabled) - { + //if (this.ErrorEnabled) + //{ FormattingTuple ft = MessageFormatter.Format(format, arg); this.logger.Log(LogLevel.Error, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Error(string format, object argA, object argB) { - if (this.ErrorEnabled) - { + //if (this.ErrorEnabled) + //{ FormattingTuple ft = MessageFormatter.Format(format, argA, argB); this.logger.Log(LogLevel.Error, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Error(string format, params object[] arguments) { - if (this.ErrorEnabled) - { + //if (this.ErrorEnabled) + //{ FormattingTuple ft = MessageFormatter.ArrayFormat(format, arguments); this.logger.Log(LogLevel.Error, 0, ft.Message, ft.Exception, MessageFormatterFunc); - } + //} } public override void Error(string msg, Exception t) => this.logger.Log(LogLevel.Error, 0, msg, t, MessageFormatterFunc); diff --git a/src/DotNetty.Common/Internal/Logging/MessageFormatter.cs b/src/DotNetty.Common/Internal/Logging/MessageFormatter.cs index dd85850f0..be8ca9dbf 100644 --- a/src/DotNetty.Common/Internal/Logging/MessageFormatter.cs +++ b/src/DotNetty.Common/Internal/Logging/MessageFormatter.cs @@ -212,55 +212,49 @@ public static bool IsEscapedDelimeter(string messagePattern, static void DeeplyAppendParameter(StringBuilder sbuf, object o, ISet seenMap) { - if (o == null) - { - sbuf.Append("null"); - return; - } - if (!o.GetType().IsArray) - { - SafeObjectAppend(sbuf, o); - } - else + switch (o) { + case null: + sbuf.Append("null"); + return; + // check for primitive array types because they // unfortunately cannot be cast to Object[] - if (o is bool[]) - { - BooleanArrayAppend(sbuf, (bool[])o); - } - else if (o is byte[]) - { - ByteArrayAppend(sbuf, (byte[])o); - } - else if (o is char[]) - { - CharArrayAppend(sbuf, (char[])o); - } - else if (o is short[]) - { - ShortArrayAppend(sbuf, (short[])o); - } - else if (o is int[]) - { - IntArrayAppend(sbuf, (int[])o); - } - else if (o is long[]) - { - LongArrayAppend(sbuf, (long[])o); - } - else if (o is float[]) - { - FloatArrayAppend(sbuf, (float[])o); - } - else if (o is double[]) - { - DoubleArrayAppend(sbuf, (double[])o); - } - else - { - ObjectArrayAppend(sbuf, (object[])o, seenMap); - } + case bool[] boolArray: + BooleanArrayAppend(sbuf, boolArray); + break; + case byte[] byteArray: + ByteArrayAppend(sbuf, byteArray); + break; + case char[] charArray: + CharArrayAppend(sbuf, charArray); + break; + case short[] shortArray: + ShortArrayAppend(sbuf, shortArray); + break; + case int[] intArray: + IntArrayAppend(sbuf, intArray); + break; + case long[] longArray: + LongArrayAppend(sbuf, longArray); + break; + case float[] floatArray: + FloatArrayAppend(sbuf, floatArray); + break; + case double[] doubleArray: + DoubleArrayAppend(sbuf, doubleArray); + break; + + default: + if (!o.GetType().IsArray) + { + SafeObjectAppend(sbuf, o); + } + else + { + ObjectArrayAppend(sbuf, (object[])o, seenMap); + } + break; } } diff --git a/src/DotNetty.Common/Internal/LoggingExtensions.cs b/src/DotNetty.Common/Internal/LoggingExtensions.cs new file mode 100644 index 000000000..0ceb9beb1 --- /dev/null +++ b/src/DotNetty.Common/Internal/LoggingExtensions.cs @@ -0,0 +1,106 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Runtime.CompilerServices; +using DotNetty.Common.Concurrency; +using DotNetty.Common.Internal.Logging; +using DotNetty.Common.Utilities; + +namespace DotNetty.Common +{ + internal static class CommonLoggingExtensions + { + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ATaskRaisedAnException(this IInternalLogger logger, IRunnable task, Exception ex) + { + logger.Warn("A task raised an exception. Task: {}", task, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ShutdownHookRaisedAnException(this IInternalLogger logger, Exception ex) + { + logger.Warn("Shutdown hook raised an exception.", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void AnEventExecutorTerminatedWithNonEmptyTaskQueue(this IInternalLogger logger, int count) + { + logger.Warn($"An event executor terminated with non-empty task queue ({count})"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToRetrieveTheListOfAvailableNetworkInterfaces(this IInternalLogger logger, Exception e) + { + logger.Warn("Failed to retrieve the list of available network interfaces", e); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void AnExcWasThrownWhileProcessingACancellationTask(this IInternalLogger logger, Exception ex) + { + logger.Warn("An exception was thrown while processing a cancellation task", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void AnExceptionWasThrownBy(this IInternalLogger logger, ITimerTask task, Exception t) + { + logger.Warn($"An exception was thrown by {task.GetType().Name}.", t); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToReleaseAMessage(this IInternalLogger logger, object msg, Exception ex) + { + logger.Warn("Failed to release a message: {}", msg, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToReleaseAMessage(this IInternalLogger logger, object msg, int decrement, Exception ex) + { + logger.Warn("Failed to release a message: {} (decrement: {})", msg, decrement, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToReleaseAObject(this IInternalLogger logger, IReferenceCounted referenceCounted, Exception ex) + { + logger.Warn("Failed to release an object: {}", referenceCounted, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NonZeroRefCnt(this IInternalLogger logger, IReferenceCounted referenceCounted, int decrement) + { + logger.Warn("Non-zero refCnt: {}", ReferenceCountUtil.FormatReleaseString(referenceCounted, decrement)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ReleasedObject(this IInternalLogger logger, IReferenceCounted referenceCounted, int decrement) + { + logger.Debug("Released: {}", ReferenceCountUtil.FormatReleaseString(referenceCounted, decrement)); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThreadDeathWatcherTaskRaisedAnException(this IInternalLogger logger, Exception t) + { + logger.Warn("Thread death watcher task raised an exception:", t); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ExecutionLoopFailed(this IInternalLogger logger, XThread thread, Exception ex) + { + logger.Error("{}: execution loop failed", thread.Name, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TimeoutProcessingFailed(this IInternalLogger logger, Exception ex) + { + logger.Error("Timeout processing failed.", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void BuggyImplementation(this IInternalLogger logger) + { + logger.Error( + $"Buggy {typeof(IEventExecutor).Name} implementation; {typeof(SingleThreadEventExecutor).Name}.ConfirmShutdown() must be called " + + "before run() implementation terminates."); + } + } +} diff --git a/src/DotNetty.Common/Internal/MacAddressUtil.cs b/src/DotNetty.Common/Internal/MacAddressUtil.cs index 63fccdbd8..c26cc8ca6 100644 --- a/src/DotNetty.Common/Internal/MacAddressUtil.cs +++ b/src/DotNetty.Common/Internal/MacAddressUtil.cs @@ -53,7 +53,7 @@ public static byte[] GetBestAvailableMac() } catch (SocketException e) { - logger.Warn("Failed to retrieve the list of available network interfaces", e); + logger.FailedToRetrieveTheListOfAvailableNetworkInterfaces(e); } foreach (var entry in ifaces) diff --git a/src/DotNetty.Common/Internal/ThrowHelper.Extensions.cs b/src/DotNetty.Common/Internal/ThrowHelper.Extensions.cs index 75e3d41ba..6c25960a1 100644 --- a/src/DotNetty.Common/Internal/ThrowHelper.Extensions.cs +++ b/src/DotNetty.Common/Internal/ThrowHelper.Extensions.cs @@ -1,6 +1,8 @@ using System; using System.Runtime.CompilerServices; using Microsoft.Extensions.Logging; +using DotNetty.Common.Concurrency; +using DotNetty.Common.Utilities; namespace DotNetty.Common { @@ -70,6 +72,7 @@ internal enum ExceptionArgument startIndex, newSize, expression, + task, } #endregion @@ -85,8 +88,10 @@ internal enum ExceptionResource partial class ThrowHelper { + #region -- Exception -- + [MethodImpl(MethodImplOptions.NoInlining)] - internal static int ThrowException_Compare() + internal static int ThrowException_CompareConstant() { throw GetException(); Exception GetException() @@ -95,6 +100,20 @@ Exception GetException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowException_CompareSignal() + { + throw GetException(); + Exception GetException() + { + return new Exception("failed to compare two different signal constants"); + } + } + + #endregion + + #region -- ArgumentException -- + [MethodImpl(MethodImplOptions.NoInlining)] internal static int ThrowArgumentException(string name) { @@ -105,6 +124,71 @@ ArgumentException GetException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowArgumentException_MustBeGreaterThanZero(TimeSpan tickInterval) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"{nameof(tickInterval)} must be greater than 0: {tickInterval}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowArgumentException_MustBeGreaterThanZero(int ticksPerWheel) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"{nameof(ticksPerWheel)} must be greater than 0: {ticksPerWheel}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowArgumentException_MustBeLessThanOrEqualTo() + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"tickInterval must be less than or equal to ${int.MaxValue} ms."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_DecodeHexByte(string s, int pos) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"invalid hex byte '{s.Substring(pos, 2)}' at index {pos} of '{s}'"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_InvalidLen(int length) + { + throw GetException(); + ArgumentException GetException() + { + return new ArgumentException($"length: {length}"); + } + } + + #endregion + + #region -- ArgumentOutOfRangeException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowArgumentOutOfRangeException_MustBeGreaterThan(int ticksPerWheel) + { + throw GetException(); + ArgumentOutOfRangeException GetException() + { + return new ArgumentOutOfRangeException( + $"{nameof(ticksPerWheel)} may not be greater than 2^30: {ticksPerWheel}"); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowArgumentOutOfRangeException_Slice(int length, int totalLength) { @@ -155,6 +239,60 @@ ArgumentOutOfRangeException GetArgumentOutOfRangeException() } } + #endregion + + #region -- InvalidOperationException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_CannotBeCalledFromTimerTask() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException($"{nameof(HashedWheelTimer)}.stop() cannot be called from timer task."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_InvalidWorkerState() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("Invalid WorkerState"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_CannotBeStartedOnceStopped() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("cannot be started once stopped"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_EnumeratorNotInit() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("Enumerator not initialized."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_EnumeratorAlreadyCompleted() + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException("Eumerator already completed."); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowInvalidOperationException_TooMany() { @@ -195,6 +333,41 @@ InvalidOperationException GetException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_CapacityMustBePositive(int newCapacity) + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException($"New capacity {newCapacity} must be positive"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_Unexpected(Signal signal) + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException($"unexpected signal: {signal}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_Deadline(TimeSpan timeoutDeadline, TimeSpan deadline) + { + throw GetException(); + InvalidOperationException GetException() + { + return new InvalidOperationException( + string.Format("timeout.deadline (%d) > deadline (%d)", timeoutDeadline, deadline)); + } + } + + #endregion + + #region -- InvalidCastException -- + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowInvalidCastException() { @@ -205,5 +378,89 @@ InvalidCastException GetException() return new InvalidCastException(msg); } } + + #endregion + + #region -- IndexOutOfRangeException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowIndexOutOfRangeException_ParseChar(int start) + { + throw GetArgumentOutOfRangeException(); + IndexOutOfRangeException GetArgumentOutOfRangeException() + { + return new IndexOutOfRangeException($"2 bytes required to convert to character. index {start} would go out of bounds."); + } + } + + #endregion + + #region -- FormatException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowFormatException() + { + throw GetException(); + FormatException GetException() + { + return new FormatException(); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowFormatException_Radix() + { + throw GetException(); + FormatException GetException() + { + return new FormatException($"Radix must be from {CharUtil.MinRadix} to {CharUtil.MaxRadix}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowFormatException(ICharSequence seq, int start, int end) + { + throw GetException(); + FormatException GetException() + { + return new FormatException(seq.SubSequence(start, end).ToString()); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowFormatException(int start, int end) + { + throw GetException(); + FormatException GetException() + { + return new FormatException($"Content is empty because {start} and {end} are the same."); + } + } + + #endregion + + #region -- RejectedExecutionException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowRejectedExecutionException_TimerStopped() + { + throw GetException(); + RejectedExecutionException GetException() + { + return new RejectedExecutionException("Timer has been stopped and cannot process new operations."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowRejectedExecutionException_NumOfPendingTimeouts(long pendingTimeoutsCount, long maxPendingTimeouts) + { + throw GetException(); + RejectedExecutionException GetException() + { + return new RejectedExecutionException($"Number of pending timeouts ({pendingTimeoutsCount}) is greater than or equal to maximum allowed pending timeouts ({maxPendingTimeouts})"); + } + } + + #endregion } } diff --git a/src/DotNetty.Common/PreciseTimeSpan.cs b/src/DotNetty.Common/PreciseTimeSpan.cs index 9a9ce8d70..aaf2f95f5 100644 --- a/src/DotNetty.Common/PreciseTimeSpan.cs +++ b/src/DotNetty.Common/PreciseTimeSpan.cs @@ -46,9 +46,9 @@ public struct PreciseTimeSpan : IComparable, IEquatable(); + var seen = new HashSet(StringComparer.Ordinal); for (; oldHead != RecordEntry.Bottom; oldHead = oldHead.Next) { string s = oldHead.ToString(); diff --git a/src/DotNetty.Common/ThreadDeathWatcher.cs b/src/DotNetty.Common/ThreadDeathWatcher.cs index c824c7e47..4438630fa 100644 --- a/src/DotNetty.Common/ThreadDeathWatcher.cs +++ b/src/DotNetty.Common/ThreadDeathWatcher.cs @@ -95,7 +95,7 @@ sealed class Watcher : IRunnable public void Run() { - for (;;) + while(true) { this.FetchWatchees(); this.NotifyWatchees(); @@ -141,7 +141,7 @@ public void Run() void FetchWatchees() { - for (;;) + while(true) { Entry e; if (!PendingEntries.TryDequeue(out e)) @@ -175,7 +175,7 @@ void NotifyWatchees() } catch (Exception t) { - Logger.Warn("Thread death watcher task raised an exception:", t); + Logger.ThreadDeathWatcherTaskRaisedAnException(t); } } else diff --git a/src/DotNetty.Common/ThreadLocalPool.cs b/src/DotNetty.Common/ThreadLocalPool.cs index a629fd17d..7e3ed2d66 100644 --- a/src/DotNetty.Common/ThreadLocalPool.cs +++ b/src/DotNetty.Common/ThreadLocalPool.cs @@ -332,7 +332,7 @@ bool ScavengeSome() // We never unlink the first queue, as we don't want to synchronize on updating the head. if (!cursor.IsEmpty) { - for (;;) + while(true) { if (cursor.Transfer(this)) { diff --git a/src/DotNetty.Common/Utilities/AbstractConstant.cs b/src/DotNetty.Common/Utilities/AbstractConstant.cs index d54b2c5bd..13c1eea49 100644 --- a/src/DotNetty.Common/Utilities/AbstractConstant.cs +++ b/src/DotNetty.Common/Utilities/AbstractConstant.cs @@ -86,7 +86,7 @@ public int CompareTo(T o) return 1; } - return ThrowHelper.ThrowException_Compare(); + return ThrowHelper.ThrowException_CompareConstant(); } } } \ No newline at end of file diff --git a/src/DotNetty.Common/Utilities/AsciiString.cs b/src/DotNetty.Common/Utilities/AsciiString.cs index 6f3c98223..64c450c9b 100644 --- a/src/DotNetty.Common/Utilities/AsciiString.cs +++ b/src/DotNetty.Common/Utilities/AsciiString.cs @@ -477,7 +477,7 @@ public int IndexOf(ICharSequence subString, int start) } var indexOfVisitor = new IndexOfProcessor((byte)firstChar); - for (; ; ) + while(true) { int i = this.ForEachByte(start, thisLen - start, indexOfVisitor); if (i == -1 || subCount + i > thisLen) @@ -961,7 +961,7 @@ public char ParseChar(int start) { if (start + 1 >= this.length) { - throw new IndexOutOfRangeException($"2 bytes required to convert to character. index {start} would go out of bounds."); + ThrowHelper.ThrowIndexOutOfRangeException_ParseChar(start); } int startWithOffset = start + this.offset; @@ -982,7 +982,7 @@ public short ParseShort(int start, int end, int radix) short result = (short)intValue; if (result != intValue) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } return result; @@ -998,18 +998,18 @@ public int ParseInt(int start, int end, int radix) { if (radix < CharUtil.MinRadix || radix > CharUtil.MaxRadix) { - throw new FormatException($"Radix must be from {CharUtil.MinRadix} to {CharUtil.MaxRadix}"); + ThrowHelper.ThrowFormatException_Radix(); } if (start == end) { - throw new FormatException($"Content is empty because {start} and {end} are the same."); + ThrowHelper.ThrowFormatException(start, end); } int i = start; bool negative = this.ByteAt(i) == '-'; if (negative && ++i == end) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } return this.ParseInt(i, end, radix, negative); @@ -1025,16 +1025,16 @@ int ParseInt(int start, int end, int radix, bool negative) int digit = CharUtil.Digit((char)(this.value[currOffset++ + this.offset]), radix); if (digit == -1) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } if (max > result) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } int next = result * radix - digit; if (next > result) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } result = next; } @@ -1044,7 +1044,7 @@ int ParseInt(int start, int end, int radix, bool negative) result = -result; if (result < 0) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } } @@ -1061,19 +1061,19 @@ public long ParseLong(int start, int end, int radix) { if (radix < CharUtil.MinRadix || radix > CharUtil.MaxRadix) { - throw new FormatException($"Radix must be from {CharUtil.MinRadix} to {CharUtil.MaxRadix}"); + ThrowHelper.ThrowFormatException_Radix(); } if (start == end) { - throw new FormatException($"Content is empty because {start} and {end} are the same."); + ThrowHelper.ThrowFormatException(start, end); } int i = start; bool negative = this.ByteAt(i) == '-'; if (negative && ++i == end) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } return this.ParseLong(i, end, radix, negative); @@ -1089,16 +1089,16 @@ long ParseLong(int start, int end, int radix, bool negative) int digit = CharUtil.Digit((char)(this.value[currOffset++ + this.offset]), radix); if (digit == -1) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } if (max > result) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } long next = result * radix - digit; if (next > result) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } result = next; } @@ -1108,7 +1108,7 @@ long ParseLong(int start, int end, int radix, bool negative) result = -result; if (result < 0) { - throw new FormatException(this.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(this, start, end); } } @@ -1314,21 +1314,22 @@ public static bool RegionMatches(ICharSequence cs, bool ignoreCase, int csStart, { return false; } - if (cs is StringCharSequence stringCharSequence && seq is StringCharSequence) + switch (cs) { - return ignoreCase - ? stringCharSequence.RegionMatchesIgnoreCase(csStart, seq, start, length) - : stringCharSequence.RegionMatches (csStart, seq, start, length); - } - if (cs is AsciiString asciiString) - { - return ignoreCase - ? asciiString.RegionMatchesIgnoreCase(csStart, seq, start, length) - : asciiString.RegionMatches(csStart, seq, start, length); - } + case StringCharSequence stringCharSequence when seq is StringCharSequence: + return ignoreCase + ? stringCharSequence.RegionMatchesIgnoreCase(csStart, seq, start, length) + : stringCharSequence.RegionMatches(csStart, seq, start, length); - return RegionMatchesCharSequences(cs, csStart, seq, start, length, - ignoreCase ? GeneralCaseInsensitiveComparator : DefaultCharComparator); + case AsciiString asciiString: + return ignoreCase + ? asciiString.RegionMatchesIgnoreCase(csStart, seq, start, length) + : asciiString.RegionMatches(csStart, seq, start, length); + + default: + return RegionMatchesCharSequences(cs, csStart, seq, start, length, + ignoreCase ? GeneralCaseInsensitiveComparator : DefaultCharComparator); + } } public static bool RegionMatchesAscii(ICharSequence cs, bool ignoreCase, int csStart, ICharSequence seq, int start, int length) @@ -1338,23 +1339,23 @@ public static bool RegionMatchesAscii(ICharSequence cs, bool ignoreCase, int csS return false; } - if (!ignoreCase && cs is StringCharSequence && seq is StringCharSequence) + switch (cs) { - //we don't call regionMatches from String for ignoreCase==true. It's a general purpose method, - //which make complex comparison in case of ignoreCase==true, which is useless for ASCII-only strings. - //To avoid applying this complex ignore-case comparison, we will use regionMatchesCharSequences - return cs.RegionMatches(csStart, seq, start, length); - } + case StringCharSequence _ when !ignoreCase && seq is StringCharSequence: + //we don't call regionMatches from String for ignoreCase==true. It's a general purpose method, + //which make complex comparison in case of ignoreCase==true, which is useless for ASCII-only strings. + //To avoid applying this complex ignore-case comparison, we will use regionMatchesCharSequences + return cs.RegionMatches(csStart, seq, start, length); - if (cs is AsciiString asciiString) - { - return ignoreCase - ? asciiString.RegionMatchesIgnoreCase(csStart, seq, start, length) - : asciiString.RegionMatches(csStart, seq, start, length); - } + case AsciiString asciiString: + return ignoreCase + ? asciiString.RegionMatchesIgnoreCase(csStart, seq, start, length) + : asciiString.RegionMatches(csStart, seq, start, length); - return RegionMatchesCharSequences(cs, csStart, seq, start, length, - ignoreCase ? AsciiCaseInsensitiveCharComparator : DefaultCharComparator); + default: + return RegionMatchesCharSequences(cs, csStart, seq, start, length, + ignoreCase ? AsciiCaseInsensitiveCharComparator : DefaultCharComparator); + } } public static int IndexOfIgnoreCase(ICharSequence str, ICharSequence searchStr, int startPos) @@ -1423,17 +1424,19 @@ public static int IndexOfIgnoreCaseAscii(ICharSequence str, ICharSequence search public static int IndexOf(ICharSequence cs, char searchChar, int start) { - if (cs is StringCharSequence stringCharSequence) + switch (cs) { - return stringCharSequence.IndexOf(searchChar, start); - } - else if (cs is AsciiString asciiString) - { - return asciiString.IndexOf(searchChar, start); - } - if (cs == null) - { - return IndexNotFound; + case StringCharSequence stringCharSequence: + return stringCharSequence.IndexOf(searchChar, start); + + case AsciiString asciiString: + return asciiString.IndexOf(searchChar, start); + + case null: + return IndexNotFound; + + default: + break; } int sz = cs.Count; if (start < 0) diff --git a/src/DotNetty.Common/Utilities/CharSequenceEnumerator.cs b/src/DotNetty.Common/Utilities/CharSequenceEnumerator.cs index fa9862b69..a2f613903 100644 --- a/src/DotNetty.Common/Utilities/CharSequenceEnumerator.cs +++ b/src/DotNetty.Common/Utilities/CharSequenceEnumerator.cs @@ -42,11 +42,11 @@ object IEnumerator.Current { if (this.index == -1) { - throw new InvalidOperationException("Enumerator not initialized."); + ThrowHelper.ThrowInvalidOperationException_EnumeratorNotInit(); } if (this.index >= this.charSequence.Count) { - throw new InvalidOperationException("Eumerator already completed."); + ThrowHelper.ThrowInvalidOperationException_EnumeratorAlreadyCompleted(); } return this.currentElement; } @@ -58,11 +58,11 @@ public char Current { if (this.index == -1) { - throw new InvalidOperationException("Enumerator not initialized."); + ThrowHelper.ThrowInvalidOperationException_EnumeratorNotInit(); } if (this.index >= this.charSequence.Count) { - throw new InvalidOperationException("Eumerator already completed."); + ThrowHelper.ThrowInvalidOperationException_EnumeratorAlreadyCompleted(); } return this.currentElement; } diff --git a/src/DotNetty.Common/Utilities/CharUtil.Extensions.cs b/src/DotNetty.Common/Utilities/CharUtil.Extensions.cs new file mode 100644 index 000000000..69bc2a9ec --- /dev/null +++ b/src/DotNetty.Common/Utilities/CharUtil.Extensions.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace DotNetty.Common.Utilities +{ + using System; + using System.Runtime.CompilerServices; + + public static partial class CharUtil + { + [MethodImpl(MethodImplOptions.NoInlining)] + private static void ThrowFormatException0(ICharSequence str) + { + throw GetFormatException(); + FormatException GetFormatException() + { + return new FormatException(str.ToString()); + } + } + } +} diff --git a/src/DotNetty.Common/Utilities/CharUtil.cs b/src/DotNetty.Common/Utilities/CharUtil.cs index 11d111ace..3f36eae88 100644 --- a/src/DotNetty.Common/Utilities/CharUtil.cs +++ b/src/DotNetty.Common/Utilities/CharUtil.cs @@ -8,7 +8,7 @@ namespace DotNetty.Common.Utilities using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; - public static class CharUtil + public static partial class CharUtil { public static readonly string Digits = "0123456789ABCDEF"; @@ -44,14 +44,14 @@ public static int ParseInt(ICharSequence seq, int start, int end, int radix) if (start == end) { - throw new FormatException(); + ThrowHelper.ThrowFormatException(); } int i = start; bool negative = seq[i] == '-'; if (negative && ++i == end) { - throw new FormatException(seq.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(seq, start, end); } return ParseInt(seq, i, end, radix, negative); @@ -72,16 +72,16 @@ public static int ParseInt(ICharSequence seq, int start, int end, int radix, boo int digit = Digit((char)(seq[currOffset++] & 0xFF), radix); if (digit == -1) { - throw new FormatException(seq.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(seq, start, end); } if (max > result) { - throw new FormatException(seq.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(seq, start, end); } int next = result * radix - digit; if (next > result) { - throw new FormatException(seq.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(seq, start, end); } result = next; } @@ -91,7 +91,7 @@ public static int ParseInt(ICharSequence seq, int start, int end, int radix, boo result = -result; if (result < 0) { - throw new FormatException(seq.SubSequence(start, end).ToString()); + ThrowHelper.ThrowFormatException(seq, start, end); } } @@ -110,7 +110,7 @@ public static long ParseLong(ICharSequence str, int radix = 10) || radix < MinRadix || radix > MaxRadix) { - ThrowFormatException(str); + ThrowFormatException0(str); } // ReSharper disable once PossibleNullReferenceException @@ -118,12 +118,12 @@ public static long ParseLong(ICharSequence str, int radix = 10) int i = 0; if (length == 0) { - ThrowFormatException(str); + ThrowFormatException0(str); } bool negative = str[i] == '-'; if (negative && ++i == length) { - ThrowFormatException(str); + ThrowFormatException0(str); } return ParseLong(str, i, radix, negative); @@ -139,16 +139,16 @@ static long ParseLong(ICharSequence str, int offset, int radix, bool negative) int digit = Digit(str[offset++], radix); if (digit == -1) { - ThrowFormatException(str); + ThrowFormatException0(str); } if (max > result) { - ThrowFormatException(str); + ThrowFormatException0(str); } long next = result * radix - digit; if (next > result) { - ThrowFormatException(str); + ThrowFormatException0(str); } result = next; } @@ -158,14 +158,14 @@ static long ParseLong(ICharSequence str, int offset, int radix, bool negative) result = -result; if (result < 0) { - ThrowFormatException(str); + ThrowFormatException0(str); } } return result; } - static void ThrowFormatException(ICharSequence str) => throw new FormatException(str.ToString()); + static void ThrowFormatException(ICharSequence str) => throw new FormatException(str.ToString()); public static bool IsNullOrEmpty(ICharSequence sequence) => sequence == null || sequence.Count == 0; @@ -423,8 +423,8 @@ public static ICharSequence Trim(ICharSequence sequence) int last = IndexOfLastNonWhiteSpaceChar(sequence, start); length = last - start + 1; - return length == sequence.Count - ? sequence + return length == sequence.Count + ? sequence : sequence.SubSequence(start, last + 1); } @@ -526,19 +526,19 @@ public static int Digit(char c, int radix) public static int IndexOf(this ICharSequence cs, char searchChar, int start) { - if (cs == null) + switch (cs) { - return AsciiString.IndexNotFound; - } + case null: + return AsciiString.IndexNotFound; - if (cs is StringCharSequence sequence) - { - return sequence.IndexOf(searchChar, start); - } + case StringCharSequence sequence: + return sequence.IndexOf(searchChar, start); - if (cs is AsciiString s) - { - return s.IndexOf(searchChar, start); + case AsciiString s: + return s.IndexOf(searchChar, start); + + default: + break; } int sz = cs.Count; @@ -576,7 +576,7 @@ public static int CodePointAt(IReadOnlyList seq, int index) Contract.Requires(index >= 0 && index < seq.Count); char high = seq[index++]; - if (index >= seq.Count) + if (index >= seq.Count) { return high; } diff --git a/src/DotNetty.Common/Utilities/HashedWheelTimer.cs b/src/DotNetty.Common/Utilities/HashedWheelTimer.cs index b2e6d3fb5..4f04a470a 100644 --- a/src/DotNetty.Common/Utilities/HashedWheelTimer.cs +++ b/src/DotNetty.Common/Utilities/HashedWheelTimer.cs @@ -66,20 +66,19 @@ public HashedWheelTimer( { if (tickInterval <= TimeSpan.Zero) { - throw new ArgumentException($"{nameof(tickInterval)} must be greater than 0: {tickInterval}"); + ThrowHelper.ThrowArgumentException_MustBeGreaterThanZero(tickInterval); } if (Math.Ceiling(tickInterval.TotalMilliseconds) > int.MaxValue) { - throw new ArgumentException($"{nameof(tickInterval)} must be less than or equal to ${int.MaxValue} ms."); + ThrowHelper.ThrowArgumentException_MustBeLessThanOrEqualTo(); } if (ticksPerWheel <= 0) { - throw new ArgumentException($"{nameof(ticksPerWheel)} must be greater than 0: {ticksPerWheel}"); + ThrowHelper.ThrowArgumentException_MustBeGreaterThanZero(ticksPerWheel); } if (ticksPerWheel > int.MaxValue / 2 + 1) { - throw new ArgumentOutOfRangeException( - $"{nameof(ticksPerWheel)} may not be greater than 2^30: {ticksPerWheel}"); + ThrowHelper.ThrowArgumentOutOfRangeException_MustBeGreaterThan(ticksPerWheel); } // Normalize ticksPerWheel to power of two and initialize the wheel. @@ -171,9 +170,9 @@ public void Start() case WorkerStateStarted: break; case WorkerStateShutdown: - throw new InvalidOperationException("cannot be started once stopped"); + ThrowHelper.ThrowInvalidOperationException_CannotBeStartedOnceStopped(); break; default: - throw new InvalidOperationException("Invalid WorkerState"); + ThrowHelper.ThrowInvalidOperationException_InvalidWorkerState(); break; } // Wait until the startTime is initialized by the worker. @@ -189,7 +188,7 @@ public async Task> StopAsync() if (XThread.CurrentThread == this.workerThread) { - throw new InvalidOperationException($"{nameof(HashedWheelTimer)}.stop() cannot be called from timer task."); + ThrowHelper.ThrowInvalidOperationException_CannotBeCalledFromTimerTask(); } if (Interlocked.CompareExchange(ref this.workerStateVolatile, WorkerStateShutdown, WorkerStateStarted) != WorkerStateStarted) @@ -220,11 +219,11 @@ public ITimeout NewTimeout(ITimerTask task, TimeSpan delay) { if (task == null) { - throw new ArgumentNullException(nameof(task)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.task); } if (this.WorkerState == WorkerStateShutdown) { - throw new RejectedExecutionException("Timer has been stopped and cannot process new operations."); + ThrowHelper.ThrowRejectedExecutionException_TimerStopped(); } if (this.ShouldLimitTimeouts) { @@ -232,7 +231,7 @@ public ITimeout NewTimeout(ITimerTask task, TimeSpan delay) if (pendingTimeoutsCount > this.maxPendingTimeouts) { Interlocked.Decrement(ref this.PendingTimeouts); - throw new RejectedExecutionException($"Number of pending timeouts ({pendingTimeoutsCount}) is greater than or equal to maximum allowed pending timeouts ({this.maxPendingTimeouts})"); + ThrowHelper.ThrowRejectedExecutionException_NumOfPendingTimeouts(pendingTimeoutsCount, this.maxPendingTimeouts); } } @@ -327,7 +326,7 @@ public void Run() } catch (Exception ex) { - Logger.Error("Timeout processing failed.", ex); + Logger.TimeoutProcessingFailed(ex); } finally { @@ -382,7 +381,7 @@ void ProcessCancelledTasks() { if (Logger.WarnEnabled) { - Logger.Warn("An exception was thrown while processing a cancellation task", ex); + Logger.AnExcWasThrownWhileProcessingACancellationTask(ex); } } } @@ -525,7 +524,7 @@ internal void Expire() { if (Logger.WarnEnabled) { - Logger.Warn($"An exception was thrown by {this.Task.GetType().Name}.", t); + Logger.AnExceptionWasThrownBy(this.Task, t); } } } @@ -619,11 +618,7 @@ public void ExpireTimeouts(TimeSpan deadline) else { // The timeout was placed into a wrong slot. This should never happen. - throw new InvalidOperationException( - string.Format( - "timeout.deadline (%d) > deadline (%d)", - timeout.Deadline, - deadline)); + ThrowHelper.ThrowInvalidOperationException_Deadline(timeout.Deadline, deadline); } } else diff --git a/src/DotNetty.Common/Utilities/ReferenceCountUtil.cs b/src/DotNetty.Common/Utilities/ReferenceCountUtil.cs index a2a8966a0..abc027740 100644 --- a/src/DotNetty.Common/Utilities/ReferenceCountUtil.cs +++ b/src/DotNetty.Common/Utilities/ReferenceCountUtil.cs @@ -118,7 +118,7 @@ public static void SafeRelease(object msg) } catch (Exception ex) { - Logger.Warn("Failed to release a message: {}", msg, ex); + Logger.FailedToReleaseAMessage(msg, ex); } } @@ -140,7 +140,7 @@ public static void SafeRelease(object msg, int decrement) { if (Logger.WarnEnabled) { - Logger.Warn("Failed to release a message: {} (decrement: {})", msg, decrement, ex); + Logger.FailedToReleaseAMessage(msg, decrement, ex); } } } @@ -153,7 +153,7 @@ public static void SafeRelease(this IReferenceCounted msg) } catch (Exception ex) { - Logger.Warn("Failed to release a message: {}", msg, ex); + Logger.FailedToReleaseAMessage(msg, ex); } } @@ -165,7 +165,7 @@ public static void SafeRelease(this IReferenceCounted msg, int decrement) } catch (Exception ex) { - Logger.Warn("Failed to release a message: {} (decrement: {})", msg, decrement, ex); + Logger.FailedToReleaseAMessage(msg, decrement, ex); } } @@ -192,23 +192,23 @@ public static T ReleaseLater(T msg, int decrement) { if (!referenceCounted.Release(decrement)) { - Logger.Warn("Non-zero refCnt: {}", FormatReleaseString(referenceCounted, decrement)); + Logger.NonZeroRefCnt(referenceCounted, decrement); } else { - if (Logger.DebugEnabled) Logger.Debug("Released: {}", FormatReleaseString(referenceCounted, decrement)); + if (Logger.DebugEnabled) Logger.ReleasedObject(referenceCounted, decrement); } } catch (Exception ex) { - Logger.Warn("Failed to release an object: {}", referenceCounted, ex); + Logger.FailedToReleaseAObject(referenceCounted, ex); } }); } return msg; } - static string FormatReleaseString(IReferenceCounted referenceCounted, int decrement) + internal static string FormatReleaseString(IReferenceCounted referenceCounted, int decrement) => $"{referenceCounted.GetType().Name}.Release({decrement.ToString()}) refCnt: {referenceCounted.ReferenceCount.ToString()}"; } } \ No newline at end of file diff --git a/src/DotNetty.Common/Utilities/Signal.cs b/src/DotNetty.Common/Utilities/Signal.cs index 72124bfdc..9009c13bf 100644 --- a/src/DotNetty.Common/Utilities/Signal.cs +++ b/src/DotNetty.Common/Utilities/Signal.cs @@ -29,7 +29,7 @@ public void Expect(Signal signal) { if (!ReferenceEquals(this, signal)) { - throw new InvalidOperationException($"unexpected signal: {signal}"); + ThrowHelper.ThrowInvalidOperationException_Unexpected(signal); } } @@ -47,12 +47,12 @@ public int CompareTo(object obj) { return 0; } - if (!ReferenceEquals(obj, null) && obj is Signal) + if (!ReferenceEquals(obj, null) && obj is Signal signal) { - return this.CompareTo((Signal)obj); + return this.CompareTo(signal); } - throw new Exception("failed to compare two different signal constants"); + return ThrowHelper.ThrowException_CompareSignal(); } public int CompareTo(Signal other) diff --git a/src/DotNetty.Common/Utilities/StringUtil.Extensions.cs b/src/DotNetty.Common/Utilities/StringUtil.Extensions.cs new file mode 100644 index 000000000..98dbb1a4f --- /dev/null +++ b/src/DotNetty.Common/Utilities/StringUtil.Extensions.cs @@ -0,0 +1,13 @@ +namespace DotNetty.Common.Utilities +{ + using System.Runtime.CompilerServices; + + partial class StringUtil + { + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowInvalidEscapedCsvFieldException(ICharSequence value, int index) + { + throw NewInvalidEscapedCsvFieldException(value, index); + } + } +} \ No newline at end of file diff --git a/src/DotNetty.Common/Utilities/StringUtil.cs b/src/DotNetty.Common/Utilities/StringUtil.cs index 724da19e8..c021aa795 100644 --- a/src/DotNetty.Common/Utilities/StringUtil.cs +++ b/src/DotNetty.Common/Utilities/StringUtil.cs @@ -13,7 +13,7 @@ namespace DotNetty.Common.Utilities /// /// String utility class. /// - public static class StringUtil + public static partial class StringUtil { public static readonly string EmptyString = ""; public static readonly string Newline = SystemPropertyUtil.Get("line.separator", Environment.NewLine); @@ -219,7 +219,7 @@ public static byte DecodeHexByte(string s, int pos) int lo = DecodeHexNibble(s[pos + 1]); if (hi == -1 || lo == -1) { - throw new ArgumentException($"invalid hex byte '{s.Substring(pos, 2)}' at index {pos} of '{s}'"); + ThrowHelper.ThrowArgumentException_DecodeHexByte(s, pos); } return (byte)((hi << 4) + lo); @@ -230,7 +230,7 @@ public static byte[] DecodeHexDump(string hexDump, int fromIndex, int length) { if (length < 0 || (length & 1) != 0) { - throw new ArgumentException($"length: {length}"); + ThrowHelper.ThrowArgumentException_InvalidLen(length); } if (length == 0) { @@ -418,7 +418,7 @@ public static ICharSequence UnescapeCsv(ICharSequence value) else { // Not followed by a double-quote or the following double-quote is the last character - throw NewInvalidEscapedCsvFieldException(value, i); + ThrowInvalidEscapedCsvFieldException(value, i); } } unescaped.Append(current); @@ -463,7 +463,7 @@ public static IList UnescapeCsvFields(ICharSequence value) else { // double-quote followed by other character is invalid - throw new ArgumentException($"invalid escaped CSV field: {value} index: {i - 1}"); + ThrowInvalidEscapedCsvFieldException(value, i - 1); } break; default: @@ -494,7 +494,7 @@ public static IList UnescapeCsvFields(ICharSequence value) case LineFeed: case CarriageReturn: // special characters appears without being enclosed with double-quotes - throw new ArgumentException($"invalid escaped CSV field: {value} index: {i}"); + ThrowInvalidEscapedCsvFieldException(value, i); break; default: current.Append(c); break; @@ -503,7 +503,7 @@ public static IList UnescapeCsvFields(ICharSequence value) } if (quoted) { - throw new ArgumentException($"invalid escaped CSV field: {value} index: {last}"); + ThrowInvalidEscapedCsvFieldException(value, last); } unescaped.Add((StringCharSequence)current.ToString()); @@ -522,7 +522,7 @@ static void ValidateCsvFormat(ICharSequence value) case CarriageReturn: case Comma: // If value contains any special character, it should be enclosed with double-quotes - throw NewInvalidEscapedCsvFieldException(value, i); + ThrowInvalidEscapedCsvFieldException(value, i); break; } } } diff --git a/src/DotNetty.Handlers/Flow/FlowControlHandler.cs b/src/DotNetty.Handlers/Flow/FlowControlHandler.cs index 0c2202592..0d3fd5bc4 100644 --- a/src/DotNetty.Handlers/Flow/FlowControlHandler.cs +++ b/src/DotNetty.Handlers/Flow/FlowControlHandler.cs @@ -82,7 +82,7 @@ void Destroy() { if (!this.queue.IsEmpty) { - if (Logger.TraceEnabled) Logger.Trace($"Non-empty queue: {this.queue}"); + if (Logger.TraceEnabled) Logger.NonEmptyQueue(this.queue); if (this.releaseMessages) { diff --git a/src/DotNetty.Handlers/Internal/LoggingExtensions.cs b/src/DotNetty.Handlers/Internal/LoggingExtensions.cs new file mode 100644 index 000000000..b1c5e29b5 --- /dev/null +++ b/src/DotNetty.Handlers/Internal/LoggingExtensions.cs @@ -0,0 +1,46 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Runtime.CompilerServices; +using DotNetty.Buffers; +using DotNetty.Common.Internal.Logging; +using DotNetty.Common.Utilities; +using DotNetty.Handlers.Flow; +using DotNetty.Handlers.Streams; + +namespace DotNetty.Handlers +{ + internal static class HttpLoggingExtensions + { + [MethodImpl(MethodImplOptions.NoInlining)] + public static void NonEmptyQueue(this IInternalLogger logger, RecyclableQueue queue) + { + logger.Trace($"Non-empty queue: {queue}"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void UnexpectedClientHelloPacket(this IInternalLogger logger, IByteBuffer input, Exception e) + { + logger.Warn($"Unexpected client hello packet: {ByteBufferUtil.HexDump(input)}", e); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void IsEndOfInputFailed(this IInternalLogger logger, Exception exception) + { + logger.Warn($"{StringUtil.SimpleClassName(typeof(ChunkedWriteHandler))}.IsEndOfInput failed", exception); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void UnexpectedExceptionWhileSendingChunks(this IInternalLogger logger, Exception exception) + { + logger.Warn("Unexpected exception while sending chunks.", exception); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCloseAChunkedInput(this IInternalLogger logger, Exception exception) + { + logger.Warn("Failed to close a chunked input.", exception); + } + } +} diff --git a/src/DotNetty.Handlers/Logging/LoggingHandler.cs b/src/DotNetty.Handlers/Logging/LoggingHandler.cs index 124d6049b..3079fe8b6 100644 --- a/src/DotNetty.Handlers/Logging/LoggingHandler.cs +++ b/src/DotNetty.Handlers/Logging/LoggingHandler.cs @@ -250,17 +250,16 @@ protected virtual string Format(IChannelHandlerContext ctx, string eventName) /// the argument of the event protected virtual string Format(IChannelHandlerContext ctx, string eventName, object arg) { - if (arg is IByteBuffer) + switch (arg) { - return this.FormatByteBuffer(ctx, eventName, (IByteBuffer)arg); - } - else if (arg is IByteBufferHolder) - { - return this.FormatByteBufferHolder(ctx, eventName, (IByteBufferHolder)arg); - } - else - { - return this.FormatSimple(ctx, eventName, arg); + case IByteBuffer byteBuffer: + return this.FormatByteBuffer(ctx, eventName, byteBuffer); + + case IByteBufferHolder byteBufferHolder: + return this.FormatByteBufferHolder(ctx, eventName, byteBufferHolder); + + default: + return this.FormatSimple(ctx, eventName, arg); } } diff --git a/src/DotNetty.Handlers/Streams/ChunkedWriteHandler.cs b/src/DotNetty.Handlers/Streams/ChunkedWriteHandler.cs index b04bc0402..a00298ce4 100644 --- a/src/DotNetty.Handlers/Streams/ChunkedWriteHandler.cs +++ b/src/DotNetty.Handlers/Streams/ChunkedWriteHandler.cs @@ -67,7 +67,7 @@ public override void ChannelWritabilityChanged(IChannelHandlerContext context) void Discard(Exception cause = null) { - for (;;) + while(true) { PendingWrite current = this.currentWrite; if (this.currentWrite == null) @@ -107,7 +107,7 @@ void Discard(Exception cause = null) catch (Exception exception) { current.Fail(exception); - Logger.Warn($"{StringUtil.SimpleClassName(typeof(ChunkedWriteHandler))}.IsEndOfInput failed", exception); + if (Logger.WarnEnabled) Logger.IsEndOfInputFailed(exception); } finally { @@ -136,7 +136,7 @@ void InvokeDoFlush(IChannelHandlerContext context) { if (Logger.WarnEnabled) { - Logger.Warn("Unexpected exception while sending chunks.", exception); + Logger.UnexpectedExceptionWhileSendingChunks(exception); } } } @@ -392,7 +392,7 @@ static void CloseInput(IChunkedInput chunks) { if (Logger.WarnEnabled) { - Logger.Warn("Failed to close a chunked input.", exception); + Logger.FailedToCloseAChunkedInput(exception); } } } diff --git a/src/DotNetty.Handlers/Tls/SniHandler.cs b/src/DotNetty.Handlers/Tls/SniHandler.cs index 0c20de1ec..2e5546151 100644 --- a/src/DotNetty.Handlers/Tls/SniHandler.cs +++ b/src/DotNetty.Handlers/Tls/SniHandler.cs @@ -152,7 +152,7 @@ protected override void Decode(IChannelHandlerContext context, IByteBuffer input break; } - for (;;) + while(true) { if (extensionsLimit - offset < 4) { @@ -249,9 +249,9 @@ protected override void Decode(IChannelHandlerContext context, IByteBuffer input error = e; // unexpected encoding, ignore sni and use default - if (Logger.DebugEnabled) + if (Logger.WarnEnabled) { - Logger.Warn($"Unexpected client hello packet: {ByteBufferUtil.HexDump(input)}", e); + Logger.UnexpectedClientHelloPacket(input, e); } } diff --git a/src/DotNetty.Transport.Libuv/DispatcherEventLoop.cs b/src/DotNetty.Transport.Libuv/DispatcherEventLoop.cs index 8dfc923d4..6cecfb0f8 100644 --- a/src/DotNetty.Transport.Libuv/DispatcherEventLoop.cs +++ b/src/DotNetty.Transport.Libuv/DispatcherEventLoop.cs @@ -42,7 +42,7 @@ protected override void Initialize() if (Logger.InfoEnabled) { - Logger.Info("{} ({}) listening on pipe {}.", nameof(DispatcherEventLoop), this.LoopThreadId, this.PipeName); + Logger.ListeningOnPipe(this.LoopThreadId, this.PipeName); } } diff --git a/src/DotNetty.Transport.Libuv/EventLoopGroup.cs b/src/DotNetty.Transport.Libuv/EventLoopGroup.cs index f41b2e403..5c9328be8 100644 --- a/src/DotNetty.Transport.Libuv/EventLoopGroup.cs +++ b/src/DotNetty.Transport.Libuv/EventLoopGroup.cs @@ -28,7 +28,7 @@ public EventLoopGroup(int eventLoopCount) var terminationTasks = new Task[eventLoopCount]; for (int i = 0; i < eventLoopCount; i++) { - EventLoop eventLoop; + EventLoop eventLoop = null; bool success = false; try { @@ -37,7 +37,7 @@ public EventLoopGroup(int eventLoopCount) } catch (Exception ex) { - throw new InvalidOperationException("failed to create a child event loop.", ex); + ThrowHelper.ThrowInvalidOperationException_FailedToCreateChildEventLoop(ex); } finally { @@ -99,7 +99,7 @@ public Task RegisterAsync(IChannel channel) } } - throw new InvalidOperationException($"Loop {loopHandle} does not exist"); + return ThrowHelper.ThrowInvalidOperationException(loopHandle); } public Task ShutdownGracefullyAsync() diff --git a/src/DotNetty.Transport.Libuv/Internal/LoggingExtensions.cs b/src/DotNetty.Transport.Libuv/Internal/LoggingExtensions.cs new file mode 100644 index 000000000..1eb9123e4 --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Internal/LoggingExtensions.cs @@ -0,0 +1,218 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Runtime.CompilerServices; +using DotNetty.Common.Concurrency; +using DotNetty.Common.Internal.Logging; +using DotNetty.Transport.Libuv.Native; + +namespace DotNetty.Transport.Libuv +{ + internal static class LibuvLoggingExtensions + { + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopWalkingHandles(this IInternalLogger logger, IntPtr handle, int count) + { + logger.Debug($"Loop {handle} walking handles, count = {count}."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopRunningDefaultToCallCloseCallbacks(this IInternalLogger logger, IntPtr handle, int count) + { + logger.Debug($"Loop {handle} running default to call close callbacks, count = {count}."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopCloseResult(this IInternalLogger logger, IntPtr handle, int result, int count) + { + logger.Debug($"Loop {handle} close result = {result}, count = {count}."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopCloseAllHandlesLimit20TimesExceeded(this IInternalLogger logger, IntPtr handle) + { + logger.Warn($"Loop {handle} close all handles limit 20 times exceeded."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopClosed(this IInternalLogger logger, IntPtr handle, int count) + { + logger.Info($"Loop {handle} closed, count = {count}."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopGCHandleReleased(this IInternalLogger logger, IntPtr handle) + { + logger.Info($"Loop {handle} GCHandle released."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopMemoryReleased(this IInternalLogger logger, IntPtr handle) + { + logger.Info($"Loop {handle} memory released."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopWalkCallbackDisposed(this IInternalLogger logger, IntPtr handle, IntPtr loopHandle, IDisposable target) + { + logger.Debug($"Loop {loopHandle} walk callback disposed {handle} {target?.GetType()}"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopWalkCallbackAttemptToCloseHandleFailed(this IInternalLogger logger, IntPtr handle, IntPtr loopHandle, Exception exception) + { + logger.Warn($"Loop {loopHandle} Walk callback attempt to close handle {handle} failed. {exception}"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCloseChannelCleanly(this IInternalLogger logger, object channelObject, Exception ex) + { + logger.Debug($"Failed to close channel {channelObject} cleanly.", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopAllocated(this IInternalLogger logger, IntPtr handle) + { + logger.Info($"Loop {handle} allocated."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ListeningOnPipe(this IInternalLogger logger, int loopThreadId, string pipeName) + { + logger.Info("{} ({}) listening on pipe {}.", nameof(DispatcherEventLoop), loopThreadId, pipeName); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void DispatcherPipeConnected(this IInternalLogger logger, int loopThreadId, string pipeName) + { + logger.Info($"{nameof(WorkerEventLoop)} ({loopThreadId}) dispatcher pipe {pipeName} connected."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopThreadFinished(this IInternalLogger logger, XThread thread, IntPtr handle) + { + logger.Info("Loop {}:{} thread finished.", thread.Name, handle); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopRunDefaultError(this IInternalLogger logger, XThread thread, IntPtr handle, Exception ex) + { + logger.Error("Loop {}:{} run default error.", thread.Name, handle, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ShuttingDownLoopError(this IInternalLogger logger, Exception ex) + { + logger.Error("{}: shutting down loop error", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopDisposed(this IInternalLogger logger, XThread thread, IntPtr handle) + { + logger.Info("{}:{} disposed.", thread.Name, handle); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopDisposing(this IInternalLogger logger, IDisposable handle) + { + logger.Info("Disposing {}", handle.GetType()); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void AcceptClientConnectionFailed(this IInternalLogger logger, Exception ex) + { + logger.Info("Accept client connection failed.", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToDisposeAClientConnection(this IInternalLogger logger, Exception ex) + { + logger.Warn("Failed to dispose a client connection.", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToConnectToDispatcher(this IInternalLogger logger, int retryCount, OperationException error) + { + logger.Info($"{nameof(WorkerEventLoop)} failed to connect to dispatcher, Retry count = {retryCount}", error); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void IPCPipeReadError(this IInternalLogger logger, OperationException error) + { + logger.Warn("IPC Pipe read error", error); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToWriteServerHandleToClient(this IInternalLogger logger, OperationException error) + { + logger.Warn($"{nameof(PipeListener)} failed to write server handle to client", error); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToSendServerHandleToClient(this IInternalLogger logger, Exception ex) + { + logger.Warn($"{nameof(PipeListener)} failed to send server handle to client", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ReadError(this IInternalLogger logger, OperationException error) + { + logger.Warn($"{nameof(PipeListener)} read error", error); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TcpHandleReadCallbcakError(this IInternalLogger logger, IntPtr handle, Exception exception) + { + logger.Warn($"Tcp {handle} read callbcak error.", exception); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TerminatedWithNonEmptyTaskQueue(this IInternalLogger logger, int count) + { + logger.Warn($"{nameof(LoopExecutor)} terminated with non-empty task queue ({count})"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopReleaseError(this IInternalLogger logger, XThread thread, IntPtr handle, Exception ex) + { + logger.Warn("{}:{} release error {}", thread.Name, handle, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void LoopDisposeError(this IInternalLogger logger, IDisposable handle, Exception ex) + { + logger.Warn("{} dispose error {}", handle.GetType(), ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCreateConnectRequestToDispatcher(this IInternalLogger logger, Exception exception) + { + logger.Warn($"{nameof(WorkerEventLoop)} failed to create connect request to dispatcher", exception); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToConnectToDispatcher(this IInternalLogger logger, ConnectRequest request) + { + logger.Warn($"{nameof(WorkerEventLoop)} failed to connect to dispatcher", request.Error); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void CallbackRrror(this IInternalLogger logger, uv_handle_type handleType, IntPtr handle, Exception exception) + { + logger.Error($"{handleType} {handle} callback error.", exception); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ErrorWhilstClosingHandle(this IInternalLogger logger, uv_req_type requestType, IntPtr handle, Exception exception) + { + logger.Error($"{requestType} {handle} error whilst closing handle.", exception); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ErrorWhilstClosingHandle(this IInternalLogger logger, IntPtr handle, Exception exception) + { + logger.Error($"{nameof(NativeHandle)} {handle} error whilst closing handle.", exception); + } + } +} diff --git a/src/DotNetty.Transport.Libuv/Internal/ThrowHelper.Extensions.cs b/src/DotNetty.Transport.Libuv/Internal/ThrowHelper.Extensions.cs index 17c4f357b..c19496b40 100644 --- a/src/DotNetty.Transport.Libuv/Internal/ThrowHelper.Extensions.cs +++ b/src/DotNetty.Transport.Libuv/Internal/ThrowHelper.Extensions.cs @@ -1,7 +1,9 @@ using System; +using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Threading.Tasks; using DotNetty.Common.Concurrency; using DotNetty.Common.Utilities; using DotNetty.Transport.Channels; @@ -110,6 +112,16 @@ ArgumentException GetArgumentException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static Task ThrowInvalidOperationException(IntPtr loopHandle) + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException($"Loop {loopHandle} does not exist"); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowInvalidOperationException_ExecutionState(int executionState) { @@ -180,6 +192,16 @@ InvalidOperationException GetInvalidOperationException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_FailedToCreateChildEventLoop(Exception ex) + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("failed to create a child event loop.", ex); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowInvalidOperationException_CreateChild(Exception ex) { @@ -190,6 +212,16 @@ InvalidOperationException GetInvalidOperationException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_HandleNotInit() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("tcpListener handle not intialized"); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowSocketException(int errorCode) { @@ -230,6 +262,16 @@ RejectedExecutionException GetSocketException() } } + internal static ChannelException GetChannelException(OperationException ex) + { + return new ChannelException(ex); + } + + internal static ChannelException GetChannelException_FailedToWrite(OperationException error) + { + return new ChannelException("Failed to write", error); + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowChannelException(Exception exc) { @@ -253,11 +295,36 @@ ChannelException GetChannelException() [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowTimeoutException(string pipeName) { - throw GetArgumentException(); - TimeoutException GetArgumentException() + throw GetException(); + TimeoutException GetException() { return new TimeoutException($"Connect to dispatcher pipe {pipeName} timed out."); } } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowNotSupportedException(IPEndPoint endPoint, out sockaddr addr) + { + throw GetException(); + NotSupportedException GetException() + { + return new NotSupportedException($"End point {endPoint} is not supported, expecting InterNetwork/InterNetworkV6."); + } + } + + internal static ConnectTimeoutException GetConnectTimeoutException(OperationException error) + { + return new ConnectTimeoutException(error.ToString()); + } + + internal static ClosedChannelException GetClosedChannelException() + { + return new ClosedChannelException(); + } + + internal static ClosedChannelException GetClosedChannelException_FailedToWrite(Exception ex) + { + return new ClosedChannelException("Failed to write", ex); + } } } diff --git a/src/DotNetty.Transport.Libuv/LoopExecutor.cs b/src/DotNetty.Transport.Libuv/LoopExecutor.cs index 9da4de94d..705b10697 100644 --- a/src/DotNetty.Transport.Libuv/LoopExecutor.cs +++ b/src/DotNetty.Transport.Libuv/LoopExecutor.cs @@ -160,12 +160,12 @@ void StartLoop() catch (Exception ex) { this.loopRunStart.Set(); - Logger.Error("Loop {}:{} run default error.", this.thread.Name, handle, ex); + Logger.LoopRunDefaultError(this.thread, handle, ex); this.terminationCompletionSource.TrySetException(ex); } finally { - Logger.Info("Loop {}:{} thread finished.", this.thread.Name, handle); + if (Logger.InfoEnabled) Logger.LoopThreadFinished(this.thread, handle); this.CleanupAndTerminate(); } } @@ -181,7 +181,7 @@ void StopLoop() } catch (Exception ex) { - Logger.Error("{}: shutting down loop error", ex); + Logger.ShuttingDownLoopError(ex); } } @@ -235,9 +235,9 @@ void CleanupAndTerminate() finally { Interlocked.Exchange(ref this.executionState, TerminatedState); - if (!this.taskQueue.IsEmpty) + if (!this.taskQueue.IsEmpty && Logger.WarnEnabled) { - Logger.Warn($"{nameof(LoopExecutor)} terminated with non-empty task queue ({this.taskQueue.Count})"); + Logger.TerminatedWithNonEmptyTaskQueue(this.taskQueue.Count); } this.terminationCompletionSource.TryComplete(); } @@ -253,25 +253,25 @@ void Cleanup() } catch (Exception ex) { - Logger.Warn("{}:{} release error {}", this.thread.Name, handle, ex); + if (Logger.WarnEnabled) Logger.LoopReleaseError(this.thread, handle, ex); } SafeDispose(this.timerHandle); SafeDispose(this.asyncHandle); SafeDispose(this.loop); - Logger.Info("{}:{} disposed.", this.thread.Name, handle); + if (Logger.InfoEnabled) Logger.LoopDisposed(this.thread, handle); } static void SafeDispose(IDisposable handle) { try { - Logger.Info("Disposing {}", handle.GetType()); + if (Logger.InfoEnabled) Logger.LoopDisposing(handle); handle.Dispose(); } catch (Exception ex) { - Logger.Warn("{} dispose error {}", handle.GetType(), ex); + if (Logger.WarnEnabled) Logger.LoopDisposeError(handle, ex); } } @@ -297,7 +297,7 @@ void RunAllTasks(long timeout) long runTasks = 0; long executionTime; this.wakeUp = false; - for (;;) + while(true) { SafeExecute(task); @@ -402,7 +402,7 @@ static bool RunAllTasksFrom(IQueue taskQueue) { return false; } - for (;;) + while(true) { SafeExecute(task); task = PollTaskFrom(taskQueue); @@ -488,7 +488,7 @@ public override Task ShutdownGracefullyAsync(TimeSpan quietPeriod, TimeSpan time bool inEventLoop = this.InEventLoop; bool wakeUpLoop; int oldState; - for (;;) + while(true) { if (this.IsShuttingDown) { diff --git a/src/DotNetty.Transport.Libuv/Native/Async.cs b/src/DotNetty.Transport.Libuv/Native/Async.cs index f8ce714db..c6739b648 100644 --- a/src/DotNetty.Transport.Libuv/Native/Async.cs +++ b/src/DotNetty.Transport.Libuv/Native/Async.cs @@ -59,7 +59,7 @@ void OnWorkCallback() } catch (Exception exception) { - Logger.Error($"{this.HandleType} {this.Handle} callback error.", exception); + Logger.CallbackRrror(this.HandleType, this.Handle, exception); } } diff --git a/src/DotNetty.Transport.Libuv/Native/Loop.Extensions.cs b/src/DotNetty.Transport.Libuv/Native/Loop.Extensions.cs new file mode 100644 index 000000000..0628f12de --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Native/Loop.Extensions.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +// ReSharper disable ConvertToAutoPropertyWithPrivateSetter +namespace DotNetty.Transport.Libuv.Native +{ + using System; + using System.Runtime.CompilerServices; + + partial class Loop + { + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowObjectDisposedException() + { + throw GetObjectDisposedException(); + ObjectDisposedException GetObjectDisposedException() + { + return new ObjectDisposedException($"{typeof(Loop)}"); + } + } + } +} diff --git a/src/DotNetty.Transport.Libuv/Native/Loop.cs b/src/DotNetty.Transport.Libuv/Native/Loop.cs index 82f9c1898..1e9696988 100644 --- a/src/DotNetty.Transport.Libuv/Native/Loop.cs +++ b/src/DotNetty.Transport.Libuv/Native/Loop.cs @@ -9,7 +9,7 @@ namespace DotNetty.Transport.Libuv.Native using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - sealed unsafe class Loop : IDisposable + sealed unsafe partial class Loop : IDisposable { static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance(); static readonly uv_walk_cb WalkCallback = OnWalkCallback; @@ -35,7 +35,7 @@ public Loop() this.handle = loopHandle; if (Logger.InfoEnabled) { - Logger.Info($"Loop {this.handle} allocated."); + Logger.LoopAllocated(this.handle); } } @@ -97,7 +97,7 @@ void Validate() { if (this.handle == IntPtr.Zero) { - NativeMethods.ThrowObjectDisposedException($"{this.GetType()}"); + ThrowObjectDisposedException(); // NativeMethods.ThrowObjectDisposedException($"{this.GetType()}"); } } @@ -128,16 +128,17 @@ static void Close(IntPtr handle) //https://github.com/libuv/libuv/blob/v1.x/test/task.h#L190 int count = 0; + var debugEnabled = Logger.DebugEnabled; while (true) { - Logger.Debug($"Loop {handle} walking handles, count = {count}."); + if (debugEnabled) Logger.LoopWalkingHandles(handle, count); NativeMethods.uv_walk(handle, WalkCallback, handle); - Logger.Debug($"Loop {handle} running default to call close callbacks, count = {count}."); + if (debugEnabled) Logger.LoopRunningDefaultToCallCloseCallbacks(handle, count); NativeMethods.uv_run(handle, uv_run_mode.UV_RUN_DEFAULT); int result = NativeMethods.uv_loop_close(handle); - Logger.Debug($"Loop {handle} close result = {result}, count = {count}."); + if (debugEnabled) Logger.LoopCloseResult(handle, result, count); if (result == 0) { break; @@ -146,11 +147,12 @@ static void Close(IntPtr handle) count++; if (count >= 20) { - Logger.Warn($"Loop {handle} close all handles limit 20 times exceeded."); + Logger.LoopCloseAllHandlesLimit20TimesExceeded(handle); break; } } - Logger.Info($"Loop {handle} closed, count = {count}."); + var infoEnabled = Logger.InfoEnabled; + if (infoEnabled) Logger.LoopClosed(handle, count); // Free GCHandle if (pHandle != IntPtr.Zero) @@ -160,13 +162,13 @@ static void Close(IntPtr handle) { nativeHandle.Free(); ((uv_loop_t*)handle)->data = IntPtr.Zero; - Logger.Info($"Loop {handle} GCHandle released."); + if (infoEnabled) Logger.LoopGCHandleReleased(handle); } } // Release memory NativeMethods.FreeMemory(handle); - Logger.Info($"Loop {handle} memory released."); + if (infoEnabled) Logger.LoopMemoryReleased(handle); } static void OnWalkCallback(IntPtr handle, IntPtr loopHandle) @@ -181,11 +183,11 @@ static void OnWalkCallback(IntPtr handle, IntPtr loopHandle) // All handles must implement IDisposable var target = NativeHandle.GetTarget(handle); target?.Dispose(); - Logger.Debug($"Loop {loopHandle} walk callback disposed {handle} {target?.GetType()}"); + if (Logger.DebugEnabled) Logger.LoopWalkCallbackDisposed(handle, loopHandle, target); } catch (Exception exception) { - Logger.Warn($"Loop {loopHandle} Walk callback attempt to close handle {handle} failed. {exception}"); + if (Logger.WarnEnabled) Logger.LoopWalkCallbackAttemptToCloseHandleFailed(handle, loopHandle, exception); } } diff --git a/src/DotNetty.Transport.Libuv/Native/NativeHandle.Extensions.cs b/src/DotNetty.Transport.Libuv/Native/NativeHandle.Extensions.cs new file mode 100644 index 000000000..e5bd3b7c0 --- /dev/null +++ b/src/DotNetty.Transport.Libuv/Native/NativeHandle.Extensions.cs @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace DotNetty.Transport.Libuv.Native +{ + using DotNetty.Common.Internal.Logging; + using System; + using System.Diagnostics; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + + partial class NativeHandle + { + [MethodImpl(MethodImplOptions.NoInlining)] + internal void ThrowObjectDisposedException() + { + throw GetObjectDisposedException(); + ObjectDisposedException GetObjectDisposedException() + { + return new ObjectDisposedException($"{this.GetType()}"); + } + } + } +} diff --git a/src/DotNetty.Transport.Libuv/Native/NativeHandle.cs b/src/DotNetty.Transport.Libuv/Native/NativeHandle.cs index e95e42d78..db56b1576 100644 --- a/src/DotNetty.Transport.Libuv/Native/NativeHandle.cs +++ b/src/DotNetty.Transport.Libuv/Native/NativeHandle.cs @@ -9,7 +9,7 @@ namespace DotNetty.Transport.Libuv.Native using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - public abstract unsafe class NativeHandle : IDisposable + public abstract unsafe partial class NativeHandle : IDisposable { protected static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance(); static readonly uv_close_cb CloseCallback = OnCloseHandle; @@ -38,7 +38,7 @@ protected void Validate() { if (!this.IsValid) { - NativeMethods.ThrowObjectDisposedException($"{this.GetType()}"); + ThrowObjectDisposedException(); // NativeMethods.ThrowObjectDisposedException($"{this.GetType()}"); } } @@ -109,7 +109,7 @@ void Dispose(bool disposing) } catch (Exception exception) { - Logger.Error($"{nameof(NativeHandle)} {this.Handle} error whilst closing handle.", exception); + Logger.ErrorWhilstClosingHandle(this.Handle, exception); // For finalizer, we cannot allow this to escape. if (disposing) throw; } diff --git a/src/DotNetty.Transport.Libuv/Native/NativeMethods.cs b/src/DotNetty.Transport.Libuv/Native/NativeMethods.cs index d2d2c3bdd..6100a446b 100644 --- a/src/DotNetty.Transport.Libuv/Native/NativeMethods.cs +++ b/src/DotNetty.Transport.Libuv/Native/NativeMethods.cs @@ -312,7 +312,7 @@ internal static void GetSocketAddress(IPEndPoint endPoint, out sockaddr addr) Debug.Assert(endPoint != null); string ip = endPoint.Address.ToString(); - int result; + int result = 0; switch (endPoint.AddressFamily) { case AddressFamily.InterNetwork: @@ -322,7 +322,7 @@ internal static void GetSocketAddress(IPEndPoint endPoint, out sockaddr addr) result = uv_ip6_addr(ip, endPoint.Port, out addr); break; default: - throw new NotSupportedException($"End point {endPoint} is not supported, expecting InterNetwork/InterNetworkV6."); + ThrowHelper.ThrowNotSupportedException(endPoint, out addr); break; } ThrowIfError(result); } diff --git a/src/DotNetty.Transport.Libuv/Native/NativeRequest.cs b/src/DotNetty.Transport.Libuv/Native/NativeRequest.cs index abd66e2ab..005f69478 100644 --- a/src/DotNetty.Transport.Libuv/Native/NativeRequest.cs +++ b/src/DotNetty.Transport.Libuv/Native/NativeRequest.cs @@ -70,7 +70,7 @@ protected virtual void Dispose(bool disposing) } catch (Exception exception) { - Logger.Error($"{this.requestType} {this.Handle} error whilst closing handle.", exception); + Logger.ErrorWhilstClosingHandle(this.requestType ,this.Handle, exception); // For finalizer, we cannot allow this to escape. if (disposing) throw; diff --git a/src/DotNetty.Transport.Libuv/Native/Pipe.cs b/src/DotNetty.Transport.Libuv/Native/Pipe.cs index 0cbfb492e..e0ebafb89 100644 --- a/src/DotNetty.Transport.Libuv/Native/Pipe.cs +++ b/src/DotNetty.Transport.Libuv/Native/Pipe.cs @@ -171,7 +171,7 @@ void OnWriteCallback(int status) if (status < 0) { OperationException error = NativeMethods.CreateError((uv_err_code)status); - Logger.Warn($"{nameof(PipeListener)} failed to write server handle to client", error); + if (Logger.WarnEnabled) Logger.FailedToWriteServerHandleToClient(error); } this.sentHandle.CloseHandle(); diff --git a/src/DotNetty.Transport.Libuv/Native/PipeListener.cs b/src/DotNetty.Transport.Libuv/Native/PipeListener.cs index d1ea5c8d1..998f8fb2f 100644 --- a/src/DotNetty.Transport.Libuv/Native/PipeListener.cs +++ b/src/DotNetty.Transport.Libuv/Native/PipeListener.cs @@ -91,7 +91,7 @@ unsafe void OnConnectionCallback(int status) catch (Exception exception) { client?.CloseHandle(); - Logger.Warn($"{nameof(PipeListener)} failed to send server handle to client", exception); + if (Logger.WarnEnabled) Logger.FailedToSendServerHandleToClient(exception); } } @@ -112,7 +112,7 @@ void OnRead(Pipe pipe, int status) if (status != NativeMethods.EOF) { OperationException error = NativeMethods.CreateError((uv_err_code)status); - Logger.Warn($"{nameof(PipeListener)} read error", error); + if (Logger.WarnEnabled) Logger.ReadError(error); } } diff --git a/src/DotNetty.Transport.Libuv/Native/Tcp.cs b/src/DotNetty.Transport.Libuv/Native/Tcp.cs index b3a5cedd9..a796d08c4 100644 --- a/src/DotNetty.Transport.Libuv/Native/Tcp.cs +++ b/src/DotNetty.Transport.Libuv/Native/Tcp.cs @@ -50,7 +50,7 @@ void OnReadCallback(int statusCode, OperationException error) } catch (Exception exception) { - Logger.Warn($"Tcp {this.Handle} read callbcak error.", exception); + if (Logger.WarnEnabled) Logger.TcpHandleReadCallbcakError(this.Handle, exception); } finally { diff --git a/src/DotNetty.Transport.Libuv/Native/Timer.cs b/src/DotNetty.Transport.Libuv/Native/Timer.cs index af95b00be..295f159f4 100644 --- a/src/DotNetty.Transport.Libuv/Native/Timer.cs +++ b/src/DotNetty.Transport.Libuv/Native/Timer.cs @@ -95,7 +95,7 @@ void OnWorkCallback() } catch (Exception exception) { - Logger.Error($"{this.HandleType} {this.Handle} callback error.", exception); + Logger.CallbackRrror(this.HandleType, this.Handle, exception); } } diff --git a/src/DotNetty.Transport.Libuv/NativeChannel.cs b/src/DotNetty.Transport.Libuv/NativeChannel.cs index 2aa6e3d7c..57e8a0972 100644 --- a/src/DotNetty.Transport.Libuv/NativeChannel.cs +++ b/src/DotNetty.Transport.Libuv/NativeChannel.cs @@ -96,7 +96,7 @@ protected override void DoClose() TaskCompletionSource promise = this.connectPromise; if (promise != null) { - promise.TrySetException(new ClosedChannelException()); + promise.TrySetException(ThrowHelper.GetClosedChannelException()); this.connectPromise = null; } } @@ -186,11 +186,11 @@ void INativeUnsafe.FinishConnect(ConnectRequest request) if (error.ErrorCode == ErrorCode.ETIMEDOUT) { // Connection timed out should use the standard ConnectTimeoutException - promise.TrySetException(new ConnectTimeoutException(error.ToString())); + promise.TrySetException(ThrowHelper.GetConnectTimeoutException(error)); } else { - promise.TrySetException(new ChannelException(error)); + promise.TrySetException(ThrowHelper.GetChannelException(error)); } } else @@ -274,7 +274,7 @@ void INativeUnsafe.FinishRead(ReadOperation operation) { if (error != null) { - pipeline.FireExceptionCaught(new ChannelException(error)); + pipeline.FireExceptionCaught(ThrowHelper.GetChannelException(error)); } this.CloseSafe(); } @@ -304,7 +304,7 @@ internal static async void CloseSafe(object channelObject, Task closeTask) { if (Logger.DebugEnabled) { - Logger.Debug($"Failed to close channel {channelObject} cleanly.", ex); + Logger.FailedToCloseChannelCleanly(channelObject, ex); } } } @@ -331,7 +331,7 @@ void INativeUnsafe.FinishWrite(int bytesWritten, OperationException error) if (error != null) { input.FailFlushed(error, true); - CloseSafe(ch, this.CloseAsync(new ChannelException("Failed to write", error), false)); + CloseSafe(ch, this.CloseAsync(ThrowHelper.GetChannelException_FailedToWrite(error), false)); } else { @@ -343,7 +343,7 @@ void INativeUnsafe.FinishWrite(int bytesWritten, OperationException error) } catch (Exception ex) { - CloseSafe(ch, this.CloseAsync(new ClosedChannelException("Failed to write", ex), false)); + CloseSafe(ch, this.CloseAsync(ThrowHelper.GetClosedChannelException_FailedToWrite(ex), false)); } this.Flush0(); } diff --git a/src/DotNetty.Transport.Libuv/TcpServerChannel.cs b/src/DotNetty.Transport.Libuv/TcpServerChannel.cs index aed7b8fe1..923347368 100644 --- a/src/DotNetty.Transport.Libuv/TcpServerChannel.cs +++ b/src/DotNetty.Transport.Libuv/TcpServerChannel.cs @@ -77,7 +77,7 @@ internal override NativeHandle GetHandle() { if (this.tcpListener == null) { - throw new InvalidOperationException("tcpListener handle not intialized"); + ThrowHelper.ThrowInvalidOperationException_HandleNotInit(); } return this.tcpListener; @@ -127,12 +127,13 @@ void IServerNativeUnsafe.Accept(RemoteConnection connection) var ch = this.channel; NativeHandle client = connection.Client; + var connError = connection.Error; // If the AutoRead is false, reject the connection - if (!ch.config.AutoRead || connection.Error != null) + if (!ch.config.AutoRead || connError != null) { - if (connection.Error != null) + if (connError != null) { - Logger.Info("Accept client connection failed.", connection.Error); + if (Logger.InfoEnabled) Logger.AcceptClientConnectionFailed(connError); } try { @@ -140,7 +141,7 @@ void IServerNativeUnsafe.Accept(RemoteConnection connection) } catch (Exception ex) { - Logger.Warn("Failed to dispose a client connection.", ex); + if (Logger.WarnEnabled) Logger.FailedToDisposeAClientConnection(ex); } finally { diff --git a/src/DotNetty.Transport.Libuv/WorkerEventLoop.cs b/src/DotNetty.Transport.Libuv/WorkerEventLoop.cs index 00f567966..a65daa32d 100644 --- a/src/DotNetty.Transport.Libuv/WorkerEventLoop.cs +++ b/src/DotNetty.Transport.Libuv/WorkerEventLoop.cs @@ -52,7 +52,7 @@ protected override void Initialize() } catch (Exception exception) { - Logger.Warn($"{nameof(WorkerEventLoop)} failed to create connect request to dispatcher", exception); + if (Logger.WarnEnabled) Logger.FailedToCreateConnectRequestToDispatcher(exception); request?.Dispose(); this.connectCompletion.TryUnwrap(exception); } @@ -66,14 +66,14 @@ void OnConnected(ConnectRequest request) { if (request.Error != null) { - Logger.Warn($"{nameof(WorkerEventLoop)} failed to connect to dispatcher", request.Error); + if (Logger.WarnEnabled) Logger.FailedToConnectToDispatcher(request); this.connectCompletion.TryUnwrap(request.Error); } else { if (Logger.InfoEnabled) { - Logger.Info($"{nameof(WorkerEventLoop)} ({this.LoopThreadId}) dispatcher pipe {this.pipeName} connected."); + Logger.DispatcherPipeConnected(this.LoopThreadId, this.pipeName); } this.pipe.ReadStart(this.OnRead); @@ -94,7 +94,7 @@ void OnRead(Pipe handle, int status) if (status != NativeMethods.EOF) { OperationException error = NativeMethods.CreateError((uv_err_code)status); - Logger.Warn("IPC Pipe read error", error); + if (Logger.WarnEnabled) Logger.IPCPipeReadError(error); } } else @@ -128,7 +128,7 @@ protected override void OnWatcherCallback() { if (this.Error != null && this.retryCount < MaximumRetryCount) { - Logger.Info($"{nameof(WorkerEventLoop)} failed to connect to dispatcher, Retry count = {this.retryCount}", this.Error); + if (Logger.InfoEnabled) Logger.FailedToConnectToDispatcher(this.retryCount, this.Error); this.Connect(); this.retryCount++; } diff --git a/src/DotNetty.Transport.Libuv/WorkerEventLoopGroup.cs b/src/DotNetty.Transport.Libuv/WorkerEventLoopGroup.cs index 70a382987..25c33eaee 100644 --- a/src/DotNetty.Transport.Libuv/WorkerEventLoopGroup.cs +++ b/src/DotNetty.Transport.Libuv/WorkerEventLoopGroup.cs @@ -109,7 +109,7 @@ public Task RegisterAsync(IChannel channel) } } - throw new InvalidOperationException($"Loop {loopHandle} does not exist"); + return ThrowHelper.ThrowInvalidOperationException(loopHandle); } public Task ShutdownGracefullyAsync() diff --git a/src/DotNetty.Transport/Bootstrapping/AbstractBootstrap.cs b/src/DotNetty.Transport/Bootstrapping/AbstractBootstrap.cs index 056f82ab2..8de827c0a 100644 --- a/src/DotNetty.Transport/Bootstrapping/AbstractBootstrap.cs +++ b/src/DotNetty.Transport/Bootstrapping/AbstractBootstrap.cs @@ -7,6 +7,7 @@ namespace DotNetty.Transport.Bootstrapping using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Net; + using System.Runtime.CompilerServices; using System.Threading.Tasks; using CuteAnt.Collections; using CuteAnt.Pool; @@ -63,7 +64,7 @@ public virtual TBootstrap Group(IEventLoopGroup group) if (this.group != null) { - throw new InvalidOperationException("group has already been set."); + ThrowHelper.ThrowInvalidOperationException_GroupHasAlreadyBeenSet(); } this.group = group; return (TBootstrap)this; @@ -171,11 +172,11 @@ public virtual TBootstrap Validate() { if (this.group == null) { - throw new InvalidOperationException("group not set"); + ThrowHelper.ThrowInvalidOperationException_GroupNotSet(); } if (this.channelFactory == null) { - throw new InvalidOperationException("channel or channelFactory not set"); + ThrowHelper.ThrowInvalidOperationException_ChannelOrFactoryNotSet(); } return (TBootstrap)this; } @@ -206,7 +207,7 @@ public Task BindAsync() EndPoint address = this.localAddress; if (address == null) { - throw new InvalidOperationException("localAddress must be set beforehand."); + ThrowHelper.ThrowInvalidOperationException_LocalAddrMustBeSetBeforehand(); } return this.DoBindAsync(address); } @@ -286,7 +287,7 @@ protected async Task InitAndRegisterAsync() } catch (Exception ex) { - Logger.Warn("Failed to close channel: " + channel, ex); + Logger.FailedToCloseChannel(channel, ex); } } else @@ -373,19 +374,32 @@ protected static void SetChannelOptions(IChannel channel, ChannelOptionValue[] o protected static void SetChannelOption(IChannel channel, ChannelOptionValue option, IInternalLogger logger) { + var warnEnabled = logger.WarnEnabled; try { if (!option.Set(channel.Configuration)) { - logger.Warn("Unknown channel option '{}' for channel '{}'", option.Option, channel); + if (warnEnabled) UnknownChannelOptionForChannel(logger, channel, option); } } catch (Exception ex) { - logger.Warn("Failed to set channel option '{}' with value '{}' for channel '{}'", option.Option, option, channel, ex); + if (warnEnabled) FailedToSetChannelOptionWithValueForChannel(logger, channel, option, ex); } } + [MethodImpl(MethodImplOptions.NoInlining)] + private static void UnknownChannelOptionForChannel(IInternalLogger logger, IChannel channel, ChannelOptionValue option) + { + logger.Warn("Unknown channel option '{}' for channel '{}'", option.Option, channel); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void FailedToSetChannelOptionWithValueForChannel(IInternalLogger logger, IChannel channel, ChannelOptionValue option, Exception ex) + { + logger.Warn("Failed to set channel option '{}' with value '{}' for channel '{}'", option.Option, option, channel, ex); + } + public override string ToString() { var buf = StringBuilderManager.Allocate() diff --git a/src/DotNetty.Transport/Bootstrapping/Bootstrap.cs b/src/DotNetty.Transport/Bootstrapping/Bootstrap.cs index b073ffb47..3685996ab 100644 --- a/src/DotNetty.Transport/Bootstrapping/Bootstrap.cs +++ b/src/DotNetty.Transport/Bootstrapping/Bootstrap.cs @@ -98,7 +98,7 @@ public Task ConnectAsync() EndPoint remoteAddress = this.remoteAddress; if (remoteAddress == null) { - throw new InvalidOperationException("remoteAddress not set"); + ThrowHelper.ThrowInvalidOperationException_RemoteAddrNotSet(); } return this.DoResolveAndConnectAsync(remoteAddress, this.LocalAddress()); @@ -177,7 +177,7 @@ async Task DoResolveAndConnectAsync(EndPoint remoteAddress, EndPoint l } catch (Exception ex) { - Logger.Warn("Failed to close channel: " + channel, ex); + if (Logger.WarnEnabled) Logger.FailedToCloseChannel(channel, ex); } throw; @@ -235,7 +235,7 @@ public override Bootstrap Validate() base.Validate(); if (this.Handler() == null) { - throw new InvalidOperationException("handler not set"); + ThrowHelper.ThrowInvalidOperationException_HandlerNotSet(); } return this; } diff --git a/src/DotNetty.Transport/Bootstrapping/ServerBootstrap.cs b/src/DotNetty.Transport/Bootstrapping/ServerBootstrap.cs index 0ed93e4c9..18c9b2b12 100644 --- a/src/DotNetty.Transport/Bootstrapping/ServerBootstrap.cs +++ b/src/DotNetty.Transport/Bootstrapping/ServerBootstrap.cs @@ -57,7 +57,7 @@ public ServerBootstrap Group(IEventLoopGroup parentGroup, IEventLoopGroup childG base.Group(parentGroup); if (this.childGroup != null) { - throw new InvalidOperationException("childGroup set already"); + ThrowHelper.ThrowInvalidOperationException_ChildGroupSetAlready(); } this.childGroup = childGroup; return this; @@ -155,11 +155,11 @@ public override ServerBootstrap Validate() base.Validate(); if (this.childHandler == null) { - throw new InvalidOperationException("childHandler not set"); + ThrowHelper.ThrowInvalidOperationException_ChildHandlerNotYet(); } if (this.childGroup == null) { - Logger.Warn("childGroup is not set. Using parentGroup instead."); + if (Logger.WarnEnabled) Logger.ChildGroupIsNotSetUsingParentGroupInstead(); this.childGroup = this.Group(); } return this; @@ -219,7 +219,7 @@ public override void ChannelRead(IChannelHandlerContext ctx, object msg) static void ForceClose(IChannel child, Exception ex) { child.Unsafe.CloseForcibly(); - Logger.Warn("Failed to register an accepted channel: " + child, ex); + if (Logger.WarnEnabled) Logger.ChildGroupIsNotSetUsingParentGroupInstead(child, ex); } public override void ExceptionCaught(IChannelHandlerContext ctx, Exception cause) diff --git a/src/DotNetty.Transport/Channels/AbstractChannel.cs b/src/DotNetty.Transport/Channels/AbstractChannel.cs index 64e9a6d0f..adbbf33e3 100644 --- a/src/DotNetty.Transport/Channels/AbstractChannel.cs +++ b/src/DotNetty.Transport/Channels/AbstractChannel.cs @@ -326,12 +326,12 @@ public Task RegisterAsync(IEventLoop eventLoop) if (this.channel.Registered) { - return TaskUtil.FromException(new InvalidOperationException("registered to an event loop already")); + return ThrowHelper.ThrowInvalidOperationException_RegisteredToEventLoopAlready(); } if (!this.channel.IsCompatible(eventLoop)) { - return TaskUtil.FromException(new InvalidOperationException("incompatible event loop type: " + eventLoop.GetType().Name)); + return ThrowHelper.ThrowInvalidOperationException_IncompatibleEventLoopType(eventLoop); } this.channel.eventLoop = eventLoop; @@ -350,7 +350,7 @@ public Task RegisterAsync(IEventLoop eventLoop) } catch (Exception ex) { - Logger.Warn("Force-closing a channel whose registration task was not accepted by an event loop: {}", this.channel, ex); + if (Logger.WarnEnabled) Logger.ForceClosingAChannel(this.channel, ex); this.CloseForcibly(); this.channel.closeFuture.Complete(); Util.SafeSetFailure(promise, ex, Logger); @@ -368,7 +368,7 @@ void Register0(TaskCompletionSource promise) // call was outside of the eventLoop if (!promise.SetUncancellable() || !this.EnsureOpen(promise)) { - Util.SafeSetFailure(promise, new ClosedChannelException(), Logger); + Util.SafeSetFailure(promise, ThrowHelper.GetClosedChannelException(), Logger); return; } bool firstRegistration = this.neverRegistered; @@ -479,7 +479,7 @@ public Task CloseAsync() /*CancellationToken cancellationToken) */ { this.AssertEventLoop(); - return this.CloseAsync(new ClosedChannelException(), false); + return this.CloseAsync(ThrowHelper.GetClosedChannelException(), false); } protected Task CloseAsync(Exception cause, bool notify) @@ -528,7 +528,7 @@ protected Task CloseAsync(Exception cause, bool notify) { // Fail all the queued messages outboundBuffer.FailFlushed(cause, notify); - outboundBuffer.Close(new ClosedChannelException()); + outboundBuffer.Close(ThrowHelper.GetClosedChannelException()); this.FireChannelInactiveAndDeregister(wasActive); }); } @@ -545,7 +545,7 @@ protected Task CloseAsync(Exception cause, bool notify) { // Fail all the queued messages. outboundBuffer.FailFlushed(cause, notify); - outboundBuffer.Close(new ClosedChannelException()); + outboundBuffer.Close(ThrowHelper.GetClosedChannelException()); } if (this.inFlush0) { @@ -587,7 +587,7 @@ public void CloseForcibly() } catch (Exception e) { - Logger.Warn("Failed to close a channel.", e); + if (Logger.WarnEnabled) Logger.FailedToCloseAChannel(e); } } @@ -636,7 +636,7 @@ Task DeregisterAsync(bool fireChannelInactive) } catch (Exception t) { - Logger.Warn("Unexpected exception occurred while deregistering a channel.", t); + if (Logger.WarnEnabled) Logger.UnexpectedExceptionOccurredWhileDeregisteringChannel(t); } finally { @@ -694,7 +694,7 @@ public Task WriteAsync(object msg) // release message now to prevent resource-leak ReferenceCountUtil.Release(msg); - return TaskUtil.FromException(new ClosedChannelException()); + return TaskUtil.FromException(ThrowHelper.GetClosedChannelException()); } int size; @@ -761,7 +761,7 @@ protected virtual void Flush0() else { // Do not trigger channelWritabilityChanged because the channel is closed already. - outboundBuffer.FailFlushed(new ClosedChannelException(), false); + outboundBuffer.FailFlushed(ThrowHelper.GetClosedChannelException(), false); } } finally @@ -777,7 +777,7 @@ protected virtual void Flush0() } catch (Exception ex) { - Util.CompleteChannelCloseTaskSafely(this.channel, this.CloseAsync(new ClosedChannelException("Failed to write", ex), false)); + Util.CompleteChannelCloseTaskSafely(this.channel, this.CloseAsync(ThrowHelper.GetClosedChannelException_FailedToWrite(ex), false)); } finally { @@ -794,11 +794,11 @@ protected bool EnsureOpen(TaskCompletionSource promise) return true; } - Util.SafeSetFailure(promise, new ClosedChannelException(), Logger); + Util.SafeSetFailure(promise, ThrowHelper.GetClosedChannelException(), Logger); return false; } - protected Task CreateClosedChannelExceptionTask() => TaskUtil.FromException(new ClosedChannelException()); + protected Task CreateClosedChannelExceptionTask() => ThrowHelper.ThrowClosedChannelException(); protected void CloseIfClosed() { @@ -828,7 +828,7 @@ void InvokeLater(Action task) } catch (RejectedExecutionException e) { - Logger.Warn("Can't invoke task later as EventLoop rejected it", e); + if (Logger.WarnEnabled) Logger.CannotInvokeTaskLaterAsEventLoopRejectedIt(e); } } diff --git a/src/DotNetty.Transport/Channels/AbstractChannelHandlerContext.cs b/src/DotNetty.Transport/Channels/AbstractChannelHandlerContext.cs index db54dab45..91b38e85e 100644 --- a/src/DotNetty.Transport/Channels/AbstractChannelHandlerContext.cs +++ b/src/DotNetty.Transport/Channels/AbstractChannelHandlerContext.cs @@ -420,10 +420,11 @@ internal static void InvokeExceptionCaught(AbstractChannelHandlerContext next, E } catch (Exception t) { - if (DefaultChannelPipeline.Logger.WarnEnabled) + var logger = DefaultChannelPipeline.Logger; + if (logger.WarnEnabled) { - DefaultChannelPipeline.Logger.Warn("Failed to submit an ExceptionCaught() event.", t); - DefaultChannelPipeline.Logger.Warn("The ExceptionCaught() event that was failed to submit was:", cause); + logger.FailedToSubmitAnExceptionCaughtEvent(t); + logger.TheExceptionCaughtEventThatWasFailedToSubmit(cause); } } } @@ -439,12 +440,11 @@ void InvokeExceptionCaught(Exception cause) } catch (Exception t) { - if (DefaultChannelPipeline.Logger.WarnEnabled) + var logger = DefaultChannelPipeline.Logger; + if (logger.WarnEnabled) { - DefaultChannelPipeline.Logger.Warn("Failed to submit an ExceptionCaught() event.", t); - DefaultChannelPipeline.Logger.Warn( - "An exception was thrown by a user handler's " + - "ExceptionCaught() method while handling the following exception:", cause); + logger.FailedToSubmitAnExceptionCaughtEvent(t); + logger.ExceptionCaughtMethodWhileHandlingTheFollowingException(cause); } } } @@ -898,11 +898,10 @@ void NotifyHandlerException(Exception cause) { if (InExceptionCaught(cause)) { - if (DefaultChannelPipeline.Logger.WarnEnabled) + var logger = DefaultChannelPipeline.Logger; + if (logger.WarnEnabled) { - DefaultChannelPipeline.Logger.Warn( - "An exception was thrown by a user handler " + - "while handling an exceptionCaught event", cause); + logger.ThrowByAUserHandlerWhileHandlingAnExceptionCaughtEvent(cause); } return; } diff --git a/src/DotNetty.Transport/Channels/ChannelHandlerAdapter.cs b/src/DotNetty.Transport/Channels/ChannelHandlerAdapter.cs index 243dfb657..ce3539780 100644 --- a/src/DotNetty.Transport/Channels/ChannelHandlerAdapter.cs +++ b/src/DotNetty.Transport/Channels/ChannelHandlerAdapter.cs @@ -79,7 +79,7 @@ protected void EnsureNotSharable() { if (this.IsSharable) { - throw new InvalidOperationException($"ChannelHandler {StringUtil.SimpleClassName(this)} is not allowed to be shared"); + ThrowHelper.ThrowInvalidOperationException_EnsureNotSharable(this); } } } diff --git a/src/DotNetty.Transport/Channels/ChannelInitializer.cs b/src/DotNetty.Transport/Channels/ChannelInitializer.cs index 8a96680b6..eeee879e4 100644 --- a/src/DotNetty.Transport/Channels/ChannelInitializer.cs +++ b/src/DotNetty.Transport/Channels/ChannelInitializer.cs @@ -63,7 +63,7 @@ public sealed override void ChannelRegistered(IChannelHandlerContext ctx) public override void ExceptionCaught(IChannelHandlerContext ctx, Exception cause) { - Logger.Warn("Failed to initialize a channel. Closing: " + ctx.Channel, cause); + if (Logger.WarnEnabled) Logger.FailedToInitializeAChannel(ctx, cause); ctx.CloseAsync(); } diff --git a/src/DotNetty.Transport/Channels/ChannelOutboundBuffer.cs b/src/DotNetty.Transport/Channels/ChannelOutboundBuffer.cs index b10f96e32..97ac1421b 100644 --- a/src/DotNetty.Transport/Channels/ChannelOutboundBuffer.cs +++ b/src/DotNetty.Transport/Channels/ChannelOutboundBuffer.cs @@ -598,7 +598,7 @@ public void FailFlushed(Exception cause, bool notify) try { this.inFail = true; - for (;;) + while(true) { if (!this.Remove0(cause, notify)) { diff --git a/src/DotNetty.Transport/Channels/CombinedChannelDuplexHandler.cs b/src/DotNetty.Transport/Channels/CombinedChannelDuplexHandler.cs index 0f5dce1a9..000ae40e5 100644 --- a/src/DotNetty.Transport/Channels/CombinedChannelDuplexHandler.cs +++ b/src/DotNetty.Transport/Channels/CombinedChannelDuplexHandler.cs @@ -6,6 +6,7 @@ namespace DotNetty.Transport.Channels using System; using System.Diagnostics.Contracts; using System.Net; + using System.Runtime.CompilerServices; using System.Threading.Tasks; using DotNetty.Buffers; using DotNetty.Common.Concurrency; @@ -52,25 +53,26 @@ void Validate(TIn inbound, TOut outbound) { if (this.InboundHandler != null) { - throw new InvalidOperationException($"init() can not be invoked if {StringUtil.SimpleClassName(this)} was constructed with non-default constructor."); + ThrowHelper.ThrowInvalidOperationException_InitCannoBeInvokedIf(this); } if (inbound == null) { - throw new ArgumentNullException(nameof(inbound)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.inbound); } if (outbound == null) { - throw new ArgumentNullException(nameof(outbound)); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.outbound); } } + [MethodImpl(InlineMethod.Value)] void CheckAdded() { if (!this.handlerAdded) { - throw new InvalidOperationException("handler not added to pipeline yet"); + ThrowHelper.ThrowInvalidOperationException_HandlerNotAddedToPipeYet(); } } @@ -90,7 +92,7 @@ public override void HandlerAdded(IChannelHandlerContext context) { if (this.InboundHandler == null) { - throw new InvalidOperationException($"Init() must be invoked before being added to a {nameof(IChannelPipeline)} if {StringUtil.SimpleClassName(this)} was constructed with the default constructor."); + ThrowHelper.ThrowInvalidOperationException_InitMustBeInvokedBefore(this); } this.outboundCtx = new DelegatingChannelHandlerContext(context, this.OutboundHandler); @@ -105,15 +107,11 @@ public override void HandlerAdded(IChannelHandlerContext context) { if (Logger.DebugEnabled) { - Logger.Debug("An exception {}" - + "was thrown by a user handler's exceptionCaught() " - + "method while handling the following exception:", error, cause); + Logger.FreedThreadLocalBufferFromThreadFull(error, cause); } else if (Logger.WarnEnabled) { - Logger.Warn("An exception '{}' [enable DEBUG level for full stacktrace] " - + "was thrown by a user handler's exceptionCaught() " - + "method while handling the following exception:", error, cause); + Logger.FreedThreadLocalBufferFromThread(error, cause); } } }); diff --git a/src/DotNetty.Transport/Channels/DefaultChannelPipeline.cs b/src/DotNetty.Transport/Channels/DefaultChannelPipeline.cs index 290840d49..4a7a3649d 100644 --- a/src/DotNetty.Transport/Channels/DefaultChannelPipeline.cs +++ b/src/DotNetty.Transport/Channels/DefaultChannelPipeline.cs @@ -534,17 +534,17 @@ void CallHandlerAdded0(AbstractChannelHandlerContext ctx) { if (Logger.WarnEnabled) { - Logger.Warn($"Failed to remove a handler: {ctx.Name}", ex2); + Logger.FailedToRemoveAHandler(ctx, ex2); } } if (removed) { - this.FireExceptionCaught(new ChannelPipelineException($"{ctx.Handler.GetType().Name}.HandlerAdded() has thrown an exception; removed.", ex)); + this.FireExceptionCaught(ThrowHelper.GetChannelPipelineException_HandlerAddedThrowRemovedExc(ctx, ex)); } else { - this.FireExceptionCaught(new ChannelPipelineException($"{ctx.Handler.GetType().Name}.HandlerAdded() has thrown an exception; also failed to remove.", ex)); + this.FireExceptionCaught(ThrowHelper.GetChannelPipelineException_HandlerAddedThrowAlsoFailedToRemovedExc(ctx, ex)); } } } @@ -565,7 +565,7 @@ void CallHandlerRemoved0(AbstractChannelHandlerContext ctx) } catch (Exception ex) { - this.FireExceptionCaught(new ChannelPipelineException($"{ctx.Handler.GetType().Name}.HandlerRemoved() has thrown an exception.", ex)); + this.FireExceptionCaught(ThrowHelper.GetChannelPipelineException_HandlerRemovedThrowExc(ctx, ex)); } } @@ -952,9 +952,7 @@ protected virtual void OnUnhandledInboundException(Exception cause) { try { - Logger.Warn("An ExceptionCaught() event was fired, and it reached at the tail of the pipeline. " + - "It usually means the last handler in the pipeline did not handle the exception.", - cause); + Logger.AnExceptionCaughtEventWasFired(cause); } finally { @@ -971,9 +969,7 @@ protected virtual void OnUnhandledInboundMessage(object msg) { try { - if(Logger.DebugEnabled) Logger.Debug("Discarded inbound message {} that reached at the tail of the pipeline. " + - "Please check your pipeline configuration.", - msg); + if(Logger.DebugEnabled) Logger.DiscardedInboundMessage(msg); } finally { @@ -1207,9 +1203,7 @@ internal override void Execute() { if (Logger.WarnEnabled) { - Logger.Warn( - "Can't invoke HandlerAdded() as the IEventExecutor {} rejected it, removing handler {}.", - executor, this.Ctx.Name, e); + Logger.CannotInvokeHandlerAddedAsTheIEventExecutorRejectedIt(executor, this.Ctx, e); } Remove0(this.Ctx); this.Ctx.SetRemoved(); @@ -1244,9 +1238,7 @@ internal override void Execute() { if (Logger.WarnEnabled) { - Logger.Warn( - "Can't invoke HandlerRemoved() as the IEventExecutor {} rejected it," + - " removing handler {}.", executor, this.Ctx.Name, e); + Logger.CannotInvokeHandlerRemovedAsTheIEventExecutorRejectedIt(executor, this.Ctx, e); } // remove0(...) was call before so just call AbstractChannelHandlerContext.setRemoved(). this.Ctx.SetRemoved(); diff --git a/src/DotNetty.Transport/Channels/DefaultFileRegion.cs b/src/DotNetty.Transport/Channels/DefaultFileRegion.cs index 15732a136..a1cdfe631 100644 --- a/src/DotNetty.Transport/Channels/DefaultFileRegion.cs +++ b/src/DotNetty.Transport/Channels/DefaultFileRegion.cs @@ -81,7 +81,7 @@ protected override void Deallocate() { if (Logger.WarnEnabled) { - Logger.Warn("Failed to close a file stream.", exception); + Logger.FailedToCloseAFileStream(exception); } } } diff --git a/src/DotNetty.Transport/Channels/Embedded/EmbeddedChannel.cs b/src/DotNetty.Transport/Channels/Embedded/EmbeddedChannel.cs index 6027878b5..9364d32f3 100644 --- a/src/DotNetty.Transport/Channels/Embedded/EmbeddedChannel.cs +++ b/src/DotNetty.Transport/Channels/Embedded/EmbeddedChannel.cs @@ -194,7 +194,7 @@ protected override void DoBeginRead() protected override void DoWrite(ChannelOutboundBuffer input) { - for (;;) + while(true) { object msg = input.Current; if (msg == null) @@ -407,7 +407,7 @@ static bool ReleaseAll(Queue queue) { if (queue != null && queue.Count > 0) { - for (;;) + while(true) { if (queue.Count == 0) { @@ -478,7 +478,7 @@ protected void EnsureOpen() { if (!this.Open) { - this.RecordException(new ClosedChannelException()); + this.RecordException(ThrowHelper.GetClosedChannelException()); this.CheckException(); } } diff --git a/src/DotNetty.Transport/Channels/Embedded/EmbeddedEventLoop.cs b/src/DotNetty.Transport/Channels/Embedded/EmbeddedEventLoop.cs index f604acb23..0d410805c 100644 --- a/src/DotNetty.Transport/Channels/Embedded/EmbeddedEventLoop.cs +++ b/src/DotNetty.Transport/Channels/Embedded/EmbeddedEventLoop.cs @@ -37,7 +37,7 @@ public override void Execute(IRunnable command) { if (command == null) { - throw new NullReferenceException("command"); + ThrowHelper.ThrowNullReferenceException_Command(); } this.tasks.Enqueue(command); } @@ -51,7 +51,7 @@ public override Task ShutdownGracefullyAsync(TimeSpan quietPeriod, TimeSpan time internal void RunTasks() { - for (;;) + while(true) { // have to perform an additional check since Queue throws upon empty dequeue in .NET if (this.tasks.Count == 0) @@ -70,7 +70,7 @@ internal void RunTasks() internal PreciseTimeSpan RunScheduledTasks() { PreciseTimeSpan time = GetNanos(); - for (;;) + while(true) { IRunnable task = this.PollScheduledTask(time); if (task == null) diff --git a/src/DotNetty.Transport/Channels/Groups/CombinedEnumerator.cs b/src/DotNetty.Transport/Channels/Groups/CombinedEnumerator.cs index 4d90a6841..4d6f335d9 100644 --- a/src/DotNetty.Transport/Channels/Groups/CombinedEnumerator.cs +++ b/src/DotNetty.Transport/Channels/Groups/CombinedEnumerator.cs @@ -30,7 +30,7 @@ public CombinedEnumerator(IEnumerator e1, IEnumerator e2) public bool MoveNext() { - for (;;) + while(true) { if (this.currentEnumerator.MoveNext()) { diff --git a/src/DotNetty.Transport/Channels/Local/LocalAddress.cs b/src/DotNetty.Transport/Channels/Local/LocalAddress.cs index 47254fb04..1cbadde7b 100644 --- a/src/DotNetty.Transport/Channels/Local/LocalAddress.cs +++ b/src/DotNetty.Transport/Channels/Local/LocalAddress.cs @@ -30,7 +30,7 @@ public LocalAddress(string id) { if (string.IsNullOrWhiteSpace(id)) { - throw new ArgumentException("id"); + ThrowHelper.ThrowArgumentNullException(ExceptionArgument.id); } this.id = id.Trim().ToLowerInvariant(); this.strVal = $"local: {this.id}"; diff --git a/src/DotNetty.Transport/Channels/Local/LocalChannel.cs b/src/DotNetty.Transport/Channels/Local/LocalChannel.cs index 18bb8ccd1..b29cc6ffb 100644 --- a/src/DotNetty.Transport/Channels/Local/LocalChannel.cs +++ b/src/DotNetty.Transport/Channels/Local/LocalChannel.cs @@ -31,7 +31,7 @@ enum State //static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance(); static readonly ChannelMetadata METADATA = new ChannelMetadata(false); static readonly int MAX_READER_STACK_DEPTH = 8; - static readonly ClosedChannelException DoWriteClosedChannelException = new ClosedChannelException(); + internal static readonly ClosedChannelException DoWriteClosedChannelException = new ClosedChannelException(); static readonly ClosedChannelException DoCloseClosedChannelException = new ClosedChannelException(); readonly IQueue inboundBuffer = PlatformDependent.NewMpscQueue(); @@ -96,7 +96,7 @@ internal LocalChannel(LocalServerChannel parent, LocalChannel peer) void InternalRead() { IChannelPipeline pipeline = this.Pipeline; - for (;;) + while(true) { if (!this.inboundBuffer.TryDequeue(out object m)) { @@ -284,7 +284,7 @@ protected override void DoBeginRead() try { - for (;;) + while(true) { if (!inboundBuffer.TryDequeue(out object received)) { @@ -322,9 +322,9 @@ protected override void DoWrite(ChannelOutboundBuffer buffer) { case State.Open: case State.Bound: - throw new NotYetConnectedException(); + ThrowHelper.ThrowNotYetConnectedException(); break; case State.Closed: - throw DoWriteClosedChannelException; + ThrowHelper.ThrowDoWriteClosedChannelException(); break; case State.Connected: break; } @@ -334,7 +334,7 @@ protected override void DoWrite(ChannelOutboundBuffer buffer) this.writeInProgress = true; try { - for (;;) + while(true) { object msg = buffer.Current; if (msg == null) @@ -481,7 +481,7 @@ public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress) if (this.channel.connectPromise != null) { - throw new ConnectionPendingException(); + ThrowHelper.ThrowConnectionPendingException(); } this.channel.connectPromise = promise; diff --git a/src/DotNetty.Transport/Channels/Local/LocalChannelRegistry.cs b/src/DotNetty.Transport/Channels/Local/LocalChannelRegistry.cs index 6a2b8ff08..0d12acd37 100644 --- a/src/DotNetty.Transport/Channels/Local/LocalChannelRegistry.cs +++ b/src/DotNetty.Transport/Channels/Local/LocalChannelRegistry.cs @@ -15,15 +15,15 @@ internal static LocalAddress Register(IChannel channel, LocalAddress oldLocalAdd { if (oldLocalAddress != null) { - throw new ChannelException("already bound"); + ThrowHelper.ThrowChannelException_AlreadyBound(); } - - if (!(localAddress is LocalAddress)) + + var addr = localAddress as LocalAddress; + if (null == addr) { - throw new ChannelException($"unsupported address type: {localAddress.GetType()}"); + ThrowHelper.ThrowChannelException_UnsupportedAddrType(localAddress); } - var addr = (LocalAddress) localAddress; if (LocalAddress.Any.Equals(addr)) { addr = new LocalAddress(channel); @@ -32,7 +32,7 @@ internal static LocalAddress Register(IChannel channel, LocalAddress oldLocalAdd var result = BoundChannels.GetOrAdd(addr, channel); if (!ReferenceEquals(result, channel)) { - throw new ChannelException($"address already in use by: {result}"); + ThrowHelper.ThrowChannelException_AddrAlreadyInUseBy(result); } return addr; diff --git a/src/DotNetty.Transport/Channels/Local/LocalServerChannel.cs b/src/DotNetty.Transport/Channels/Local/LocalServerChannel.cs index 1a5a4abfa..f8d301573 100644 --- a/src/DotNetty.Transport/Channels/Local/LocalServerChannel.cs +++ b/src/DotNetty.Transport/Channels/Local/LocalServerChannel.cs @@ -85,7 +85,7 @@ protected override void DoBeginRead() } IChannelPipeline pipeline = this.Pipeline; - for (; ; ) + while (true) { if (!inboundBuffer.TryDequeue(out object m)) { diff --git a/src/DotNetty.Transport/Channels/Pool/FixedChannelPool.cs b/src/DotNetty.Transport/Channels/Pool/FixedChannelPool.cs index ccc2cbddb..33c4d0dd8 100644 --- a/src/DotNetty.Transport/Channels/Pool/FixedChannelPool.cs +++ b/src/DotNetty.Transport/Channels/Pool/FixedChannelPool.cs @@ -22,13 +22,13 @@ namespace DotNetty.Transport.Channels.Pool /// public class FixedChannelPool : SimpleChannelPool { - static readonly InvalidOperationException FullException = new InvalidOperationException("Too many outstanding acquire operations"); + internal static readonly InvalidOperationException FullException = new InvalidOperationException("Too many outstanding acquire operations"); static readonly TimeoutException TimeoutException = new TimeoutException("Acquire operation took longer then configured maximum time"); internal static readonly InvalidOperationException PoolClosedOnReleaseException = new InvalidOperationException("FixedChannelPooled was closed"); - static readonly InvalidOperationException PoolClosedOnAcquireException = new InvalidOperationException("FixedChannelPooled was closed"); + internal static readonly InvalidOperationException PoolClosedOnAcquireException = new InvalidOperationException("FixedChannelPooled was closed"); public enum AcquireTimeoutAction { @@ -176,11 +176,11 @@ public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChann { if (maxConnections < 1) { - throw new ArgumentException($"maxConnections: {maxConnections} (expected: >= 1)"); + ThrowHelper.ThrowArgumentException_MaxConnections(maxConnections); } if (maxPendingAcquires < 1) { - throw new ArgumentException($"maxPendingAcquires: {maxPendingAcquires} (expected: >= 1)"); + ThrowHelper.ThrowArgumentException_MaxPendingAcquires(maxPendingAcquires); } this.acquireTimeout = acquireTimeout; @@ -190,11 +190,11 @@ public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChann } else if (action == AcquireTimeoutAction.None && acquireTimeout != TimeoutShim.InfiniteTimeSpan) { - throw new ArgumentException("action"); + ThrowHelper.ThrowArgumentException_Action(); } else if (action != AcquireTimeoutAction.None && acquireTimeout < TimeSpan.Zero) { - throw new ArgumentException($"acquireTimeoutMillis: {acquireTimeout} (expected: >= 1)"); + ThrowHelper.ThrowArgumentException_AcquireTimeoutMillis(acquireTimeout); } else { @@ -207,7 +207,7 @@ public FixedChannelPool(Bootstrap bootstrap, IChannelPoolHandler handler, IChann this.timeoutTask = new TimeoutTask(this, this.OnTimeoutNew); break; default: - throw new ArgumentException("action"); + ThrowHelper.ThrowArgumentException_Action(); break; } } @@ -248,7 +248,7 @@ ValueTask DoAcquireAsync(TaskCompletionSource promise) if (this.closed) { - throw PoolClosedOnAcquireException; + ThrowHelper.ThrowInvalidOperationException_PoolClosedOnAcquireException(); } if (this.acquiredChannelCount < this.maxConnections) @@ -260,7 +260,7 @@ ValueTask DoAcquireAsync(TaskCompletionSource promise) { if (this.pendingAcquireCount >= this.maxPendingAcquires) { - throw FullException; + ThrowHelper.ThrowInvalidOperationException_TooManyOutstandingAcquireOperations(); return default; } else { @@ -277,7 +277,7 @@ ValueTask DoAcquireAsync(TaskCompletionSource promise) } else { - throw FullException; + ThrowHelper.ThrowInvalidOperationException_TooManyOutstandingAcquireOperations(); } return new ValueTask(promise.Task); @@ -345,7 +345,7 @@ void FailIfClosed(IChannel ch) if (this.closed) { ch.CloseAsync(); - throw PoolClosedOnReleaseException; + ThrowHelper.ThrowInvalidOperationException_PoolClosedOnReleaseException(); } } } @@ -401,7 +401,7 @@ void Close() while(this.pendingAcquireQueue.TryDequeue(out AcquireTask task)) { task.TimeoutTask?.Cancel(); - task.Promise.TrySetException(new ClosedChannelException()); + task.Promise.TrySetException(ThrowHelper.GetClosedChannelException()); } this.acquiredChannelCount = 0; @@ -474,7 +474,7 @@ public ValueTask AcquireAsync() } else { - throw PoolClosedOnAcquireException; + ThrowHelper.ThrowInvalidOperationException_PoolClosedOnAcquireException(); } } diff --git a/src/DotNetty.Transport/Channels/Pool/SimpleChannelPool.cs b/src/DotNetty.Transport/Channels/Pool/SimpleChannelPool.cs index 2e39b7a65..6697e5990 100644 --- a/src/DotNetty.Transport/Channels/Pool/SimpleChannelPool.cs +++ b/src/DotNetty.Transport/Channels/Pool/SimpleChannelPool.cs @@ -22,7 +22,7 @@ public class SimpleChannelPool : IChannelPool { public static readonly AttributeKey PoolKey = AttributeKey.NewInstance("channelPool"); - static readonly InvalidOperationException FullException = new InvalidOperationException("ChannelPool full"); + //static readonly InvalidOperationException FullException = new InvalidOperationException("ChannelPool full"); readonly IQueue store; @@ -263,7 +263,7 @@ async ValueTask DoReleaseChannel(IChannel channel) { CloseChannel(channel); // Better include a stacktrace here as this is an user error. - throw new ArgumentException($"Channel {channel} was not acquired from this ChannelPool"); + return ThrowHelper.ThrowArgumentException_ChannelWasNotAcquiredFromPool(channel); } else { @@ -320,7 +320,7 @@ void ReleaseAndOffer(IChannel channel) else { CloseChannel(channel); - throw FullException; + ThrowHelper.ThrowInvalidOperationException_ChannelPoolFull(); } } diff --git a/src/DotNetty.Transport/Channels/Sockets/AbstractSocketByteChannel.cs b/src/DotNetty.Transport/Channels/Sockets/AbstractSocketByteChannel.cs index e27e1ae9a..9fac36e65 100644 --- a/src/DotNetty.Transport/Channels/Sockets/AbstractSocketByteChannel.cs +++ b/src/DotNetty.Transport/Channels/Sockets/AbstractSocketByteChannel.cs @@ -276,7 +276,7 @@ protected override void DoWrite(ChannelOutboundBuffer input) else { // Should not reach here. - throw new InvalidOperationException(); + ThrowHelper.ThrowInvalidOperationException(); } } } @@ -299,8 +299,7 @@ protected override object FilterOutboundMessage(object msg) // return msg; //} - throw new NotSupportedException( - "unsupported message type: " + msg.GetType().Name + ExpectedTypes); + return ThrowHelper.ThrowNotSupportedException_UnsupportedMsgType(msg); } protected bool IncompleteWrite(bool scheduleAsync, SocketChannelAsyncOperation operation) diff --git a/src/DotNetty.Transport/Channels/Sockets/AbstractSocketChannel.cs b/src/DotNetty.Transport/Channels/Sockets/AbstractSocketChannel.cs index ffc590f77..e522e68fd 100644 --- a/src/DotNetty.Transport/Channels/Sockets/AbstractSocketChannel.cs +++ b/src/DotNetty.Transport/Channels/Sockets/AbstractSocketChannel.cs @@ -64,11 +64,11 @@ protected AbstractSocketChannel(IChannel parent, Socket socket) { if (Logger.WarnEnabled) { - Logger.Warn("Failed to close a partially initialized socket.", ex2); + Logger.FailedToCloseAPartiallyInitializedSocket(ex2); } } - throw new ChannelException("Failed to enter non-blocking mode.", ex); + ThrowHelper.ThrowChannelException_FailedToEnterNonBlockingMode(ex); } } @@ -221,7 +221,7 @@ static void OnIoCompleted(object sender, SocketAsyncEventArgs args) break; default: // todo: think of a better way to comm exception - throw new ArgumentException("The last operation completed on the socket was not expected"); + ThrowHelper.ThrowArgumentException_TheLastOpCompleted(); break; } } @@ -263,7 +263,7 @@ public sealed override Task ConnectAsync(EndPoint remoteAddress, EndPoint localA { if (ch.connectPromise != null) { - throw new InvalidOperationException("connection attempt already made"); + ThrowHelper.ThrowInvalidOperationException_ConnAttemptAlreadyMade(); } bool wasActive = this.channel.Active; @@ -430,7 +430,7 @@ public void FinishWrite(SocketChannelAsyncOperation operation } catch (Exception ex) { - Util.CompleteChannelCloseTaskSafely(this.channel, this.CloseAsync(new ClosedChannelException("Failed to write", ex), false)); + Util.CompleteChannelCloseTaskSafely(this.channel, this.CloseAsync(ThrowHelper.GetClosedChannelException_FailedToWrite(ex), false)); } // Double check if there's no pending flush @@ -482,7 +482,7 @@ protected override void DoClose() if (promise != null) { // Use TrySetException() instead of SetException() to avoid the race against cancellation due to timeout. - promise.TrySetException(new ClosedChannelException()); + promise.TrySetException(ThrowHelper.GetClosedChannelException()); this.connectPromise = null; } diff --git a/src/DotNetty.Transport/Channels/Sockets/DefaultSocketChannelConfiguration.cs b/src/DotNetty.Transport/Channels/Sockets/DefaultSocketChannelConfiguration.cs index 3b43a0c19..ab99f5ee0 100644 --- a/src/DotNetty.Transport/Channels/Sockets/DefaultSocketChannelConfiguration.cs +++ b/src/DotNetty.Transport/Channels/Sockets/DefaultSocketChannelConfiguration.cs @@ -133,11 +133,11 @@ public int ReceiveBufferSize } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Int(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Int(ex); } } set @@ -148,11 +148,11 @@ public int ReceiveBufferSize } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } } } @@ -167,11 +167,11 @@ public virtual int SendBufferSize } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Int(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Int(ex); } } set @@ -182,11 +182,11 @@ public virtual int SendBufferSize } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } } } @@ -202,11 +202,11 @@ public int Linger } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Int(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Int(ex); } } set @@ -231,11 +231,11 @@ public int Linger } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } } } @@ -250,11 +250,11 @@ public bool KeepAlive } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Bool(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Bool(ex); } } set @@ -265,11 +265,11 @@ public bool KeepAlive } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } } } @@ -284,11 +284,11 @@ public bool ReuseAddress } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Bool(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Bool(ex); } } set @@ -299,11 +299,11 @@ public bool ReuseAddress } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } } } @@ -318,11 +318,11 @@ public bool TcpNoDelay } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Bool(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + return ThrowHelper.ThrowChannelException_Get_Bool(ex); } } set @@ -333,11 +333,11 @@ public bool TcpNoDelay } catch (ObjectDisposedException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } catch (SocketException ex) { - throw new ChannelException(ex); + ThrowHelper.ThrowChannelException_Set(ex); } } } diff --git a/src/DotNetty.Transport/Channels/Sockets/SocketChannelAsyncOperation.cs b/src/DotNetty.Transport/Channels/Sockets/SocketChannelAsyncOperation.cs index a1b6c480e..834343b3d 100644 --- a/src/DotNetty.Transport/Channels/Sockets/SocketChannelAsyncOperation.cs +++ b/src/DotNetty.Transport/Channels/Sockets/SocketChannelAsyncOperation.cs @@ -33,7 +33,7 @@ public void Validate() SocketError socketError = this.SocketError; if (socketError != SocketError.Success) { - throw new SocketException((int)socketError); + ThrowHelper.ThrowSocketException(socketError); } } diff --git a/src/DotNetty.Transport/Channels/Sockets/TcpServerSocketChannel.cs b/src/DotNetty.Transport/Channels/Sockets/TcpServerSocketChannel.cs index 07503c5f4..0106a7012 100644 --- a/src/DotNetty.Transport/Channels/Sockets/TcpServerSocketChannel.cs +++ b/src/DotNetty.Transport/Channels/Sockets/TcpServerSocketChannel.cs @@ -108,7 +108,7 @@ protected override void ScheduleSocketRead() { // socket exceptions here are internal to channel's operation and should not go through the pipeline // especially as they have no effect on overall channel's operation - Logger.Info("Exception on accept.", ex); + if (Logger.InfoEnabled) Logger.ExceptionOnAccept(ex); } catch (ObjectDisposedException) { @@ -224,7 +224,7 @@ public override void FinishRead(SocketChannelAsyncOperation 0) @@ -288,7 +288,7 @@ protected override void DoWrite(ChannelOutboundBuffer input) long localWrittenBytes = socket.Send(bufferList, SocketFlags.None, out SocketError errorCode); if (errorCode != SocketError.Success && errorCode != SocketError.WouldBlock) { - throw new SocketException((int)errorCode); + ThrowHelper.ThrowSocketException(errorCode); } if (localWrittenBytes == 0) diff --git a/src/DotNetty.Transport/Channels/Util.cs b/src/DotNetty.Transport/Channels/Util.cs index 105860e87..602462c07 100644 --- a/src/DotNetty.Transport/Channels/Util.cs +++ b/src/DotNetty.Transport/Channels/Util.cs @@ -22,7 +22,7 @@ public static void SafeSetSuccess(TaskCompletionSource promise, IInternalLogger { if (promise != TaskCompletionSource.Void && !promise.TryComplete()) { - logger.Warn($"Failed to mark a promise as success because it is done already: {promise}"); + if (logger.WarnEnabled) logger.FailedToMarkAPromiseAsSuccess(promise); } } @@ -37,7 +37,7 @@ public static void SafeSetFailure(TaskCompletionSource promise, Exception cause, { if (promise != TaskCompletionSource.Void && !promise.TrySetException(cause)) { - logger.Warn($"Failed to mark a promise as failure because it's done already: {promise}", cause); + if (logger.WarnEnabled) logger.FailedToMarkAPromiseAsFailure(promise, cause); } } @@ -64,7 +64,7 @@ internal static async void CompleteChannelCloseTaskSafely(object channelObject, { if (Log.DebugEnabled) { - Log.Debug("Failed to close channel " + channelObject + " cleanly.", ex); + Log.FailedToCloseChannelCleanly(channelObject, ex); } } } diff --git a/src/DotNetty.Transport/Internal/LoggingExtensions.cs b/src/DotNetty.Transport/Internal/LoggingExtensions.cs new file mode 100644 index 000000000..b9816ae02 --- /dev/null +++ b/src/DotNetty.Transport/Internal/LoggingExtensions.cs @@ -0,0 +1,185 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Net.Sockets; +using System.Runtime.CompilerServices; +using DotNetty.Common.Concurrency; +using DotNetty.Common.Internal.Logging; +using DotNetty.Transport.Channels; + +namespace DotNetty.Transport +{ + internal static class TransportLoggingExtensions + { + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FreedThreadLocalBufferFromThreadFull(this IInternalLogger logger, Exception error, Exception cause) + { + logger.Debug("An exception {}" + + "was thrown by a user handler's exceptionCaught() " + + "method while handling the following exception:", error, cause); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FreedThreadLocalBufferFromThread(this IInternalLogger logger, Exception error, Exception cause) + { + logger.Warn("An exception '{}' [enable DEBUG level for full stacktrace] " + + "was thrown by a user handler's exceptionCaught() " + + "method while handling the following exception:", error, cause); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCloseChannelCleanly(this IInternalLogger logger, object channelObject, Exception ex) + { + logger.Debug("Failed to close channel " + channelObject + " cleanly.", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCloseChannel(this IInternalLogger logger, IChannel channel, Exception ex) + { + logger.Warn("Failed to close channel: " + channel, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void DiscardedInboundMessage(this IInternalLogger logger, object msg) + { + logger.Debug("Discarded inbound message {} that reached at the tail of the pipeline. " + + "Please check your pipeline configuration.", msg); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ExceptionOnAccept(this IInternalLogger logger, SocketException ex) + { + logger.Info("Exception on accept.", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ChildGroupIsNotSetUsingParentGroupInstead(this IInternalLogger logger) + { + logger.Warn("childGroup is not set. Using parentGroup instead."); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ChildGroupIsNotSetUsingParentGroupInstead(this IInternalLogger logger, IChannel child, Exception ex) + { + logger.Warn("Failed to register an accepted channel: " + child, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCloseAPartiallyInitializedSocket(this IInternalLogger logger, SocketException ex2) + { + logger.Warn("Failed to close a partially initialized socket.", ex2); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCreateANewChannelFromAcceptedSocket(this IInternalLogger logger, Exception ex) + { + logger.Warn("Failed to create a new channel from accepted socket.", ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCloseASocketCleanly(this IInternalLogger logger, Exception ex2) + { + logger.Warn("Failed to close a socket cleanly.", ex2); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCloseAChannel(this IInternalLogger logger, Exception e) + { + logger.Warn("Failed to close a channel.", e); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ForceClosingAChannel(this IInternalLogger logger, IChannel channel, Exception ex) + { + logger.Warn("Force-closing a channel whose registration task was not accepted by an event loop: {}", channel, ex); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void UnexpectedExceptionOccurredWhileDeregisteringChannel(this IInternalLogger logger, Exception t) + { + logger.Warn("Unexpected exception occurred while deregistering a channel.", t); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void CannotInvokeTaskLaterAsEventLoopRejectedIt(this IInternalLogger logger, RejectedExecutionException e) + { + logger.Warn("Can't invoke task later as EventLoop rejected it", e); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToSubmitAnExceptionCaughtEvent(this IInternalLogger logger, Exception t) + { + logger.Warn("Failed to submit an ExceptionCaught() event.", t); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void TheExceptionCaughtEventThatWasFailedToSubmit(this IInternalLogger logger, Exception cause) + { + logger.Warn("The ExceptionCaught() event that was failed to submit was:", cause); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ExceptionCaughtMethodWhileHandlingTheFollowingException(this IInternalLogger logger, Exception cause) + { + logger.Warn("An exception was thrown by a user handler's ExceptionCaught() method while handling the following exception:", cause); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowByAUserHandlerWhileHandlingAnExceptionCaughtEvent(this IInternalLogger logger, Exception cause) + { + logger.Warn("An exception was thrown by a user handler while handling an exceptionCaught event", cause); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToInitializeAChannel(this IInternalLogger logger, IChannelHandlerContext ctx, Exception cause) + { + logger.Warn("Failed to initialize a channel. Closing: " + ctx.Channel, cause); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToRemoveAHandler(this IInternalLogger logger, IChannelHandlerContext ctx, Exception ex2) + { + logger.Warn($"Failed to remove a handler: {ctx.Name}", ex2); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void AnExceptionCaughtEventWasFired(this IInternalLogger logger, Exception cause) + { + logger.Warn("An ExceptionCaught() event was fired, and it reached at the tail of the pipeline. " + + "It usually means the last handler in the pipeline did not handle the exception.", cause); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void CannotInvokeHandlerAddedAsTheIEventExecutorRejectedIt(this IInternalLogger logger, IEventExecutor executor, IChannelHandlerContext ctx, Exception e) + { + logger.Warn("Can't invoke HandlerAdded() as the IEventExecutor {} rejected it, removing handler {}.", + executor, ctx.Name, e); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void CannotInvokeHandlerRemovedAsTheIEventExecutorRejectedIt(this IInternalLogger logger, IEventExecutor executor, IChannelHandlerContext ctx, Exception e) + { + logger.Warn("Can't invoke HandlerRemoved() as the IEventExecutor {} rejected it, removing handler {}.", + executor, ctx.Name, e); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToCloseAFileStream(this IInternalLogger logger, Exception exception) + { + logger.Warn("Failed to close a file stream.", exception); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToMarkAPromiseAsSuccess(this IInternalLogger logger, TaskCompletionSource promise) + { + logger.Warn($"Failed to mark a promise as success because it is done already: {promise}"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void FailedToMarkAPromiseAsFailure(this IInternalLogger logger, TaskCompletionSource promise, Exception cause) + { + logger.Warn($"Failed to mark a promise as failure because it's done already: {promise}", cause); + } + } +} diff --git a/src/DotNetty.Transport/Internal/ThrowHelper.Extensions.cs b/src/DotNetty.Transport/Internal/ThrowHelper.Extensions.cs index b75f2a75f..8e3c58286 100644 --- a/src/DotNetty.Transport/Internal/ThrowHelper.Extensions.cs +++ b/src/DotNetty.Transport/Internal/ThrowHelper.Extensions.cs @@ -1,7 +1,15 @@ using System; +using System.Net; +using System.Net.Sockets; using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using DotNetty.Buffers; using DotNetty.Common.Utilities; using DotNetty.Transport.Channels; +#if !NET40 +using DotNetty.Transport.Channels.Local; +using DotNetty.Transport.Channels.Pool; +#endif namespace DotNetty.Transport { @@ -74,6 +82,9 @@ internal enum ExceptionArgument allocator, matchers, exceptions, + id, + inbound, + outbound, } #endregion @@ -89,6 +100,8 @@ internal enum ExceptionResource partial class ThrowHelper { + #region -- ArgumentException -- + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowArgumentException_Excs() { @@ -99,6 +112,66 @@ ArgumentException GetArgumentException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_TheLastOpCompleted() + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException("The last operation completed on the socket was not expected"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_Action() + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException("action"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static bool ThrowArgumentException_ChannelWasNotAcquiredFromPool(IChannel channel) + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException($"Channel {channel} was not acquired from this ChannelPool"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_AcquireTimeoutMillis(TimeSpan acquireTimeout) + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException($"acquireTimeoutMillis: {acquireTimeout} (expected: >= 1)"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_MaxPendingAcquires(int maxPendingAcquires) + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException($"maxPendingAcquires: {maxPendingAcquires} (expected: >= 1)"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowArgumentException_MaxConnections(int maxConnections) + { + throw GetArgumentException(); + ArgumentException GetArgumentException() + { + return new ArgumentException($"maxConnections: {maxConnections} (expected: >= 1)"); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowArgumentException_DuplicateHandler(string name) { @@ -139,6 +212,10 @@ ArgumentException GetArgumentException() } } + #endregion + + #region -- ArgumentOutOfRangeException -- + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowArgumentOutOfRangeException_Position(long pos, long count) { @@ -149,6 +226,147 @@ ArgumentOutOfRangeException GetArgumentOutOfRangeException() } } + #endregion + + #region -- InvalidOperationException -- + +#if !NET40 + static readonly InvalidOperationException s_fullException = new InvalidOperationException("ChannelPool full"); + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_ChannelPoolFull() + { + throw s_fullException; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_TooManyOutstandingAcquireOperations() + { + throw FixedChannelPool.FullException; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_PoolClosedOnReleaseException() + { + throw FixedChannelPool.PoolClosedOnReleaseException; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_PoolClosedOnAcquireException() + { + throw FixedChannelPool.PoolClosedOnAcquireException; + } +#endif + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException(); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_ChildGroupSetAlready() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("childGroup set already"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_HandlerNotSet() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("handler not set"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_RemoteAddrNotSet() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("remoteAddress not set"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_LocalAddrMustBeSetBeforehand() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("localAddress must be set beforehand."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_ChannelOrFactoryNotSet() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("channel or channelFactory not set"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_GroupNotSet() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("group not set"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_GroupHasAlreadyBeenSet() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("group has already been set."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_ChildHandlerNotYet() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("childHandler not set"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_HandlerNotAddedToPipeYet() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("handler not added to pipeline yet"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_ConnAttemptAlreadyMade() + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("connection attempt already made"); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowInvalidOperationException(Exception e) { @@ -209,6 +427,246 @@ InvalidOperationException GetInvalidOperationException() } } + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_EnsureNotSharable(object handlerAdapter) + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException($"ChannelHandler {StringUtil.SimpleClassName(handlerAdapter)} is not allowed to be shared"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_InitCannoBeInvokedIf(object msg) + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException($"init() can not be invoked if {StringUtil.SimpleClassName(msg)} was constructed with non-default constructor."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowInvalidOperationException_InitMustBeInvokedBefore(object msg) + { + throw GetInvalidOperationException(); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException($"Init() must be invoked before being added to a {nameof(IChannelPipeline)} if {StringUtil.SimpleClassName(msg)} was constructed with the default constructor."); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static Task ThrowInvalidOperationException_RegisteredToEventLoopAlready() + { + return TaskUtil.FromException(GetInvalidOperationException()); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("registered to an event loop already"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static Task ThrowInvalidOperationException_IncompatibleEventLoopType(IEventLoop eventLoop) + { + return TaskUtil.FromException(GetInvalidOperationException()); + InvalidOperationException GetInvalidOperationException() + { + return new InvalidOperationException("incompatible event loop type: " + eventLoop.GetType().Name); + } + } + + #endregion + + #region -- ChannelException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowChannelException() + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException(); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowChannelException_AlreadyBound() + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException("already bound"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowChannelException_UnsupportedAddrType(EndPoint localAddress) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException($"unsupported address type: {localAddress?.GetType()}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowChannelException_AddrAlreadyInUseBy(IChannel result) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException($"address already in use by: {result}"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowChannelException_FailedToEnterNonBlockingMode(SocketException ex) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException("Failed to enter non-blocking mode.", ex); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static bool ThrowChannelException_Get_Bool(ObjectDisposedException ex) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException(ex); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static bool ThrowChannelException_Get_Bool(SocketException ex) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException(ex); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowChannelException_Get_Int(ObjectDisposedException ex) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException(ex); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static int ThrowChannelException_Get_Int(SocketException ex) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException(ex); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowChannelException_Set(ObjectDisposedException ex) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException(ex); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowChannelException_Set(SocketException ex) + { + throw GetException(); + ChannelException GetException() + { + return new ChannelException(ex); + } + } + + #endregion + + #region -- NotSupportedException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static object ThrowNotSupportedException_UnsupportedMsgType(object msg) + { + throw GetArgumentException(); + NotSupportedException GetArgumentException() + { + return new NotSupportedException($"unsupported message type: {msg.GetType().Name} (expected: {StringUtil.SimpleClassName()})"); + } + } + + #endregion + + #region -- ClosedChannelException -- + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static Task ThrowClosedChannelException() + { + return TaskUtil.FromException(GetClosedChannelException()); + } + + public static ClosedChannelException GetClosedChannelException() + { + return new ClosedChannelException(); + } + + public static ClosedChannelException GetClosedChannelException_FailedToWrite(Exception ex) + { + return new ClosedChannelException("Failed to write", ex); + } + +#if !NET40 + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowDoWriteClosedChannelException() + { + throw LocalChannel.DoWriteClosedChannelException; + } +#endif + + #endregion + + #region -- ChannelPipelineException -- + + public static ChannelPipelineException GetChannelPipelineException_HandlerAddedThrowRemovedExc(AbstractChannelHandlerContext ctx, Exception ex) + { + return new ChannelPipelineException($"{ctx.Handler.GetType().Name}.HandlerAdded() has thrown an exception; removed.", ex); + } + + public static ChannelPipelineException GetChannelPipelineException_HandlerAddedThrowAlsoFailedToRemovedExc(AbstractChannelHandlerContext ctx, Exception ex) + { + return new ChannelPipelineException($"{ctx.Handler.GetType().Name}.HandlerAdded() has thrown an exception; also failed to remove.", ex); + } + + public static ChannelPipelineException GetChannelPipelineException_HandlerRemovedThrowExc(AbstractChannelHandlerContext ctx, Exception ex) + { + return new ChannelPipelineException($"{ctx.Handler.GetType().Name}.HandlerRemoved() has thrown an exception.", ex); + } + + #endregion + + #region -- Others -- + + // + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowNotImplementedException_OnlyIByteBufferImpl() + { + throw GetNotImplementedException(); + NotImplementedException GetNotImplementedException() + { + return new NotImplementedException("Only IByteBuffer implementations backed by array are supported."); + } + } + [MethodImpl(MethodImplOptions.NoInlining)] internal static void ThrowChannelPipelineException(ChannelHandlerAdapter h) { @@ -229,5 +687,47 @@ IllegalReferenceCountException GetInvalidOperationException() return new IllegalReferenceCountException(0); } } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowNotYetConnectedException() + { + throw GetException(); + NotYetConnectedException GetException() + { + return new NotYetConnectedException(); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowConnectionPendingException() + { + throw GetException(); + ConnectionPendingException GetException() + { + return new ConnectionPendingException(); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowSocketException(SocketError err) + { + throw GetException(); + SocketException GetException() + { + return new SocketException((int)err); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + internal static void ThrowNullReferenceException_Command() + { + throw GetException(); + NullReferenceException GetException() + { + return new NullReferenceException("command"); + } + } + + #endregion } } diff --git a/src/version.props b/src/version.props index d51594bde..27f5f81d5 100644 --- a/src/version.props +++ b/src/version.props @@ -4,7 +4,7 @@ 0.4.0.0 0.4.9 rtm - 180626-01 + 180808-01 $(VersionSuffix)-$(VersionDateSuffix)